From 52a243afcabde3ccc375aaf6e79a9f50c046f54b Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Wed, 25 Aug 2021 21:42:15 +0300 Subject: [PATCH 0001/2991] Don't select random beatmap when previous was filtered --- .../SongSelect/TestSceneBeatmapCarousel.cs | 99 +++++++++++-------- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 +- .../Carousel/CarouselGroupEagerSelect.cs | 25 ++++- 3 files changed, 82 insertions(+), 44 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 78ddfa9ed2..f42ff3811a 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -616,55 +616,72 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("Selection was remembered", () => eagerSelectedIDs.Count == 1); } - [Test] - public void TestRandomFallbackOnNonMatchingPrevious() + [TestCase(10, 1)] + [TestCase(10, 10)] + public void TestCarouselSelectsNextWhenPreviousIsFiltered(int makeThisManyGroups, int haveThisManySetsInGroup) { - List manySets = new List(); + List sets = new List(); - AddStep("populate maps", () => + for (int i = 0; i < makeThisManyGroups; i++) { - for (int i = 0; i < 10; i++) + for (int j = 0; j < haveThisManySetsInGroup; j++) { - var set = createTestBeatmapSet(i); - - foreach (var b in set.Beatmaps) + var testBeatmap = createTestBeatmapSet(i * haveThisManySetsInGroup + j + 1); + var rulesetID = i % 3; + testBeatmap.Beatmaps.ForEach(b => { - // all taiko except for first - int ruleset = i > 0 ? 1 : 0; - - b.Ruleset = rulesets.GetRuleset(ruleset); - b.RulesetID = ruleset; - } - - manySets.Add(set); + b.Ruleset = rulesets.AvailableRulesets.ElementAt(rulesetID); + b.RulesetID = rulesetID; + }); + sets.Add(testBeatmap); } - }); - - loadBeatmaps(manySets); - - for (int i = 0; i < 10; i++) - { - AddStep("Reset filter", () => carousel.Filter(new FilterCriteria(), false)); - - AddStep("select first beatmap", () => carousel.SelectBeatmap(manySets.First().Beatmaps.First())); - - AddStep("Toggle non-matching filter", () => - { - carousel.Filter(new FilterCriteria { SearchText = Guid.NewGuid().ToString() }, false); - }); - - AddAssert("selection lost", () => carousel.SelectedBeatmap == null); - - AddStep("Restore different ruleset filter", () => - { - carousel.Filter(new FilterCriteria { Ruleset = rulesets.GetRuleset(1) }, false); - eagerSelectedIDs.Add(carousel.SelectedBeatmapSet.ID); - }); - - AddAssert("selection changed", () => carousel.SelectedBeatmap != manySets.First().Beatmaps.First()); } - AddAssert("Selection was random", () => eagerSelectedIDs.Count > 2); + loadBeatmaps(sets); + setSelected(1, 1); + advanceSelection(false); + + for (int i = 1; i < makeThisManyGroups; i++) + { + var rulesetID = i % 3; + AddStep($"Toggle filter to ruleset {rulesetID}", () => + { + carousel.Filter(new FilterCriteria { Ruleset = rulesets.AvailableRulesets.ElementAt(rulesetID) }, false); + carousel.Filter(new FilterCriteria(), false); + }); + waitForSelection(i * haveThisManySetsInGroup + 1); + } + } + + [Test] + public void TestCarouselSelectsBackwardsWhenPreviousIsFilteredNearTheEnd() + { + List sets = new List(); + + for (int i = 1; i <= 40; i++) + { + var testBeatmap = createTestBeatmapSet(i); + var rulesetID = (i - 1) / 10; + testBeatmap.Beatmaps.ForEach(b => + { + b.Ruleset = rulesets.AvailableRulesets.ElementAt(rulesetID); + b.RulesetID = rulesetID; + }); + sets.Add(testBeatmap); + } + + loadBeatmaps(sets); + + for (int i = 1; i < 4; i++) + { + setSelected(i * 10 + 1, 1); + AddStep("Toggle filter to ruleset 0", () => + { + carousel.Filter(new FilterCriteria { Ruleset = rulesets.AvailableRulesets.ElementAt(0) }, false); + carousel.Filter(new FilterCriteria(), false); + }); + waitForSelection(10); + } } [Test] diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index b05b7aeb32..7c1403da82 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -911,7 +911,7 @@ namespace osu.Game.Screens.Select protected override void PerformSelection() { - if (LastSelected == null || LastSelected.Filtered.Value) + if (LastSelected == null) carousel?.SelectNextRandom(); else base.PerformSelection(); diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs index 9e8aad4b6f..79bcdbf1c1 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs @@ -101,8 +101,29 @@ namespace osu.Game.Screens.Select.Carousel protected virtual CarouselItem GetNextToSelect() { - return Children.Skip(lastSelectedIndex).FirstOrDefault(i => !i.Filtered.Value) ?? - Children.Reverse().Skip(InternalChildren.Count - lastSelectedIndex).FirstOrDefault(i => !i.Filtered.Value); + // our return value should be the item (that is not filtered and) that is nearest to the previously selected one + + // find nearest such item going forwards in selection + int forwardsDistance = 0; + var forwards = Children.Skip(lastSelectedIndex).SkipWhile((c) => + { + forwardsDistance++; + return c.Filtered.Value; + }).FirstOrDefault(); + // and backwards + int backwardsDistance = 0; + var backwards = Children.Reverse().Skip(InternalChildren.Count - lastSelectedIndex - 1).SkipWhile((c) => + { + backwardsDistance++; + return c.Filtered.Value; + }).FirstOrDefault(); + + // if only one direction had such an item, return that + if (forwards == null || backwards == null) + return forwards ?? backwards; + + // else return the closest item + return forwardsDistance < backwardsDistance ? forwards : backwards; } protected virtual void PerformSelection() From b484bd1af3ab2e49387d4eb9bb6f09b86b035cdf Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Wed, 25 Aug 2021 22:43:58 +0300 Subject: [PATCH 0002/2991] Rename parameter and remove redundant parentheses --- .../Screens/Select/Carousel/CarouselGroupEagerSelect.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs index 79bcdbf1c1..2894209206 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs @@ -105,17 +105,17 @@ namespace osu.Game.Screens.Select.Carousel // find nearest such item going forwards in selection int forwardsDistance = 0; - var forwards = Children.Skip(lastSelectedIndex).SkipWhile((c) => + var forwards = Children.Skip(lastSelectedIndex).SkipWhile(item => { forwardsDistance++; - return c.Filtered.Value; + return item.Filtered.Value; }).FirstOrDefault(); // and backwards int backwardsDistance = 0; - var backwards = Children.Reverse().Skip(InternalChildren.Count - lastSelectedIndex - 1).SkipWhile((c) => + var backwards = Children.Reverse().Skip(InternalChildren.Count - lastSelectedIndex - 1).SkipWhile(item => { backwardsDistance++; - return c.Filtered.Value; + return item.Filtered.Value; }).FirstOrDefault(); // if only one direction had such an item, return that From a8d869c31cace6e8b47bda6f972459b07af50119 Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Thu, 26 Aug 2021 18:31:19 +0300 Subject: [PATCH 0003/2991] Replace `SkipWhile()` LINQ with a while loop --- .../Carousel/CarouselGroupEagerSelect.cs | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs index 2894209206..aedeac04d3 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs @@ -99,31 +99,32 @@ namespace osu.Game.Screens.Select.Carousel PerformSelection(); } + /// + /// Finds the item this group would select next if it attempted selection + /// + /// An unfiltered item nearest to the last selected one or null if all items are filtered protected virtual CarouselItem GetNextToSelect() { - // our return value should be the item (that is not filtered and) that is nearest to the previously selected one + int forwardsIndex = lastSelectedIndex; + int backwardsIndex = lastSelectedIndex; - // find nearest such item going forwards in selection - int forwardsDistance = 0; - var forwards = Children.Skip(lastSelectedIndex).SkipWhile(item => + while (true) { - forwardsDistance++; - return item.Filtered.Value; - }).FirstOrDefault(); - // and backwards - int backwardsDistance = 0; - var backwards = Children.Reverse().Skip(InternalChildren.Count - lastSelectedIndex - 1).SkipWhile(item => - { - backwardsDistance++; - return item.Filtered.Value; - }).FirstOrDefault(); + if (forwardsIndex >= Children.Count) + return Children.Reverse().Skip(Children.Count - backwardsIndex).FirstOrDefault(item => !item.Filtered.Value); - // if only one direction had such an item, return that - if (forwards == null || backwards == null) - return forwards ?? backwards; + if (backwardsIndex < 0) + return Children.Skip(forwardsIndex).FirstOrDefault(item => !item.Filtered.Value); - // else return the closest item - return forwardsDistance < backwardsDistance ? forwards : backwards; + if (!Children[forwardsIndex].Filtered.Value) + return Children[forwardsIndex]; + + if (!Children[backwardsIndex].Filtered.Value) + return Children[backwardsIndex]; + + forwardsIndex++; + backwardsIndex--; + } } protected virtual void PerformSelection() From 8bd7837bf747600e67ffdc8f06062b847e10cd20 Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Thu, 26 Aug 2021 19:29:58 +0300 Subject: [PATCH 0004/2991] Fix off-by-one skip amount --- osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs index aedeac04d3..9793b69eca 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs @@ -111,7 +111,7 @@ namespace osu.Game.Screens.Select.Carousel while (true) { if (forwardsIndex >= Children.Count) - return Children.Reverse().Skip(Children.Count - backwardsIndex).FirstOrDefault(item => !item.Filtered.Value); + return Children.Reverse().Skip(Children.Count - backwardsIndex - 1).FirstOrDefault(item => !item.Filtered.Value); if (backwardsIndex < 0) return Children.Skip(forwardsIndex).FirstOrDefault(item => !item.Filtered.Value); From 43e8e3e9229cef1d5ac72203d8e71c0f7584c49f Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Fri, 27 Aug 2021 18:16:53 +0300 Subject: [PATCH 0005/2991] Add comments to `GetNextToSelect()` --- osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs index 9793b69eca..cdd6d48e66 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs @@ -110,18 +110,19 @@ namespace osu.Game.Screens.Select.Carousel while (true) { + // check if a direction has been exhausted and an item (or null) from the other direction should be returned if (forwardsIndex >= Children.Count) return Children.Reverse().Skip(Children.Count - backwardsIndex - 1).FirstOrDefault(item => !item.Filtered.Value); - if (backwardsIndex < 0) return Children.Skip(forwardsIndex).FirstOrDefault(item => !item.Filtered.Value); + // check if an unfiltered item has been reached if (!Children[forwardsIndex].Filtered.Value) return Children[forwardsIndex]; - if (!Children[backwardsIndex].Filtered.Value) return Children[backwardsIndex]; + // increment the indices forwardsIndex++; backwardsIndex--; } From dde0756bed9702c95c918af247e9339bc913bb48 Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Tue, 24 May 2022 10:23:44 -0400 Subject: [PATCH 0006/2991] add accuracy challenge mod --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 1 + osu.Game.Rulesets.Mania/ManiaRuleset.cs | 1 + osu.Game.Rulesets.Osu/OsuRuleset.cs | 3 +- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 1 + .../Rulesets/Mods/ModAccuracyChallenge.cs | 59 +++++++++++++++++++ .../Rulesets/Mods/ModEasyWithExtraLives.cs | 3 + osu.Game/Rulesets/Mods/ModPerfect.cs | 2 +- 7 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 80b9436b2c..bcce28adb2 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -109,6 +109,7 @@ namespace osu.Game.Rulesets.Catch new MultiMod(new CatchModDoubleTime(), new CatchModNightcore()), new CatchModHidden(), new CatchModFlashlight(), + //new ModAccuracyChallenge(), }; case ModType.Conversion: diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index bd6a67bf67..8f2d679750 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -222,6 +222,7 @@ namespace osu.Game.Rulesets.Mania new MultiMod(new ManiaModDoubleTime(), new ManiaModNightcore()), new MultiMod(new ManiaModFadeIn(), new ManiaModHidden()), new ManiaModFlashlight(), + //new ModAccuracyChallenge(), }; case ModType.Conversion: diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 207e7a4ab0..15998a48c3 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -159,7 +159,8 @@ namespace osu.Game.Rulesets.Osu new MultiMod(new OsuModDoubleTime(), new OsuModNightcore()), new OsuModHidden(), new MultiMod(new OsuModFlashlight(), new OsuModBlinds()), - new OsuModStrictTracking() + new OsuModStrictTracking(), + new ModAccuracyChallenge(), }; case ModType.Conversion: diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 615fbf093f..655aba88e3 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -128,6 +128,7 @@ namespace osu.Game.Rulesets.Taiko new MultiMod(new TaikoModDoubleTime(), new TaikoModNightcore()), new TaikoModHidden(), new TaikoModFlashlight(), + //new ModAccuracyChallenge(), }; case ModType.Conversion: diff --git a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs new file mode 100644 index 0000000000..bb7d3896b2 --- /dev/null +++ b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs @@ -0,0 +1,59 @@ +// 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.Framework.Graphics.Sprites; +using osu.Game.Configuration; +using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Settings; +using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.Judgements; + +namespace osu.Game.Rulesets.Mods +{ + public class ModAccuracyChallenge : ModFailCondition + { + public override string Name => "Accuracy Challenge"; + public override string Acronym => "AC"; + public override string Description => "Fail the map if you don't maintain a certain accuracy."; + public override IconUsage? Icon => FontAwesome.Solid.Calculator; + public override ModType Type => ModType.DifficultyIncrease; + public override double ScoreMultiplier => 1.0; + public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModEasyWithExtraLives)).Append(typeof(ModPerfect)).ToArray(); + + [SettingSource("Minimum accuracy", "Trigger a failure if your accuracy goes below this value.", SettingControlType = typeof(SettingsSlider))] + public BindableNumber MinimumAccuracy { get; } = new BindableDouble + { + MinValue = 0, + MaxValue = 1, + Precision = 0.01, + Default = 0.9, + Value = 0.9, + }; + + private double baseScore; + private double maxBaseScore; + private double accuracy => maxBaseScore > 0 ? baseScore / maxBaseScore : 1; + + protected override bool FailCondition(HealthProcessor healthProcessor, JudgementResult result) + { + if (!result.Type.IsScorable() || result.Type.IsBonus()) + return false; + + baseScore += result.Type.IsHit() ? result.Judgement.NumericResultFor(result) : 0; + maxBaseScore += result.Judgement.MaxNumericResult; + + return accuracy < MinimumAccuracy.Value; + } + } + + public class PercentSlider : OsuSliderBar + { + public PercentSlider() + { + DisplayAsPercentage = true; + } + } +} diff --git a/osu.Game/Rulesets/Mods/ModEasyWithExtraLives.cs b/osu.Game/Rulesets/Mods/ModEasyWithExtraLives.cs index 2ac0f59d84..7e6b085f8a 100644 --- a/osu.Game/Rulesets/Mods/ModEasyWithExtraLives.cs +++ b/osu.Game/Rulesets/Mods/ModEasyWithExtraLives.cs @@ -1,6 +1,8 @@ // 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 Humanizer; using osu.Framework.Bindables; using osu.Game.Beatmaps; @@ -19,6 +21,7 @@ namespace osu.Game.Rulesets.Mods }; public override string SettingDescription => Retries.IsDefault ? string.Empty : $"{"lives".ToQuantity(Retries.Value)}"; + public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModAccuracyChallenge)).ToArray(); private int retries; diff --git a/osu.Game/Rulesets/Mods/ModPerfect.cs b/osu.Game/Rulesets/Mods/ModPerfect.cs index 9016a24f8d..4c68d0d375 100644 --- a/osu.Game/Rulesets/Mods/ModPerfect.cs +++ b/osu.Game/Rulesets/Mods/ModPerfect.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mods public override double ScoreMultiplier => 1; public override string Description => "SS or quit."; - public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModSuddenDeath)).ToArray(); + public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModSuddenDeath)).Append(typeof(ModAccuracyChallenge)).ToArray(); protected ModPerfect() { From 252bacc8d4aeee7bacf96598b97a28eef7e884c7 Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Tue, 24 May 2022 10:56:31 -0400 Subject: [PATCH 0007/2991] revert more testing leftovers... --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 +- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index bcce28adb2..9ddafc9315 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -109,7 +109,7 @@ namespace osu.Game.Rulesets.Catch new MultiMod(new CatchModDoubleTime(), new CatchModNightcore()), new CatchModHidden(), new CatchModFlashlight(), - //new ModAccuracyChallenge(), + new ModAccuracyChallenge(), }; case ModType.Conversion: diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 8f2d679750..659d7f242f 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -222,7 +222,7 @@ namespace osu.Game.Rulesets.Mania new MultiMod(new ManiaModDoubleTime(), new ManiaModNightcore()), new MultiMod(new ManiaModFadeIn(), new ManiaModHidden()), new ManiaModFlashlight(), - //new ModAccuracyChallenge(), + new ModAccuracyChallenge(), }; case ModType.Conversion: diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 655aba88e3..a80c87ecd3 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -128,7 +128,7 @@ namespace osu.Game.Rulesets.Taiko new MultiMod(new TaikoModDoubleTime(), new TaikoModNightcore()), new TaikoModHidden(), new TaikoModFlashlight(), - //new ModAccuracyChallenge(), + new ModAccuracyChallenge(), }; case ModType.Conversion: From 5944a15c30abfa9dfc56b169d68955f68bd0edbb Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Tue, 24 May 2022 20:04:57 -0400 Subject: [PATCH 0008/2991] review pass eins --- osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs | 5 +++-- osu.Game/Rulesets/Mods/ModPerfect.cs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs index bb7d3896b2..804ce867af 100644 --- a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs +++ b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs @@ -21,12 +21,13 @@ namespace osu.Game.Rulesets.Mods public override IconUsage? Icon => FontAwesome.Solid.Calculator; public override ModType Type => ModType.DifficultyIncrease; public override double ScoreMultiplier => 1.0; - public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModEasyWithExtraLives)).Append(typeof(ModPerfect)).ToArray(); + public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(ModEasyWithExtraLives), typeof(ModPerfect) }).ToArray(); + public override bool RequiresConfiguration => false; [SettingSource("Minimum accuracy", "Trigger a failure if your accuracy goes below this value.", SettingControlType = typeof(SettingsSlider))] public BindableNumber MinimumAccuracy { get; } = new BindableDouble { - MinValue = 0, + MinValue = 0.01, MaxValue = 1, Precision = 0.01, Default = 0.9, diff --git a/osu.Game/Rulesets/Mods/ModPerfect.cs b/osu.Game/Rulesets/Mods/ModPerfect.cs index 4c68d0d375..c40c651655 100644 --- a/osu.Game/Rulesets/Mods/ModPerfect.cs +++ b/osu.Game/Rulesets/Mods/ModPerfect.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mods public override double ScoreMultiplier => 1; public override string Description => "SS or quit."; - public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModSuddenDeath)).Append(typeof(ModAccuracyChallenge)).ToArray(); + public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(ModSuddenDeath), typeof(ModAccuracyChallenge) }).ToArray(); protected ModPerfect() { From 58d4aeb4fb1b60fe5c5fe7e701fc5db469e1ad8e Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Wed, 25 May 2022 15:11:06 -0400 Subject: [PATCH 0009/2991] add accuracy calculation comment --- osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs index 804ce867af..fe12b72d1e 100644 --- a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs +++ b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs @@ -40,6 +40,7 @@ namespace osu.Game.Rulesets.Mods protected override bool FailCondition(HealthProcessor healthProcessor, JudgementResult result) { + // accuracy calculation logic taken from `ScoreProcessor`. should be updated here if the formula ever changes. if (!result.Type.IsScorable() || result.Type.IsBonus()) return false; From 6710df94a79052689d67b79c3ec55dfd81fd7107 Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Mon, 6 Jun 2022 12:05:45 -0400 Subject: [PATCH 0010/2991] change max accuracy to 99% --- osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs index fe12b72d1e..307a9594fe 100644 --- a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs +++ b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Mods public BindableNumber MinimumAccuracy { get; } = new BindableDouble { MinValue = 0.01, - MaxValue = 1, + MaxValue = 0.99, Precision = 0.01, Default = 0.9, Value = 0.9, From dc75d55f72af11bdf81b081dad8f5e84be3ed2e2 Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Wed, 8 Jun 2022 14:02:15 -0400 Subject: [PATCH 0011/2991] allow modfailcondition to arbitrarily trigger fail --- osu.Game/Rulesets/Mods/ModFailCondition.cs | 19 +++++++++++++++++++ osu.Game/Rulesets/Scoring/HealthProcessor.cs | 14 ++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModFailCondition.cs b/osu.Game/Rulesets/Mods/ModFailCondition.cs index 4425ece513..1aab0ab880 100644 --- a/osu.Game/Rulesets/Mods/ModFailCondition.cs +++ b/osu.Game/Rulesets/Mods/ModFailCondition.cs @@ -19,12 +19,31 @@ namespace osu.Game.Rulesets.Mods public virtual bool PerformFail() => true; public virtual bool RestartOnFail => Restart.Value; + private HealthProcessor healthProcessorInternal; public void ApplyToHealthProcessor(HealthProcessor healthProcessor) { + healthProcessorInternal = healthProcessor; healthProcessor.FailConditions += FailCondition; } + /// + /// Immediately triggers a failure on the loaded . + /// + protected void TriggerArbitraryFailure() => healthProcessorInternal.TriggerFailure(); + + /// + /// Determines whether should trigger a failure. Called every time a + /// judgement is applied to . + /// + /// The loaded . + /// The latest . + /// Whether the fail condition has been met. + /// + /// This method should only be used to trigger failures based on . + /// Using outside values to evaluate failure may introduce event ordering discrepancies, use + /// an with instead. + /// protected abstract bool FailCondition(HealthProcessor healthProcessor, JudgementResult result); } } diff --git a/osu.Game/Rulesets/Scoring/HealthProcessor.cs b/osu.Game/Rulesets/Scoring/HealthProcessor.cs index 0f51560476..4f5ff95477 100644 --- a/osu.Game/Rulesets/Scoring/HealthProcessor.cs +++ b/osu.Game/Rulesets/Scoring/HealthProcessor.cs @@ -33,6 +33,15 @@ namespace osu.Game.Rulesets.Scoring /// public bool HasFailed { get; private set; } + /// + /// Immediately triggers a failure for this HealthProcessor. + /// + public void TriggerFailure() + { + if (Failed?.Invoke() != false) + HasFailed = true; + } + protected override void ApplyResultInternal(JudgementResult result) { result.HealthAtJudgement = Health.Value; @@ -44,10 +53,7 @@ namespace osu.Game.Rulesets.Scoring Health.Value += GetHealthIncreaseFor(result); if (meetsAnyFailCondition(result)) - { - if (Failed?.Invoke() != false) - HasFailed = true; - } + TriggerFailure(); } protected override void RevertResultInternal(JudgementResult result) From fdbec4f8c0c8082445beaef065c7df9aa4a36065 Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Wed, 8 Jun 2022 23:44:34 -0400 Subject: [PATCH 0012/2991] display tooltip accuracy as percentage --- osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs index 307a9594fe..2c088e880b 100644 --- a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs +++ b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs @@ -23,6 +23,7 @@ namespace osu.Game.Rulesets.Mods public override double ScoreMultiplier => 1.0; public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(ModEasyWithExtraLives), typeof(ModPerfect) }).ToArray(); public override bool RequiresConfiguration => false; + public override string SettingDescription => base.SettingDescription.Replace(MinimumAccuracy.Value.ToString(), MinimumAccuracy.Value.ToString("##%")); [SettingSource("Minimum accuracy", "Trigger a failure if your accuracy goes below this value.", SettingControlType = typeof(SettingsSlider))] public BindableNumber MinimumAccuracy { get; } = new BindableDouble From 99dc2fbc3e51a4d8a81eba6c595eeda7079532a9 Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Thu, 9 Jun 2022 00:15:15 -0400 Subject: [PATCH 0013/2991] specify culture --- osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs index 2c088e880b..891832a353 100644 --- a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs +++ b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Globalization; using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; @@ -23,7 +24,7 @@ namespace osu.Game.Rulesets.Mods public override double ScoreMultiplier => 1.0; public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(ModEasyWithExtraLives), typeof(ModPerfect) }).ToArray(); public override bool RequiresConfiguration => false; - public override string SettingDescription => base.SettingDescription.Replace(MinimumAccuracy.Value.ToString(), MinimumAccuracy.Value.ToString("##%")); + public override string SettingDescription => base.SettingDescription.Replace(MinimumAccuracy.ToString(), MinimumAccuracy.Value.ToString("##%", NumberFormatInfo.InvariantInfo)); [SettingSource("Minimum accuracy", "Trigger a failure if your accuracy goes below this value.", SettingControlType = typeof(SettingsSlider))] public BindableNumber MinimumAccuracy { get; } = new BindableDouble From 4b73c423bda6c0c8d14b0db3d046c8cd8820fb9f Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Thu, 9 Jun 2022 18:58:22 -0400 Subject: [PATCH 0014/2991] don't specify icon --- osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs index 891832a353..74a9a205a0 100644 --- a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs +++ b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs @@ -5,7 +5,6 @@ using System; using System.Globalization; using System.Linq; using osu.Framework.Bindables; -using osu.Framework.Graphics.Sprites; using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Settings; @@ -19,7 +18,6 @@ namespace osu.Game.Rulesets.Mods public override string Name => "Accuracy Challenge"; public override string Acronym => "AC"; public override string Description => "Fail the map if you don't maintain a certain accuracy."; - public override IconUsage? Icon => FontAwesome.Solid.Calculator; public override ModType Type => ModType.DifficultyIncrease; public override double ScoreMultiplier => 1.0; public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(ModEasyWithExtraLives), typeof(ModPerfect) }).ToArray(); From 21c5499da16eb88f12d6f5bee8d28b1557559b2f Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Fri, 10 Jun 2022 13:11:17 -0400 Subject: [PATCH 0015/2991] remove arbitrary from method name --- osu.Game/Rulesets/Mods/ModFailCondition.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModFailCondition.cs b/osu.Game/Rulesets/Mods/ModFailCondition.cs index 1aab0ab880..9500734408 100644 --- a/osu.Game/Rulesets/Mods/ModFailCondition.cs +++ b/osu.Game/Rulesets/Mods/ModFailCondition.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mods /// /// Immediately triggers a failure on the loaded . /// - protected void TriggerArbitraryFailure() => healthProcessorInternal.TriggerFailure(); + protected void TriggerFailure() => healthProcessorInternal.TriggerFailure(); /// /// Determines whether should trigger a failure. Called every time a @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mods /// /// This method should only be used to trigger failures based on . /// Using outside values to evaluate failure may introduce event ordering discrepancies, use - /// an with instead. + /// an with instead. /// protected abstract bool FailCondition(HealthProcessor healthProcessor, JudgementResult result); } From 6e64a8f55ef5838a5d58625668138fb3c85e34db Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Fri, 10 Jun 2022 13:13:35 -0400 Subject: [PATCH 0016/2991] use event to trigger failure --- osu.Game/Rulesets/Mods/ModFailCondition.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModFailCondition.cs b/osu.Game/Rulesets/Mods/ModFailCondition.cs index 9500734408..63cebc9747 100644 --- a/osu.Game/Rulesets/Mods/ModFailCondition.cs +++ b/osu.Game/Rulesets/Mods/ModFailCondition.cs @@ -19,18 +19,18 @@ namespace osu.Game.Rulesets.Mods public virtual bool PerformFail() => true; public virtual bool RestartOnFail => Restart.Value; - private HealthProcessor healthProcessorInternal; + private event Action failureTriggered; public void ApplyToHealthProcessor(HealthProcessor healthProcessor) { - healthProcessorInternal = healthProcessor; + failureTriggered = healthProcessor.TriggerFailure; healthProcessor.FailConditions += FailCondition; } /// /// Immediately triggers a failure on the loaded . /// - protected void TriggerFailure() => healthProcessorInternal.TriggerFailure(); + protected void TriggerFailure() => failureTriggered?.Invoke(); /// /// Determines whether should trigger a failure. Called every time a From 8e84f76bf9547d349e25090423468c9e2efb71fd Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Fri, 8 Jul 2022 15:49:10 -0400 Subject: [PATCH 0017/2991] add hidden item toggle to directory/file selectors --- .../UserInterfaceV2/OsuDirectorySelector.cs | 2 ++ .../OsuDirectorySelectorHiddenToggle.cs | 29 +++++++++++++++++++ .../UserInterfaceV2/OsuFileSelector.cs | 2 ++ 3 files changed, 33 insertions(+) create mode 100644 osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelector.cs b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelector.cs index 42e1073baf..0e348108aa 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelector.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelector.cs @@ -31,6 +31,8 @@ namespace osu.Game.Graphics.UserInterfaceV2 protected override DirectorySelectorBreadcrumbDisplay CreateBreadcrumb() => new OsuDirectorySelectorBreadcrumbDisplay(); + protected override Drawable CreateHiddenToggleButton() => new OsuDirectorySelectorHiddenToggle { Current = { BindTarget = ShowHiddenItems } }; + protected override DirectorySelectorDirectory CreateParentDirectoryItem(DirectoryInfo directory) => new OsuDirectorySelectorParentDirectory(directory); protected override DirectorySelectorDirectory CreateDirectoryItem(DirectoryInfo directory, string displayName = null) => new OsuDirectorySelectorDirectory(directory, displayName); diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs new file mode 100644 index 0000000000..bb582cad8f --- /dev/null +++ b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs @@ -0,0 +1,29 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Game.Graphics.UserInterface; +using osuTK.Graphics; + +namespace osu.Game.Graphics.UserInterfaceV2 +{ + internal class OsuDirectorySelectorHiddenToggle : OsuCheckbox + { + public OsuDirectorySelectorHiddenToggle() + { + RelativeSizeAxes = Axes.None; + AutoSizeAxes = Axes.Both; + Anchor = Anchor.CentreLeft; + Origin = Anchor.CentreLeft; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Nub.AccentColour = colours.GreySeaFoamLighter; + Nub.GlowingAccentColour = Color4.White; + Nub.GlowColour = Color4.White; + } + } +} diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs b/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs index 3e8b7dc209..70af68d595 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs @@ -33,6 +33,8 @@ namespace osu.Game.Graphics.UserInterfaceV2 protected override DirectorySelectorBreadcrumbDisplay CreateBreadcrumb() => new OsuDirectorySelectorBreadcrumbDisplay(); + protected override Drawable CreateHiddenToggleButton() => new OsuDirectorySelectorHiddenToggle { Current = { BindTarget = ShowHiddenItems } }; + protected override DirectorySelectorDirectory CreateParentDirectoryItem(DirectoryInfo directory) => new OsuDirectorySelectorParentDirectory(directory); protected override DirectorySelectorDirectory CreateDirectoryItem(DirectoryInfo directory, string displayName = null) => new OsuDirectorySelectorDirectory(directory, displayName); From b92979acd69b61330d1456a15dafe682df5756bd Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Fri, 8 Jul 2022 16:00:48 -0400 Subject: [PATCH 0018/2991] add tooltip to checkbox --- .../UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs index bb582cad8f..5b5af1d71d 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs @@ -3,13 +3,17 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; using osuTK.Graphics; namespace osu.Game.Graphics.UserInterfaceV2 { - internal class OsuDirectorySelectorHiddenToggle : OsuCheckbox + internal class OsuDirectorySelectorHiddenToggle : OsuCheckbox, IHasTooltip { + public LocalisableString TooltipText => @"Show hidden items"; + public OsuDirectorySelectorHiddenToggle() { RelativeSizeAxes = Axes.None; From 84002aefae779efefc9602215716e43542a9d0ac Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 11 Jul 2022 20:18:50 +0300 Subject: [PATCH 0019/2991] Update file/directory selector tests to use `ThemeComparisonTestScene` --- .../Settings/TestSceneDirectorySelector.cs | 11 +++--- .../Visual/Settings/TestSceneFileSelector.cs | 34 +++++++++++++++---- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneDirectorySelector.cs b/osu.Game.Tests/Visual/Settings/TestSceneDirectorySelector.cs index 4f05194e08..16110e5595 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneDirectorySelector.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneDirectorySelector.cs @@ -3,18 +3,17 @@ #nullable disable -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Tests.Visual.UserInterface; namespace osu.Game.Tests.Visual.Settings { - public class TestSceneDirectorySelector : OsuTestScene + public class TestSceneDirectorySelector : ThemeComparisonTestScene { - [BackgroundDependencyLoader] - private void load() + protected override Drawable CreateContent() => new OsuDirectorySelector { - Add(new OsuDirectorySelector { RelativeSizeAxes = Axes.Both }); - } + RelativeSizeAxes = Axes.Both + }; } } diff --git a/osu.Game.Tests/Visual/Settings/TestSceneFileSelector.cs b/osu.Game.Tests/Visual/Settings/TestSceneFileSelector.cs index 6f25012bfa..97bf0d212a 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneFileSelector.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneFileSelector.cs @@ -4,23 +4,43 @@ #nullable disable using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Tests.Visual.UserInterface; namespace osu.Game.Tests.Visual.Settings { - public class TestSceneFileSelector : OsuTestScene + public class TestSceneFileSelector : ThemeComparisonTestScene { - [Test] - public void TestAllFiles() - { - AddStep("create", () => Child = new OsuFileSelector { RelativeSizeAxes = Axes.Both }); - } + [Resolved] + private OsuColour colours { get; set; } [Test] public void TestJpgFilesOnly() { - AddStep("create", () => Child = new OsuFileSelector(validFileExtensions: new[] { ".jpg" }) { RelativeSizeAxes = Axes.Both }); + AddStep("create", () => + { + Cell(0, 0).Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.GreySeaFoam + }, + new OsuFileSelector(validFileExtensions: new[] { ".jpg" }) + { + RelativeSizeAxes = Axes.Both, + }, + }; + }); } + + protected override Drawable CreateContent() => new OsuFileSelector + { + RelativeSizeAxes = Axes.Both, + }; } } From 7d26f178c6c1b8b3bc7b56e20352c52389c3bd75 Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Mon, 11 Jul 2022 16:36:17 -0400 Subject: [PATCH 0020/2991] use `OverlayColourProvider` for nub colors when possible --- .../UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs index 5b5af1d71d..74e9312eda 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs @@ -6,6 +6,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Cursor; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays; using osuTK.Graphics; namespace osu.Game.Graphics.UserInterfaceV2 @@ -22,9 +23,12 @@ namespace osu.Game.Graphics.UserInterfaceV2 Origin = Anchor.CentreLeft; } - [BackgroundDependencyLoader] - private void load(OsuColour colours) + [BackgroundDependencyLoader(true)] + private void load(OverlayColourProvider? overlayColourProvider, OsuColour colours) { + if (overlayColourProvider != null) + return; + Nub.AccentColour = colours.GreySeaFoamLighter; Nub.GlowingAccentColour = Color4.White; Nub.GlowColour = Color4.White; From 77f5ec3a4ec24dcc6b5df8b7b7fd2dd1a8657dd4 Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Mon, 11 Jul 2022 16:39:53 -0400 Subject: [PATCH 0021/2991] use checkbox label instead of tooltip --- .../OsuDirectorySelectorHiddenToggle.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs index 74e9312eda..38ec602fe7 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs @@ -3,24 +3,23 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Cursor; -using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays; +using osuTK; using osuTK.Graphics; namespace osu.Game.Graphics.UserInterfaceV2 { - internal class OsuDirectorySelectorHiddenToggle : OsuCheckbox, IHasTooltip + internal class OsuDirectorySelectorHiddenToggle : OsuCheckbox { - public LocalisableString TooltipText => @"Show hidden items"; - public OsuDirectorySelectorHiddenToggle() { RelativeSizeAxes = Axes.None; - AutoSizeAxes = Axes.Both; + AutoSizeAxes = Axes.None; + Size = new Vector2(100, 50); Anchor = Anchor.CentreLeft; Origin = Anchor.CentreLeft; + LabelText = "Show hidden items"; } [BackgroundDependencyLoader(true)] From 8617b94c9d6865a65007acbc79010f89b2c04be8 Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Mon, 11 Jul 2022 17:12:14 -0400 Subject: [PATCH 0022/2991] shorten label --- .../UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs index 38ec602fe7..28f6049683 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs @@ -19,7 +19,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 Size = new Vector2(100, 50); Anchor = Anchor.CentreLeft; Origin = Anchor.CentreLeft; - LabelText = "Show hidden items"; + LabelText = @"Show hidden"; } [BackgroundDependencyLoader(true)] From d6abdc597d68459fd6539d49123a5e5cec7f7051 Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Mon, 11 Jul 2022 17:12:41 -0400 Subject: [PATCH 0023/2991] correct label positioning --- .../Graphics/UserInterface/OsuCheckbox.cs | 20 +++++++++---------- .../OsuDirectorySelectorHiddenToggle.cs | 2 ++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuCheckbox.cs b/osu.Game/Graphics/UserInterface/OsuCheckbox.cs index bbd8f8ecea..8772c1e2d9 100644 --- a/osu.Game/Graphics/UserInterface/OsuCheckbox.cs +++ b/osu.Game/Graphics/UserInterface/OsuCheckbox.cs @@ -26,24 +26,24 @@ namespace osu.Game.Graphics.UserInterface { set { - if (labelText != null) - labelText.Text = value; + if (LabelTextFlowContainer != null) + LabelTextFlowContainer.Text = value; } } public MarginPadding LabelPadding { - get => labelText?.Padding ?? new MarginPadding(); + get => LabelTextFlowContainer?.Padding ?? new MarginPadding(); set { - if (labelText != null) - labelText.Padding = value; + if (LabelTextFlowContainer != null) + LabelTextFlowContainer.Padding = value; } } protected readonly Nub Nub; - private readonly OsuTextFlowContainer labelText; + protected readonly OsuTextFlowContainer LabelTextFlowContainer; private Sample sampleChecked; private Sample sampleUnchecked; @@ -56,7 +56,7 @@ namespace osu.Game.Graphics.UserInterface Children = new Drawable[] { - labelText = new OsuTextFlowContainer(ApplyLabelParameters) + LabelTextFlowContainer = new OsuTextFlowContainer(ApplyLabelParameters) { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, @@ -70,19 +70,19 @@ namespace osu.Game.Graphics.UserInterface Nub.Anchor = Anchor.CentreRight; Nub.Origin = Anchor.CentreRight; Nub.Margin = new MarginPadding { Right = nub_padding }; - labelText.Padding = new MarginPadding { Right = Nub.EXPANDED_SIZE + nub_padding * 2 }; + LabelTextFlowContainer.Padding = new MarginPadding { Right = Nub.EXPANDED_SIZE + nub_padding * 2 }; } else { Nub.Anchor = Anchor.CentreLeft; Nub.Origin = Anchor.CentreLeft; Nub.Margin = new MarginPadding { Left = nub_padding }; - labelText.Padding = new MarginPadding { Left = Nub.EXPANDED_SIZE + nub_padding * 2 }; + LabelTextFlowContainer.Padding = new MarginPadding { Left = Nub.EXPANDED_SIZE + nub_padding * 2 }; } Nub.Current.BindTo(Current); - Current.DisabledChanged += disabled => labelText.Alpha = Nub.Alpha = disabled ? 0.3f : 1; + Current.DisabledChanged += disabled => LabelTextFlowContainer.Alpha = Nub.Alpha = disabled ? 0.3f : 1; } /// diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs index 28f6049683..7aaf12ca34 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs @@ -19,6 +19,8 @@ namespace osu.Game.Graphics.UserInterfaceV2 Size = new Vector2(100, 50); Anchor = Anchor.CentreLeft; Origin = Anchor.CentreLeft; + LabelTextFlowContainer.Anchor = Anchor.CentreLeft; + LabelTextFlowContainer.Origin = Anchor.CentreLeft; LabelText = @"Show hidden"; } From 320c4abb66ba388bb19d04bb22b64cd4b56fa181 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 31 Jul 2022 20:13:06 -0700 Subject: [PATCH 0024/2991] Add failing online play non-current sub screen onexiting test --- .../Navigation/TestSceneScreenNavigation.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 8fce43f9b0..7ee0998281 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -26,6 +26,7 @@ using osu.Game.Rulesets.Osu.Mods; using osu.Game.Scoring; using osu.Game.Screens.Menu; using osu.Game.Screens.OnlinePlay.Lounge; +using osu.Game.Screens.OnlinePlay.Match.Components; using osu.Game.Screens.OnlinePlay.Playlists; using osu.Game.Screens.Play; using osu.Game.Screens.Ranking; @@ -79,7 +80,25 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for return to playlist screen", () => playlistScreen.CurrentSubScreen is PlaylistsRoomSubScreen); + AddStep("go back to song select", () => + { + InputManager.MoveMouseTo(playlistScreen.ChildrenOfType().Single(b => b.Text == "Edit playlist")); + InputManager.Click(MouseButton.Left); + }); + + AddUntilStep("wait for song select", () => (playlistScreen.CurrentSubScreen as PlaylistsSongSelect)?.BeatmapSetsLoaded == true); + + AddStep("press home button", () => + { + InputManager.MoveMouseTo(Game.Toolbar.ChildrenOfType().Single()); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("confirmation dialog shown", () => Game.ChildrenOfType().Single().CurrentDialog is not null); + pushEscape(); + pushEscape(); + AddAssert("confirmation dialog shown", () => Game.ChildrenOfType().Single().CurrentDialog is not null); AddStep("confirm exit", () => InputManager.Key(Key.Enter)); From 1dbb2a4d376a61d744292967e077cd20eb0b7780 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 1 Aug 2022 07:52:07 -0700 Subject: [PATCH 0025/2991] Fix online play screen only accounting for current sub screen onexiting blocks --- osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs index 61ea7d68ee..ad52363c95 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs @@ -147,9 +147,14 @@ namespace osu.Game.Screens.OnlinePlay public override bool OnExiting(ScreenExitEvent e) { - var subScreen = screenStack.CurrentScreen as Drawable; - if (subScreen?.IsLoaded == true && screenStack.CurrentScreen.OnExiting(e)) - return true; + while (screenStack.CurrentScreen is not LoungeSubScreen) + { + var lastSubScreen = screenStack.CurrentScreen; + if (((Drawable)lastSubScreen)?.IsLoaded == true) + screenStack.Exit(); + + if (lastSubScreen == screenStack.CurrentScreen) return true; + } RoomManager.PartRoom(); From 7add3a69508abd2d2cffc9f9ec0ebe329b9faa26 Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Thu, 18 Aug 2022 19:00:54 +0200 Subject: [PATCH 0026/2991] ar var test --- osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs | 61 +++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs new file mode 100644 index 0000000000..e291e92901 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs @@ -0,0 +1,61 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using osu.Framework.Bindables; +using osu.Framework.Graphics.Sprites; +using osu.Game.Beatmaps; +using osu.Game.Configuration; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Osu.Objects; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModFlash : ModWithVisibilityAdjustment, IApplicableAfterBeatmapConversion + { + public override string Name => "Var AR Test"; + public override string Acronym => "TP"; + public override ModType Type => ModType.Fun; + public override IconUsage? Icon => FontAwesome.Regular.Sun; + public override string Description => @"how far will your reading stretch"; + public override double ScoreMultiplier => 1.03; + + public override void ApplyToBeatmap(IBeatmap beatmap) + { + base.ApplyToBeatmap(beatmap); + double lastObjectEnd = beatmap.HitObjects.LastOrDefault()?.GetEndTime() ?? 0; + + foreach (var obj in beatmap.HitObjects.OfType()) + applyVariableAr(obj); + + void applyVariableAr(OsuHitObject osuObject) + { + double percentageofmap = osuObject.StartTime / lastObjectEnd; + osuObject.TimePreempt = (percentageofmap * osuObject.TimePreempt) * ARadded.Value + osuObject.TimePreempt; + foreach (var nested in osuObject.NestedHitObjects.OfType()) + applyVariableAr(nested); + } + } + + protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) + { + } + + protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) + { + } + + [SettingSource("Additional AR", "how much AR change to add")] + public BindableDouble ARadded { get; } = new BindableDouble(1) + { + Precision = 0.1f, + MinValue = 0, + MaxValue = 10, + }; + + /*[SettingSource("Additional Ar", "how much ar change to add")] + public BindableBool scaledown { get; } = new BindableBool();*/ + } +} From 217fa00a72af23ae2971dba4d10beb9a5a185930 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 26 Aug 2022 19:32:49 +0900 Subject: [PATCH 0027/2991] Bring logic up-to-date --- .../SongSelect/TestSceneBeatmapCarousel.cs | 22 +++---------------- .../Carousel/CarouselGroupEagerSelect.cs | 14 ++++++------ 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 8f7d630a19..7623704a4b 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -834,16 +834,7 @@ namespace osu.Game.Tests.Visual.SongSelect for (int i = 0; i < makeThisManyGroups; i++) { for (int j = 0; j < haveThisManySetsInGroup; j++) - { - var testBeatmap = createTestBeatmapSet(i * haveThisManySetsInGroup + j + 1); - var rulesetID = i % 3; - testBeatmap.Beatmaps.ForEach(b => - { - b.Ruleset = rulesets.AvailableRulesets.ElementAt(rulesetID); - b.RulesetID = rulesetID; - }); - sets.Add(testBeatmap); - } + sets.Add(TestResources.CreateTestBeatmapSetInfo(i * haveThisManySetsInGroup + j + 1)); } loadBeatmaps(sets); @@ -852,7 +843,7 @@ namespace osu.Game.Tests.Visual.SongSelect for (int i = 1; i < makeThisManyGroups; i++) { - var rulesetID = i % 3; + int rulesetID = i % 3; AddStep($"Toggle filter to ruleset {rulesetID}", () => { carousel.Filter(new FilterCriteria { Ruleset = rulesets.AvailableRulesets.ElementAt(rulesetID) }, false); @@ -869,14 +860,7 @@ namespace osu.Game.Tests.Visual.SongSelect for (int i = 1; i <= 40; i++) { - var testBeatmap = createTestBeatmapSet(i); - var rulesetID = (i - 1) / 10; - testBeatmap.Beatmaps.ForEach(b => - { - b.Ruleset = rulesets.AvailableRulesets.ElementAt(rulesetID); - b.RulesetID = rulesetID; - }); - sets.Add(testBeatmap); + sets.Add(TestResources.CreateTestBeatmapSetInfo(i)); } loadBeatmaps(sets); diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs index 432f795f4c..2c1ccebfab 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs @@ -120,16 +120,16 @@ namespace osu.Game.Screens.Select.Carousel while (true) { // check if a direction has been exhausted and an item (or null) from the other direction should be returned - if (forwardsIndex >= Children.Count) - return Children.Reverse().Skip(Children.Count - backwardsIndex - 1).FirstOrDefault(item => !item.Filtered.Value); + if (forwardsIndex >= Items.Count) + return Items.Reverse().Skip(Items.Count - backwardsIndex - 1).FirstOrDefault(item => !item.Filtered.Value); if (backwardsIndex < 0) - return Children.Skip(forwardsIndex).FirstOrDefault(item => !item.Filtered.Value); + return Items.Skip(forwardsIndex).FirstOrDefault(item => !item.Filtered.Value); // check if an unfiltered item has been reached - if (!Children[forwardsIndex].Filtered.Value) - return Children[forwardsIndex]; - if (!Children[backwardsIndex].Filtered.Value) - return Children[backwardsIndex]; + if (!Items[forwardsIndex].Filtered.Value) + return Items[forwardsIndex]; + if (!Items[backwardsIndex].Filtered.Value) + return Items[backwardsIndex]; // increment the indices forwardsIndex++; From 5a1b2f9a77b62f0ef01e010bfef942ff68385b9f Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Thu, 8 Sep 2022 00:05:48 +0200 Subject: [PATCH 0028/2991] Freeze frame testing --- osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs | 85 ++++++++++++++--------- osu.Game.Rulesets.Osu/OsuRuleset.cs | 3 +- 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs index e291e92901..b50de12465 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs @@ -1,61 +1,84 @@ -// 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.Framework.Graphics.Sprites; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Rulesets.Osu.UI; +using osu.Game.Rulesets.UI; +using osuTK; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModFlash : ModWithVisibilityAdjustment, IApplicableAfterBeatmapConversion + public class OsuModFlash : ModWithVisibilityAdjustment, IHidesApproachCircles, IApplicableToDrawableRuleset { - public override string Name => "Var AR Test"; - public override string Acronym => "TP"; + public override string Name => "Freeze frame"; + + public override string Acronym => "FF"; + + public override double ScoreMultiplier => 1; + + public override string Description => "Burn the notes into your memory"; + public override ModType Type => ModType.Fun; - public override IconUsage? Icon => FontAwesome.Regular.Sun; - public override string Description => @"how far will your reading stretch"; - public override double ScoreMultiplier => 1.03; + + public override IconUsage? Icon => FontAwesome.Solid.Fire; + + public override Type[] IncompatibleMods => new[] { typeof(OsuModTarget), typeof(OsuModStrictTracking) }; + + [SettingSource("Beat divisor")] + public BindableFloat BeatDivisor { get; } = new BindableFloat(2) + { + MinValue = .25f, + MaxValue = 2, + Precision = .25F + }; public override void ApplyToBeatmap(IBeatmap beatmap) { base.ApplyToBeatmap(beatmap); - double lastObjectEnd = beatmap.HitObjects.LastOrDefault()?.GetEndTime() ?? 0; - foreach (var obj in beatmap.HitObjects.OfType()) - applyVariableAr(obj); - - void applyVariableAr(OsuHitObject osuObject) + foreach (var hitObject in beatmap.HitObjects.OfType()) { - double percentageofmap = osuObject.StartTime / lastObjectEnd; - osuObject.TimePreempt = (percentageofmap * osuObject.TimePreempt) * ARadded.Value + osuObject.TimePreempt; - foreach (var nested in osuObject.NestedHitObjects.OfType()) - applyVariableAr(nested); + hitObject.TimeFadeIn = hitObject.TimePreempt; + var point = beatmap.ControlPointInfo.TimingPointAt(hitObject.StartTime); + hitObject.TimePreempt += hitObject.StartTime % (point.BeatLength / BeatDivisor.Value); } } + public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) + { + (drawableRuleset.Playfield as OsuPlayfield)?.FollowPoints.Hide(); + } + protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) { } - protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) + protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) => applyFrozenState(hitObject, state); + + private void applyFrozenState(DrawableHitObject drawable, ArmedState state) { + if (drawable is DrawableSpinner) + return; + + var h = (OsuHitObject)drawable.HitObject; + + switch (drawable) + { + case DrawableHitCircle circle: + using (circle.BeginAbsoluteSequence(h.StartTime - h.TimePreempt)) + { + circle.ApproachCircle.Hide(); + } + + break; + } } - - [SettingSource("Additional AR", "how much AR change to add")] - public BindableDouble ARadded { get; } = new BindableDouble(1) - { - Precision = 0.1f, - MinValue = 0, - MaxValue = 10, - }; - - /*[SettingSource("Additional Ar", "how much ar change to add")] - public BindableBool scaledown { get; } = new BindableBool();*/ } } + diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 302194e91a..466b770399 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -198,7 +198,8 @@ namespace osu.Game.Rulesets.Osu new OsuModMuted(), new OsuModNoScope(), new MultiMod(new OsuModMagnetised(), new OsuModRepel()), - new ModAdaptiveSpeed() + new ModAdaptiveSpeed(), + new OsuModFlash() }; case ModType.System: From 7f08de522d68efd5d79e7b08d1d64e1ed81454f3 Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Thu, 8 Sep 2022 01:21:03 +0200 Subject: [PATCH 0029/2991] Fixed --- osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs | 25 +++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs index b50de12465..e1ce43d875 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs @@ -2,6 +2,7 @@ using System; using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets.Mods; @@ -10,7 +11,6 @@ using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; -using osuTK; namespace osu.Game.Rulesets.Osu.Mods { @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override double ScoreMultiplier => 1; - public override string Description => "Burn the notes into your memory"; + public override LocalisableString Description => "Burn the notes into your memory"; public override ModType Type => ModType.Fun; @@ -31,22 +31,29 @@ namespace osu.Game.Rulesets.Osu.Mods public override Type[] IncompatibleMods => new[] { typeof(OsuModTarget), typeof(OsuModStrictTracking) }; [SettingSource("Beat divisor")] - public BindableFloat BeatDivisor { get; } = new BindableFloat(2) + public BindableFloat BeatDivisor { get; } = new BindableFloat(1) { MinValue = .25f, - MaxValue = 2, - Precision = .25F + MaxValue = 5, + Precision = .25f }; public override void ApplyToBeatmap(IBeatmap beatmap) { base.ApplyToBeatmap(beatmap); - foreach (var hitObject in beatmap.HitObjects.OfType()) + foreach (var obj in beatmap.HitObjects.OfType()) { - hitObject.TimeFadeIn = hitObject.TimePreempt; - var point = beatmap.ControlPointInfo.TimingPointAt(hitObject.StartTime); - hitObject.TimePreempt += hitObject.StartTime % (point.BeatLength / BeatDivisor.Value); + applyFadeInAdjustment(obj); + var point = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime); + obj.TimePreempt += obj.StartTime % (point.BeatLength * BeatDivisor.Value); + } + + static void applyFadeInAdjustment(OsuHitObject osuObject) + { + osuObject.TimeFadeIn = osuObject.TimePreempt; + foreach (var nested in osuObject.NestedHitObjects.OfType()) + applyFadeInAdjustment(nested); } } From 4a6c8785af7bd24b5f2e4a1be9e85c19624ac4c8 Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Thu, 8 Sep 2022 11:14:56 +0200 Subject: [PATCH 0030/2991] Clean up --- osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs | 31 ++++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs index e1ce43d875..818eb93bfb 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs @@ -38,30 +38,31 @@ namespace osu.Game.Rulesets.Osu.Mods Precision = .25f }; + + public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) + { + (drawableRuleset.Playfield as OsuPlayfield)?.FollowPoints.Hide(); + } + public override void ApplyToBeatmap(IBeatmap beatmap) { base.ApplyToBeatmap(beatmap); foreach (var obj in beatmap.HitObjects.OfType()) { - applyFadeInAdjustment(obj); var point = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime); - obj.TimePreempt += obj.StartTime % (point.BeatLength * BeatDivisor.Value); - } + double val = obj.TimePreempt + obj.StartTime % (point.BeatLength * BeatDivisor.Value); + applyFadeInAdjustment(obj); - static void applyFadeInAdjustment(OsuHitObject osuObject) - { - osuObject.TimeFadeIn = osuObject.TimePreempt; - foreach (var nested in osuObject.NestedHitObjects.OfType()) - applyFadeInAdjustment(nested); + void applyFadeInAdjustment(OsuHitObject osuObject) + { + osuObject.TimePreempt = val; + foreach (var nested in osuObject.NestedHitObjects.OfType()) + applyFadeInAdjustment(nested); + } } } - public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) - { - (drawableRuleset.Playfield as OsuPlayfield)?.FollowPoints.Hide(); - } - protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) { } @@ -74,7 +75,7 @@ namespace osu.Game.Rulesets.Osu.Mods return; var h = (OsuHitObject)drawable.HitObject; - + /* switch (drawable) { case DrawableHitCircle circle: @@ -84,7 +85,7 @@ namespace osu.Game.Rulesets.Osu.Mods } break; - } + }*/ } } } From e416c87970de92b0b10e27733c2509bfacdf215c Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Thu, 8 Sep 2022 15:17:22 +0200 Subject: [PATCH 0031/2991] readded approach circles --- .../{OsuModFlash.cs => OsuModFreezeFrame.cs} | 23 +++---------------- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- 2 files changed, 4 insertions(+), 21 deletions(-) rename osu.Game.Rulesets.Osu/Mods/{OsuModFlash.cs => OsuModFreezeFrame.cs} (76%) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs similarity index 76% rename from osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs rename to osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 818eb93bfb..b6b6f4e588 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFlash.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -8,13 +8,12 @@ using osu.Game.Configuration; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModFlash : ModWithVisibilityAdjustment, IHidesApproachCircles, IApplicableToDrawableRuleset + public class OsuModFreezeFrame : ModWithVisibilityAdjustment, IHidesApproachCircles, IApplicableToDrawableRuleset { public override string Name => "Freeze frame"; @@ -26,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Fun; - public override IconUsage? Icon => FontAwesome.Solid.Fire; + public override IconUsage? Icon => FontAwesome.Solid.Camera; public override Type[] IncompatibleMods => new[] { typeof(OsuModTarget), typeof(OsuModStrictTracking) }; @@ -38,7 +37,6 @@ namespace osu.Game.Rulesets.Osu.Mods Precision = .25f }; - public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { (drawableRuleset.Playfield as OsuPlayfield)?.FollowPoints.Hide(); @@ -69,23 +67,8 @@ namespace osu.Game.Rulesets.Osu.Mods protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) => applyFrozenState(hitObject, state); - private void applyFrozenState(DrawableHitObject drawable, ArmedState state) + private void applyFrozenState(DrawableHitObject drawableObject, ArmedState state) { - if (drawable is DrawableSpinner) - return; - - var h = (OsuHitObject)drawable.HitObject; - /* - switch (drawable) - { - case DrawableHitCircle circle: - using (circle.BeginAbsoluteSequence(h.StartTime - h.TimePreempt)) - { - circle.ApproachCircle.Hide(); - } - - break; - }*/ } } } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 6fdf4c3bf8..2b42dc7eef 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -202,7 +202,7 @@ namespace osu.Game.Rulesets.Osu new OsuModNoScope(), new MultiMod(new OsuModMagnetised(), new OsuModRepel()), new ModAdaptiveSpeed(), - new OsuModFlash() + new OsuModFreezeFrame() }; case ModType.System: From cb17fb2091b351c0bf79f31a0818923529d2b274 Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Fri, 9 Sep 2022 23:13:19 +0200 Subject: [PATCH 0032/2991] Create Test Scene --- .../Mods/TestSceneOsuModFreezeFrame.cs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs new file mode 100644 index 0000000000..4642229436 --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs @@ -0,0 +1,27 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Rulesets.Osu.Mods; + +namespace osu.Game.Rulesets.Osu.Tests.Mods +{ + public class TestSceneOsuModFreezeFrame : OsuModTestScene + { + [TestCase(0.5f)] + [TestCase(1)] + [TestCase(2)] + public void TestFreezeFrequency(float beatMeasure) + { + CreateModTest(new ModTestData + { + Mod = new OsuModFreezeFrame + { + BeatDivisor = { Value = beatMeasure } + }, + PassCondition = () => true, + Autoplay = true + }); + } + } +} From 23d435bc427c8d1e2780a46d500b77eff084c9df Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Sat, 10 Sep 2022 14:08:04 +0200 Subject: [PATCH 0033/2991] name changes --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index b6b6f4e588..6bbe01063b 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -49,12 +49,12 @@ namespace osu.Game.Rulesets.Osu.Mods foreach (var obj in beatmap.HitObjects.OfType()) { var point = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime); - double val = obj.TimePreempt + obj.StartTime % (point.BeatLength * BeatDivisor.Value); + double newPreempt = obj.TimePreempt + (obj.StartTime +5) % (point.BeatLength * BeatDivisor.Value); applyFadeInAdjustment(obj); void applyFadeInAdjustment(OsuHitObject osuObject) { - osuObject.TimePreempt = val; + osuObject.TimePreempt = newPreempt; foreach (var nested in osuObject.NestedHitObjects.OfType()) applyFadeInAdjustment(nested); } From eb84c513e34a682914322ee94bf78b6836e64e1a Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Fri, 16 Sep 2022 02:14:14 +0200 Subject: [PATCH 0034/2991] Add ability to adjust to BPM changes fix first hitcircle being off time Bpm changes not working fix --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 6bbe01063b..84e41810ab 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -26,7 +26,6 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Fun; public override IconUsage? Icon => FontAwesome.Solid.Camera; - public override Type[] IncompatibleMods => new[] { typeof(OsuModTarget), typeof(OsuModStrictTracking) }; [SettingSource("Beat divisor")] @@ -48,13 +47,17 @@ namespace osu.Game.Rulesets.Osu.Mods foreach (var obj in beatmap.HitObjects.OfType()) { - var point = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime); - double newPreempt = obj.TimePreempt + (obj.StartTime +5) % (point.BeatLength * BeatDivisor.Value); + var lastTimingPoint = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime + 1); + double controlPointDifference = obj.StartTime + 1 - lastTimingPoint.Time; + double remainder = controlPointDifference % (lastTimingPoint.BeatLength * BeatDivisor.Value); + + double finalPreempt = obj.TimePreempt + remainder; + obj.TimePreempt = finalPreempt; applyFadeInAdjustment(obj); void applyFadeInAdjustment(OsuHitObject osuObject) { - osuObject.TimePreempt = newPreempt; + osuObject.TimePreempt = finalPreempt; foreach (var nested in osuObject.NestedHitObjects.OfType()) applyFadeInAdjustment(nested); } From 5a9b027ebcb32ecb44f6985ea86813682b5202f9 Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Fri, 16 Sep 2022 02:57:21 +0200 Subject: [PATCH 0035/2991] Use Enum for Settings --- .../Mods/OsuModFreezeFrame.cs | 46 ++++++++++++++----- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 84e41810ab..42c4a8fa20 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -29,12 +29,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override Type[] IncompatibleMods => new[] { typeof(OsuModTarget), typeof(OsuModStrictTracking) }; [SettingSource("Beat divisor")] - public BindableFloat BeatDivisor { get; } = new BindableFloat(1) - { - MinValue = .25f, - MaxValue = 5, - Precision = .25f - }; + public Bindable Divisor { get; } = new Bindable(BeatDivisor.Measure); public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { @@ -48,11 +43,11 @@ namespace osu.Game.Rulesets.Osu.Mods foreach (var obj in beatmap.HitObjects.OfType()) { var lastTimingPoint = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime + 1); + // +1 is added due to First HitCircle in each measure not appearing appropriately without it double controlPointDifference = obj.StartTime + 1 - lastTimingPoint.Time; - double remainder = controlPointDifference % (lastTimingPoint.BeatLength * BeatDivisor.Value); + double remainder = controlPointDifference % (lastTimingPoint.BeatLength * getMeasure(Divisor.Value)); double finalPreempt = obj.TimePreempt + remainder; - obj.TimePreempt = finalPreempt; applyFadeInAdjustment(obj); void applyFadeInAdjustment(OsuHitObject osuObject) @@ -64,14 +59,41 @@ namespace osu.Game.Rulesets.Osu.Mods } } - protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) + protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) { } + + protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) { } + + private float getMeasure(BeatDivisor divisor) { + switch (divisor) + { + case BeatDivisor.Quarter_Measure: + return 0.25f; + + case BeatDivisor.Half_Measure: + return 0.5f; + + case BeatDivisor.Measure: + return 1; + + case BeatDivisor.Double_Measure: + return 2; + + case BeatDivisor.Quadruple_Measure: + return 4; + + default: + throw new ArgumentOutOfRangeException(nameof(divisor), divisor, null); + } } - protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) => applyFrozenState(hitObject, state); - - private void applyFrozenState(DrawableHitObject drawableObject, ArmedState state) + public enum BeatDivisor { + Quarter_Measure, + Half_Measure, + Measure, + Double_Measure, + Quadruple_Measure } } } From 7fc0366afd56bfea4fcc91c45fc14124924218a6 Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Fri, 16 Sep 2022 13:18:38 +0200 Subject: [PATCH 0036/2991] Improve Tests Fix divisor in test --- .../Mods/TestSceneOsuModFreezeFrame.cs | 31 +++++++++++++------ .../Mods/OsuModFreezeFrame.cs | 17 +++++----- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs index 4642229436..8af63aa5e2 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs @@ -1,27 +1,40 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using NUnit.Framework; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; namespace osu.Game.Rulesets.Osu.Tests.Mods { public class TestSceneOsuModFreezeFrame : OsuModTestScene { - [TestCase(0.5f)] - [TestCase(1)] - [TestCase(2)] - public void TestFreezeFrequency(float beatMeasure) + [TestCase(OsuModFreezeFrame.BeatDivisor.Quarter_Measure)] + [TestCase(OsuModFreezeFrame.BeatDivisor.Single_Measure)] + [TestCase(OsuModFreezeFrame.BeatDivisor.Quadruple_Measure)] + public void TestFreezeFrequency(OsuModFreezeFrame.BeatDivisor divisor) { CreateModTest(new ModTestData { - Mod = new OsuModFreezeFrame - { - BeatDivisor = { Value = beatMeasure } - }, - PassCondition = () => true, + Mod = new OsuModFreezeFrame { Divisor = { Value = divisor } }, + PassCondition = checkSomeHit, Autoplay = true }); } + + [Test] + public void TestWithHidden() + { + var mods = new List { new OsuModHidden(), new OsuModFreezeFrame { Divisor = { Value = OsuModFreezeFrame.BeatDivisor.Quadruple_Measure } } }; + CreateModTest(new ModTestData + { + Mods = mods, + PassCondition = checkSomeHit, + Autoplay = true + }); + } + + private bool checkSomeHit() => Player.ScoreProcessor.JudgedHits >= 8; } } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 42c4a8fa20..08a8a85740 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModFreezeFrame : ModWithVisibilityAdjustment, IHidesApproachCircles, IApplicableToDrawableRuleset { - public override string Name => "Freeze frame"; + public override string Name => "Freeze Frame"; public override string Acronym => "FF"; @@ -26,10 +26,9 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Fun; public override IconUsage? Icon => FontAwesome.Solid.Camera; - public override Type[] IncompatibleMods => new[] { typeof(OsuModTarget), typeof(OsuModStrictTracking) }; - [SettingSource("Beat divisor")] - public Bindable Divisor { get; } = new Bindable(BeatDivisor.Measure); + [SettingSource("Measure", "How often the hitcircles should be Grouped to freeze")] + public Bindable Divisor { get; } = new Bindable(BeatDivisor.Single_Measure); public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { @@ -42,11 +41,10 @@ namespace osu.Game.Rulesets.Osu.Mods foreach (var obj in beatmap.HitObjects.OfType()) { + // The +1s below are added due to First HitCircle in each measure not appearing appropriately without them. var lastTimingPoint = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime + 1); - // +1 is added due to First HitCircle in each measure not appearing appropriately without it double controlPointDifference = obj.StartTime + 1 - lastTimingPoint.Time; - double remainder = controlPointDifference % (lastTimingPoint.BeatLength * getMeasure(Divisor.Value)); - + double remainder = controlPointDifference % (lastTimingPoint.BeatLength * getMeasure(Divisor.Value)) - 1; double finalPreempt = obj.TimePreempt + remainder; applyFadeInAdjustment(obj); @@ -73,7 +71,7 @@ namespace osu.Game.Rulesets.Osu.Mods case BeatDivisor.Half_Measure: return 0.5f; - case BeatDivisor.Measure: + case BeatDivisor.Single_Measure: return 1; case BeatDivisor.Double_Measure: @@ -87,11 +85,12 @@ namespace osu.Game.Rulesets.Osu.Mods } } + //Todo: find better way to represent these Enums to the player public enum BeatDivisor { Quarter_Measure, Half_Measure, - Measure, + Single_Measure, Double_Measure, Quadruple_Measure } From 427bd182697cf40af987cd09526f643213752520 Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Fri, 16 Sep 2022 13:36:04 +0200 Subject: [PATCH 0037/2991] Add Copyright header --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 08a8a85740..6b29c511ec 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -1,3 +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; @@ -27,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override IconUsage? Icon => FontAwesome.Solid.Camera; - [SettingSource("Measure", "How often the hitcircles should be Grouped to freeze")] + [SettingSource("Measure", "How often the hit-circles should be Grouped to freeze")] public Bindable Divisor { get; } = new Bindable(BeatDivisor.Single_Measure); public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) From 6db8f51c02fd7d96e67870951a02ded4eb7c865b Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Fri, 16 Sep 2022 13:45:18 +0200 Subject: [PATCH 0038/2991] Improve Tests Fix divisor in test Add Copyright header --- .../Mods/TestSceneOsuModFreezeFrame.cs | 31 +++++++++++++------ .../Mods/OsuModFreezeFrame.cs | 20 ++++++------ 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs index 4642229436..8af63aa5e2 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs @@ -1,27 +1,40 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using NUnit.Framework; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; namespace osu.Game.Rulesets.Osu.Tests.Mods { public class TestSceneOsuModFreezeFrame : OsuModTestScene { - [TestCase(0.5f)] - [TestCase(1)] - [TestCase(2)] - public void TestFreezeFrequency(float beatMeasure) + [TestCase(OsuModFreezeFrame.BeatDivisor.Quarter_Measure)] + [TestCase(OsuModFreezeFrame.BeatDivisor.Single_Measure)] + [TestCase(OsuModFreezeFrame.BeatDivisor.Quadruple_Measure)] + public void TestFreezeFrequency(OsuModFreezeFrame.BeatDivisor divisor) { CreateModTest(new ModTestData { - Mod = new OsuModFreezeFrame - { - BeatDivisor = { Value = beatMeasure } - }, - PassCondition = () => true, + Mod = new OsuModFreezeFrame { Divisor = { Value = divisor } }, + PassCondition = checkSomeHit, Autoplay = true }); } + + [Test] + public void TestWithHidden() + { + var mods = new List { new OsuModHidden(), new OsuModFreezeFrame { Divisor = { Value = OsuModFreezeFrame.BeatDivisor.Quadruple_Measure } } }; + CreateModTest(new ModTestData + { + Mods = mods, + PassCondition = checkSomeHit, + Autoplay = true + }); + } + + private bool checkSomeHit() => Player.ScoreProcessor.JudgedHits >= 8; } } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 42c4a8fa20..6b29c511ec 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -1,3 +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; @@ -15,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModFreezeFrame : ModWithVisibilityAdjustment, IHidesApproachCircles, IApplicableToDrawableRuleset { - public override string Name => "Freeze frame"; + public override string Name => "Freeze Frame"; public override string Acronym => "FF"; @@ -26,10 +29,9 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Fun; public override IconUsage? Icon => FontAwesome.Solid.Camera; - public override Type[] IncompatibleMods => new[] { typeof(OsuModTarget), typeof(OsuModStrictTracking) }; - [SettingSource("Beat divisor")] - public Bindable Divisor { get; } = new Bindable(BeatDivisor.Measure); + [SettingSource("Measure", "How often the hit-circles should be Grouped to freeze")] + public Bindable Divisor { get; } = new Bindable(BeatDivisor.Single_Measure); public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { @@ -42,11 +44,10 @@ namespace osu.Game.Rulesets.Osu.Mods foreach (var obj in beatmap.HitObjects.OfType()) { + // The +1s below are added due to First HitCircle in each measure not appearing appropriately without them. var lastTimingPoint = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime + 1); - // +1 is added due to First HitCircle in each measure not appearing appropriately without it double controlPointDifference = obj.StartTime + 1 - lastTimingPoint.Time; - double remainder = controlPointDifference % (lastTimingPoint.BeatLength * getMeasure(Divisor.Value)); - + double remainder = controlPointDifference % (lastTimingPoint.BeatLength * getMeasure(Divisor.Value)) - 1; double finalPreempt = obj.TimePreempt + remainder; applyFadeInAdjustment(obj); @@ -73,7 +74,7 @@ namespace osu.Game.Rulesets.Osu.Mods case BeatDivisor.Half_Measure: return 0.5f; - case BeatDivisor.Measure: + case BeatDivisor.Single_Measure: return 1; case BeatDivisor.Double_Measure: @@ -87,11 +88,12 @@ namespace osu.Game.Rulesets.Osu.Mods } } + //Todo: find better way to represent these Enums to the player public enum BeatDivisor { Quarter_Measure, Half_Measure, - Measure, + Single_Measure, Double_Measure, Quadruple_Measure } From a0c493656f7e738bb0fe5d52d00308ebc4310ab2 Mon Sep 17 00:00:00 2001 From: Mk-56spn Date: Fri, 16 Sep 2022 15:27:36 +0200 Subject: [PATCH 0039/2991] Remove Incompatibility with Approach Circle requiring mods --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 6b29c511ec..6a0faf9298 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -16,7 +16,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModFreezeFrame : ModWithVisibilityAdjustment, IHidesApproachCircles, IApplicableToDrawableRuleset + public class OsuModFreezeFrame : ModWithVisibilityAdjustment, IApplicableToDrawableRuleset { public override string Name => "Freeze Frame"; From c1077d909ca5e41270522714e8457733a36043f2 Mon Sep 17 00:00:00 2001 From: Ryuki Date: Sat, 17 Sep 2022 21:09:34 +0200 Subject: [PATCH 0040/2991] Basic avatar HUD implementation --- osu.Game/Screens/Play/HUD/SkinnableAvatar.cs | 50 ++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 osu.Game/Screens/Play/HUD/SkinnableAvatar.cs diff --git a/osu.Game/Screens/Play/HUD/SkinnableAvatar.cs b/osu.Game/Screens/Play/HUD/SkinnableAvatar.cs new file mode 100644 index 0000000000..abec4402a7 --- /dev/null +++ b/osu.Game/Screens/Play/HUD/SkinnableAvatar.cs @@ -0,0 +1,50 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Configuration; +using osu.Game.Skinning; +using osu.Game.Users.Drawables; +using osuTK; + +namespace osu.Game.Screens.Play.HUD +{ + public class SkinnableAvatar : CompositeDrawable, ISkinnableDrawable + { + [SettingSource("Corner radius", "How much the edges should be rounded.")] + public new BindableFloat CornerRadius { get; set; } = new BindableFloat(0) + { + MinValue = 0, + MaxValue = 100, + Precision = 0.01f + }; + + [Resolved] + private GameplayState gameplayState { get; set; } = null!; + + private readonly UpdateableAvatar avatar; + + public SkinnableAvatar() + { + Size = new Vector2(128f); + InternalChild = avatar = new UpdateableAvatar(isInteractive: false) + { + RelativeSizeAxes = Axes.Both, + Masking = true + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + avatar.User = gameplayState.Score.ScoreInfo.User; + CornerRadius.BindValueChanged(e => avatar.CornerRadius = e.NewValue); + } + + public bool UsesFixedAnchor { get; set; } + } +} From ecf71df8a23bfca5cbe5a78daef23908135d92c2 Mon Sep 17 00:00:00 2001 From: Ryuki Date: Sun, 18 Sep 2022 00:04:56 +0200 Subject: [PATCH 0041/2991] Change CornerRadius Max Value --- osu.Game/Screens/Play/HUD/SkinnableAvatar.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/SkinnableAvatar.cs b/osu.Game/Screens/Play/HUD/SkinnableAvatar.cs index abec4402a7..d675176a0a 100644 --- a/osu.Game/Screens/Play/HUD/SkinnableAvatar.cs +++ b/osu.Game/Screens/Play/HUD/SkinnableAvatar.cs @@ -15,10 +15,10 @@ namespace osu.Game.Screens.Play.HUD public class SkinnableAvatar : CompositeDrawable, ISkinnableDrawable { [SettingSource("Corner radius", "How much the edges should be rounded.")] - public new BindableFloat CornerRadius { get; set; } = new BindableFloat(0) + public new BindableFloat CornerRadius { get; set; } = new BindableFloat { MinValue = 0, - MaxValue = 100, + MaxValue = 63, Precision = 0.01f }; From 6d3e42a248021605150fbda3a7cfb8d9a4b98dd4 Mon Sep 17 00:00:00 2001 From: "D.Headley" Date: Sun, 18 Sep 2022 19:35:12 +0200 Subject: [PATCH 0042/2991] Give enums descriptions, change acronym and remove icon --- .../Mods/OsuModFreezeFrame.cs | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 6a0faf9298..26adc0f25f 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -3,8 +3,8 @@ using System; using System.Linq; +using System.ComponentModel; using osu.Framework.Bindables; -using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Configuration; @@ -20,17 +20,15 @@ namespace osu.Game.Rulesets.Osu.Mods { public override string Name => "Freeze Frame"; - public override string Acronym => "FF"; + public override string Acronym => "FR"; public override double ScoreMultiplier => 1; - public override LocalisableString Description => "Burn the notes into your memory"; + public override LocalisableString Description => "Burn the notes into your memory."; public override ModType Type => ModType.Fun; - public override IconUsage? Icon => FontAwesome.Solid.Camera; - - [SettingSource("Measure", "How often the hit-circles should be Grouped to freeze")] + [SettingSource("Beat Divisor", "How often the hitobjects should be grouped according to BPM")] public Bindable Divisor { get; } = new Bindable(BeatDivisor.Single_Measure); public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) @@ -88,15 +86,22 @@ namespace osu.Game.Rulesets.Osu.Mods } } - //Todo: find better way to represent these Enums to the player public enum BeatDivisor { + [Description("1/4")] Quarter_Measure, + + [Description("1/2")] Half_Measure, + + [Description("1")] Single_Measure, + + [Description("2")] Double_Measure, + + [Description("4")] Quadruple_Measure } } } - From 9c4ae768f16e3d7c0f4c7f57c78480eb92ce34d4 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Tue, 27 Sep 2022 20:08:32 +0900 Subject: [PATCH 0043/2991] show object in timeline before placed just BeginPlacement() --- .../Edit/Blueprints/HitPlacementBlueprint.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs index df1450bf77..08e7e57688 100644 --- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs @@ -26,6 +26,11 @@ namespace osu.Game.Rulesets.Taiko.Edit.Blueprints Size = new Vector2(TaikoHitObject.DEFAULT_SIZE * TaikoPlayfield.DEFAULT_HEIGHT) }; } + protected override void LoadComplete() + { + base.LoadComplete(); + BeginPlacement(); + } protected override bool OnMouseDown(MouseDownEvent e) { From 344015a6e6bec291b9829007938354b0e1474325 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Tue, 27 Sep 2022 20:12:40 +0900 Subject: [PATCH 0044/2991] do not move timeline when EndPlacement --- .../Edit/TaikoHitObjectComposer.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs b/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs index 1c1a5c325f..06c982397c 100644 --- a/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs +++ b/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Tools; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Screens.Edit.Compose.Components; @@ -18,6 +19,16 @@ namespace osu.Game.Rulesets.Taiko.Edit { } + public override void EndPlacement(HitObject hitObject, bool commit) + { + EditorBeatmap.PlacementObject.Value = null; + + if (commit) + { + EditorBeatmap.Add(hitObject); + } + } + protected override IReadOnlyList CompositionTools => new HitObjectCompositionTool[] { new HitCompositionTool(), From d84c956af9c648966da6a0063c39f63e34805651 Mon Sep 17 00:00:00 2001 From: vun Date: Thu, 29 Sep 2022 15:27:26 +0800 Subject: [PATCH 0045/2991] Refactor to move first-object detection to evaluation --- .../Difficulty/Evaluators/ColourEvaluator.cs | 12 +++++----- .../Colour/Data/AlternatingMonoPattern.cs | 6 +++++ .../Colour/Data/RepeatingHitPatterns.cs | 8 ++++++- .../TaikoColourDifficultyPreprocessor.cs | 23 +++++++++++++------ .../Colour/TaikoDifficultyHitObjectColour.cs | 6 ++--- 5 files changed, 38 insertions(+), 17 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs index 7d88be2f70..36f8babc6b 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs @@ -54,12 +54,12 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators TaikoDifficultyHitObjectColour colour = ((TaikoDifficultyHitObject)hitObject).Colour; double difficulty = 0.0d; - if (colour.MonoStreak != null) // Difficulty for MonoStreak - difficulty += EvaluateDifficultyOf(colour.MonoStreak); - if (colour.AlternatingMonoPattern != null) // Difficulty for AlternatingMonoPattern - difficulty += EvaluateDifficultyOf(colour.AlternatingMonoPattern); - if (colour.RepeatingHitPattern != null) // Difficulty for RepeatingHitPattern - difficulty += EvaluateDifficultyOf(colour.RepeatingHitPattern); + if (colour.MonoStreak?.FirstHitObject == hitObject) // Difficulty for MonoStreak + difficulty += EvaluateDifficultyOf(colour.MonoStreak!); + if (colour.AlternatingMonoPattern?.FirstHitObject == hitObject) // Difficulty for AlternatingMonoPattern + difficulty += EvaluateDifficultyOf(colour.AlternatingMonoPattern!); + if (colour.RepeatingHitPattern?.FirstHitObject == hitObject) // Difficulty for RepeatingHitPattern + difficulty += EvaluateDifficultyOf(colour.RepeatingHitPattern!); return difficulty; } diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/AlternatingMonoPattern.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/AlternatingMonoPattern.cs index 7910a8262b..bc6e02319d 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/AlternatingMonoPattern.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/AlternatingMonoPattern.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.Linq; namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data { @@ -31,6 +32,11 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data /// public TaikoDifficultyHitObject FirstHitObject => MonoStreaks[0].FirstHitObject; + /// + /// All s in this . + /// + public IEnumerable AllHitObjects => MonoStreaks.SelectMany(streak => streak.HitObjects); + /// /// Determine if this is a repetition of another . This /// is a strict comparison and is true if and only if the colour sequence is exactly the same. diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs index fe0dc6dd9a..9e3d9a21b2 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using System.Collections.Generic; namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data @@ -23,10 +24,15 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data public readonly List AlternatingMonoPatterns = new List(); /// - /// The parent in this + /// The first in this /// public TaikoDifficultyHitObject FirstHitObject => AlternatingMonoPatterns[0].FirstHitObject; + /// + /// All s in this . + /// + public IEnumerable AllHitObjects => AlternatingMonoPatterns.SelectMany(pattern => pattern.AllHitObjects); + /// /// The previous . This is used to determine the repetition interval. /// diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs index d19e05f4e0..500078a879 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs @@ -15,18 +15,19 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour { /// /// Processes and encodes a list of s into a list of s, - /// assigning the appropriate s to each , - /// and pre-evaluating colour difficulty of each . + /// assigning the appropriate s to each . /// public static void ProcessAndAssign(List hitObjects) { List hitPatterns = encode(hitObjects); - // Assign indexing and encoding data to all relevant objects. Only the first note of each encoding type is - // assigned with the relevant encodings. + // Assign indexing and encoding data to all relevant objects. foreach (var repeatingHitPattern in hitPatterns) { - repeatingHitPattern.FirstHitObject.Colour.RepeatingHitPattern = repeatingHitPattern; + foreach (var hitObject in repeatingHitPattern.AllHitObjects) + { + hitObject.Colour.RepeatingHitPattern = repeatingHitPattern; + } // The outermost loop is kept a ForEach loop since it doesn't need index information, and we want to // keep i and j for AlternatingMonoPattern's and MonoStreak's index respectively, to keep it in line with @@ -36,14 +37,22 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour AlternatingMonoPattern monoPattern = repeatingHitPattern.AlternatingMonoPatterns[i]; monoPattern.Parent = repeatingHitPattern; monoPattern.Index = i; - monoPattern.FirstHitObject.Colour.AlternatingMonoPattern = monoPattern; + + foreach (var hitObject in monoPattern.AllHitObjects) + { + hitObject.Colour.AlternatingMonoPattern = monoPattern; + } for (int j = 0; j < monoPattern.MonoStreaks.Count; ++j) { MonoStreak monoStreak = monoPattern.MonoStreaks[j]; monoStreak.Parent = monoPattern; monoStreak.Index = j; - monoStreak.FirstHitObject.Colour.MonoStreak = monoStreak; + + foreach (var hitObject in monoStreak.HitObjects) + { + hitObject.Colour.MonoStreak = monoStreak; + } } } } diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs index 9c147eee9c..84b6871ba7 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs @@ -11,17 +11,17 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour public class TaikoDifficultyHitObjectColour { /// - /// The that encodes this note, only present if this is the first note within a + /// The that encodes this note. /// public MonoStreak? MonoStreak; /// - /// The that encodes this note, only present if this is the first note within a + /// The that encodes this note. /// public AlternatingMonoPattern? AlternatingMonoPattern; /// - /// The that encodes this note, only present if this is the first note within a + /// The that encodes this note. /// public RepeatingHitPatterns? RepeatingHitPattern; } From 09a38fec94b55ed5edd25f36496a4e5de375bf95 Mon Sep 17 00:00:00 2001 From: vun Date: Fri, 30 Sep 2022 09:10:56 +0800 Subject: [PATCH 0046/2991] Implement mono tl nerf for stamina, disable convert specific nerfs --- .../Difficulty/Evaluators/StaminaEvaluator.cs | 25 ++++++++++++++++++- .../Preprocessing/Colour/Data/MonoStreak.cs | 5 ++++ .../Difficulty/TaikoDifficultyCalculator.cs | 9 ------- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs index 49b3ae2e19..9c5251df9b 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs @@ -24,6 +24,29 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators return 30 / interval; } + /// + /// Determines the number of fingers available to hit the current . + /// Any mono notes that is more than 0.5s apart from note of the other colour will be considered to have more + /// than 2 fingers available, since players can move their hand over to hit the same key with multiple fingers. + /// + private static int availableFingersFor(TaikoDifficultyHitObject hitObject) + { + DifficultyHitObject? previousColourChange = hitObject.Colour.MonoStreak?.FirstHitObject.Previous(0); + DifficultyHitObject? nextColourChange = hitObject.Colour.MonoStreak?.LastHitObject.Next(0); + + if (previousColourChange != null && hitObject.StartTime - previousColourChange.StartTime < 300) + { + return 2; + } + + if (nextColourChange != null && nextColourChange.StartTime - hitObject.StartTime < 300) + { + return 2; + } + + return 5; + } + /// /// Evaluates the minimum mechanical stamina required to play the current object. This is calculated using the /// maximum possible interval between two hits using the same key, by alternating 2 keys for each colour. @@ -37,7 +60,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators // Find the previous hit object hit by the current key, which is two notes of the same colour prior. TaikoDifficultyHitObject taikoCurrent = (TaikoDifficultyHitObject)current; - TaikoDifficultyHitObject? keyPrevious = taikoCurrent.PreviousMono(1); + TaikoDifficultyHitObject? keyPrevious = taikoCurrent.PreviousMono(availableFingersFor(taikoCurrent) - 1); if (keyPrevious == null) { diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/MonoStreak.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/MonoStreak.cs index 174988bed7..c01a0f6686 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/MonoStreak.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/MonoStreak.cs @@ -33,6 +33,11 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data /// public TaikoDifficultyHitObject FirstHitObject => HitObjects[0]; + /// + /// The last in this . + /// + public TaikoDifficultyHitObject LastHitObject => HitObjects[^1]; + /// /// The hit type of all objects encoded within this /// diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs index 2b0b563323..24b5f5939a 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs @@ -83,15 +83,6 @@ namespace osu.Game.Rulesets.Taiko.Difficulty double combinedRating = combined.DifficultyValue() * difficulty_multiplier; double starRating = rescale(combinedRating * 1.4); - // TODO: This is temporary measure as we don't detect abuse of multiple-input playstyles of converts within the current system. - if (beatmap.BeatmapInfo.Ruleset.OnlineID == 0) - { - starRating *= 0.925; - // For maps with low colour variance and high stamina requirement, multiple inputs are more likely to be abused. - if (colourRating < 2 && staminaRating > 8) - starRating *= 0.80; - } - HitWindows hitWindows = new TaikoHitWindows(); hitWindows.SetDifficulty(beatmap.Difficulty.OverallDifficulty); From 02092ede649fbcb5126c0d48197a1778414c3768 Mon Sep 17 00:00:00 2001 From: vun Date: Fri, 30 Sep 2022 11:42:48 +0800 Subject: [PATCH 0047/2991] Refactor previous and next colour change into TaikoDifficultyHitObjectColour --- .../Difficulty/Evaluators/StaminaEvaluator.cs | 4 ++-- .../Colour/TaikoDifficultyHitObjectColour.cs | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs index 9c5251df9b..6a07d49f98 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs @@ -31,8 +31,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators /// private static int availableFingersFor(TaikoDifficultyHitObject hitObject) { - DifficultyHitObject? previousColourChange = hitObject.Colour.MonoStreak?.FirstHitObject.Previous(0); - DifficultyHitObject? nextColourChange = hitObject.Colour.MonoStreak?.LastHitObject.Next(0); + DifficultyHitObject? previousColourChange = hitObject.Colour.PreviousColourChange; + DifficultyHitObject? nextColourChange = hitObject.Colour.NextColourChange; if (previousColourChange != null && hitObject.StartTime - previousColourChange.StartTime < 300) { diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs index 84b6871ba7..abf6fb3672 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs @@ -24,5 +24,15 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour /// The that encodes this note. /// public RepeatingHitPatterns? RepeatingHitPattern; + + /// + /// The closest past that's not the same colour. + /// + public TaikoDifficultyHitObject? PreviousColourChange => MonoStreak?.FirstHitObject.PreviousNote(0); + + /// + /// The closest future that's not the same colour. + /// + public TaikoDifficultyHitObject? NextColourChange => MonoStreak?.LastHitObject.NextNote(0); } } From e6093f94df42cacce79dcd42208989ecbb76bf33 Mon Sep 17 00:00:00 2001 From: vun Date: Fri, 30 Sep 2022 20:56:16 +0800 Subject: [PATCH 0048/2991] Apply nerfs to HD/FL bonuses with converts --- .../Difficulty/TaikoPerformanceCalculator.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index 95a1e8bc66..6becfd349d 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -41,6 +41,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (totalSuccessfulHits > 0) effectiveMissCount = Math.Max(1.0, 1000.0 / totalSuccessfulHits) * countMiss; + // We are disabling some HD and/or FL Bonus for converts for now due to them having low pattern difficulty, and thus being easy to memorize. + bool readingBonusEnabled = score.BeatmapInfo.Ruleset.OnlineID == 1; + double multiplier = 1.13; if (score.Mods.Any(m => m is ModHidden)) @@ -49,8 +52,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModEasy)) multiplier *= 0.975; - double difficultyValue = computeDifficultyValue(score, taikoAttributes); - double accuracyValue = computeAccuracyValue(score, taikoAttributes); + double difficultyValue = computeDifficultyValue(score, taikoAttributes, readingBonusEnabled); + double accuracyValue = computeAccuracyValue(score, taikoAttributes, readingBonusEnabled); double totalValue = Math.Pow( Math.Pow(difficultyValue, 1.1) + @@ -66,7 +69,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty }; } - private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes) + private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool readingBonusEnabled) { double difficultyValue = Math.Pow(5 * Math.Max(1.0, attributes.StarRating / 0.115) - 4.0, 2.25) / 1150.0; @@ -78,19 +81,19 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModEasy)) difficultyValue *= 0.985; - if (score.Mods.Any(m => m is ModHidden)) + if (score.Mods.Any(m => m is ModHidden) && readingBonusEnabled) difficultyValue *= 1.025; if (score.Mods.Any(m => m is ModHardRock)) difficultyValue *= 1.050; - if (score.Mods.Any(m => m is ModFlashlight)) + if (score.Mods.Any(m => m is ModFlashlight) && readingBonusEnabled) difficultyValue *= 1.050 * lengthBonus; return difficultyValue * Math.Pow(score.Accuracy, 2.0); } - private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes) + private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool readingBonusEnabled) { if (attributes.GreatHitWindow <= 0) return 0; @@ -100,8 +103,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty double lengthBonus = Math.Min(1.15, Math.Pow(totalHits / 1500.0, 0.3)); accuracyValue *= lengthBonus; - // Slight HDFL Bonus for accuracy. A clamp is used to prevent against negative values - if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden)) + // Slight HDFL Bonus for accuracy. A clamp is used to prevent against negative values. + if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && readingBonusEnabled) accuracyValue *= Math.Max(1.050, 1.075 * lengthBonus); return accuracyValue; From a276e400333517524a2c4c6ea14dce891c24480d Mon Sep 17 00:00:00 2001 From: Jay L Date: Sun, 2 Oct 2022 09:05:58 +1000 Subject: [PATCH 0049/2991] reintroduce fl bonus to converts --- .../Difficulty/TaikoPerformanceCalculator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index 6becfd349d..fe3dd1fad1 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModHardRock)) difficultyValue *= 1.050; - if (score.Mods.Any(m => m is ModFlashlight) && readingBonusEnabled) + if (score.Mods.Any(m => m is ModFlashlight)) difficultyValue *= 1.050 * lengthBonus; return difficultyValue * Math.Pow(score.Accuracy, 2.0); @@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty double lengthBonus = Math.Min(1.15, Math.Pow(totalHits / 1500.0, 0.3)); accuracyValue *= lengthBonus; - // Slight HDFL Bonus for accuracy. A clamp is used to prevent against negative values. + // Slight HDFL Bonus for accuracy. A clamp is used to prevent against negative values. if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && readingBonusEnabled) accuracyValue *= Math.Max(1.050, 1.075 * lengthBonus); From 4b562f782f35327e5e13f928aebe79c0836535eb Mon Sep 17 00:00:00 2001 From: Jay L Date: Sun, 2 Oct 2022 15:28:39 +1000 Subject: [PATCH 0050/2991] decrease finger count --- .idea/.idea.osu/.idea/discord.xml | 7 +++++++ .../Difficulty/Evaluators/StaminaEvaluator.cs | 2 +- .../Difficulty/TaikoPerformanceCalculator.cs | 16 ++++++++-------- 3 files changed, 16 insertions(+), 9 deletions(-) create mode 100644 .idea/.idea.osu/.idea/discord.xml diff --git a/.idea/.idea.osu/.idea/discord.xml b/.idea/.idea.osu/.idea/discord.xml new file mode 100644 index 0000000000..30bab2abb1 --- /dev/null +++ b/.idea/.idea.osu/.idea/discord.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs index 6a07d49f98..3585393bbb 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators return 2; } - return 5; + return 4; } /// diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index fe3dd1fad1..63c18e5709 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty effectiveMissCount = Math.Max(1.0, 1000.0 / totalSuccessfulHits) * countMiss; // We are disabling some HD and/or FL Bonus for converts for now due to them having low pattern difficulty, and thus being easy to memorize. - bool readingBonusEnabled = score.BeatmapInfo.Ruleset.OnlineID == 1; + bool rulesetTaiko = score.BeatmapInfo.Ruleset.OnlineID == 1; double multiplier = 1.13; @@ -52,8 +52,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModEasy)) multiplier *= 0.975; - double difficultyValue = computeDifficultyValue(score, taikoAttributes, readingBonusEnabled); - double accuracyValue = computeAccuracyValue(score, taikoAttributes, readingBonusEnabled); + double difficultyValue = computeDifficultyValue(score, taikoAttributes, rulesetTaiko); + double accuracyValue = computeAccuracyValue(score, taikoAttributes, rulesetTaiko); double totalValue = Math.Pow( Math.Pow(difficultyValue, 1.1) + @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty }; } - private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool readingBonusEnabled) + private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool rulesetTaiko) { double difficultyValue = Math.Pow(5 * Math.Max(1.0, attributes.StarRating / 0.115) - 4.0, 2.25) / 1150.0; @@ -81,7 +81,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModEasy)) difficultyValue *= 0.985; - if (score.Mods.Any(m => m is ModHidden) && readingBonusEnabled) + if (score.Mods.Any(m => m is ModHidden) && rulesetTaiko) difficultyValue *= 1.025; if (score.Mods.Any(m => m is ModHardRock)) @@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty return difficultyValue * Math.Pow(score.Accuracy, 2.0); } - private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool readingBonusEnabled) + private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool rulesetTaiko) { if (attributes.GreatHitWindow <= 0) return 0; @@ -104,8 +104,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty accuracyValue *= lengthBonus; // Slight HDFL Bonus for accuracy. A clamp is used to prevent against negative values. - if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && readingBonusEnabled) - accuracyValue *= Math.Max(1.050, 1.075 * lengthBonus); + if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && rulesetTaiko) + accuracyValue *= Math.Max(1.0, 1.1 * lengthBonus); return accuracyValue; } From 6752655b5a181b05065d22a0e13da3714a5ba588 Mon Sep 17 00:00:00 2001 From: Jay L Date: Sun, 2 Oct 2022 16:08:14 +1000 Subject: [PATCH 0051/2991] xml, remove speedbonus cap --- .../Difficulty/Evaluators/StaminaEvaluator.cs | 6 ++---- .../Difficulty/TaikoPerformanceCalculator.cs | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs index 3585393bbb..3326d72588 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs @@ -16,10 +16,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators /// The interval between the current and previous note hit using the same key. private static double speedBonus(double interval) { - // Cap to 600bpm 1/4, 25ms note interval, 50ms key interval - // Interval will be capped at a very small value to avoid infinite/negative speed bonuses. - // TODO - This is a temporary measure as we need to implement methods of detecting playstyle-abuse of SpeedBonus. - interval = Math.Max(interval, 50); + // Interval is capped at a very small value to prevent infinite values. + interval = Math.Max(interval, 1); return 30 / interval; } diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index 63c18e5709..b9a9dacddc 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (totalSuccessfulHits > 0) effectiveMissCount = Math.Max(1.0, 1000.0 / totalSuccessfulHits) * countMiss; - // We are disabling some HD and/or FL Bonus for converts for now due to them having low pattern difficulty, and thus being easy to memorize. + // TODO: The detection of rulesets is temporary until the leftover old skills have been reworked. bool rulesetTaiko = score.BeatmapInfo.Ruleset.OnlineID == 1; double multiplier = 1.13; From c933b62df63ccd4b6fdf78e49622748902e2723c Mon Sep 17 00:00:00 2001 From: vun Date: Mon, 3 Oct 2022 14:16:53 +0800 Subject: [PATCH 0052/2991] Correct xmldoc --- .../Difficulty/Evaluators/StaminaEvaluator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs index 3326d72588..55dce4e9b3 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs @@ -24,8 +24,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators /// /// Determines the number of fingers available to hit the current . - /// Any mono notes that is more than 0.5s apart from note of the other colour will be considered to have more - /// than 2 fingers available, since players can move their hand over to hit the same key with multiple fingers. + /// Any mono notes that is more than 300ms apart from a colour change will be considered to have more than 2 + /// fingers available, since players can hit the same key with multiple fingers. /// private static int availableFingersFor(TaikoDifficultyHitObject hitObject) { From 25976e1f105ab36e185fa9ee8d274e20c2a733d7 Mon Sep 17 00:00:00 2001 From: vun Date: Mon, 3 Oct 2022 14:20:01 +0800 Subject: [PATCH 0053/2991] Correct xmldocs --- .../Difficulty/Evaluators/StaminaEvaluator.cs | 11 ++++++----- osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs | 3 --- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs index 55dce4e9b3..59b61f47d1 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs @@ -11,9 +11,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators public class StaminaEvaluator { /// - /// Applies a speed bonus dependent on the time since the last hit performed using this key. + /// Applies a speed bonus dependent on the time since the last hit performed using this finger. /// - /// The interval between the current and previous note hit using the same key. + /// The interval between the current and previous note hit using the same finger. private static double speedBonus(double interval) { // Interval is capped at a very small value to prevent infinite values. @@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators /// /// Evaluates the minimum mechanical stamina required to play the current object. This is calculated using the - /// maximum possible interval between two hits using the same key, by alternating 2 keys for each colour. + /// maximum possible interval between two hits using the same key, by alternating available fingers for each colour. /// public static double EvaluateDifficultyOf(DifficultyHitObject current) { @@ -56,13 +56,14 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators return 0.0; } - // Find the previous hit object hit by the current key, which is two notes of the same colour prior. + // Find the previous hit object hit by the current finger, which is n notes prior, n being the number of + // available fingers. TaikoDifficultyHitObject taikoCurrent = (TaikoDifficultyHitObject)current; TaikoDifficultyHitObject? keyPrevious = taikoCurrent.PreviousMono(availableFingersFor(taikoCurrent) - 1); if (keyPrevious == null) { - // There is no previous hit object hit by the current key + // There is no previous hit object hit by the current finger return 0.0; } diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs index 344004bcf6..d04c028fec 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs @@ -13,9 +13,6 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills /// /// Calculates the stamina coefficient of taiko difficulty. /// - /// - /// The reference play style chosen uses two hands, with full alternating (the hand changes after every hit). - /// public class Stamina : StrainDecaySkill { protected override double SkillMultiplier => 1.1; From 7e578f868c6eed983485c29f99874d786714720c Mon Sep 17 00:00:00 2001 From: Jay L Date: Mon, 3 Oct 2022 16:55:11 +1000 Subject: [PATCH 0054/2991] remove idea plugin xml --- .idea/.idea.osu/.idea/discord.xml | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 .idea/.idea.osu/.idea/discord.xml diff --git a/.idea/.idea.osu/.idea/discord.xml b/.idea/.idea.osu/.idea/discord.xml deleted file mode 100644 index 30bab2abb1..0000000000 --- a/.idea/.idea.osu/.idea/discord.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - \ No newline at end of file From 47781a8f94ae17baf44dda250e32bfdfad7eecd6 Mon Sep 17 00:00:00 2001 From: vun Date: Mon, 3 Oct 2022 17:31:45 +0800 Subject: [PATCH 0055/2991] Fix code inspect issues and SR test cases --- .../TaikoDifficultyCalculatorTest.cs | 8 ++++---- .../Difficulty/Evaluators/StaminaEvaluator.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoDifficultyCalculatorTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoDifficultyCalculatorTest.cs index 425f72cadc..5685ac0f60 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TaikoDifficultyCalculatorTest.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TaikoDifficultyCalculatorTest.cs @@ -16,13 +16,13 @@ namespace osu.Game.Rulesets.Taiko.Tests { protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko"; - [TestCase(3.1098944660126882d, 200, "diffcalc-test")] - [TestCase(3.1098944660126882d, 200, "diffcalc-test-strong")] + [TestCase(3.0920212594351191d, 200, "diffcalc-test")] + [TestCase(3.0920212594351191d, 200, "diffcalc-test-strong")] public void Test(double expectedStarRating, int expectedMaxCombo, string name) => base.Test(expectedStarRating, expectedMaxCombo, name); - [TestCase(4.0974106752474251d, 200, "diffcalc-test")] - [TestCase(4.0974106752474251d, 200, "diffcalc-test-strong")] + [TestCase(4.0789820318081444d, 200, "diffcalc-test")] + [TestCase(4.0789820318081444d, 200, "diffcalc-test-strong")] public void TestClockRateAdjusted(double expectedStarRating, int expectedMaxCombo, string name) => Test(expectedStarRating, expectedMaxCombo, name, new TaikoModDoubleTime()); diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs index 59b61f47d1..84d5de4c63 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators /// /// Determines the number of fingers available to hit the current . - /// Any mono notes that is more than 300ms apart from a colour change will be considered to have more than 2 + /// Any mono notes that is more than 300ms apart from a colour change will be considered to have more than 2 /// fingers available, since players can hit the same key with multiple fingers. /// private static int availableFingersFor(TaikoDifficultyHitObject hitObject) From 122064d03fcdb4fa65dd7ccbbb20eebd4148a33e Mon Sep 17 00:00:00 2001 From: vun Date: Sun, 9 Oct 2022 07:09:05 +0800 Subject: [PATCH 0056/2991] Minor refactoring to reduce amount of looping --- .../Colour/Data/AlternatingMonoPattern.cs | 6 ------ .../Colour/Data/RepeatingHitPatterns.cs | 6 ------ .../Colour/TaikoColourDifficultyPreprocessor.cs | 12 ++---------- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/AlternatingMonoPattern.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/AlternatingMonoPattern.cs index bc6e02319d..7910a8262b 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/AlternatingMonoPattern.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/AlternatingMonoPattern.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; -using System.Linq; namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data { @@ -32,11 +31,6 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data /// public TaikoDifficultyHitObject FirstHitObject => MonoStreaks[0].FirstHitObject; - /// - /// All s in this . - /// - public IEnumerable AllHitObjects => MonoStreaks.SelectMany(streak => streak.HitObjects); - /// /// Determine if this is a repetition of another . This /// is a strict comparison and is true if and only if the colour sequence is exactly the same. diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs index 9e3d9a21b2..468a9ab876 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Linq; using System.Collections.Generic; namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data @@ -28,11 +27,6 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data /// public TaikoDifficultyHitObject FirstHitObject => AlternatingMonoPatterns[0].FirstHitObject; - /// - /// All s in this . - /// - public IEnumerable AllHitObjects => AlternatingMonoPatterns.SelectMany(pattern => pattern.AllHitObjects); - /// /// The previous . This is used to determine the repetition interval. /// diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs index 500078a879..18a299ae92 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs @@ -24,11 +24,6 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour // Assign indexing and encoding data to all relevant objects. foreach (var repeatingHitPattern in hitPatterns) { - foreach (var hitObject in repeatingHitPattern.AllHitObjects) - { - hitObject.Colour.RepeatingHitPattern = repeatingHitPattern; - } - // The outermost loop is kept a ForEach loop since it doesn't need index information, and we want to // keep i and j for AlternatingMonoPattern's and MonoStreak's index respectively, to keep it in line with // documentation. @@ -38,11 +33,6 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour monoPattern.Parent = repeatingHitPattern; monoPattern.Index = i; - foreach (var hitObject in monoPattern.AllHitObjects) - { - hitObject.Colour.AlternatingMonoPattern = monoPattern; - } - for (int j = 0; j < monoPattern.MonoStreaks.Count; ++j) { MonoStreak monoStreak = monoPattern.MonoStreaks[j]; @@ -51,6 +41,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour foreach (var hitObject in monoStreak.HitObjects) { + hitObject.Colour.RepeatingHitPattern = repeatingHitPattern; + hitObject.Colour.AlternatingMonoPattern = monoPattern; hitObject.Colour.MonoStreak = monoStreak; } } From e0904e263f4c976e24277c19f380650fb025499f Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Sun, 9 Oct 2022 11:25:47 +0200 Subject: [PATCH 0057/2991] Fix legacy BpmMultiplier clamp value --- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 9c066ada08..360a91a7e5 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -178,7 +178,7 @@ namespace osu.Game.Beatmaps.Formats : this() { // Note: In stable, the division occurs on floats, but with compiler optimisations turned on actually seems to occur on doubles via some .NET black magic (possibly inlining?). - BpmMultiplier = beatLength < 0 ? Math.Clamp((float)-beatLength, 10, 10000) / 100.0 : 1; + BpmMultiplier = beatLength < 0 ? Math.Clamp((float)-beatLength, 10, 1000) / 100.0 : 1; GenerateTicks = !double.IsNaN(beatLength); } From f8036658c701e3f85b808c1b121ec9f35d50b0f0 Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Mon, 10 Oct 2022 09:36:18 +0200 Subject: [PATCH 0058/2991] Move clamps directly to the usages in the conversion algorithm --- .../Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs | 2 +- osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 2bdd0e16ad..89b52a3c75 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy #pragma warning disable 618 if (difficultyPoint is LegacyBeatmapDecoder.LegacyDifficultyControlPoint legacyDifficultyPoint) #pragma warning restore 618 - beatLength = timingPoint.BeatLength * legacyDifficultyPoint.BpmMultiplier; + beatLength = timingPoint.BeatLength * Math.Min(legacyDifficultyPoint.BpmMultiplier, 10); else beatLength = timingPoint.BeatLength / difficultyPoint.SliderVelocity; diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 524565a863..33f1535437 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -162,7 +162,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps #pragma warning disable 618 if (difficultyPoint is LegacyBeatmapDecoder.LegacyDifficultyControlPoint legacyDifficultyPoint) #pragma warning restore 618 - beatLength = timingPoint.BeatLength * legacyDifficultyPoint.BpmMultiplier; + beatLength = timingPoint.BeatLength * Math.Min(legacyDifficultyPoint.BpmMultiplier, 10); else beatLength = timingPoint.BeatLength / difficultyPoint.SliderVelocity; diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 360a91a7e5..9c066ada08 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -178,7 +178,7 @@ namespace osu.Game.Beatmaps.Formats : this() { // Note: In stable, the division occurs on floats, but with compiler optimisations turned on actually seems to occur on doubles via some .NET black magic (possibly inlining?). - BpmMultiplier = beatLength < 0 ? Math.Clamp((float)-beatLength, 10, 1000) / 100.0 : 1; + BpmMultiplier = beatLength < 0 ? Math.Clamp((float)-beatLength, 10, 10000) / 100.0 : 1; GenerateTicks = !double.IsNaN(beatLength); } From 9c611019b37d770355ccee2c23088238ac47d8e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20K=C3=A4llberg?= Date: Tue, 11 Oct 2022 09:30:32 +0200 Subject: [PATCH 0059/2991] Toolbar localisation --- osu.Game/Localisation/HomeStrings.cs | 24 +++++++++++++++++++ osu.Game/Localisation/RulesetStrings.cs | 20 ++++++++++++++++ .../Overlays/Toolbar/ToolbarHomeButton.cs | 5 ++-- .../Toolbar/ToolbarRulesetTabButton.cs | 4 +++- 4 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 osu.Game/Localisation/HomeStrings.cs create mode 100644 osu.Game/Localisation/RulesetStrings.cs diff --git a/osu.Game/Localisation/HomeStrings.cs b/osu.Game/Localisation/HomeStrings.cs new file mode 100644 index 0000000000..4a2cea00ca --- /dev/null +++ b/osu.Game/Localisation/HomeStrings.cs @@ -0,0 +1,24 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class HomeStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.Home"; + + /// + /// "home" + /// + public static LocalisableString HeaderTitle => new TranslatableString(getKey(@"header_title"), @"home"); + + /// + /// "return to the main menu" + /// + public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"return to the main menu"); + + private static string getKey(string key) => $"{prefix}:{key}"; + } +} \ No newline at end of file diff --git a/osu.Game/Localisation/RulesetStrings.cs b/osu.Game/Localisation/RulesetStrings.cs new file mode 100644 index 0000000000..201831cd91 --- /dev/null +++ b/osu.Game/Localisation/RulesetStrings.cs @@ -0,0 +1,20 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class RulesetStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.Ruleset"; + + /// + /// "play some" + /// + + public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"play some"); + + private static string getKey(string key) => $"{prefix}:{key}"; + } +} \ No newline at end of file diff --git a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs index f170ec84ac..52fa83e37a 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs @@ -5,6 +5,7 @@ using osu.Framework.Allocation; using osu.Game.Input.Bindings; +using osu.Game.Localisation; namespace osu.Game.Overlays.Toolbar { @@ -19,8 +20,8 @@ namespace osu.Game.Overlays.Toolbar [BackgroundDependencyLoader] private void load() { - TooltipMain = "home"; - TooltipSub = "return to the main menu"; + TooltipMain = HomeStrings.HeaderTitle; + TooltipSub = HomeStrings.HeaderDescription; SetIcon("Icons/Hexacons/home"); } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs index 31c6802fda..101bba95cc 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs @@ -9,6 +9,8 @@ using osu.Game.Rulesets; using osuTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Input.Events; +using osu.Framework.Localisation; +using osu.Game.Localisation; namespace osu.Game.Overlays.Toolbar { @@ -29,7 +31,7 @@ namespace osu.Game.Overlays.Toolbar var rInstance = value.CreateInstance(); ruleset.TooltipMain = rInstance.Description; - ruleset.TooltipSub = $"play some {rInstance.Description}"; + ruleset.TooltipSub = LocalisableString.Format("{0} {1}", RulesetStrings.HeaderDescription, ($"{rInstance.Description}")); ruleset.SetIcon(rInstance.CreateIcon()); } From 63e651130af1954d7f8ce5ac1923a95abb2bc926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20K=C3=A4llberg?= Date: Tue, 11 Oct 2022 10:59:07 +0200 Subject: [PATCH 0060/2991] Grouped localisation strings --- osu.Game/Localisation/HomeStrings.cs | 24 ------------------- osu.Game/Localisation/RulesetStrings.cs | 20 ---------------- osu.Game/Localisation/ToolbarStrings.cs | 16 +++++++++++++ .../Overlays/Toolbar/ToolbarHomeButton.cs | 4 ++-- .../Toolbar/ToolbarRulesetTabButton.cs | 8 +++---- 5 files changed, 22 insertions(+), 50 deletions(-) delete mode 100644 osu.Game/Localisation/HomeStrings.cs delete mode 100644 osu.Game/Localisation/RulesetStrings.cs diff --git a/osu.Game/Localisation/HomeStrings.cs b/osu.Game/Localisation/HomeStrings.cs deleted file mode 100644 index 4a2cea00ca..0000000000 --- a/osu.Game/Localisation/HomeStrings.cs +++ /dev/null @@ -1,24 +0,0 @@ -// 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.Localisation; - -namespace osu.Game.Localisation -{ - public static class HomeStrings - { - private const string prefix = @"osu.Game.Resources.Localisation.Home"; - - /// - /// "home" - /// - public static LocalisableString HeaderTitle => new TranslatableString(getKey(@"header_title"), @"home"); - - /// - /// "return to the main menu" - /// - public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"return to the main menu"); - - private static string getKey(string key) => $"{prefix}:{key}"; - } -} \ No newline at end of file diff --git a/osu.Game/Localisation/RulesetStrings.cs b/osu.Game/Localisation/RulesetStrings.cs deleted file mode 100644 index 201831cd91..0000000000 --- a/osu.Game/Localisation/RulesetStrings.cs +++ /dev/null @@ -1,20 +0,0 @@ -// 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.Localisation; - -namespace osu.Game.Localisation -{ - public static class RulesetStrings - { - private const string prefix = @"osu.Game.Resources.Localisation.Ruleset"; - - /// - /// "play some" - /// - - public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"play some"); - - private static string getKey(string key) => $"{prefix}:{key}"; - } -} \ No newline at end of file diff --git a/osu.Game/Localisation/ToolbarStrings.cs b/osu.Game/Localisation/ToolbarStrings.cs index 6dc8a1e50c..b76c643332 100644 --- a/osu.Game/Localisation/ToolbarStrings.cs +++ b/osu.Game/Localisation/ToolbarStrings.cs @@ -19,6 +19,22 @@ namespace osu.Game.Localisation /// public static LocalisableString Connecting => new TranslatableString(getKey(@"connecting"), @"Connecting..."); + /// + /// "home" + /// + public static LocalisableString HomeHeaderTitle => new TranslatableString(getKey(@"header_title"), @"home"); + + /// + /// "return to the main menu" + /// + public static LocalisableString HomeHeaderDescription => new TranslatableString(getKey(@"header_description"), @"return to the main menu"); + + /// + /// "play some" + /// + + public static LocalisableString RulesetHeaderDescription => new TranslatableString(getKey(@"header_description"), @"play some"); + private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs index 52fa83e37a..959706b805 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs @@ -20,8 +20,8 @@ namespace osu.Game.Overlays.Toolbar [BackgroundDependencyLoader] private void load() { - TooltipMain = HomeStrings.HeaderTitle; - TooltipSub = HomeStrings.HeaderDescription; + TooltipMain = ToolbarStrings.HomeHeaderTitle; + TooltipSub = ToolbarStrings.HomeHeaderDescription; SetIcon("Icons/Hexacons/home"); } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs index 101bba95cc..bffd8b96e5 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs @@ -3,14 +3,14 @@ #nullable disable +using osu.Framework.Graphics; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.UserInterface; -using osu.Game.Rulesets; -using osuTK.Graphics; -using osu.Framework.Graphics; using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Game.Localisation; +using osu.Game.Rulesets; +using osuTK.Graphics; namespace osu.Game.Overlays.Toolbar { @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Toolbar var rInstance = value.CreateInstance(); ruleset.TooltipMain = rInstance.Description; - ruleset.TooltipSub = LocalisableString.Format("{0} {1}", RulesetStrings.HeaderDescription, ($"{rInstance.Description}")); + ruleset.TooltipSub = LocalisableString.Format("{0} {1}", ToolbarStrings.RulesetHeaderDescription, ($"{rInstance.Description}")); ruleset.SetIcon(rInstance.CreateIcon()); } From 0a0d6993084ce9f2a9010eea9a00a45c2f03df31 Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Tue, 11 Oct 2022 22:43:47 +0200 Subject: [PATCH 0061/2991] Convert slider velocity to scroll speed in taiko beatmap conversion --- .../Beatmaps/TaikoBeatmapConverter.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 524565a863..c1e1052569 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -57,6 +57,29 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps Beatmap converted = base.ConvertBeatmap(original, cancellationToken); + if (original.BeatmapInfo.Ruleset.OnlineID == 0) + { + // Post processing step to transform standard slider velocity changes into scroll speed changes + double lastScrollSpeed = 1; + + foreach (HitObject hitObject in original.HitObjects) + { + double nextScrollSpeed = hitObject.DifficultyControlPoint.SliderVelocity; + + if (!Precision.AlmostEquals(lastScrollSpeed, nextScrollSpeed)) + { + EffectControlPoint currentControlPoint = converted.ControlPointInfo.EffectPointAt(hitObject.StartTime); + + if (Precision.AlmostEquals(currentControlPoint.Time, hitObject.StartTime)) + currentControlPoint.ScrollSpeed = nextScrollSpeed; + else + converted.ControlPointInfo.Add(hitObject.StartTime, new EffectControlPoint { ScrollSpeed = nextScrollSpeed }); + + lastScrollSpeed = nextScrollSpeed; + } + } + } + if (original.BeatmapInfo.Ruleset.OnlineID == 3) { // Post processing step to transform mania hit objects with the same start time into strong hits From df0501235d21dee2e24c9801b099bf27a4e97725 Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Wed, 12 Oct 2022 11:14:01 +0200 Subject: [PATCH 0062/2991] Introduce `BpmMultiplierMania`, remove after the fact clamps --- .../Legacy/DistanceObjectPatternGenerator.cs | 2 +- .../Beatmaps/TaikoBeatmapConverter.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 14 ++++++++++++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 89b52a3c75..2bdd0e16ad 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy #pragma warning disable 618 if (difficultyPoint is LegacyBeatmapDecoder.LegacyDifficultyControlPoint legacyDifficultyPoint) #pragma warning restore 618 - beatLength = timingPoint.BeatLength * Math.Min(legacyDifficultyPoint.BpmMultiplier, 10); + beatLength = timingPoint.BeatLength * legacyDifficultyPoint.BpmMultiplier; else beatLength = timingPoint.BeatLength / difficultyPoint.SliderVelocity; diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 33f1535437..524565a863 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -162,7 +162,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps #pragma warning disable 618 if (difficultyPoint is LegacyBeatmapDecoder.LegacyDifficultyControlPoint legacyDifficultyPoint) #pragma warning restore 618 - beatLength = timingPoint.BeatLength * Math.Min(legacyDifficultyPoint.BpmMultiplier, 10); + beatLength = timingPoint.BeatLength * legacyDifficultyPoint.BpmMultiplier; else beatLength = timingPoint.BeatLength / difficultyPoint.SliderVelocity; diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 9c066ada08..03819af149 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -168,6 +168,13 @@ namespace osu.Game.Beatmaps.Formats /// public double BpmMultiplier { get; private set; } + /// + /// Legacy BPM multiplier that introduces floating-point errors for rulesets that depend on it. + /// This is to be used for taiko and mania specific beatmaps. + /// DO NOT USE THIS UNLESS 100% SURE. + /// + public double BpmMultiplierMania { get; private set; } + /// /// Whether or not slider ticks should be generated at this control point. /// This exists for backwards compatibility with maps that abuse NaN slider velocity behavior on osu!stable (e.g. /b/2628991). @@ -178,7 +185,8 @@ namespace osu.Game.Beatmaps.Formats : this() { // Note: In stable, the division occurs on floats, but with compiler optimisations turned on actually seems to occur on doubles via some .NET black magic (possibly inlining?). - BpmMultiplier = beatLength < 0 ? Math.Clamp((float)-beatLength, 10, 10000) / 100.0 : 1; + BpmMultiplier = beatLength < 0 ? Math.Clamp((float)-beatLength, 10, 1000) / 100.0 : 1; + BpmMultiplierMania = beatLength < 0 ? Math.Clamp((float)-beatLength, 10, 10000) / 100.0 : 1; GenerateTicks = !double.IsNaN(beatLength); } @@ -196,6 +204,7 @@ namespace osu.Game.Beatmaps.Formats base.CopyFrom(other); BpmMultiplier = ((LegacyDifficultyControlPoint)other).BpmMultiplier; + BpmMultiplierMania = ((LegacyDifficultyControlPoint)other).BpmMultiplierMania; GenerateTicks = ((LegacyDifficultyControlPoint)other).GenerateTicks; } @@ -206,10 +215,11 @@ namespace osu.Game.Beatmaps.Formats public bool Equals(LegacyDifficultyControlPoint? other) => base.Equals(other) && BpmMultiplier == other.BpmMultiplier + && BpmMultiplierMania == other.BpmMultiplierMania && GenerateTicks == other.GenerateTicks; // ReSharper disable twice NonReadonlyMemberInGetHashCode - public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), BpmMultiplier, GenerateTicks); + public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), BpmMultiplier, BpmMultiplierMania, GenerateTicks); } internal class LegacySampleControlPoint : SampleControlPoint, IEquatable From 2579ed46ce552c3c610f5bacb8359e0f764616df Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Wed, 12 Oct 2022 11:22:54 +0200 Subject: [PATCH 0063/2991] Select multiplier per mode --- .../Beatmaps/TaikoBeatmapConverter.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 524565a863..613c41a59a 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -162,7 +162,14 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps #pragma warning disable 618 if (difficultyPoint is LegacyBeatmapDecoder.LegacyDifficultyControlPoint legacyDifficultyPoint) #pragma warning restore 618 - beatLength = timingPoint.BeatLength * legacyDifficultyPoint.BpmMultiplier; + { + double bpmMultiplier; + if (beatmap.BeatmapInfo.OnlineID == 1 || beatmap.BeatmapInfo.OnlineID == 3) + bpmMultiplier = legacyDifficultyPoint.BpmMultiplierMania; + else + bpmMultiplier = legacyDifficultyPoint.BpmMultiplier; + beatLength = timingPoint.BeatLength * bpmMultiplier; + } else beatLength = timingPoint.BeatLength / difficultyPoint.SliderVelocity; From 83aedb193079a016f841298d2e4e68227d3fe58b Mon Sep 17 00:00:00 2001 From: "D.Headley" Date: Wed, 12 Oct 2022 12:42:26 +0200 Subject: [PATCH 0064/2991] Make mod use new Combo, remove pointless test --- .../Mods/TestSceneOsuModFreezeFrame.cs | 40 --------- .../Mods/OsuModFreezeFrame.cs | 89 +++++-------------- 2 files changed, 22 insertions(+), 107 deletions(-) delete mode 100644 osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs deleted file mode 100644 index 8af63aa5e2..0000000000 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Collections.Generic; -using NUnit.Framework; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu.Mods; - -namespace osu.Game.Rulesets.Osu.Tests.Mods -{ - public class TestSceneOsuModFreezeFrame : OsuModTestScene - { - [TestCase(OsuModFreezeFrame.BeatDivisor.Quarter_Measure)] - [TestCase(OsuModFreezeFrame.BeatDivisor.Single_Measure)] - [TestCase(OsuModFreezeFrame.BeatDivisor.Quadruple_Measure)] - public void TestFreezeFrequency(OsuModFreezeFrame.BeatDivisor divisor) - { - CreateModTest(new ModTestData - { - Mod = new OsuModFreezeFrame { Divisor = { Value = divisor } }, - PassCondition = checkSomeHit, - Autoplay = true - }); - } - - [Test] - public void TestWithHidden() - { - var mods = new List { new OsuModHidden(), new OsuModFreezeFrame { Divisor = { Value = OsuModFreezeFrame.BeatDivisor.Quadruple_Measure } } }; - CreateModTest(new ModTestData - { - Mods = mods, - PassCondition = checkSomeHit, - Autoplay = true - }); - } - - private bool checkSomeHit() => Player.ScoreProcessor.JudgedHits >= 8; - } -} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 26adc0f25f..b21e8a4a5f 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -1,22 +1,17 @@ // 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 System.ComponentModel; -using osu.Framework.Bindables; using osu.Framework.Localisation; using osu.Game.Beatmaps; -using osu.Game.Configuration; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModFreezeFrame : ModWithVisibilityAdjustment, IApplicableToDrawableRuleset + public class OsuModFreezeFrame : Mod, IApplicableToBeatmap, IApplicableToDrawableRuleset { public override string Name => "Freeze Frame"; @@ -28,80 +23,40 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Fun; - [SettingSource("Beat Divisor", "How often the hitobjects should be grouped according to BPM")] - public Bindable Divisor { get; } = new Bindable(BeatDivisor.Single_Measure); - public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { (drawableRuleset.Playfield as OsuPlayfield)?.FollowPoints.Hide(); } - public override void ApplyToBeatmap(IBeatmap beatmap) + public void ApplyToBeatmap(IBeatmap beatmap) { - base.ApplyToBeatmap(beatmap); + double lastNewComboTime = 0; foreach (var obj in beatmap.HitObjects.OfType()) { - // The +1s below are added due to First HitCircle in each measure not appearing appropriately without them. - var lastTimingPoint = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime + 1); - double controlPointDifference = obj.StartTime + 1 - lastTimingPoint.Time; - double remainder = controlPointDifference % (lastTimingPoint.BeatLength * getMeasure(Divisor.Value)) - 1; - double finalPreempt = obj.TimePreempt + remainder; - applyFadeInAdjustment(obj); + if (obj.NewCombo) { lastNewComboTime = obj.StartTime; } - void applyFadeInAdjustment(OsuHitObject osuObject) + applyFadeInAdjustment(obj); + } + + void applyFadeInAdjustment(OsuHitObject osuObject) + { + osuObject.TimePreempt += osuObject.StartTime - lastNewComboTime; + + foreach (var nested in osuObject.NestedHitObjects.OfType()) { - osuObject.TimePreempt = finalPreempt; - foreach (var nested in osuObject.NestedHitObjects.OfType()) - applyFadeInAdjustment(nested); + switch (nested) + { + //SliderRepeat wont layer correctly if preempt is changed. + case SliderRepeat: + return; + + default: + applyFadeInAdjustment(nested); + break; + } } } } - - protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) { } - - protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) { } - - private float getMeasure(BeatDivisor divisor) - { - switch (divisor) - { - case BeatDivisor.Quarter_Measure: - return 0.25f; - - case BeatDivisor.Half_Measure: - return 0.5f; - - case BeatDivisor.Single_Measure: - return 1; - - case BeatDivisor.Double_Measure: - return 2; - - case BeatDivisor.Quadruple_Measure: - return 4; - - default: - throw new ArgumentOutOfRangeException(nameof(divisor), divisor, null); - } - } - - public enum BeatDivisor - { - [Description("1/4")] - Quarter_Measure, - - [Description("1/2")] - Half_Measure, - - [Description("1")] - Single_Measure, - - [Description("2")] - Double_Measure, - - [Description("4")] - Quadruple_Measure - } } } From f67f6cc99ca914b152a355122589900437b6b91d Mon Sep 17 00:00:00 2001 From: "D.Headley" Date: Wed, 12 Oct 2022 19:45:08 +0200 Subject: [PATCH 0065/2991] Fix switch case --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index b21e8a4a5f..a91d7831c3 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Osu.Mods { //SliderRepeat wont layer correctly if preempt is changed. case SliderRepeat: - return; + break; default: applyFadeInAdjustment(nested); From 4149235e63173f374a80a7235411ef72588c455b Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 5 Oct 2022 17:50:36 +0900 Subject: [PATCH 0066/2991] Limit minimum brightness of combo colours --- osu.Game/Configuration/OsuConfigManager.cs | 4 +- osu.Game/Graphics/OsuColour.cs | 167 ++++++++++++++++++ .../Sections/Gameplay/BeatmapSettings.cs | 6 + .../Objects/Drawables/DrawableHitObject.cs | 14 +- 4 files changed, 189 insertions(+), 2 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index e3bfb6b1e9..b433d81f31 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -175,6 +175,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f); SetDefault(OsuSetting.LastProcessedMetadataId, -1); + SetDefault(OsuSetting.ComboColourBrightness, 0.7f, 0f, 1f); } protected override bool CheckLookupContainsPrivateInformation(OsuSetting lookup) @@ -370,6 +371,7 @@ namespace osu.Game.Configuration DiscordRichPresence, AutomaticallyDownloadWhenSpectating, ShowOnlineExplicitContent, - LastProcessedMetadataId + LastProcessedMetadataId, + ComboColourBrightness } } diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index 91161d5c71..bd0604bb76 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -229,6 +229,173 @@ namespace osu.Game.Graphics return Gray(brightness > 0.5f ? 0.2f : 0.9f); } + /// + /// Converts RGBA to HSPA. + /// + public static Color4 ToHSPA(Color4 colour) + { + const float p_r = 0.299f; + const float p_g = 0.587f; + const float p_b = 0.114f; + + Color4 result = new Color4 + { + A = colour.A, + B = MathF.Sqrt(colour.R * colour.R * p_r + colour.G * colour.G * p_g + colour.B + colour.B * p_b) + }; + + if (colour.R == colour.G && colour.R == colour.B) + return result; + + if (colour.R >= colour.G && colour.R >= colour.B) + { + if (colour.B >= colour.G) + { + result.R = 6f / 6f - 1f / 6f * (colour.B - colour.G) / (colour.R - colour.G); + result.G = 1f - colour.G / colour.R; + } + else + { + result.R = 0f / 6f + 1f / 6f * (colour.G - colour.B) / (colour.R - colour.B); + result.G = 1f - colour.B / colour.R; + } + } + else if (colour.G >= colour.R && colour.G >= colour.B) + { + if (colour.R >= colour.B) + { + result.R = 2f / 6f - 1f / 6f * (colour.R - colour.B) / (colour.G - colour.B); + result.G = 1f - colour.B / colour.G; + } + else + { + result.R = 2f / 6f + 1f / 6f * (colour.B - colour.R) / (colour.G - colour.R); + result.G = 1f - colour.R / colour.G; + } + } + else + { + if (colour.G >= colour.R) + { + result.R = 4f / 6f - 1f / 6f * (colour.G - colour.R) / (colour.B - colour.R); + result.G = 1f - colour.R / colour.B; + } + else + { + result.R = 4f / 6f + 1f / 6f * (colour.R - colour.G) / (colour.B - colour.G); + result.G = 1f - colour.G / colour.B; + } + } + + return result; + } + + public static Color4 FromHSPA(Color4 colour) + { + const float p_r = 0.299f; + const float p_g = 0.587f; + const float p_b = 0.114f; + + float minOverMax = 1f - colour.G; + + Color4 result = new Color4 { A = colour.A }; + + if (minOverMax > 0f) + { + float part = 1f + colour.R * (1f / minOverMax - 1f); + + if (colour.R < 1f / 6f) + { + colour.R = 6f * (colour.R - 0f / 6f); + result.B = colour.B / MathF.Sqrt(p_r / minOverMax / minOverMax + p_g * part * part + p_b); + result.R = result.B / minOverMax; + result.G = result.B + colour.R * (result.R - result.B); + } + else if (colour.R < 2f / 6f) + { + colour.R = 6f * (-colour.R + 2f / 6f); + result.B = colour.B / MathF.Sqrt(p_g / minOverMax / minOverMax + p_r * part * part + p_b); + result.G = result.B / minOverMax; + result.R = result.B + colour.R * (result.R - result.B); + } + else if (colour.R < 3f / 6f) + { + colour.R = 6f * (colour.R - 2f / 6f); + result.R = colour.B / MathF.Sqrt(p_g / minOverMax / minOverMax + p_b * part * part + p_r); + result.G = result.R / minOverMax; + result.B = result.R + colour.R * (result.G - result.R); + } + else if (colour.R < 4f / 6f) + { + colour.R = 6f * (-colour.R + 4f / 6f); + result.R = colour.B / MathF.Sqrt(p_b / minOverMax / minOverMax + p_g * part * part + p_r); + result.B = result.R / minOverMax; + result.G = result.R + colour.R * (result.B - result.R); + } + else if (colour.R < 5f / 6f) + { + colour.R = 6f * (colour.R - 4f / 6f); + result.G = colour.B / MathF.Sqrt(p_b / minOverMax / minOverMax + p_r * part * part + p_g); + result.B = result.G / minOverMax; + result.R = result.G + colour.R * (result.B - result.G); + } + else + { + colour.R = 6f * (-colour.R + 6f / 6f); + result.G = colour.B / MathF.Sqrt(p_r / minOverMax / minOverMax + p_b * part * part + p_g); + result.R = result.G / minOverMax; + result.B = result.G + colour.R * (result.R - result.G); + } + } + else + { + if (colour.R < 1f / 6f) + { + colour.R = 6f * (colour.R - 0f / 6f); + result.R = MathF.Sqrt(colour.B * colour.B / (p_r + p_g * colour.R * colour.R)); + result.G = result.R * colour.R; + result.B = 0f; + } + else if (colour.R < 2f / 6f) + { + colour.R = 6f * (-colour.R + 2f / 6f); + result.G = MathF.Sqrt(colour.B * colour.B / (p_g + p_r * colour.R * colour.R)); + result.R = result.G * colour.R; + result.B = 0f; + } + else if (colour.R < 3f / 6f) + { + colour.R = 6f * (colour.R - 2f / 6f); + result.G = MathF.Sqrt(colour.B * colour.B / (p_g + p_b * colour.R * colour.R)); + result.B = result.G * colour.R; + result.R = 0f; + } + else if (colour.R < 4f / 6f) + { + colour.R = 6f * (-colour.R + 4f / 6f); + result.B = MathF.Sqrt(colour.B * colour.B / (p_b + p_g * colour.R * colour.R)); + result.G = result.B * colour.R; + result.R = 0f; + } + else if (colour.R < 5f / 6f) + { + colour.R = 6f * (colour.R - 4f / 6f); + result.B = MathF.Sqrt(colour.B * colour.B / (p_b + p_r * colour.R * colour.R)); + result.R = result.B * colour.R; + result.G = 0f; + } + else + { + colour.R = 6f * (-colour.R + 6f / 6f); + result.R = MathF.Sqrt(colour.B * colour.B / (p_r + p_b * colour.R * colour.R)); + result.B = result.R * colour.R; + result.G = 0f; + } + } + + return result; + } + public readonly Color4 TeamColourRed = Color4Extensions.FromHex("#AA1414"); public readonly Color4 TeamColourBlue = Color4Extensions.FromHex("#1462AA"); diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs index becb7aa80f..16b7b74f38 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs @@ -40,6 +40,12 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay LabelText = GraphicsSettingsStrings.StoryboardVideo, Current = config.GetBindable(OsuSetting.ShowStoryboard) }, + new SettingsSlider + { + LabelText = "Combo colour brightness", + Current = config.GetBindable(OsuSetting.ComboColourBrightness), + DisplayAsPercentage = true + } }; } } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index dec68a6c22..0ef15ed5c2 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -17,6 +17,7 @@ using osu.Framework.Graphics.Primitives; using osu.Framework.Threading; using osu.Game.Audio; using osu.Game.Configuration; +using osu.Game.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Pooling; using osu.Game.Rulesets.Objects.Types; @@ -128,6 +129,7 @@ namespace osu.Game.Rulesets.Objects.Drawables private readonly Bindable comboIndexBindable = new Bindable(); private readonly Bindable positionalHitsoundsLevel = new Bindable(); + private readonly Bindable comboColourBrightness = new Bindable(); private readonly Bindable comboIndexWithOffsetsBindable = new Bindable(); protected override bool RequiresChildrenUpdate => true; @@ -171,6 +173,7 @@ namespace osu.Game.Rulesets.Objects.Drawables private void load(OsuConfigManager config, ISkinSource skinSource) { config.BindWith(OsuSetting.PositionalHitsoundsLevel, positionalHitsoundsLevel); + config.BindWith(OsuSetting.ComboColourBrightness, comboColourBrightness); // Explicit non-virtual function call in case a DrawableHitObject overrides AddInternal. base.AddInternal(Samples = new PausableSkinnableSound()); @@ -192,6 +195,8 @@ namespace osu.Game.Rulesets.Objects.Drawables comboIndexBindable.BindValueChanged(_ => UpdateComboColour()); comboIndexWithOffsetsBindable.BindValueChanged(_ => UpdateComboColour(), true); + comboColourBrightness.BindValueChanged(_ => UpdateComboColour()); + // Apply transforms updateState(State.Value, true); } @@ -519,7 +524,14 @@ namespace osu.Game.Rulesets.Objects.Drawables { if (!(HitObject is IHasComboInformation combo)) return; - AccentColour.Value = combo.GetComboColour(CurrentSkin); + Color4 colour = combo.GetComboColour(CurrentSkin); + + // Normalise the combo colour to the given brightness level. + colour = OsuColour.ToHSPA(colour); + colour.B = comboColourBrightness.Value; + colour = OsuColour.FromHSPA(colour); + + AccentColour.Value = colour; } /// From 338115ff6a00d4eaf9ce90e061c71f9504307174 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Thu, 13 Oct 2022 15:05:15 +0900 Subject: [PATCH 0067/2991] Move check to LegacyDifficultyControlPoint --- .../Beatmaps/TaikoBeatmapConverter.cs | 9 +-------- .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 6 +++--- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 20 +++++++------------ 3 files changed, 11 insertions(+), 24 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 613c41a59a..524565a863 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -162,14 +162,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps #pragma warning disable 618 if (difficultyPoint is LegacyBeatmapDecoder.LegacyDifficultyControlPoint legacyDifficultyPoint) #pragma warning restore 618 - { - double bpmMultiplier; - if (beatmap.BeatmapInfo.OnlineID == 1 || beatmap.BeatmapInfo.OnlineID == 3) - bpmMultiplier = legacyDifficultyPoint.BpmMultiplierMania; - else - bpmMultiplier = legacyDifficultyPoint.BpmMultiplier; - beatLength = timingPoint.BeatLength * bpmMultiplier; - } + beatLength = timingPoint.BeatLength * legacyDifficultyPoint.BpmMultiplier; else beatLength = timingPoint.BeatLength / difficultyPoint.SliderVelocity; diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 75500fbc4e..683bc19ce6 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -427,8 +427,10 @@ namespace osu.Game.Beatmaps.Formats addControlPoint(time, controlPoint, true); } + int onlineRulesetID = beatmap.BeatmapInfo.Ruleset.OnlineID; + #pragma warning disable 618 - addControlPoint(time, new LegacyDifficultyControlPoint(beatLength) + addControlPoint(time, new LegacyDifficultyControlPoint(onlineRulesetID, beatLength) #pragma warning restore 618 { SliderVelocity = speedMultiplier, @@ -440,8 +442,6 @@ namespace osu.Game.Beatmaps.Formats OmitFirstBarLine = omitFirstBarSignature, }; - int onlineRulesetID = beatmap.BeatmapInfo.Ruleset.OnlineID; - // osu!taiko and osu!mania use effect points rather than difficulty points for scroll speed adjustments. if (onlineRulesetID == 1 || onlineRulesetID == 3) effectPoint.ScrollSpeed = speedMultiplier; diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 03819af149..ed7ca47cfd 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -168,25 +168,21 @@ namespace osu.Game.Beatmaps.Formats /// public double BpmMultiplier { get; private set; } - /// - /// Legacy BPM multiplier that introduces floating-point errors for rulesets that depend on it. - /// This is to be used for taiko and mania specific beatmaps. - /// DO NOT USE THIS UNLESS 100% SURE. - /// - public double BpmMultiplierMania { get; private set; } - /// /// Whether or not slider ticks should be generated at this control point. /// This exists for backwards compatibility with maps that abuse NaN slider velocity behavior on osu!stable (e.g. /b/2628991). /// public bool GenerateTicks { get; private set; } = true; - public LegacyDifficultyControlPoint(double beatLength) + public LegacyDifficultyControlPoint(int rulesetId, double beatLength) : this() { // Note: In stable, the division occurs on floats, but with compiler optimisations turned on actually seems to occur on doubles via some .NET black magic (possibly inlining?). - BpmMultiplier = beatLength < 0 ? Math.Clamp((float)-beatLength, 10, 1000) / 100.0 : 1; - BpmMultiplierMania = beatLength < 0 ? Math.Clamp((float)-beatLength, 10, 10000) / 100.0 : 1; + if (rulesetId == 1 || rulesetId == 3) + BpmMultiplier = beatLength < 0 ? Math.Clamp((float)-beatLength, 10, 10000) / 100.0 : 1; + else + BpmMultiplier = beatLength < 0 ? Math.Clamp((float)-beatLength, 10, 1000) / 100.0 : 1; + GenerateTicks = !double.IsNaN(beatLength); } @@ -204,7 +200,6 @@ namespace osu.Game.Beatmaps.Formats base.CopyFrom(other); BpmMultiplier = ((LegacyDifficultyControlPoint)other).BpmMultiplier; - BpmMultiplierMania = ((LegacyDifficultyControlPoint)other).BpmMultiplierMania; GenerateTicks = ((LegacyDifficultyControlPoint)other).GenerateTicks; } @@ -215,11 +210,10 @@ namespace osu.Game.Beatmaps.Formats public bool Equals(LegacyDifficultyControlPoint? other) => base.Equals(other) && BpmMultiplier == other.BpmMultiplier - && BpmMultiplierMania == other.BpmMultiplierMania && GenerateTicks == other.GenerateTicks; // ReSharper disable twice NonReadonlyMemberInGetHashCode - public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), BpmMultiplier, BpmMultiplierMania, GenerateTicks); + public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), BpmMultiplier, GenerateTicks); } internal class LegacySampleControlPoint : SampleControlPoint, IEquatable From aa8040d69675ef646a4bc8f2fea0db70fb00e574 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 13 Oct 2022 15:52:06 +0300 Subject: [PATCH 0068/2991] Add hover box to beatmap card icon button --- .../Cards/Buttons/BeatmapCardIconButton.cs | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs index c5b251cc2b..de75fceec8 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs @@ -4,13 +4,16 @@ #nullable disable using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Graphics.Containers; using osu.Game.Overlays; using osuTK; +using osuTK.Graphics; namespace osu.Game.Beatmaps.Drawables.Cards.Buttons { @@ -59,6 +62,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons protected override Container Content => content; private readonly Container content; + private readonly Box hover; protected BeatmapCardIconButton() { @@ -69,6 +73,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons { RelativeSizeAxes = Axes.Both, Masking = true, + CornerRadius = BeatmapCard.CORNER_RADIUS, Origin = Anchor.Centre, Anchor = Anchor.Centre, Children = new Drawable[] @@ -76,8 +81,14 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons Icon = new SpriteIcon { Origin = Anchor.Centre, - Anchor = Anchor.Centre - } + Anchor = Anchor.Centre, + }, + hover = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.White.Opacity(0.1f), + Blending = BlendingParameters.Additive, + }, } }); @@ -116,8 +127,9 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons { bool isHovered = IsHovered && Enabled.Value; - content.ScaleTo(isHovered ? 1.2f : 1, 500, Easing.OutQuint); - content.FadeColour(isHovered ? HoverColour : IdleColour, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); + hover.FadeTo(isHovered ? 1f : 0f, 500, Easing.OutQuint); + Icon.ScaleTo(isHovered ? 1.2f : 1, 500, Easing.OutQuint); + Icon.FadeColour(isHovered ? HoverColour : IdleColour, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); } } } From 6c316bcc9e8746104b6875da8efecf0e668d8406 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 13 Oct 2022 15:52:20 +0300 Subject: [PATCH 0069/2991] Make beatmap card icon buttons fill up to the area --- .../TestSceneBeatmapCardDownloadButton.cs | 3 ++- .../TestSceneBeatmapCardFavouriteButton.cs | 12 ++++++++++-- .../Drawables/Cards/BeatmapCardExtra.cs | 1 - .../Drawables/Cards/BeatmapCardNormal.cs | 1 - .../Cards/Buttons/BeatmapCardIconButton.cs | 1 - .../Cards/CollapsibleButtonContainer.cs | 19 ++++++++++--------- 6 files changed, 22 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDownloadButton.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDownloadButton.cs index 10515fd95f..82e18e45bb 100644 --- a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDownloadButton.cs +++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDownloadButton.cs @@ -59,8 +59,9 @@ namespace osu.Game.Tests.Visual.Beatmaps { Anchor = Anchor.Centre, Origin = Anchor.Centre, + Size = new Vector2(25f, 50f), + Scale = new Vector2(2f), State = { Value = DownloadState.NotDownloaded }, - Scale = new Vector2(2) }; }); } diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs index 2fe2264348..9540d9e4f7 100644 --- a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs +++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs @@ -37,7 +37,11 @@ namespace osu.Game.Tests.Visual.Beatmaps beatmapSetInfo = CreateAPIBeatmapSet(Ruleset.Value); beatmapSetInfo.HasFavourited = favourited; }); - AddStep("create button", () => Child = button = new FavouriteButton(beatmapSetInfo) { Scale = new Vector2(2) }); + AddStep("create button", () => Child = button = new FavouriteButton(beatmapSetInfo) + { + Size = new Vector2(25f, 50f), + Scale = new Vector2(2f), + }); assertCorrectIcon(favourited); AddAssert("correct tooltip text", () => button.TooltipText == (favourited ? BeatmapsetsStrings.ShowDetailsUnfavourite : BeatmapsetsStrings.ShowDetailsFavourite)); @@ -51,7 +55,11 @@ namespace osu.Game.Tests.Visual.Beatmaps BeatmapFavouriteAction? lastRequestAction = null; AddStep("create beatmap set", () => beatmapSetInfo = CreateAPIBeatmapSet(Ruleset.Value)); - AddStep("create button", () => Child = button = new FavouriteButton(beatmapSetInfo) { Scale = new Vector2(2) }); + AddStep("create button", () => Child = button = new FavouriteButton(beatmapSetInfo) + { + Size = new Vector2(25f, 50f), + Scale = new Vector2(2f), + }); assertCorrectIcon(false); diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs index 4b9e5d9ae4..646c990564 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs @@ -81,7 +81,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards FavouriteState = { BindTarget = FavouriteState }, ButtonsCollapsedWidth = CORNER_RADIUS, ButtonsExpandedWidth = 30, - ButtonsPadding = new MarginPadding { Vertical = 35 }, Children = new Drawable[] { new FillFlowContainer diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs index d9ce64879f..addc88700c 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs @@ -82,7 +82,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards FavouriteState = { BindTarget = FavouriteState }, ButtonsCollapsedWidth = CORNER_RADIUS, ButtonsExpandedWidth = 30, - ButtonsPadding = new MarginPadding { Vertical = 17.5f }, Children = new Drawable[] { new FillFlowContainer diff --git a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs index de75fceec8..a4beab02ed 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs @@ -92,7 +92,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons } }); - Size = new Vector2(24); IconSize = 12; } diff --git a/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs b/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs index 107c126eb5..5ace3233e2 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs @@ -48,12 +48,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards } } - public MarginPadding ButtonsPadding - { - get => buttons.Padding; - set => buttons.Padding = value; - } - protected override Container Content => mainContent; private readonly Container background; @@ -104,25 +98,32 @@ namespace osu.Game.Beatmaps.Drawables.Cards Child = buttons = new Container { RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding(3), Children = new BeatmapCardIconButton[] { new FavouriteButton(beatmapSet) { Current = FavouriteState, Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.Both, + Height = 0.48f, }, new DownloadButton(beatmapSet) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, - State = { BindTarget = downloadTracker.State } + State = { BindTarget = downloadTracker.State }, + RelativeSizeAxes = Axes.Both, + Height = 0.48f, }, new GoToBeatmapButton(beatmapSet) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, - State = { BindTarget = downloadTracker.State } + State = { BindTarget = downloadTracker.State }, + RelativeSizeAxes = Axes.Both, + Height = 0.48f, } } } From ef72b66dad05a31ed45c979d9e8468d0a12c4e16 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 13 Oct 2022 16:09:50 +0300 Subject: [PATCH 0070/2991] Remove beatmap card background workaround to fix broken corners --- .../Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs b/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs index 5ace3233e2..f70694bdda 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs @@ -80,9 +80,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards RelativeSizeAxes = Axes.Both, Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - // workaround for masking artifacts at the top & bottom of card, - // which become especially visible on downloaded beatmaps (when the icon area has a lime background). - Padding = new MarginPadding { Vertical = 1 }, Child = new Box { RelativeSizeAxes = Axes.Both, From 3e5e717fce3a47983793f60ef8147aa624178b84 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 14 Oct 2022 01:59:55 +0300 Subject: [PATCH 0071/2991] Add failing test cases --- .../TestSceneModSelectOverlay.cs | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs index 4c43a2fdcd..0292ce5905 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs @@ -17,6 +17,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Mods; using osu.Game.Overlays.Settings; using osu.Game.Rulesets; +using osu.Game.Rulesets.Catch.Mods; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Mods; @@ -338,26 +339,36 @@ namespace osu.Game.Tests.Visual.UserInterface } [Test] - public void TestRulesetChanges() + public void TestCommonModsMaintainedOnRulesetChange() { createScreen(); changeRuleset(0); - var noFailMod = new OsuRuleset().GetModsFor(ModType.DifficultyReduction).FirstOrDefault(m => m is OsuModNoFail); - - AddStep("set mods externally", () => { SelectedMods.Value = new[] { noFailMod }; }); + AddStep("select relax mod", () => SelectedMods.Value = new[] { Ruleset.Value.CreateInstance().CreateMod() }); changeRuleset(0); + AddAssert("ensure mod still selected", () => SelectedMods.Value.SingleOrDefault() is OsuModRelax); - AddAssert("ensure mods still selected", () => SelectedMods.Value.SingleOrDefault(m => m is OsuModNoFail) != null); + changeRuleset(2); + AddAssert("catch variant selected", () => SelectedMods.Value.SingleOrDefault() is CatchModRelax); changeRuleset(3); + AddAssert("no mod selected", () => SelectedMods.Value.Count == 0); + } - AddAssert("ensure mods not selected", () => SelectedMods.Value.Count == 0); - + [Test] + public void TestUncommonModsDiscardedOnRulesetChange() + { + createScreen(); changeRuleset(0); - AddAssert("ensure mods not selected", () => SelectedMods.Value.Count == 0); + AddStep("select single tap mod", () => SelectedMods.Value = new[] { new OsuModSingleTap() }); + + changeRuleset(0); + AddAssert("ensure mod still selected", () => SelectedMods.Value.SingleOrDefault() is OsuModSingleTap); + + changeRuleset(3); + AddAssert("no mod selected", () => SelectedMods.Value.Count == 0); } [Test] From 739b21ab3bb3245910ce1115e6f6003fa589e2c1 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 14 Oct 2022 02:02:24 +0300 Subject: [PATCH 0072/2991] Maintain mod selection on ruleset change for common mods --- osu.Game/OsuGameBase.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 478f154d58..662d165580 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -586,11 +586,16 @@ namespace osu.Game return; } + var previouslySelectedMods = SelectedMods.Value.ToArray(); + if (!SelectedMods.Disabled) SelectedMods.Value = Array.Empty(); AvailableMods.Value = dict; + if (!SelectedMods.Disabled) + SelectedMods.Value = previouslySelectedMods.Select(m => instance.CreateModFromAcronym(m.Acronym)).Where(m => m != null).ToArray(); + void revertRulesetChange() => Ruleset.Value = r.OldValue?.Available == true ? r.OldValue : RulesetStore.AvailableRulesets.First(); } From 01c65d3cc1281da68e501506785724ac5e2f9f58 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 14 Oct 2022 02:16:23 +0300 Subject: [PATCH 0073/2991] Remove seemingly unnecessary/leftover code --- osu.Game/Screens/Select/SongSelect.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index ece94b5365..f5a058e945 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -502,8 +502,6 @@ namespace osu.Game.Screens.Select if (transferRulesetValue()) { - Mods.Value = Array.Empty(); - // transferRulesetValue() may trigger a re-filter. If the current selection does not match the new ruleset, we want to switch away from it. // The default logic on WorkingBeatmap change is to switch to a matching ruleset (see workingBeatmapChanged()), but we don't want that here. // We perform an early selection attempt and clear out the beatmap selection to avoid a second ruleset change (revert). From b43bae122c1ec719b074b7f2e1ac39cbda338541 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 14 Oct 2022 13:40:48 +0900 Subject: [PATCH 0074/2991] Fix incorrect porting of code --- osu.Game/Graphics/OsuColour.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index bd0604bb76..0f055856d3 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -302,11 +302,10 @@ namespace osu.Game.Graphics if (minOverMax > 0f) { - float part = 1f + colour.R * (1f / minOverMax - 1f); - if (colour.R < 1f / 6f) { colour.R = 6f * (colour.R - 0f / 6f); + float part = 1f + colour.R * (1f / minOverMax - 1f); result.B = colour.B / MathF.Sqrt(p_r / minOverMax / minOverMax + p_g * part * part + p_b); result.R = result.B / minOverMax; result.G = result.B + colour.R * (result.R - result.B); @@ -314,13 +313,15 @@ namespace osu.Game.Graphics else if (colour.R < 2f / 6f) { colour.R = 6f * (-colour.R + 2f / 6f); + float part = 1f + colour.R * (1f / minOverMax - 1f); result.B = colour.B / MathF.Sqrt(p_g / minOverMax / minOverMax + p_r * part * part + p_b); result.G = result.B / minOverMax; - result.R = result.B + colour.R * (result.R - result.B); + result.R = result.B + colour.R * (result.G - result.B); } else if (colour.R < 3f / 6f) { colour.R = 6f * (colour.R - 2f / 6f); + float part = 1f + colour.R * (1f / minOverMax - 1f); result.R = colour.B / MathF.Sqrt(p_g / minOverMax / minOverMax + p_b * part * part + p_r); result.G = result.R / minOverMax; result.B = result.R + colour.R * (result.G - result.R); @@ -328,6 +329,7 @@ namespace osu.Game.Graphics else if (colour.R < 4f / 6f) { colour.R = 6f * (-colour.R + 4f / 6f); + float part = 1f + colour.R * (1f / minOverMax - 1f); result.R = colour.B / MathF.Sqrt(p_b / minOverMax / minOverMax + p_g * part * part + p_r); result.B = result.R / minOverMax; result.G = result.R + colour.R * (result.B - result.R); @@ -335,6 +337,7 @@ namespace osu.Game.Graphics else if (colour.R < 5f / 6f) { colour.R = 6f * (colour.R - 4f / 6f); + float part = 1f + colour.R * (1f / minOverMax - 1f); result.G = colour.B / MathF.Sqrt(p_b / minOverMax / minOverMax + p_r * part * part + p_g); result.B = result.G / minOverMax; result.R = result.G + colour.R * (result.B - result.G); @@ -342,6 +345,7 @@ namespace osu.Game.Graphics else { colour.R = 6f * (-colour.R + 6f / 6f); + float part = 1f + colour.R * (1f / minOverMax - 1f); result.G = colour.B / MathF.Sqrt(p_r / minOverMax / minOverMax + p_b * part * part + p_g); result.R = result.G / minOverMax; result.B = result.G + colour.R * (result.R - result.G); From 15db65c037c22f672272733fb4b8e1d9a25f731b Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 14 Oct 2022 14:12:48 +0900 Subject: [PATCH 0075/2991] Extract to struct, add dictionary term --- osu.Game/Graphics/HSPAColour.cs | 200 ++++++++++++++++++ osu.Game/Graphics/OsuColour.cs | 171 --------------- .../Objects/Drawables/DrawableHitObject.cs | 4 +- osu.sln.DotSettings | 1 + 4 files changed, 202 insertions(+), 174 deletions(-) create mode 100644 osu.Game/Graphics/HSPAColour.cs diff --git a/osu.Game/Graphics/HSPAColour.cs b/osu.Game/Graphics/HSPAColour.cs new file mode 100644 index 0000000000..5e3bc29b7e --- /dev/null +++ b/osu.Game/Graphics/HSPAColour.cs @@ -0,0 +1,200 @@ +// 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 osuTK.Graphics; + +namespace osu.Game.Graphics +{ + public struct HSPAColour + { + private const float p_r = 0.299f; + private const float p_g = 0.587f; + private const float p_b = 0.114f; + + /// + /// The hue. + /// + public float H; + + /// + /// The saturation. + /// + public float S; + + /// + /// The perceived brightness of this colour. + /// + public float P; + + /// + /// The alpha. + /// + public float A; + + public HSPAColour(float h, float s, float p, float a) + { + H = h; + S = s; + P = p; + A = a; + } + + public HSPAColour(Color4 colour) + { + H = 0; + S = 0; + P = MathF.Sqrt(colour.R * colour.R * p_r + colour.G * colour.G * p_g + colour.B + colour.B * p_b); + A = colour.A; + + if (colour.R == colour.G && colour.R == colour.B) + return; + + if (colour.R >= colour.G && colour.R >= colour.B) + { + if (colour.B >= colour.G) + { + H = 6f / 6f - 1f / 6f * (colour.B - colour.G) / (colour.R - colour.G); + S = 1f - colour.G / colour.R; + } + else + { + H = 0f / 6f + 1f / 6f * (colour.G - colour.B) / (colour.R - colour.B); + S = 1f - colour.B / colour.R; + } + } + else if (colour.G >= colour.R && colour.G >= colour.B) + { + if (colour.R >= colour.B) + { + H = 2f / 6f - 1f / 6f * (colour.R - colour.B) / (colour.G - colour.B); + S = 1f - colour.B / colour.G; + } + else + { + H = 2f / 6f + 1f / 6f * (colour.B - colour.R) / (colour.G - colour.R); + S = 1f - colour.R / colour.G; + } + } + else + { + if (colour.G >= colour.R) + { + H = 4f / 6f - 1f / 6f * (colour.G - colour.R) / (colour.B - colour.R); + S = 1f - colour.R / colour.B; + } + else + { + H = 4f / 6f + 1f / 6f * (colour.R - colour.G) / (colour.B - colour.G); + S = 1f - colour.G / colour.B; + } + } + } + + public Color4 ToColor4() + { + float minOverMax = 1f - S; + + Color4 result = new Color4 { A = A }; + + if (minOverMax > 0f) + { + if (H < 1f / 6f) + { + H = 6f * (H - 0f / 6f); + float part = 1f + H * (1f / minOverMax - 1f); + result.B = P / MathF.Sqrt(p_r / minOverMax / minOverMax + p_g * part * part + p_b); + result.R = result.B / minOverMax; + result.G = result.B + H * (result.R - result.B); + } + else if (H < 2f / 6f) + { + H = 6f * (-H + 2f / 6f); + float part = 1f + H * (1f / minOverMax - 1f); + result.B = P / MathF.Sqrt(p_g / minOverMax / minOverMax + p_r * part * part + p_b); + result.G = result.B / minOverMax; + result.R = result.B + H * (result.G - result.B); + } + else if (H < 3f / 6f) + { + H = 6f * (H - 2f / 6f); + float part = 1f + H * (1f / minOverMax - 1f); + result.R = P / MathF.Sqrt(p_g / minOverMax / minOverMax + p_b * part * part + p_r); + result.G = result.R / minOverMax; + result.B = result.R + H * (result.G - result.R); + } + else if (H < 4f / 6f) + { + H = 6f * (-H + 4f / 6f); + float part = 1f + H * (1f / minOverMax - 1f); + result.R = P / MathF.Sqrt(p_b / minOverMax / minOverMax + p_g * part * part + p_r); + result.B = result.R / minOverMax; + result.G = result.R + H * (result.B - result.R); + } + else if (H < 5f / 6f) + { + H = 6f * (H - 4f / 6f); + float part = 1f + H * (1f / minOverMax - 1f); + result.G = P / MathF.Sqrt(p_b / minOverMax / minOverMax + p_r * part * part + p_g); + result.B = result.G / minOverMax; + result.R = result.G + H * (result.B - result.G); + } + else + { + H = 6f * (-H + 6f / 6f); + float part = 1f + H * (1f / minOverMax - 1f); + result.G = P / MathF.Sqrt(p_r / minOverMax / minOverMax + p_b * part * part + p_g); + result.R = result.G / minOverMax; + result.B = result.G + H * (result.R - result.G); + } + } + else + { + if (H < 1f / 6f) + { + H = 6f * (H - 0f / 6f); + result.R = MathF.Sqrt(P * P / (p_r + p_g * H * H)); + result.G = result.R * H; + result.B = 0f; + } + else if (H < 2f / 6f) + { + H = 6f * (-H + 2f / 6f); + result.G = MathF.Sqrt(P * P / (p_g + p_r * H * H)); + result.R = result.G * H; + result.B = 0f; + } + else if (H < 3f / 6f) + { + H = 6f * (H - 2f / 6f); + result.G = MathF.Sqrt(P * P / (p_g + p_b * H * H)); + result.B = result.G * H; + result.R = 0f; + } + else if (H < 4f / 6f) + { + H = 6f * (-H + 4f / 6f); + result.B = MathF.Sqrt(P * P / (p_b + p_g * H * H)); + result.G = result.B * H; + result.R = 0f; + } + else if (H < 5f / 6f) + { + H = 6f * (H - 4f / 6f); + result.B = MathF.Sqrt(P * P / (p_b + p_r * H * H)); + result.R = result.B * H; + result.G = 0f; + } + else + { + H = 6f * (-H + 6f / 6f); + result.R = MathF.Sqrt(P * P / (p_r + p_b * H * H)); + result.B = result.R * H; + result.G = 0f; + } + } + + return result; + } + } +} diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index 0f055856d3..91161d5c71 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -229,177 +229,6 @@ namespace osu.Game.Graphics return Gray(brightness > 0.5f ? 0.2f : 0.9f); } - /// - /// Converts RGBA to HSPA. - /// - public static Color4 ToHSPA(Color4 colour) - { - const float p_r = 0.299f; - const float p_g = 0.587f; - const float p_b = 0.114f; - - Color4 result = new Color4 - { - A = colour.A, - B = MathF.Sqrt(colour.R * colour.R * p_r + colour.G * colour.G * p_g + colour.B + colour.B * p_b) - }; - - if (colour.R == colour.G && colour.R == colour.B) - return result; - - if (colour.R >= colour.G && colour.R >= colour.B) - { - if (colour.B >= colour.G) - { - result.R = 6f / 6f - 1f / 6f * (colour.B - colour.G) / (colour.R - colour.G); - result.G = 1f - colour.G / colour.R; - } - else - { - result.R = 0f / 6f + 1f / 6f * (colour.G - colour.B) / (colour.R - colour.B); - result.G = 1f - colour.B / colour.R; - } - } - else if (colour.G >= colour.R && colour.G >= colour.B) - { - if (colour.R >= colour.B) - { - result.R = 2f / 6f - 1f / 6f * (colour.R - colour.B) / (colour.G - colour.B); - result.G = 1f - colour.B / colour.G; - } - else - { - result.R = 2f / 6f + 1f / 6f * (colour.B - colour.R) / (colour.G - colour.R); - result.G = 1f - colour.R / colour.G; - } - } - else - { - if (colour.G >= colour.R) - { - result.R = 4f / 6f - 1f / 6f * (colour.G - colour.R) / (colour.B - colour.R); - result.G = 1f - colour.R / colour.B; - } - else - { - result.R = 4f / 6f + 1f / 6f * (colour.R - colour.G) / (colour.B - colour.G); - result.G = 1f - colour.G / colour.B; - } - } - - return result; - } - - public static Color4 FromHSPA(Color4 colour) - { - const float p_r = 0.299f; - const float p_g = 0.587f; - const float p_b = 0.114f; - - float minOverMax = 1f - colour.G; - - Color4 result = new Color4 { A = colour.A }; - - if (minOverMax > 0f) - { - if (colour.R < 1f / 6f) - { - colour.R = 6f * (colour.R - 0f / 6f); - float part = 1f + colour.R * (1f / minOverMax - 1f); - result.B = colour.B / MathF.Sqrt(p_r / minOverMax / minOverMax + p_g * part * part + p_b); - result.R = result.B / minOverMax; - result.G = result.B + colour.R * (result.R - result.B); - } - else if (colour.R < 2f / 6f) - { - colour.R = 6f * (-colour.R + 2f / 6f); - float part = 1f + colour.R * (1f / minOverMax - 1f); - result.B = colour.B / MathF.Sqrt(p_g / minOverMax / minOverMax + p_r * part * part + p_b); - result.G = result.B / minOverMax; - result.R = result.B + colour.R * (result.G - result.B); - } - else if (colour.R < 3f / 6f) - { - colour.R = 6f * (colour.R - 2f / 6f); - float part = 1f + colour.R * (1f / minOverMax - 1f); - result.R = colour.B / MathF.Sqrt(p_g / minOverMax / minOverMax + p_b * part * part + p_r); - result.G = result.R / minOverMax; - result.B = result.R + colour.R * (result.G - result.R); - } - else if (colour.R < 4f / 6f) - { - colour.R = 6f * (-colour.R + 4f / 6f); - float part = 1f + colour.R * (1f / minOverMax - 1f); - result.R = colour.B / MathF.Sqrt(p_b / minOverMax / minOverMax + p_g * part * part + p_r); - result.B = result.R / minOverMax; - result.G = result.R + colour.R * (result.B - result.R); - } - else if (colour.R < 5f / 6f) - { - colour.R = 6f * (colour.R - 4f / 6f); - float part = 1f + colour.R * (1f / minOverMax - 1f); - result.G = colour.B / MathF.Sqrt(p_b / minOverMax / minOverMax + p_r * part * part + p_g); - result.B = result.G / minOverMax; - result.R = result.G + colour.R * (result.B - result.G); - } - else - { - colour.R = 6f * (-colour.R + 6f / 6f); - float part = 1f + colour.R * (1f / minOverMax - 1f); - result.G = colour.B / MathF.Sqrt(p_r / minOverMax / minOverMax + p_b * part * part + p_g); - result.R = result.G / minOverMax; - result.B = result.G + colour.R * (result.R - result.G); - } - } - else - { - if (colour.R < 1f / 6f) - { - colour.R = 6f * (colour.R - 0f / 6f); - result.R = MathF.Sqrt(colour.B * colour.B / (p_r + p_g * colour.R * colour.R)); - result.G = result.R * colour.R; - result.B = 0f; - } - else if (colour.R < 2f / 6f) - { - colour.R = 6f * (-colour.R + 2f / 6f); - result.G = MathF.Sqrt(colour.B * colour.B / (p_g + p_r * colour.R * colour.R)); - result.R = result.G * colour.R; - result.B = 0f; - } - else if (colour.R < 3f / 6f) - { - colour.R = 6f * (colour.R - 2f / 6f); - result.G = MathF.Sqrt(colour.B * colour.B / (p_g + p_b * colour.R * colour.R)); - result.B = result.G * colour.R; - result.R = 0f; - } - else if (colour.R < 4f / 6f) - { - colour.R = 6f * (-colour.R + 4f / 6f); - result.B = MathF.Sqrt(colour.B * colour.B / (p_b + p_g * colour.R * colour.R)); - result.G = result.B * colour.R; - result.R = 0f; - } - else if (colour.R < 5f / 6f) - { - colour.R = 6f * (colour.R - 4f / 6f); - result.B = MathF.Sqrt(colour.B * colour.B / (p_b + p_r * colour.R * colour.R)); - result.R = result.B * colour.R; - result.G = 0f; - } - else - { - colour.R = 6f * (-colour.R + 6f / 6f); - result.R = MathF.Sqrt(colour.B * colour.B / (p_r + p_b * colour.R * colour.R)); - result.B = result.R * colour.R; - result.G = 0f; - } - } - - return result; - } - public readonly Color4 TeamColourRed = Color4Extensions.FromHex("#AA1414"); public readonly Color4 TeamColourBlue = Color4Extensions.FromHex("#1462AA"); diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 0ef15ed5c2..4ba64687db 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -527,9 +527,7 @@ namespace osu.Game.Rulesets.Objects.Drawables Color4 colour = combo.GetComboColour(CurrentSkin); // Normalise the combo colour to the given brightness level. - colour = OsuColour.ToHSPA(colour); - colour.B = comboColourBrightness.Value; - colour = OsuColour.FromHSPA(colour); + colour = new HSPAColour(colour) { P = comboColourBrightness.Value }.ToColor4(); AccentColour.Value = colour; } diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 44df495929..154ad0fe8c 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -334,6 +334,7 @@ GL GLSL HID + HSPA HSV HTML HUD From 8a88339e787293a7b585acce105aaff236f2c565 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 14 Oct 2022 14:37:24 +0900 Subject: [PATCH 0076/2991] Allow combo colour normalisation to be disabled --- osu.Game/Configuration/OsuConfigManager.cs | 3 +++ .../Sections/Gameplay/BeatmapSettings.cs | 23 +++++++++++++++++-- .../Objects/Drawables/DrawableHitObject.cs | 6 ++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index b433d81f31..33e61372da 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -175,6 +175,8 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f); SetDefault(OsuSetting.LastProcessedMetadataId, -1); + + SetDefault(OsuSetting.NormaliseComboColourBrightness, false); SetDefault(OsuSetting.ComboColourBrightness, 0.7f, 0f, 1f); } @@ -372,6 +374,7 @@ namespace osu.Game.Configuration AutomaticallyDownloadWhenSpectating, ShowOnlineExplicitContent, LastProcessedMetadataId, + NormaliseComboColourBrightness, ComboColourBrightness } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs index 16b7b74f38..0de8f6509f 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs @@ -4,6 +4,7 @@ #nullable disable using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Configuration; @@ -15,9 +16,15 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { protected override LocalisableString Header => GameplaySettingsStrings.BeatmapHeader; + private readonly BindableFloat comboColourBrightness = new BindableFloat(); + private readonly BindableBool normaliseComboColourBrightness = new BindableBool(); + [BackgroundDependencyLoader] private void load(OsuConfigManager config) { + config.BindWith(OsuSetting.ComboColourBrightness, comboColourBrightness); + config.BindWith(OsuSetting.NormaliseComboColourBrightness, normaliseComboColourBrightness); + Children = new Drawable[] { new SettingsCheckbox @@ -40,13 +47,25 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay LabelText = GraphicsSettingsStrings.StoryboardVideo, Current = config.GetBindable(OsuSetting.ShowStoryboard) }, + new SettingsCheckbox + { + LabelText = "Normalise combo colour brightness", + Current = normaliseComboColourBrightness + }, new SettingsSlider { LabelText = "Combo colour brightness", - Current = config.GetBindable(OsuSetting.ComboColourBrightness), - DisplayAsPercentage = true + Current = comboColourBrightness, + DisplayAsPercentage = true, } }; } + + protected override void LoadComplete() + { + base.LoadComplete(); + + normaliseComboColourBrightness.BindValueChanged(normalise => comboColourBrightness.Disabled = !normalise.NewValue, true); + } } } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 4ba64687db..7e2f93dced 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -129,6 +129,7 @@ namespace osu.Game.Rulesets.Objects.Drawables private readonly Bindable comboIndexBindable = new Bindable(); private readonly Bindable positionalHitsoundsLevel = new Bindable(); + private readonly Bindable normaliseComboColourBrightness = new Bindable(); private readonly Bindable comboColourBrightness = new Bindable(); private readonly Bindable comboIndexWithOffsetsBindable = new Bindable(); @@ -173,6 +174,7 @@ namespace osu.Game.Rulesets.Objects.Drawables private void load(OsuConfigManager config, ISkinSource skinSource) { config.BindWith(OsuSetting.PositionalHitsoundsLevel, positionalHitsoundsLevel); + config.BindWith(OsuSetting.NormaliseComboColourBrightness, normaliseComboColourBrightness); config.BindWith(OsuSetting.ComboColourBrightness, comboColourBrightness); // Explicit non-virtual function call in case a DrawableHitObject overrides AddInternal. @@ -195,6 +197,7 @@ namespace osu.Game.Rulesets.Objects.Drawables comboIndexBindable.BindValueChanged(_ => UpdateComboColour()); comboIndexWithOffsetsBindable.BindValueChanged(_ => UpdateComboColour(), true); + normaliseComboColourBrightness.BindValueChanged(_ => UpdateComboColour()); comboColourBrightness.BindValueChanged(_ => UpdateComboColour()); // Apply transforms @@ -527,7 +530,8 @@ namespace osu.Game.Rulesets.Objects.Drawables Color4 colour = combo.GetComboColour(CurrentSkin); // Normalise the combo colour to the given brightness level. - colour = new HSPAColour(colour) { P = comboColourBrightness.Value }.ToColor4(); + if (normaliseComboColourBrightness.Value) + colour = new HSPAColour(colour) { P = comboColourBrightness.Value }.ToColor4(); AccentColour.Value = colour; } From dcb6357964abbbd3643c83f6cd9a5c9556573d24 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 14 Oct 2022 20:23:55 +0900 Subject: [PATCH 0077/2991] Add ability to remove the current item in multiplayer --- .../Multiplayer/Match/Playlist/MultiplayerQueueList.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerQueueList.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerQueueList.cs index 39740e650f..ba6b482729 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerQueueList.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerQueueList.cs @@ -78,9 +78,13 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist return; bool isItemOwner = Item.OwnerID == api.LocalUser.Value.OnlineID || multiplayerClient.IsHost; + bool isValidItem = isItemOwner && !Item.Expired; - AllowDeletion = isItemOwner && !Item.Expired && Item.ID != multiplayerClient.Room.Settings.PlaylistItemId; - AllowEditing = isItemOwner && !Item.Expired; + AllowDeletion = isValidItem + && (Item.ID != multiplayerClient.Room.Settings.PlaylistItemId // This is an optimisation for the following check. + || multiplayerClient.Room.Playlist.Count(i => !i.Expired) > 1); + + AllowEditing = isValidItem; } protected override void Dispose(bool isDisposing) From c65a8a83f390d8bc49d0946cf4c1588b5afc185f Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 14 Oct 2022 15:52:09 +0300 Subject: [PATCH 0078/2991] Add basic UI for reporting --- .../Visual/Online/TestSceneCommentActions.cs | 9 ++- .../Overlays/Comments/CommentReportReason.cs | 14 ++++ osu.Game/Overlays/Comments/DrawableComment.cs | 13 +++- .../Overlays/Comments/ReportCommentPopover.cs | 78 +++++++++++++++++++ 4 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 osu.Game/Overlays/Comments/CommentReportReason.cs create mode 100644 osu.Game/Overlays/Comments/ReportCommentPopover.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs index bf01d3b0ac..1f3e9dd54c 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs @@ -10,6 +10,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Testing; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; @@ -42,9 +43,13 @@ namespace osu.Game.Tests.Visual.Online { base.Content.AddRange(new Drawable[] { - content = new OsuScrollContainer + new PopoverContainer() { - RelativeSizeAxes = Axes.Both + RelativeSizeAxes = Axes.Both, + Child = content = new OsuScrollContainer + { + RelativeSizeAxes = Axes.Both + } }, dialogOverlay }); diff --git a/osu.Game/Overlays/Comments/CommentReportReason.cs b/osu.Game/Overlays/Comments/CommentReportReason.cs new file mode 100644 index 0000000000..e768214438 --- /dev/null +++ b/osu.Game/Overlays/Comments/CommentReportReason.cs @@ -0,0 +1,14 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Overlays.Comments +{ + public enum CommentReportReason + { + Insults, + Spam, + UnwantedContent, + Nonsense, + Other + } +} diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 193d15064a..e675ceef4e 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -19,6 +19,8 @@ using System; using osu.Framework.Graphics.Shapes; using osu.Framework.Extensions.IEnumerableExtensions; using System.Collections.Specialized; +using osu.Framework.Extensions; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; @@ -29,7 +31,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments { - public class DrawableComment : CompositeDrawable + public class DrawableComment : CompositeDrawable, IHasPopover { private const int avatar_size = 40; @@ -324,9 +326,9 @@ namespace osu.Game.Overlays.Comments makeDeleted(); if (Comment.UserId.HasValue && Comment.UserId.Value == api.LocalUser.Value.Id) - { actionsContainer.AddLink("Delete", deleteComment); - } + else + actionsContainer.AddLink("Report", this.ShowPopover); if (Comment.IsTopLevel) { @@ -544,5 +546,10 @@ namespace osu.Game.Overlays.Comments return parentComment.HasMessage ? parentComment.Message : parentComment.IsDeleted ? "deleted" : string.Empty; } } + + public Popover GetPopover() + { + return new ReportCommentPopover(Comment.Id); + } } } diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs new file mode 100644 index 0000000000..119b51a7d7 --- /dev/null +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -0,0 +1,78 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterfaceV2; +using osuTK; + +namespace osu.Game.Overlays.Comments +{ + public class ReportCommentPopover : OsuPopover + { + public readonly long ID; + private LabelledEnumDropdown reason = null!; + private LabelledTextBox info = null!; + private ShakeContainer shaker = null!; + + public ReportCommentPopover(long id) + { + ID = id; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Child = new FillFlowContainer + { + Direction = FillDirection.Vertical, + Width = 500, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(7), + Children = new Drawable[] + { + reason = new LabelledEnumDropdown + { + Label = "Reason" + }, + info = new LabelledTextBox + { + Label = "Additional info", + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = shaker = new ShakeContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = new RoundedButton + { + BackgroundColour = colours.Pink3, + Text = "Send report", + RelativeSizeAxes = Axes.X, + Action = send + } + } + } + } + }; + } + + private void send() + { + string infoValue = info.Current.Value; + var reasonValue = reason.Current.Value; + + if (reasonValue == CommentReportReason.Other && string.IsNullOrWhiteSpace(infoValue)) + { + shaker.Shake(); + return; + } + } + } +} From 7251d41deba1823276c129cb99e9d35823a1c094 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 14 Oct 2022 16:15:28 +0300 Subject: [PATCH 0079/2991] Add request class --- .../API/Requests/CommentReportRequest.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 osu.Game/Online/API/Requests/CommentReportRequest.cs diff --git a/osu.Game/Online/API/Requests/CommentReportRequest.cs b/osu.Game/Online/API/Requests/CommentReportRequest.cs new file mode 100644 index 0000000000..2195d612f3 --- /dev/null +++ b/osu.Game/Online/API/Requests/CommentReportRequest.cs @@ -0,0 +1,39 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Net.Http; +using osu.Framework.IO.Network; +using osu.Game.Overlays.Comments; + +namespace osu.Game.Online.API.Requests +{ + public class CommentReportRequest : APIRequest + { + public readonly long CommentID; + public readonly CommentReportReason Reason; + public readonly string? Info; + + public CommentReportRequest(long commentID, CommentReportReason reason, string? info) + { + CommentID = commentID; + Reason = reason; + Info = info; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + req.Method = HttpMethod.Post; + + req.AddParameter(@"reportable_type", @"comment"); + req.AddParameter(@"reportable_id", $"{CommentID}"); + req.AddParameter(@"reason", Reason.ToString()); + if (!string.IsNullOrWhiteSpace(Info)) + req.AddParameter(@"comments", Info); + + return req; + } + + protected override string Target => @"reports"; + } +} From 3e9fd4c08c9dde11b6925ffa43ae3c1a486da50f Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 14 Oct 2022 16:26:25 +0300 Subject: [PATCH 0080/2991] Implement reporting flow --- osu.Game/Overlays/Comments/DrawableComment.cs | 28 ++++++++++++++++++- .../Overlays/Comments/ReportCommentPopover.cs | 11 ++++++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index e675ceef4e..f7f71788ee 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -27,6 +27,7 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Comments.Buttons; using osu.Game.Overlays.Dialog; +using osu.Game.Overlays.Notifications; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments @@ -73,6 +74,9 @@ namespace osu.Game.Overlays.Comments [Resolved] private IAPIProvider api { get; set; } = null!; + [Resolved(canBeNull: true)] + private NotificationOverlay? notificationOverlay { get; set; } + public DrawableComment(Comment comment) { Comment = comment; @@ -405,6 +409,28 @@ namespace osu.Game.Overlays.Comments api.Queue(request); } + public void ReportComment(CommentReportReason reason, string comment) + { + actionsContainer.Hide(); + actionsLoading.Show(); + var request = new CommentReportRequest(Comment.Id, reason, comment); + request.Success += () => + { + actionsLoading.Hide(); + notificationOverlay?.Post(new SimpleNotification + { + Icon = FontAwesome.Solid.CheckCircle, + Text = "The comment reported successfully." + }); + }; + request.Failure += _ => + { + actionsLoading.Hide(); + actionsContainer.Show(); + }; + api.Queue(request); + } + protected override void LoadComplete() { ShowDeleted.BindValueChanged(show => @@ -549,7 +575,7 @@ namespace osu.Game.Overlays.Comments public Popover GetPopover() { - return new ReportCommentPopover(Comment.Id); + return new ReportCommentPopover(ReportComment); } } } diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index 119b51a7d7..5f9e7ff45c 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -1,7 +1,9 @@ // 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.Allocation; +using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; @@ -13,14 +15,14 @@ namespace osu.Game.Overlays.Comments { public class ReportCommentPopover : OsuPopover { - public readonly long ID; + private readonly Action action; private LabelledEnumDropdown reason = null!; private LabelledTextBox info = null!; private ShakeContainer shaker = null!; - public ReportCommentPopover(long id) + public ReportCommentPopover(Action action) { - ID = id; + this.action = action; } [BackgroundDependencyLoader] @@ -73,6 +75,9 @@ namespace osu.Game.Overlays.Comments shaker.Shake(); return; } + + this.HidePopover(); + action.Invoke(reasonValue, infoValue); } } } From dc0aa2295a6969172e736686892b3f59fb93e34d Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 14 Oct 2022 16:51:48 +0300 Subject: [PATCH 0081/2991] Add test --- .../Visual/Online/TestSceneCommentActions.cs | 85 +++++++++++++++++-- osu.Game/Overlays/Comments/DrawableComment.cs | 8 +- 2 files changed, 83 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs index 1f3e9dd54c..00ae59fa30 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs @@ -15,6 +15,7 @@ using osu.Framework.Testing; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; @@ -38,12 +39,14 @@ namespace osu.Game.Tests.Visual.Online private CommentsContainer commentsContainer = null!; + private readonly ManualResetEventSlim requestLock = new ManualResetEventSlim(); + [BackgroundDependencyLoader] private void load() { base.Content.AddRange(new Drawable[] { - new PopoverContainer() + new PopoverContainer { RelativeSizeAxes = Axes.Both, Child = content = new OsuScrollContainer @@ -85,8 +88,6 @@ namespace osu.Game.Tests.Visual.Online }); } - private readonly ManualResetEventSlim deletionPerformed = new ManualResetEventSlim(); - [Test] public void TestDeletion() { @@ -110,7 +111,7 @@ namespace osu.Game.Tests.Visual.Online }); AddStep("Setup request handling", () => { - deletionPerformed.Reset(); + requestLock.Reset(); dummyAPI.HandleRequest = request => { @@ -143,7 +144,7 @@ namespace osu.Game.Tests.Visual.Online Task.Run(() => { - deletionPerformed.Wait(10000); + requestLock.Wait(10000); req.TriggerSuccess(cb); }); @@ -154,7 +155,7 @@ namespace osu.Game.Tests.Visual.Online AddAssert("Loading spinner shown", () => commentsContainer.ChildrenOfType().Any(d => d.IsPresent)); - AddStep("Complete request", () => deletionPerformed.Set()); + AddStep("Complete request", () => requestLock.Set()); AddUntilStep("Comment is deleted locally", () => this.ChildrenOfType().Single(x => x.Comment.Id == 1).WasDeleted); } @@ -209,6 +210,78 @@ namespace osu.Game.Tests.Visual.Online }); } + [Test] + public void TestReport() + { + const string report_text = "I don't like this comment"; + DrawableComment? targetComment = null; + CommentReportRequest? request = null; + + addTestComments(); + AddUntilStep("Comment exists", () => + { + var comments = this.ChildrenOfType(); + targetComment = comments.SingleOrDefault(x => x.Comment.Id == 2); + return targetComment != null; + }); + AddStep("Setup request handling", () => + { + requestLock.Reset(); + + dummyAPI.HandleRequest = r => + { + if (!(r is CommentReportRequest req)) + return false; + + Task.Run(() => + { + request = req; + requestLock.Wait(10000); + req.TriggerSuccess(); + }); + + return true; + }; + }); + AddStep("Click the button", () => + { + var btn = targetComment.ChildrenOfType().Single(x => x.Text == "Report"); + InputManager.MoveMouseTo(btn); + InputManager.Click(MouseButton.Left); + }); + AddStep("Select \"other\"", () => + { + var field = this.ChildrenOfType>().Single(); + field.Current.Value = CommentReportReason.Other; + }); + AddStep("Try to report", () => + { + var btn = this.ChildrenOfType().Single().ChildrenOfType().Single(); + InputManager.MoveMouseTo(btn); + InputManager.Click(MouseButton.Left); + }); + AddWaitStep("Wait", 3); + AddAssert("Nothing happened", () => this.ChildrenOfType().Any()); + AddStep("Enter some text", () => + { + var field = this.ChildrenOfType().Single(); + field.Current.Value = report_text; + }); + AddStep("Try to report", () => + { + var btn = this.ChildrenOfType().Single().ChildrenOfType().Single(); + InputManager.MoveMouseTo(btn); + InputManager.Click(MouseButton.Left); + }); + AddWaitStep("Wait", 3); + AddAssert("Overlay closed", () => !this.ChildrenOfType().Any()); + AddAssert("Loading spinner shown", () => targetComment.ChildrenOfType().Any(d => d.IsPresent)); + AddStep("Complete request", () => requestLock.Set()); + AddUntilStep("Request sent", () => request != null); + AddAssert("Request is correct", () => request != null && request.CommentID == 2 && request.Info == report_text && request.Reason == CommentReportReason.Other); + AddUntilStep("Buttons hidden", () => !targetComment.ChildrenOfType().Single(x => x.Name == @"Actions buttons").IsPresent); + } + private void addTestComments() { AddStep("set up response", () => diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index f7f71788ee..362e0634c5 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -414,7 +414,7 @@ namespace osu.Game.Overlays.Comments actionsContainer.Hide(); actionsLoading.Show(); var request = new CommentReportRequest(Comment.Id, reason, comment); - request.Success += () => + request.Success += () => Schedule(() => { actionsLoading.Hide(); notificationOverlay?.Post(new SimpleNotification @@ -422,12 +422,12 @@ namespace osu.Game.Overlays.Comments Icon = FontAwesome.Solid.CheckCircle, Text = "The comment reported successfully." }); - }; - request.Failure += _ => + }); + request.Failure += _ => Schedule(() => { actionsLoading.Hide(); actionsContainer.Show(); - }; + }); api.Queue(request); } From 7d53d35bf619aa209391edd773d5c594d7bce15d Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 15 Oct 2022 16:23:54 +0300 Subject: [PATCH 0082/2991] Remove duplicate & outdated test case --- .../SongSelect/TestScenePlaySongSelect.cs | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index cc8746959b..248bf9f5ed 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -538,36 +538,6 @@ namespace osu.Game.Tests.Visual.SongSelect AddUntilStep("selection shown on wedge", () => songSelect!.CurrentBeatmapDetailsBeatmap.BeatmapInfo.MatchesOnlineID(target)); } - [Test] - public void TestRulesetChangeResetsMods() - { - createSongSelect(); - changeRuleset(0); - - changeMods(new OsuModHardRock()); - - int actionIndex = 0; - int modChangeIndex = 0; - int rulesetChangeIndex = 0; - - AddStep("change ruleset", () => - { - SelectedMods.ValueChanged += onModChange; - songSelect!.Ruleset.ValueChanged += onRulesetChange; - - Ruleset.Value = new TaikoRuleset().RulesetInfo; - - SelectedMods.ValueChanged -= onModChange; - songSelect!.Ruleset.ValueChanged -= onRulesetChange; - }); - - AddAssert("mods changed before ruleset", () => modChangeIndex < rulesetChangeIndex); - AddAssert("empty mods", () => !SelectedMods.Value.Any()); - - void onModChange(ValueChangedEvent> e) => modChangeIndex = actionIndex++; - void onRulesetChange(ValueChangedEvent e) => rulesetChangeIndex = actionIndex++; - } - [Test] public void TestModsRetainedBetweenSongSelect() { From 841e20c3363ebe2dd5e9fd0c408d7342ca78273d Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 15 Oct 2022 17:16:08 +0300 Subject: [PATCH 0083/2991] Remove unused usings --- osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 248bf9f5ed..63532fdba8 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; @@ -32,7 +31,6 @@ using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Mods; -using osu.Game.Rulesets.Taiko; using osu.Game.Scoring; using osu.Game.Screens.Play; using osu.Game.Screens.Select; From 9822a092c4f11c46f8e185d029772eb5ef71d934 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 16 Oct 2022 19:50:55 +0300 Subject: [PATCH 0084/2991] Add localization for enum --- osu.Game/Overlays/Comments/CommentReportReason.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game/Overlays/Comments/CommentReportReason.cs b/osu.Game/Overlays/Comments/CommentReportReason.cs index e768214438..4fbec0164d 100644 --- a/osu.Game/Overlays/Comments/CommentReportReason.cs +++ b/osu.Game/Overlays/Comments/CommentReportReason.cs @@ -1,14 +1,26 @@ // 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.Localisation; +using osu.Game.Resources.Localisation.Web; + namespace osu.Game.Overlays.Comments { public enum CommentReportReason { + [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsInsults))] Insults, + + [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsSpam))] Spam, + + [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsUnwantedContent))] UnwantedContent, + + [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsNonsense))] Nonsense, + + [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsOther))] Other } } From ba595ab8fa6f9d520e98f3adb46c53d98ed1ab00 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 16 Oct 2022 19:57:21 +0300 Subject: [PATCH 0085/2991] Display toast instead of notification --- osu.Game/Overlays/Comments/DrawableComment.cs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 362e0634c5..998f3b8e62 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -23,11 +23,12 @@ using osu.Framework.Extensions; using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Comments.Buttons; using osu.Game.Overlays.Dialog; -using osu.Game.Overlays.Notifications; +using osu.Game.Overlays.OSD; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments @@ -75,7 +76,7 @@ namespace osu.Game.Overlays.Comments private IAPIProvider api { get; set; } = null!; [Resolved(canBeNull: true)] - private NotificationOverlay? notificationOverlay { get; set; } + private OnScreenDisplay? onScreenDisplay { get; set; } public DrawableComment(Comment comment) { @@ -417,11 +418,7 @@ namespace osu.Game.Overlays.Comments request.Success += () => Schedule(() => { actionsLoading.Hide(); - notificationOverlay?.Post(new SimpleNotification - { - Icon = FontAwesome.Solid.CheckCircle, - Text = "The comment reported successfully." - }); + onScreenDisplay?.Display(new ReportToast()); }); request.Failure += _ => Schedule(() => { @@ -577,5 +574,13 @@ namespace osu.Game.Overlays.Comments { return new ReportCommentPopover(ReportComment); } + + private class ReportToast : Toast + { + public ReportToast() + : base(UserInterfaceStrings.GeneralHeader, UsersStrings.ReportThanks, "") + { + } + } } } From e1785f73a28c3da1befcc9aa8dd1b41f3f8207d2 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 16 Oct 2022 20:14:05 +0300 Subject: [PATCH 0086/2991] Make report's comment not optional --- osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs | 2 +- osu.Game/Online/API/Requests/CommentReportRequest.cs | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs index 00ae59fa30..3515b5fb0a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs @@ -278,7 +278,7 @@ namespace osu.Game.Tests.Visual.Online AddAssert("Loading spinner shown", () => targetComment.ChildrenOfType().Any(d => d.IsPresent)); AddStep("Complete request", () => requestLock.Set()); AddUntilStep("Request sent", () => request != null); - AddAssert("Request is correct", () => request != null && request.CommentID == 2 && request.Info == report_text && request.Reason == CommentReportReason.Other); + AddAssert("Request is correct", () => request != null && request.CommentID == 2 && request.Comment == report_text && request.Reason == CommentReportReason.Other); AddUntilStep("Buttons hidden", () => !targetComment.ChildrenOfType().Single(x => x.Name == @"Actions buttons").IsPresent); } diff --git a/osu.Game/Online/API/Requests/CommentReportRequest.cs b/osu.Game/Online/API/Requests/CommentReportRequest.cs index 2195d612f3..3f57756ced 100644 --- a/osu.Game/Online/API/Requests/CommentReportRequest.cs +++ b/osu.Game/Online/API/Requests/CommentReportRequest.cs @@ -11,13 +11,13 @@ namespace osu.Game.Online.API.Requests { public readonly long CommentID; public readonly CommentReportReason Reason; - public readonly string? Info; + public readonly string Comment; - public CommentReportRequest(long commentID, CommentReportReason reason, string? info) + public CommentReportRequest(long commentID, CommentReportReason reason, string comment) { CommentID = commentID; Reason = reason; - Info = info; + Comment = comment; } protected override WebRequest CreateWebRequest() @@ -28,8 +28,7 @@ namespace osu.Game.Online.API.Requests req.AddParameter(@"reportable_type", @"comment"); req.AddParameter(@"reportable_id", $"{CommentID}"); req.AddParameter(@"reason", Reason.ToString()); - if (!string.IsNullOrWhiteSpace(Info)) - req.AddParameter(@"comments", Info); + req.AddParameter(@"comments", Comment); return req; } From ae05f374a2e79a57373010324fbaea833611b456 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 17 Oct 2022 03:26:28 +0300 Subject: [PATCH 0087/2991] Fix potential invalid operation exception in `SubmittingPlayer` token retrieval --- osu.Game/Screens/Play/SubmittingPlayer.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/SubmittingPlayer.cs b/osu.Game/Screens/Play/SubmittingPlayer.cs index d56b9c23c8..345bd5a134 100644 --- a/osu.Game/Screens/Play/SubmittingPlayer.cs +++ b/osu.Game/Screens/Play/SubmittingPlayer.cs @@ -86,16 +86,13 @@ namespace osu.Game.Screens.Play // Generally a timeout would not happen here as APIAccess will timeout first. if (!tcs.Task.Wait(60000)) - handleTokenFailure(new InvalidOperationException("Token retrieval timed out (request never run)")); + req.TriggerFailure(new InvalidOperationException("Token retrieval timed out (request never run)")); return true; void handleTokenFailure(Exception exception) { - // This method may be invoked multiple times due to the Task.Wait call above. - // We only really care about the first error. - if (!tcs.TrySetResult(false)) - return; + tcs.SetResult(false); if (HandleTokenRetrievalFailure(exception)) { From 2adbf4cc1a5d27aad1d5a99d41766c598b7dfa60 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 17 Oct 2022 08:26:51 +0300 Subject: [PATCH 0088/2991] Add arc-shaped progress bars to "argon" spinner --- .../Skinning/Argon/ArgonSpinnerDisc.cs | 105 +++++++++++++----- .../Skinning/Argon/ArgonSpinnerProgressArc.cs | 67 +++++++++++ .../Skinning/Argon/ArgonSpinnerRingArc.cs | 33 ++++++ 3 files changed, 175 insertions(+), 30 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs create mode 100644 osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs index 4669b5b913..3b418fcb2d 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs @@ -16,7 +16,6 @@ using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Skinning.Default; using osuTK; -using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Argon { @@ -52,6 +51,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon private Container centre = null!; private CircularContainer fill = null!; + private Container ticksContainer = null!; + private ArgonSpinnerTicks ticks = null!; + [BackgroundDependencyLoader] private void load(DrawableHitObject drawableHitObject) { @@ -70,41 +72,84 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - fill = new CircularContainer + new Container { - Name = @"Fill", - Anchor = Anchor.Centre, - Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - Masking = true, - EdgeEffect = new EdgeEffectParameters + Padding = new MarginPadding(8f), + Children = new[] { - Type = EdgeEffectType.Shadow, - Colour = Colour4.FromHex("FC618F").Opacity(1f), - Radius = 40, + fill = new CircularContainer + { + Name = @"Fill", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Masking = true, + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Colour = Colour4.FromHex("FC618F").Opacity(1f), + Radius = 40, + }, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0f, + AlwaysPresent = true, + } + }, + new Container + { + Name = @"Ring", + Masking = true, + RelativeSizeAxes = Axes.Both, + Children = new[] + { + new ArgonSpinnerRingArc + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Name = "Top Arc", + }, + new ArgonSpinnerRingArc + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Name = "Bottom Arc", + Scale = new Vector2(1, -1), + }, + } + }, + ticksContainer = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Child = ticks = new ArgonSpinnerTicks(), + } }, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0f, - AlwaysPresent = true, - } }, - new CircularContainer + new Container { - Name = @"Ring", - Masking = true, - BorderColour = Color4.White, - BorderThickness = 5, + Name = @"Sides", RelativeSizeAxes = Axes.Both, - Child = new Box + Children = new[] { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - AlwaysPresent = true, + new ArgonSpinnerProgressArc + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Name = "Left Bar" + }, + new ArgonSpinnerProgressArc + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Name = "Right Bar", + Scale = new Vector2(-1, 1), + }, } }, - new ArgonSpinnerTicks(), } }, centre = new Container @@ -167,7 +212,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon float targetScale = initial_fill_scale + (0.98f - initial_fill_scale) * drawableSpinner.Progress; fill.Scale = new Vector2((float)Interpolation.Lerp(fill.Scale.X, targetScale, Math.Clamp(Math.Abs(Time.Elapsed) / 100, 0, 1))); - disc.Rotation = drawableSpinner.RotationTracker.Rotation; + ticks.Rotation = drawableSpinner.RotationTracker.Rotation; } private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state) @@ -180,12 +225,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt)) { this.ScaleTo(initial_scale); - this.RotateTo(0); + ticksContainer.RotateTo(0); using (BeginDelayedSequence(spinner.TimePreempt / 2)) { // constant ambient rotation to give the spinner "spinning" character. - this.RotateTo((float)(25 * spinner.Duration / 2000), spinner.TimePreempt + spinner.Duration); + ticksContainer.RotateTo((float)(25 * spinner.Duration / 2000), spinner.TimePreempt + spinner.Duration); } using (BeginDelayedSequence(spinner.TimePreempt + spinner.Duration + drawableHitObject.Result.TimeOffset)) @@ -194,7 +239,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon { case ArmedState.Hit: this.ScaleTo(initial_scale * 1.2f, 320, Easing.Out); - this.RotateTo(Rotation + 180, 320); + ticksContainer.RotateTo(ticksContainer.Rotation + 180, 320); break; case ArmedState.Miss: diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs new file mode 100644 index 0000000000..be7921a1f1 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs @@ -0,0 +1,67 @@ +// 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.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Utils; +using osu.Game.Graphics; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Osu.Objects.Drawables; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Osu.Skinning.Argon +{ + public class ArgonSpinnerProgressArc : CompositeDrawable + { + private const float arc_fill = 0.15f; + private const float arc_radius = 0.12f; + + private CircularProgress fill = null!; + + private DrawableSpinner spinner = null!; + + [BackgroundDependencyLoader] + private void load(DrawableHitObject drawableHitObject, OsuColour colours) + { + RelativeSizeAxes = Axes.Both; + + spinner = (DrawableSpinner)drawableHitObject; + + InternalChildren = new Drawable[] + { + new CircularProgress + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Colour = Color4.White.Opacity(0.25f), + RelativeSizeAxes = Axes.Both, + Current = { Value = arc_fill }, + Rotation = 90 - arc_fill * 180, + InnerRadius = arc_radius, + RoundedCaps = true, + }, + fill = new CircularProgress + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + InnerRadius = arc_radius, + RoundedCaps = true, + } + }; + } + + protected override void Update() + { + base.Update(); + + fill.Alpha = (float)Interpolation.DampContinuously(fill.Alpha, spinner.Progress > 0 ? 1 : 0, 120f, (float)Math.Abs(Time.Elapsed)); + fill.Current.Value = (float)Interpolation.DampContinuously(fill.Current.Value, arc_fill * spinner.Progress, 120f, (float)Math.Abs(Time.Elapsed)); + fill.Rotation = (float)(90 - fill.Current.Value * 180); + } + } +} diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs new file mode 100644 index 0000000000..ec9d7bbae5 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs @@ -0,0 +1,33 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.UserInterface; + +namespace osu.Game.Rulesets.Osu.Skinning.Argon +{ + public class ArgonSpinnerRingArc : CompositeDrawable + { + private const float arc_fill = 0.31f; + private const float arc_radius = 0.02f; + + [BackgroundDependencyLoader] + private void load() + { + RelativeSizeAxes = Axes.Both; + + InternalChild = new CircularProgress + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Current = { Value = arc_fill }, + Rotation = -arc_fill * 180, + InnerRadius = arc_radius, + RoundedCaps = true, + }; + } + } +} From 7ed26369a3e7b974466d15131bdc3e4a722ef210 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 17 Oct 2022 12:41:57 +0300 Subject: [PATCH 0089/2991] Make a new report form, closer to web --- .../Overlays/Comments/CommentReportDialog.cs | 144 ++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 osu.Game/Overlays/Comments/CommentReportDialog.cs diff --git a/osu.Game/Overlays/Comments/CommentReportDialog.cs b/osu.Game/Overlays/Comments/CommentReportDialog.cs new file mode 100644 index 0000000000..26a768b4ec --- /dev/null +++ b/osu.Game/Overlays/Comments/CommentReportDialog.cs @@ -0,0 +1,144 @@ +// 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.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Resources.Localisation.Web; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Comments +{ + public class CommentReportDialog : VisibilityContainer + { + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider, OsuColour colours) + { + RelativeSizeAxes = Axes.Both; + + Child = new Container + { + Masking = true, + CornerRadius = 10, + Width = 500, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Box + { + Colour = colourProvider.Background6, + RelativeSizeAxes = Axes.Both, + }, + new FillFlowContainer + { + Direction = FillDirection.Vertical, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding(10), + Children = new[] + { + new CircularContainer + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Masking = true, + Size = new Vector2(100f), + BorderColour = Color4.White, + BorderThickness = 5f, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0), + }, + new SpriteIcon + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Icon = FontAwesome.Solid.ExclamationTriangle, + Size = new Vector2(50), + }, + }, + }, + new OsuTextFlowContainer(t => t.Font = t.Font.With(size: 25)) + { + Text = UsersStrings.ReportTitle("the comment"), + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + TextAnchor = Anchor.TopCentre, + }, + Empty().With(d => d.Height = 10), + new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = UsersStrings.ReportReason, + Font = OsuFont.Torus.With(size: 20), + }, + new OsuEnumDropdown + { + RelativeSizeAxes = Axes.X + }, + new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = UsersStrings.ReportComments, + Font = OsuFont.Torus.With(size: 20), + }, + new OsuTextBox + { + RelativeSizeAxes = Axes.X, + PlaceholderText = UsersStrings.ReportPlaceholder + }, + new RoundedButton + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Width = 200, + BackgroundColour = colours.Red3, + Text = UsersStrings.ReportActionsSend, + Action = send, + Margin = new MarginPadding { Bottom = 5, Top = 10 }, + }, + new RoundedButton + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Width = 200, + Text = UsersStrings.ReportActionsCancel, + Action = () => + { + Hide(); + Expire(); + } + } + } + } + } + }; + } + + private void send() + { + } + + protected override void PopIn() + { + } + + protected override void PopOut() + { + } + } +} From 28277dd880a20ce80d71efedb5767edda74169ef Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 17 Oct 2022 19:34:05 +0900 Subject: [PATCH 0090/2991] Fix tests --- .../Multiplayer/TestSceneMultiplayerQueueList.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerQueueList.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerQueueList.cs index f31261dc1f..63677ce378 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerQueueList.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerQueueList.cs @@ -97,14 +97,23 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] - public void TestCurrentItemDoesNotHaveDeleteButton() + public void TestSingleItemDoesNotHaveDeleteButton() + { + AddStep("set all players queue mode", () => MultiplayerClient.ChangeSettings(new MultiplayerRoomSettings { QueueMode = QueueMode.AllPlayers }).WaitSafely()); + AddUntilStep("wait for queue mode change", () => MultiplayerClient.ClientAPIRoom?.QueueMode.Value == QueueMode.AllPlayers); + + assertDeleteButtonVisibility(0, false); + } + + [Test] + public void TestCurrentItemHasDeleteButtonIfNotSingle() { AddStep("set all players queue mode", () => MultiplayerClient.ChangeSettings(new MultiplayerRoomSettings { QueueMode = QueueMode.AllPlayers }).WaitSafely()); AddUntilStep("wait for queue mode change", () => MultiplayerClient.ClientAPIRoom?.QueueMode.Value == QueueMode.AllPlayers); addPlaylistItem(() => API.LocalUser.Value.OnlineID); - assertDeleteButtonVisibility(0, false); + assertDeleteButtonVisibility(0, true); assertDeleteButtonVisibility(1, true); AddStep("finish current item", () => MultiplayerClient.FinishCurrentItem().WaitSafely()); From d7e5bcbd3c401a99e5414a25cd5e097c3c6a7836 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 17 Oct 2022 13:41:46 +0300 Subject: [PATCH 0091/2991] Add popover containers to overlays --- osu.Game/Overlays/BeatmapSetOverlay.cs | 24 ++++++---- .../Changelog/ChangelogSingleBuild.cs | 46 +++++++++++-------- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 207dc91ca5..904fd6ead6 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -10,6 +10,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.BeatmapSet; @@ -44,20 +45,25 @@ namespace osu.Game.Overlays Info info; CommentsSection comments; - Child = new FillFlowContainer + Child = new PopoverContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), - Children = new Drawable[] + Child = new FillFlowContainer { - info = new Info(), - new ScoresContainer + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Children = new Drawable[] { - Beatmap = { BindTarget = Header.HeaderContent.Picker.Beatmap } - }, - comments = new CommentsSection() + info = new Info(), + new ScoresContainer + { + Beatmap = { BindTarget = Header.HeaderContent.Picker.Beatmap } + }, + comments = new CommentsSection() + } } }; diff --git a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs index e4f240f0e7..afdfd0ff68 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs @@ -10,6 +10,7 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; @@ -63,28 +64,33 @@ namespace osu.Game.Overlays.Changelog { CommentsContainer comments; - Children = new Drawable[] + Child = new PopoverContainer { - new ChangelogBuildWithNavigation(build) { SelectBuild = SelectBuild }, - new Box + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - Height = 2, - Colour = colourProvider.Background6, - Margin = new MarginPadding { Top = 30 }, - }, - new ChangelogSupporterPromo - { - Alpha = api.LocalUser.Value.IsSupporter ? 0 : 1, - }, - new Box - { - RelativeSizeAxes = Axes.X, - Height = 2, - Colour = colourProvider.Background6, - Alpha = api.LocalUser.Value.IsSupporter ? 0 : 1, - }, - comments = new CommentsContainer() + new ChangelogBuildWithNavigation(build) { SelectBuild = SelectBuild }, + new Box + { + RelativeSizeAxes = Axes.X, + Height = 2, + Colour = colourProvider.Background6, + Margin = new MarginPadding { Top = 30 }, + }, + new ChangelogSupporterPromo + { + Alpha = api.LocalUser.Value.IsSupporter ? 0 : 1, + }, + new Box + { + RelativeSizeAxes = Axes.X, + Height = 2, + Colour = colourProvider.Background6, + Alpha = api.LocalUser.Value.IsSupporter ? 0 : 1, + }, + comments = new CommentsContainer() + } }; comments.ShowComments(CommentableType.Build, build.Id); From ffa22d8a682983cd8aa7e2ade12d824cb6f18f46 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 17 Oct 2022 13:42:17 +0300 Subject: [PATCH 0092/2991] Update popover not to use labelled drawables --- osu.Game/Overlays/Comments/DrawableComment.cs | 5 +-- .../Overlays/Comments/ReportCommentPopover.cs | 43 ++++++++++++++----- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 998f3b8e62..04e088dc35 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -570,10 +570,7 @@ namespace osu.Game.Overlays.Comments } } - public Popover GetPopover() - { - return new ReportCommentPopover(ReportComment); - } + public Popover GetPopover() => new ReportCommentPopover(ReportComment); private class ReportToast : Toast { diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index 5f9e7ff45c..ad135f7eec 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -8,7 +8,10 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Resources.Localisation.Web; using osuTK; namespace osu.Game.Overlays.Comments @@ -16,8 +19,8 @@ namespace osu.Game.Overlays.Comments public class ReportCommentPopover : OsuPopover { private readonly Action action; - private LabelledEnumDropdown reason = null!; - private LabelledTextBox info = null!; + private OsuEnumDropdown reason = null!; + private OsuTextBox info = null!; private ShakeContainer shaker = null!; public ReportCommentPopover(Action action) @@ -36,13 +39,28 @@ namespace osu.Game.Overlays.Comments Spacing = new Vector2(7), Children = new Drawable[] { - reason = new LabelledEnumDropdown + new OsuSpriteText { - Label = "Reason" + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = UsersStrings.ReportReason, + Font = OsuFont.Torus.With(size: 20), }, - info = new LabelledTextBox + reason = new OsuEnumDropdown { - Label = "Additional info", + RelativeSizeAxes = Axes.X + }, + new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = UsersStrings.ReportComments, + Font = OsuFont.Torus.With(size: 20), + }, + info = new OsuTextBox + { + RelativeSizeAxes = Axes.X, + PlaceholderText = UsersStrings.ReportPlaceholder }, new Container { @@ -54,10 +72,13 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.Y, Child = new RoundedButton { - BackgroundColour = colours.Pink3, - Text = "Send report", - RelativeSizeAxes = Axes.X, - Action = send + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Width = 200, + BackgroundColour = colours.Red3, + Text = UsersStrings.ReportActionsSend, + Action = send, + Margin = new MarginPadding { Bottom = 5, Top = 10 }, } } } @@ -70,7 +91,7 @@ namespace osu.Game.Overlays.Comments string infoValue = info.Current.Value; var reasonValue = reason.Current.Value; - if (reasonValue == CommentReportReason.Other && string.IsNullOrWhiteSpace(infoValue)) + if (string.IsNullOrWhiteSpace(infoValue)) { shaker.Shake(); return; From ceb4d624b5b4749dc08ea2591ce93513aeb1afe6 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 17 Oct 2022 13:43:35 +0300 Subject: [PATCH 0093/2991] Delete wip form --- .../Overlays/Comments/CommentReportDialog.cs | 144 ------------------ 1 file changed, 144 deletions(-) delete mode 100644 osu.Game/Overlays/Comments/CommentReportDialog.cs diff --git a/osu.Game/Overlays/Comments/CommentReportDialog.cs b/osu.Game/Overlays/Comments/CommentReportDialog.cs deleted file mode 100644 index 26a768b4ec..0000000000 --- a/osu.Game/Overlays/Comments/CommentReportDialog.cs +++ /dev/null @@ -1,144 +0,0 @@ -// 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.Allocation; -using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using osu.Game.Graphics.UserInterfaceV2; -using osu.Game.Resources.Localisation.Web; -using osuTK; -using osuTK.Graphics; - -namespace osu.Game.Overlays.Comments -{ - public class CommentReportDialog : VisibilityContainer - { - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider, OsuColour colours) - { - RelativeSizeAxes = Axes.Both; - - Child = new Container - { - Masking = true, - CornerRadius = 10, - Width = 500, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - new Box - { - Colour = colourProvider.Background6, - RelativeSizeAxes = Axes.Both, - }, - new FillFlowContainer - { - Direction = FillDirection.Vertical, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding(10), - Children = new[] - { - new CircularContainer - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Masking = true, - Size = new Vector2(100f), - BorderColour = Color4.White, - BorderThickness = 5f, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0), - }, - new SpriteIcon - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Icon = FontAwesome.Solid.ExclamationTriangle, - Size = new Vector2(50), - }, - }, - }, - new OsuTextFlowContainer(t => t.Font = t.Font.With(size: 25)) - { - Text = UsersStrings.ReportTitle("the comment"), - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - TextAnchor = Anchor.TopCentre, - }, - Empty().With(d => d.Height = 10), - new OsuSpriteText - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Text = UsersStrings.ReportReason, - Font = OsuFont.Torus.With(size: 20), - }, - new OsuEnumDropdown - { - RelativeSizeAxes = Axes.X - }, - new OsuSpriteText - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Text = UsersStrings.ReportComments, - Font = OsuFont.Torus.With(size: 20), - }, - new OsuTextBox - { - RelativeSizeAxes = Axes.X, - PlaceholderText = UsersStrings.ReportPlaceholder - }, - new RoundedButton - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Width = 200, - BackgroundColour = colours.Red3, - Text = UsersStrings.ReportActionsSend, - Action = send, - Margin = new MarginPadding { Bottom = 5, Top = 10 }, - }, - new RoundedButton - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Width = 200, - Text = UsersStrings.ReportActionsCancel, - Action = () => - { - Hide(); - Expire(); - } - } - } - } - } - }; - } - - private void send() - { - } - - protected override void PopIn() - { - } - - protected override void PopOut() - { - } - } -} From 3bcc91511fb185d63061d80268c88cec9e57e31e Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 17 Oct 2022 13:46:13 +0300 Subject: [PATCH 0094/2991] Update test --- osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs index 3515b5fb0a..a6524aad1a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs @@ -249,11 +249,6 @@ namespace osu.Game.Tests.Visual.Online InputManager.MoveMouseTo(btn); InputManager.Click(MouseButton.Left); }); - AddStep("Select \"other\"", () => - { - var field = this.ChildrenOfType>().Single(); - field.Current.Value = CommentReportReason.Other; - }); AddStep("Try to report", () => { var btn = this.ChildrenOfType().Single().ChildrenOfType().Single(); @@ -264,7 +259,7 @@ namespace osu.Game.Tests.Visual.Online AddAssert("Nothing happened", () => this.ChildrenOfType().Any()); AddStep("Enter some text", () => { - var field = this.ChildrenOfType().Single(); + var field = this.ChildrenOfType().Single(); field.Current.Value = report_text; }); AddStep("Try to report", () => From 18cc3b0bd313772d92f58c34c2cf71e9561cb74f Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 17 Oct 2022 20:23:25 +0300 Subject: [PATCH 0095/2991] Fix reason not set in test --- osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs index a6524aad1a..54c135ba15 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs @@ -257,10 +257,12 @@ namespace osu.Game.Tests.Visual.Online }); AddWaitStep("Wait", 3); AddAssert("Nothing happened", () => this.ChildrenOfType().Any()); - AddStep("Enter some text", () => + AddStep("Set report data", () => { var field = this.ChildrenOfType().Single(); field.Current.Value = report_text; + var reason = this.ChildrenOfType>().Single(); + reason.Current.Value = CommentReportReason.Other; }); AddStep("Try to report", () => { From 797acf334f431f02795722a8495e81cfe2e181fe Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 17 Oct 2022 20:41:13 +0300 Subject: [PATCH 0096/2991] Show username in popup --- osu.Game/Overlays/Comments/DrawableComment.cs | 2 +- .../Overlays/Comments/ReportCommentPopover.cs | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 04e088dc35..5fca9b0b4b 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -570,7 +570,7 @@ namespace osu.Game.Overlays.Comments } } - public Popover GetPopover() => new ReportCommentPopover(ReportComment); + public Popover GetPopover() => new ReportCommentPopover(this); private class ReportToast : Toast { diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index ad135f7eec..5214f8a3e3 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.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 osu.Framework.Allocation; using osu.Framework.Extensions; using osu.Framework.Graphics; @@ -18,14 +17,14 @@ namespace osu.Game.Overlays.Comments { public class ReportCommentPopover : OsuPopover { - private readonly Action action; + private readonly DrawableComment comment; private OsuEnumDropdown reason = null!; private OsuTextBox info = null!; private ShakeContainer shaker = null!; - public ReportCommentPopover(Action action) + public ReportCommentPopover(DrawableComment comment) { - this.action = action; + this.comment = comment; } [BackgroundDependencyLoader] @@ -39,6 +38,14 @@ namespace osu.Game.Overlays.Comments Spacing = new Vector2(7), Children = new Drawable[] { + new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = UsersStrings.ReportTitle(comment.Comment.User?.Username ?? comment.Comment.LegacyName!), + Font = OsuFont.Torus.With(size: 25), + Margin = new MarginPadding { Bottom = 10 } + }, new OsuSpriteText { Origin = Anchor.TopCentre, @@ -98,7 +105,7 @@ namespace osu.Game.Overlays.Comments } this.HidePopover(); - action.Invoke(reasonValue, infoValue); + comment.ReportComment(reasonValue, infoValue); } } } From cd77ae062e43a2202bd2a1e074700d30793ce4bc Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 17 Oct 2022 20:41:23 +0300 Subject: [PATCH 0097/2991] Localize the button --- osu.Game/Overlays/Comments/DrawableComment.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 5fca9b0b4b..6182f9b188 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -333,7 +333,7 @@ namespace osu.Game.Overlays.Comments if (Comment.UserId.HasValue && Comment.UserId.Value == api.LocalUser.Value.Id) actionsContainer.AddLink("Delete", deleteComment); else - actionsContainer.AddLink("Report", this.ShowPopover); + actionsContainer.AddLink(UsersStrings.ReportButtonText, this.ShowPopover); if (Comment.IsTopLevel) { From ec3761ced9122bdf5d5ab0b79a1de6de4ae8893c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Oct 2022 16:01:04 +0900 Subject: [PATCH 0098/2991] Standardise control point search logic in `OverlappingScrollAlgorithm` Was using a very local algorithm which I cannot guarantee is correct. I'd rather it just use the one used everywhere else. --- .../Gameplay/TestSceneScrollingHitObjects.cs | 4 +-- .../Beatmaps/ControlPoints/ControlPoint.cs | 5 +--- .../ControlPoints/ControlPointInfo.cs | 8 +++--- .../Beatmaps/ControlPoints/IControlPoint.cs | 13 ++++++++++ .../Rulesets/Timing/MultiplierControlPoint.cs | 12 ++++----- .../Algorithms/OverlappingScrollAlgorithm.cs | 26 +++---------------- .../Algorithms/SequentialScrollAlgorithm.cs | 6 ++--- .../UI/Scrolling/DrawableScrollingRuleset.cs | 4 +-- 8 files changed, 35 insertions(+), 43 deletions(-) create mode 100644 osu.Game/Beatmaps/ControlPoints/IControlPoint.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs index 156a1ee34a..6d036f8e9b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs @@ -214,7 +214,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void addControlPoints(IList controlPoints, double sequenceStartTime) { - controlPoints.ForEach(point => point.StartTime += sequenceStartTime); + controlPoints.ForEach(point => point.Time += sequenceStartTime); scrollContainers.ForEach(container => { @@ -224,7 +224,7 @@ namespace osu.Game.Tests.Visual.Gameplay foreach (var playfield in playfields) { foreach (var controlPoint in controlPoints) - playfield.Add(createDrawablePoint(playfield, controlPoint.StartTime)); + playfield.Add(createDrawablePoint(playfield, controlPoint.Time)); } } diff --git a/osu.Game/Beatmaps/ControlPoints/ControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/ControlPoint.cs index 56a432aec4..0a09e6e7e6 100644 --- a/osu.Game/Beatmaps/ControlPoints/ControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/ControlPoint.cs @@ -9,11 +9,8 @@ using osuTK.Graphics; namespace osu.Game.Beatmaps.ControlPoints { - public abstract class ControlPoint : IComparable, IDeepCloneable, IEquatable + public abstract class ControlPoint : IComparable, IDeepCloneable, IEquatable, IControlPoint { - /// - /// The time at which the control point takes effect. - /// [JsonIgnore] public double Time { get; set; } diff --git a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs index 4be6b5eede..cfe3c671ac 100644 --- a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs +++ b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs @@ -196,8 +196,8 @@ namespace osu.Game.Beatmaps.ControlPoints /// The time to find the control point at. /// The control point to use when is before any control points. /// The active control point at , or a fallback if none found. - protected T BinarySearchWithFallback(IReadOnlyList list, double time, T fallback) - where T : ControlPoint + internal static T BinarySearchWithFallback(IReadOnlyList list, double time, T fallback) + where T : class, IControlPoint { return BinarySearch(list, time) ?? fallback; } @@ -208,8 +208,8 @@ namespace osu.Game.Beatmaps.ControlPoints /// The list to search. /// The time to find the control point at. /// The active control point at . - protected virtual T BinarySearch(IReadOnlyList list, double time) - where T : ControlPoint + internal static T BinarySearch(IReadOnlyList list, double time) + where T : class, IControlPoint { if (list == null) throw new ArgumentNullException(nameof(list)); diff --git a/osu.Game/Beatmaps/ControlPoints/IControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/IControlPoint.cs new file mode 100644 index 0000000000..6a287285d8 --- /dev/null +++ b/osu.Game/Beatmaps/ControlPoints/IControlPoint.cs @@ -0,0 +1,13 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Beatmaps.ControlPoints +{ + public interface IControlPoint + { + /// + /// The time at which the control point takes effect. + /// + public double Time { get; } + } +} diff --git a/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs b/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs index 1e80bd165b..279de2f940 100644 --- a/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs +++ b/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs @@ -11,12 +11,12 @@ namespace osu.Game.Rulesets.Timing /// /// A control point which adds an aggregated multiplier based on the provided 's BeatLength and 's SpeedMultiplier. /// - public class MultiplierControlPoint : IComparable + public class MultiplierControlPoint : IComparable, IControlPoint { /// /// The time in milliseconds at which this starts. /// - public double StartTime; + public double Time { get; set; } /// /// The aggregate multiplier which this provides. @@ -54,13 +54,13 @@ namespace osu.Game.Rulesets.Timing /// /// Creates a . /// - /// The start time of this . - public MultiplierControlPoint(double startTime) + /// The start time of this . + public MultiplierControlPoint(double time) { - StartTime = startTime; + Time = time; } // ReSharper disable once ImpureMethodCallOnReadonlyValueField - public int CompareTo(MultiplierControlPoint other) => StartTime.CompareTo(other?.StartTime); + public int CompareTo(MultiplierControlPoint other) => Time.CompareTo(other?.Time); } } diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs index d41117bce8..8fd7677a52 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs @@ -5,21 +5,18 @@ using System; using osu.Framework.Lists; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Timing; namespace osu.Game.Rulesets.UI.Scrolling.Algorithms { public class OverlappingScrollAlgorithm : IScrollAlgorithm { - private readonly MultiplierControlPoint searchPoint; - private readonly SortedList controlPoints; public OverlappingScrollAlgorithm(SortedList controlPoints) { this.controlPoints = controlPoints; - - searchPoint = new MultiplierControlPoint(); } public double GetDisplayStartTime(double originTime, float offset, double timeRange, float scrollLength) @@ -52,7 +49,7 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms for (; i < controlPoints.Count; i++) { float lastPos = pos; - pos = PositionAt(controlPoints[i].StartTime, currentTime, timeRange, scrollLength); + pos = PositionAt(controlPoints[i].Time, currentTime, timeRange, scrollLength); if (pos > position) { @@ -64,7 +61,7 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms i = Math.Clamp(i, 0, controlPoints.Count - 1); - return controlPoints[i].StartTime + (position - pos) * timeRange / controlPoints[i].Multiplier / scrollLength; + return controlPoints[i].Time + (position - pos) * timeRange / controlPoints[i].Multiplier / scrollLength; } public void Reset() @@ -76,21 +73,6 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms /// /// The time which the should affect. /// The . - private MultiplierControlPoint controlPointAt(double time) - { - if (controlPoints.Count == 0) - return new MultiplierControlPoint(double.NegativeInfinity); - - if (time < controlPoints[0].StartTime) - return controlPoints[0]; - - searchPoint.StartTime = time; - int index = controlPoints.BinarySearch(searchPoint); - - if (index < 0) - index = ~index - 1; - - return controlPoints[index]; - } + private MultiplierControlPoint controlPointAt(double time) => ControlPointInfo.BinarySearch(controlPoints, time) ?? new MultiplierControlPoint(double.NegativeInfinity); } } diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/SequentialScrollAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/SequentialScrollAlgorithm.cs index bfddc22573..8d43185eac 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/SequentialScrollAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/SequentialScrollAlgorithm.cs @@ -121,7 +121,7 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms if (controlPoints.Count == 0) return; - positionMappings.Add(new PositionMapping(controlPoints[0].StartTime, controlPoints[0])); + positionMappings.Add(new PositionMapping(controlPoints[0].Time, controlPoints[0])); for (int i = 0; i < controlPoints.Count - 1; i++) { @@ -129,9 +129,9 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms var next = controlPoints[i + 1]; // Figure out how much of the time range the duration represents, and adjust it by the speed multiplier - float length = (float)((next.StartTime - current.StartTime) / timeRange * current.Multiplier); + float length = (float)((next.Time - current.Time) / timeRange * current.Multiplier); - positionMappings.Add(new PositionMapping(next.StartTime, next, positionMappings[^1].Position + length)); + positionMappings.Add(new PositionMapping(next.Time, next, positionMappings[^1].Position + length)); } } diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs index 825aba5bc2..68469d083c 100644 --- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs @@ -158,9 +158,9 @@ namespace osu.Game.Rulesets.UI.Scrolling // Trim unwanted sequences of timing changes timingChanges = timingChanges // Collapse sections after the last hit object - .Where(s => s.StartTime <= lastObjectTime) + .Where(s => s.Time <= lastObjectTime) // Collapse sections with the same start time - .GroupBy(s => s.StartTime).Select(g => g.Last()).OrderBy(s => s.StartTime); + .GroupBy(s => s.Time).Select(g => g.Last()).OrderBy(s => s.Time); ControlPoints.AddRange(timingChanges); From d237c818f6d744f4a92697f7b45cbc6ff7747dc4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Oct 2022 16:15:21 +0900 Subject: [PATCH 0099/2991] Fix nested objects in overlapping scrolling hit object container ruleset not using correct reference time --- .../UI/Scrolling/Algorithms/ConstantScrollAlgorithm.cs | 2 +- .../UI/Scrolling/Algorithms/IScrollAlgorithm.cs | 5 +++-- .../Scrolling/Algorithms/OverlappingScrollAlgorithm.cs | 4 ++-- .../Scrolling/Algorithms/SequentialScrollAlgorithm.cs | 2 +- .../UI/Scrolling/ScrollingHitObjectContainer.cs | 10 +++++----- osu.Game/Tests/Visual/ScrollingTestContainer.cs | 2 +- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/ConstantScrollAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/ConstantScrollAlgorithm.cs index 0bd8aa64c9..c957a84eb1 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/ConstantScrollAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/ConstantScrollAlgorithm.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms return -PositionAt(startTime, endTime, timeRange, scrollLength); } - public float PositionAt(double time, double currentTime, double timeRange, float scrollLength) + public float PositionAt(double time, double currentTime, double timeRange, float scrollLength, double? originTime = null) => (float)((time - currentTime) / timeRange * scrollLength); public double TimeAt(float position, double currentTime, double timeRange, float scrollLength) diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollAlgorithm.cs index d2fb9e3531..f78509f919 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollAlgorithm.cs @@ -53,8 +53,9 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms /// The current time. /// The amount of visible time. /// The absolute spatial length through . + /// The time to be used for control point lookups (ie. the parent's start time for nested hit objects). /// The absolute spatial position. - float PositionAt(double time, double currentTime, double timeRange, float scrollLength); + float PositionAt(double time, double currentTime, double timeRange, float scrollLength, double? originTime = null); /// /// Computes the time which brings a point to a provided spatial position given the current time. @@ -63,7 +64,7 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms /// The current time. /// The amount of visible time. /// The absolute spatial length through . - /// The time at which == . + /// The time at which == . double TimeAt(float position, double currentTime, double timeRange, float scrollLength); /// diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs index 8fd7677a52..00bc7453d8 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs @@ -34,8 +34,8 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms return -PositionAt(startTime, endTime, timeRange, scrollLength); } - public float PositionAt(double time, double currentTime, double timeRange, float scrollLength) - => (float)((time - currentTime) / timeRange * controlPointAt(time).Multiplier * scrollLength); + public float PositionAt(double time, double currentTime, double timeRange, float scrollLength, double? originTime = null) + => (float)((time - currentTime) / timeRange * controlPointAt(originTime ?? time).Multiplier * scrollLength); public double TimeAt(float position, double currentTime, double timeRange, float scrollLength) { diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/SequentialScrollAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/SequentialScrollAlgorithm.cs index 8d43185eac..774beb20c7 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/SequentialScrollAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/SequentialScrollAlgorithm.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms return (float)(objectLength * scrollLength); } - public float PositionAt(double time, double currentTime, double timeRange, float scrollLength) + public float PositionAt(double time, double currentTime, double timeRange, float scrollLength, double? originTime = null) { double timelineLength = relativePositionAt(time, timeRange) - relativePositionAt(currentTime, timeRange); return (float)(timelineLength * scrollLength); diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 37da157cc1..443a37ab1c 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -93,9 +93,9 @@ namespace osu.Game.Rulesets.UI.Scrolling /// /// Given a time, return the position along the scrolling axis within this at time . /// - public float PositionAtTime(double time, double currentTime) + public float PositionAtTime(double time, double currentTime, double? originTime = null) { - float scrollPosition = scrollingInfo.Algorithm.PositionAt(time, currentTime, timeRange.Value, scrollLength); + float scrollPosition = scrollingInfo.Algorithm.PositionAt(time, currentTime, timeRange.Value, scrollLength, originTime); return axisInverted ? -scrollPosition : scrollPosition; } @@ -252,14 +252,14 @@ namespace osu.Game.Rulesets.UI.Scrolling updateLayoutRecursive(obj); // Nested hitobjects don't need to scroll, but they do need accurate positions and start lifetime - updatePosition(obj, hitObject.HitObject.StartTime); + updatePosition(obj, hitObject.HitObject.StartTime, hitObject.HitObject.StartTime); setComputedLifetimeStart(obj.Entry); } } - private void updatePosition(DrawableHitObject hitObject, double currentTime) + private void updatePosition(DrawableHitObject hitObject, double currentTime, double? parentHitObjectStartTime = null) { - float position = PositionAtTime(hitObject.HitObject.StartTime, currentTime); + float position = PositionAtTime(hitObject.HitObject.StartTime, currentTime, parentHitObjectStartTime); if (scrollingAxis == Direction.Horizontal) hitObject.X = position; diff --git a/osu.Game/Tests/Visual/ScrollingTestContainer.cs b/osu.Game/Tests/Visual/ScrollingTestContainer.cs index cf7fe6e45d..87f4bb3f3b 100644 --- a/osu.Game/Tests/Visual/ScrollingTestContainer.cs +++ b/osu.Game/Tests/Visual/ScrollingTestContainer.cs @@ -99,7 +99,7 @@ namespace osu.Game.Tests.Visual public float GetLength(double startTime, double endTime, double timeRange, float scrollLength) => implementation.GetLength(startTime, endTime, timeRange, scrollLength); - public float PositionAt(double time, double currentTime, double timeRange, float scrollLength) + public float PositionAt(double time, double currentTime, double timeRange, float scrollLength, double? originTime = null) => implementation.PositionAt(time, currentTime, timeRange, scrollLength); public double TimeAt(float position, double currentTime, double timeRange, float scrollLength) From 49d5931022de62351712c71d7c53789c2bc45ac1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 16 Oct 2022 18:39:25 +0900 Subject: [PATCH 0100/2991] Initial setup with adjustable max combo --- osu.Game.Tests/Gameplay/TestSceneScoring.cs | 138 ++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 osu.Game.Tests/Gameplay/TestSceneScoring.cs diff --git a/osu.Game.Tests/Gameplay/TestSceneScoring.cs b/osu.Game.Tests/Gameplay/TestSceneScoring.cs new file mode 100644 index 0000000000..febe6aa123 --- /dev/null +++ b/osu.Game.Tests/Gameplay/TestSceneScoring.cs @@ -0,0 +1,138 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Threading; +using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Settings; +using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Osu.Beatmaps; +using osu.Game.Rulesets.Osu.Judgements; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Scoring; +using osu.Game.Tests.Visual; +using osuTK.Graphics; + +namespace osu.Game.Tests.Gameplay +{ + public class TestSceneScoring : OsuTestScene + { + private Container graphs = null!; + private SettingsSlider sliderMaxCombo = null!; + + [Test] + public void TestBasic() + { + AddStep("setup tests", () => + { + Children = new Drawable[] + { + new GridContainer + { + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new Drawable[] + { + graphs = new Container + { + RelativeSizeAxes = Axes.X, + Height = 200, + }, + }, + new Drawable[] + { + new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Direction = FillDirection.Full, + Children = new Drawable[] + { + sliderMaxCombo = new SettingsSlider + { + Width = 0.5f, + Current = new BindableInt(1024) + { + MinValue = 96, + MaxValue = 8192, + }, + LabelText = "max combo", + } + } + }, + }, + } + } + }; + + sliderMaxCombo.Current.BindValueChanged(_ => rerun()); + + rerun(); + }); + } + + private ScheduledDelegate? debouncedRun; + + private void rerun() + { + graphs.Clear(); + + debouncedRun?.Cancel(); + debouncedRun = Scheduler.AddDelayed(() => + { + runForProcessor("lazer-classic", new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Classic } }); + runForProcessor("lazer-standardised", new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Standardised } }); + }, 200); + } + + private void runForProcessor(string name, ScoreProcessor processor) + { + int maxCombo = sliderMaxCombo.Current.Value; + + var beatmap = new OsuBeatmap(); + + for (int i = 0; i < maxCombo; i++) + { + beatmap.HitObjects.Add(new HitCircle()); + } + + processor.ApplyBeatmap(beatmap); + + int[] missLocations = { 200, 500, 800 }; + + List results = new List(); + + for (int i = 0; i < maxCombo; i++) + { + if (missLocations.Contains(i)) + { + processor.ApplyResult(new OsuJudgementResult(new HitCircle(), new OsuJudgement()) + { + Type = HitResult.Miss + }); + } + else + { + processor.ApplyResult(new OsuJudgementResult(new HitCircle(), new OsuJudgement()) + { + Type = HitResult.Great + }); + } + + results.Add((float)processor.TotalScore.Value); + } + + graphs.Add(new LineGraph + { + RelativeSizeAxes = Axes.Both, + LineColour = Color4.Red, + Values = results + }); + } + } +} From 94c57a459defc4ee6764dae1aa6b7d0fa3fa3f69 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Oct 2022 23:27:26 +0900 Subject: [PATCH 0101/2991] Add ability to add miss locations by clicking --- osu.Game.Tests/Gameplay/TestSceneScoring.cs | 107 ++++++++++++++++++-- 1 file changed, 98 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneScoring.cs b/osu.Game.Tests/Gameplay/TestSceneScoring.cs index febe6aa123..e18bf5f0bf 100644 --- a/osu.Game.Tests/Gameplay/TestSceneScoring.cs +++ b/osu.Game.Tests/Gameplay/TestSceneScoring.cs @@ -2,12 +2,14 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; -using System.Linq; using NUnit.Framework; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Input.Events; using osu.Framework.Threading; +using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Osu; @@ -22,7 +24,7 @@ namespace osu.Game.Tests.Gameplay { public class TestSceneScoring : OsuTestScene { - private Container graphs = null!; + private GraphContainer graphs = null!; private SettingsSlider sliderMaxCombo = null!; [Test] @@ -39,7 +41,7 @@ namespace osu.Game.Tests.Gameplay { new Drawable[] { - graphs = new Container + graphs = new GraphContainer { RelativeSizeAxes = Axes.X, Height = 200, @@ -70,7 +72,10 @@ namespace osu.Game.Tests.Gameplay } }; - sliderMaxCombo.Current.BindValueChanged(_ => rerun()); + sliderMaxCombo.Current.BindValueChanged(_ => rerun(true)); + graphs.MissLocations.BindCollectionChanged((_, __) => rerun()); + + graphs.MaxCombo.BindTo(sliderMaxCombo.Current); rerun(); }); @@ -78,7 +83,7 @@ namespace osu.Game.Tests.Gameplay private ScheduledDelegate? debouncedRun; - private void rerun() + private void rerun(bool debounce = false) { graphs.Clear(); @@ -87,7 +92,7 @@ namespace osu.Game.Tests.Gameplay { runForProcessor("lazer-classic", new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Classic } }); runForProcessor("lazer-standardised", new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Standardised } }); - }, 200); + }, debounce ? 200 : 0); } private void runForProcessor(string name, ScoreProcessor processor) @@ -103,13 +108,11 @@ namespace osu.Game.Tests.Gameplay processor.ApplyBeatmap(beatmap); - int[] missLocations = { 200, 500, 800 }; - List results = new List(); for (int i = 0; i < maxCombo; i++) { - if (missLocations.Contains(i)) + if (graphs.MissLocations.Contains(i)) { processor.ApplyResult(new OsuJudgementResult(new HitCircle(), new OsuJudgement()) { @@ -135,4 +138,90 @@ namespace osu.Game.Tests.Gameplay }); } } + + public class GraphContainer : Container + { + public readonly BindableList MissLocations = new BindableList(); + + public Bindable MaxCombo = new Bindable(); + + protected override Container Content { get; } = new Container { RelativeSizeAxes = Axes.Both }; + + private readonly Box hoverLine; + + private readonly Container missLines; + + public GraphContainer() + { + InternalChild = new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Box + { + Colour = OsuColour.Gray(0.1f), + RelativeSizeAxes = Axes.Both, + }, + Content, + hoverLine = new Box + { + Colour = Color4.Yellow, + RelativeSizeAxes = Axes.Y, + Alpha = 0, + Width = 1, + }, + missLines = new Container + { + RelativeSizeAxes = Axes.Both, + }, + } + }; + + MissLocations.BindCollectionChanged((_, _) => updateMissLocations(), true); + + MaxCombo.BindValueChanged(_ => updateMissLocations()); + } + + private void updateMissLocations() + { + missLines.Clear(); + + foreach (int miss in MissLocations) + { + missLines.Add(new Box + { + Colour = Color4.Red, + Width = 1, + RelativeSizeAxes = Axes.Y, + RelativePositionAxes = Axes.X, + X = (float)miss / MaxCombo.Value, + }); + } + } + + protected override bool OnHover(HoverEvent e) + { + hoverLine.Show(); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + hoverLine.Hide(); + base.OnHoverLost(e); + } + + protected override bool OnMouseMove(MouseMoveEvent e) + { + hoverLine.X = e.MousePosition.X; + return base.OnMouseMove(e); + } + + protected override bool OnClick(ClickEvent e) + { + MissLocations.Add((int)(e.MousePosition.X / DrawWidth * MaxCombo.Value)); + return true; + } + } } From 1ea2a1ff04bcac4fab4fdeee27d18ccc417d51bd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Oct 2022 23:41:07 +0900 Subject: [PATCH 0102/2991] Add basic legend and line colouring --- osu.Game.Tests/Gameplay/TestSceneScoring.cs | 54 ++++++++++++++++----- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneScoring.cs b/osu.Game.Tests/Gameplay/TestSceneScoring.cs index e18bf5f0bf..95b7868b91 100644 --- a/osu.Game.Tests/Gameplay/TestSceneScoring.cs +++ b/osu.Game.Tests/Gameplay/TestSceneScoring.cs @@ -1,15 +1,18 @@ // 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 NUnit.Framework; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; -using osu.Framework.Threading; using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Osu; @@ -27,6 +30,20 @@ namespace osu.Game.Tests.Gameplay private GraphContainer graphs = null!; private SettingsSlider sliderMaxCombo = null!; + private FillFlowContainer legend = null!; + + private static readonly Color4[] line_colours = + { + Color4Extensions.FromHex("588c7e"), + Color4Extensions.FromHex("b2a367"), + Color4Extensions.FromHex("c98f65"), + Color4Extensions.FromHex("bc5151"), + Color4Extensions.FromHex("5c8bd6"), + Color4Extensions.FromHex("7f6ab7"), + Color4Extensions.FromHex("a368ad"), + Color4Extensions.FromHex("aa6880"), + }; + [Test] public void TestBasic() { @@ -48,6 +65,15 @@ namespace osu.Game.Tests.Gameplay }, }, new Drawable[] + { + legend = new FillFlowContainer + { + Direction = FillDirection.Vertical, + RelativeSizeAxes = Axes.X, + Height = 200, + }, + }, + new Drawable[] { new FillFlowContainer { @@ -58,6 +84,7 @@ namespace osu.Game.Tests.Gameplay sliderMaxCombo = new SettingsSlider { Width = 0.5f, + TransferValueOnCommit = true, Current = new BindableInt(1024) { MinValue = 96, @@ -72,7 +99,7 @@ namespace osu.Game.Tests.Gameplay } }; - sliderMaxCombo.Current.BindValueChanged(_ => rerun(true)); + sliderMaxCombo.Current.BindValueChanged(_ => rerun()); graphs.MissLocations.BindCollectionChanged((_, __) => rerun()); graphs.MaxCombo.BindTo(sliderMaxCombo.Current); @@ -81,22 +108,19 @@ namespace osu.Game.Tests.Gameplay }); } - private ScheduledDelegate? debouncedRun; - - private void rerun(bool debounce = false) + private void rerun() { graphs.Clear(); + legend.Clear(); - debouncedRun?.Cancel(); - debouncedRun = Scheduler.AddDelayed(() => - { - runForProcessor("lazer-classic", new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Classic } }); - runForProcessor("lazer-standardised", new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Standardised } }); - }, debounce ? 200 : 0); + runForProcessor("lazer-classic", new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Classic } }); + runForProcessor("lazer-standardised", new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Standardised } }); } private void runForProcessor(string name, ScoreProcessor processor) { + Color4 colour = line_colours[Math.Abs(name.GetHashCode()) % line_colours.Length]; + int maxCombo = sliderMaxCombo.Current.Value; var beatmap = new OsuBeatmap(); @@ -133,9 +157,15 @@ namespace osu.Game.Tests.Gameplay graphs.Add(new LineGraph { RelativeSizeAxes = Axes.Both, - LineColour = Color4.Red, + LineColour = colour, Values = results }); + + legend.Add(new OsuSpriteText + { + Colour = colour, + Text = $"{FontAwesome.Solid.Circle.Icon} {name}" + }); } } From 19b4d2d25ed4ed28a9bb4db2db8130da2298079c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Oct 2022 23:49:15 +0900 Subject: [PATCH 0103/2991] Add vertical grid lines --- osu.Game.Tests/Gameplay/TestSceneScoring.cs | 33 +++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneScoring.cs b/osu.Game.Tests/Gameplay/TestSceneScoring.cs index 95b7868b91..363f1ea758 100644 --- a/osu.Game.Tests/Gameplay/TestSceneScoring.cs +++ b/osu.Game.Tests/Gameplay/TestSceneScoring.cs @@ -180,6 +180,7 @@ namespace osu.Game.Tests.Gameplay private readonly Box hoverLine; private readonly Container missLines; + private readonly Container verticalGridLines; public GraphContainer() { @@ -193,6 +194,10 @@ namespace osu.Game.Tests.Gameplay Colour = OsuColour.Gray(0.1f), RelativeSizeAxes = Axes.Both, }, + verticalGridLines = new Container + { + RelativeSizeAxes = Axes.Both, + }, Content, hoverLine = new Box { @@ -208,9 +213,33 @@ namespace osu.Game.Tests.Gameplay } }; - MissLocations.BindCollectionChanged((_, _) => updateMissLocations(), true); + MissLocations.BindCollectionChanged((_, _) => updateMissLocations()); - MaxCombo.BindValueChanged(_ => updateMissLocations()); + MaxCombo.BindValueChanged(_ => + { + updateMissLocations(); + updateVerticalGridLines(); + }, true); + } + + private void updateVerticalGridLines() + { + verticalGridLines.Clear(); + + for (int i = 0; i < MaxCombo.Value; i++) + { + if (i % 100 == 0) + { + verticalGridLines.Add(new Box + { + Colour = OsuColour.Gray(0.2f), + Width = 1, + RelativeSizeAxes = Axes.Y, + RelativePositionAxes = Axes.X, + X = (float)i / MaxCombo.Value, + }); + } + } } private void updateMissLocations() From c77847b2844ae8e7f8793a092884c00545b54927 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Oct 2022 16:50:30 +0900 Subject: [PATCH 0104/2991] Improve layout and add combo text --- osu.Game.Tests/Gameplay/TestSceneScoring.cs | 41 ++++++++++++++++----- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneScoring.cs b/osu.Game.Tests/Gameplay/TestSceneScoring.cs index 363f1ea758..54ead45992 100644 --- a/osu.Game.Tests/Gameplay/TestSceneScoring.cs +++ b/osu.Game.Tests/Gameplay/TestSceneScoring.cs @@ -54,30 +54,38 @@ namespace osu.Game.Tests.Gameplay new GridContainer { RelativeSizeAxes = Axes.Both, + RowDimensions = new[] + { + new Dimension(), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + }, Content = new[] { new Drawable[] { graphs = new GraphContainer { - RelativeSizeAxes = Axes.X, - Height = 200, + RelativeSizeAxes = Axes.Both, }, }, new Drawable[] { legend = new FillFlowContainer { + Padding = new MarginPadding(20), Direction = FillDirection.Vertical, RelativeSizeAxes = Axes.X, - Height = 200, + AutoSizeAxes = Axes.Y, }, }, new Drawable[] { new FillFlowContainer { - RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding(20), + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, Direction = FillDirection.Full, Children = new Drawable[] { @@ -230,13 +238,26 @@ namespace osu.Game.Tests.Gameplay { if (i % 100 == 0) { - verticalGridLines.Add(new Box + verticalGridLines.AddRange(new Drawable[] { - Colour = OsuColour.Gray(0.2f), - Width = 1, - RelativeSizeAxes = Axes.Y, - RelativePositionAxes = Axes.X, - X = (float)i / MaxCombo.Value, + new Box + { + Colour = OsuColour.Gray(0.2f), + Width = 1, + RelativeSizeAxes = Axes.Y, + RelativePositionAxes = Axes.X, + X = (float)i / MaxCombo.Value, + }, + new OsuSpriteText + { + RelativePositionAxes = Axes.X, + X = (float)i / MaxCombo.Value, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Text = $"{i:#,0}", + Rotation = -30, + Y = -20, + } }); } } From d694c8b7711693b53a9bc3db22c420940688a4c3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Oct 2022 16:55:04 +0900 Subject: [PATCH 0105/2991] Move test scene more correctly into visual folder --- osu.Game.Tests/{ => Visual}/Gameplay/TestSceneScoring.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename osu.Game.Tests/{ => Visual}/Gameplay/TestSceneScoring.cs (99%) diff --git a/osu.Game.Tests/Gameplay/TestSceneScoring.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs similarity index 99% rename from osu.Game.Tests/Gameplay/TestSceneScoring.cs rename to osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs index 54ead45992..f2ad97dc03 100644 --- a/osu.Game.Tests/Gameplay/TestSceneScoring.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs @@ -20,10 +20,9 @@ using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Scoring; -using osu.Game.Tests.Visual; using osuTK.Graphics; -namespace osu.Game.Tests.Gameplay +namespace osu.Game.Tests.Visual.Gameplay { public class TestSceneScoring : OsuTestScene { From 7360cca047baa8ad309c1fe459433a8792647533 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Oct 2022 17:23:23 +0900 Subject: [PATCH 0106/2991] Add stable v1 algorithm --- .../Visual/Gameplay/TestSceneScoring.cs | 53 ++++++++++++------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs index f2ad97dc03..1cd96a65e9 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs @@ -122,43 +122,60 @@ namespace osu.Game.Tests.Visual.Gameplay runForProcessor("lazer-classic", new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Classic } }); runForProcessor("lazer-standardised", new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Standardised } }); + + int totalScore = 0; + int currentCombo = 0; + + runForAlgorithm("stable-v1", () => + { + const int base_score = 300; + const float score_multiplier = 1; + + totalScore += base_score; + + // combo multiplier + // ReSharper disable once PossibleLossOfFraction + totalScore += (int)(Math.Max(0, currentCombo - 1) * (base_score / 25 * score_multiplier)); + + currentCombo++; + }, () => + { + currentCombo = 0; + }, () => totalScore); } private void runForProcessor(string name, ScoreProcessor processor) { - Color4 colour = line_colours[Math.Abs(name.GetHashCode()) % line_colours.Length]; - int maxCombo = sliderMaxCombo.Current.Value; var beatmap = new OsuBeatmap(); - for (int i = 0; i < maxCombo; i++) - { beatmap.HitObjects.Add(new HitCircle()); - } processor.ApplyBeatmap(beatmap); + runForAlgorithm(name, + () => processor.ApplyResult(new OsuJudgementResult(new HitCircle(), new OsuJudgement()) { Type = HitResult.Great }), + () => processor.ApplyResult(new OsuJudgementResult(new HitCircle(), new OsuJudgement()) { Type = HitResult.Miss }), + () => (int)processor.TotalScore.Value); + } + + private void runForAlgorithm(string name, Action applyHit, Action applyMiss, Func getTotalScore) + { + int maxCombo = sliderMaxCombo.Current.Value; + + Color4 colour = line_colours[Math.Abs(name.GetHashCode()) % line_colours.Length]; + List results = new List(); for (int i = 0; i < maxCombo; i++) { if (graphs.MissLocations.Contains(i)) - { - processor.ApplyResult(new OsuJudgementResult(new HitCircle(), new OsuJudgement()) - { - Type = HitResult.Miss - }); - } + applyMiss(); else - { - processor.ApplyResult(new OsuJudgementResult(new HitCircle(), new OsuJudgement()) - { - Type = HitResult.Great - }); - } + applyHit(); - results.Add((float)processor.TotalScore.Value); + results.Add(getTotalScore()); } graphs.Add(new LineGraph From 743ae10df5f9e537605d3431ded469a4d8d74420 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Oct 2022 17:28:13 +0900 Subject: [PATCH 0107/2991] Improve colouring --- .../Visual/Gameplay/TestSceneScoring.cs | 26 +++++-------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs index 1cd96a65e9..d7d5a8f4ab 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs @@ -31,18 +31,6 @@ namespace osu.Game.Tests.Visual.Gameplay private FillFlowContainer legend = null!; - private static readonly Color4[] line_colours = - { - Color4Extensions.FromHex("588c7e"), - Color4Extensions.FromHex("b2a367"), - Color4Extensions.FromHex("c98f65"), - Color4Extensions.FromHex("bc5151"), - Color4Extensions.FromHex("5c8bd6"), - Color4Extensions.FromHex("7f6ab7"), - Color4Extensions.FromHex("a368ad"), - Color4Extensions.FromHex("aa6880"), - }; - [Test] public void TestBasic() { @@ -120,13 +108,13 @@ namespace osu.Game.Tests.Visual.Gameplay graphs.Clear(); legend.Clear(); - runForProcessor("lazer-classic", new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Classic } }); - runForProcessor("lazer-standardised", new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Standardised } }); + runForProcessor("lazer-standardised", Color4.Cyan, new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Standardised } }); + runForProcessor("lazer-classic", Color4.Orange, new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Classic } }); int totalScore = 0; int currentCombo = 0; - runForAlgorithm("stable-v1", () => + runForAlgorithm("stable-v1", Color4.Beige, () => { const int base_score = 300; const float score_multiplier = 1; @@ -144,7 +132,7 @@ namespace osu.Game.Tests.Visual.Gameplay }, () => totalScore); } - private void runForProcessor(string name, ScoreProcessor processor) + private void runForProcessor(string name, Color4 colour, ScoreProcessor processor) { int maxCombo = sliderMaxCombo.Current.Value; @@ -154,18 +142,16 @@ namespace osu.Game.Tests.Visual.Gameplay processor.ApplyBeatmap(beatmap); - runForAlgorithm(name, + runForAlgorithm(name, colour, () => processor.ApplyResult(new OsuJudgementResult(new HitCircle(), new OsuJudgement()) { Type = HitResult.Great }), () => processor.ApplyResult(new OsuJudgementResult(new HitCircle(), new OsuJudgement()) { Type = HitResult.Miss }), () => (int)processor.TotalScore.Value); } - private void runForAlgorithm(string name, Action applyHit, Action applyMiss, Func getTotalScore) + private void runForAlgorithm(string name, Color4 colour, Action applyHit, Action applyMiss, Func getTotalScore) { int maxCombo = sliderMaxCombo.Current.Value; - Color4 colour = line_colours[Math.Abs(name.GetHashCode()) % line_colours.Length]; - List results = new List(); for (int i = 0; i < maxCombo; i++) From 4b2fe72a908d9c20aa2dce1e9d12a7286d767299 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Oct 2022 17:50:51 +0900 Subject: [PATCH 0108/2991] Add stable v2 algorithm --- .../Visual/Gameplay/TestSceneScoring.cs | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs index d7d5a8f4ab..937c52a3cf 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using NUnit.Framework; using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -109,14 +108,15 @@ namespace osu.Game.Tests.Visual.Gameplay legend.Clear(); runForProcessor("lazer-standardised", Color4.Cyan, new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Standardised } }); - runForProcessor("lazer-classic", Color4.Orange, new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Classic } }); + runForProcessor("lazer-classic", Color4.MediumPurple, new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Classic } }); int totalScore = 0; int currentCombo = 0; - runForAlgorithm("stable-v1", Color4.Beige, () => + const int base_score = 300; + + runForAlgorithm("ScoreV1 (classic)", Color4.Beige, () => { - const int base_score = 300; const float score_multiplier = 1; totalScore += base_score; @@ -130,6 +130,43 @@ namespace osu.Game.Tests.Visual.Gameplay { currentCombo = 0; }, () => totalScore); + + double comboPortion = 0; + + int maxCombo = sliderMaxCombo.Current.Value; + + double currentBaseScore = 0; + double maxBaseScore = 0; + + int currentHits = 0; + + double comboPortionMax = 0; + for (int i = 0; i < maxCombo; i++) + comboPortionMax += base_score * (1 + (i + 1) / 10.0); + + runForAlgorithm("ScoreV2", Color4.OrangeRed, () => + { + maxBaseScore += base_score; + currentBaseScore += base_score; + comboPortion += base_score * (1 + ++currentCombo / 10.0); + + currentHits++; + }, () => + { + currentHits++; + maxBaseScore += base_score; + + currentCombo = 0; + }, () => + { + double accuracy = currentBaseScore / maxBaseScore; + + return (int)Math.Round + ( + 700000 * comboPortion / comboPortionMax + + 300000 * Math.Pow(accuracy, 10) * ((double)currentHits / maxCombo) + ); + }); } private void runForProcessor(string name, Color4 colour, ScoreProcessor processor) From 74986e0c8c38c3ba600dc6e1292fe61e67f96165 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Oct 2022 18:05:54 +0900 Subject: [PATCH 0109/2991] Show final scores and change colouring again --- .../Visual/Gameplay/TestSceneScoring.cs | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs index 937c52a3cf..5f053e9982 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs @@ -60,7 +60,7 @@ namespace osu.Game.Tests.Visual.Gameplay legend = new FillFlowContainer { Padding = new MarginPadding(20), - Direction = FillDirection.Vertical, + Direction = FillDirection.Full, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, }, @@ -107,7 +107,7 @@ namespace osu.Game.Tests.Visual.Gameplay graphs.Clear(); legend.Clear(); - runForProcessor("lazer-standardised", Color4.Cyan, new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Standardised } }); + runForProcessor("lazer-standardised", Color4.YellowGreen, new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Standardised } }); runForProcessor("lazer-classic", Color4.MediumPurple, new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Classic } }); int totalScore = 0; @@ -115,7 +115,7 @@ namespace osu.Game.Tests.Visual.Gameplay const int base_score = 300; - runForAlgorithm("ScoreV1 (classic)", Color4.Beige, () => + runForAlgorithm("ScoreV1 (classic)", Color4.Purple, () => { const float score_multiplier = 1; @@ -129,7 +129,13 @@ namespace osu.Game.Tests.Visual.Gameplay }, () => { currentCombo = 0; - }, () => totalScore); + }, () => + { + // Arbitrary value chosen towards the upper range. + const double score_multiplier = 4; + + return (int)(totalScore * score_multiplier); + }); double comboPortion = 0; @@ -211,8 +217,18 @@ namespace osu.Game.Tests.Visual.Gameplay legend.Add(new OsuSpriteText { Colour = colour, + RelativeSizeAxes = Axes.X, + Width = 0.5f, Text = $"{FontAwesome.Solid.Circle.Icon} {name}" }); + + legend.Add(new OsuSpriteText + { + Colour = colour, + RelativeSizeAxes = Axes.X, + Width = 0.5f, + Text = $"final score {getTotalScore():#,0}" + }); } } From a7b3aa62fb4b560c88e95c2be8e318a6e6f9ccf1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Oct 2022 18:13:13 +0900 Subject: [PATCH 0110/2991] Move lines to background to better visualise graphs at points of change --- osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs index 5f053e9982..14678bd617 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Settings; @@ -85,6 +86,13 @@ namespace osu.Game.Tests.Visual.Gameplay MaxValue = 8192, }, LabelText = "max combo", + }, + new OsuTextFlowContainer + { + RelativeSizeAxes = Axes.X, + Width = 0.5f, + AutoSizeAxes = Axes.Y, + Text = "Left click to add miss" } } }, @@ -261,18 +269,20 @@ namespace osu.Game.Tests.Visual.Gameplay { RelativeSizeAxes = Axes.Both, }, - Content, hoverLine = new Box { Colour = Color4.Yellow, RelativeSizeAxes = Axes.Y, + Origin = Anchor.TopCentre, Alpha = 0, Width = 1, }, missLines = new Container { + Alpha = 0.6f, RelativeSizeAxes = Axes.Both, }, + Content, } }; @@ -298,6 +308,7 @@ namespace osu.Game.Tests.Visual.Gameplay new Box { Colour = OsuColour.Gray(0.2f), + Origin = Anchor.TopCentre, Width = 1, RelativeSizeAxes = Axes.Y, RelativePositionAxes = Axes.X, @@ -327,6 +338,7 @@ namespace osu.Game.Tests.Visual.Gameplay missLines.Add(new Box { Colour = Color4.Red, + Origin = Anchor.TopCentre, Width = 1, RelativeSizeAxes = Axes.Y, RelativePositionAxes = Axes.X, From 74e1b5794bcfd1d30f086d8f999b6b73469a16fc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Oct 2022 18:27:05 +0900 Subject: [PATCH 0111/2991] Add ability to add "OK" or 100s via right click --- .../Visual/Gameplay/TestSceneScoring.cs | 132 +++++++++++++----- 1 file changed, 94 insertions(+), 38 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs index 14678bd617..f0deeb118b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs @@ -21,6 +21,7 @@ using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Scoring; using osuTK.Graphics; +using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { @@ -92,7 +93,7 @@ namespace osu.Game.Tests.Visual.Gameplay RelativeSizeAxes = Axes.X, Width = 0.5f, AutoSizeAxes = Axes.Y, - Text = "Left click to add miss" + Text = $"Left click to add miss\nRight click to add OK/{base_ok}" } } }, @@ -102,7 +103,9 @@ namespace osu.Game.Tests.Visual.Gameplay }; sliderMaxCombo.Current.BindValueChanged(_ => rerun()); + graphs.MissLocations.BindCollectionChanged((_, __) => rerun()); + graphs.NonPerfectLocations.BindCollectionChanged((_, __) => rerun()); graphs.MaxCombo.BindTo(sliderMaxCombo.Current); @@ -110,6 +113,9 @@ namespace osu.Game.Tests.Visual.Gameplay }); } + private const int base_great = 300; + private const int base_ok = 100; + private void rerun() { graphs.Clear(); @@ -118,33 +124,50 @@ namespace osu.Game.Tests.Visual.Gameplay runForProcessor("lazer-standardised", Color4.YellowGreen, new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Standardised } }); runForProcessor("lazer-classic", Color4.MediumPurple, new ScoreProcessor(new OsuRuleset()) { Mode = { Value = ScoringMode.Classic } }); + runScoreV1(); + runScoreV2(); + } + + private void runScoreV1() + { int totalScore = 0; int currentCombo = 0; - const int base_score = 300; - - runForAlgorithm("ScoreV1 (classic)", Color4.Purple, () => + void applyHitV1(int baseScore) { + if (baseScore == 0) + { + currentCombo = 0; + return; + } + const float score_multiplier = 1; - totalScore += base_score; + totalScore += baseScore; // combo multiplier // ReSharper disable once PossibleLossOfFraction - totalScore += (int)(Math.Max(0, currentCombo - 1) * (base_score / 25 * score_multiplier)); + totalScore += (int)(Math.Max(0, currentCombo - 1) * (baseScore / 25 * score_multiplier)); currentCombo++; - }, () => - { - currentCombo = 0; - }, () => - { - // Arbitrary value chosen towards the upper range. - const double score_multiplier = 4; + } - return (int)(totalScore * score_multiplier); - }); + runForAlgorithm("ScoreV1 (classic)", Color4.Purple, + () => applyHitV1(base_great), + () => applyHitV1(base_ok), + () => applyHitV1(0), + () => + { + // Arbitrary value chosen towards the upper range. + const double score_multiplier = 4; + return (int)(totalScore * score_multiplier); + }); + } + + private void runScoreV2() + { + int currentCombo = 0; double comboPortion = 0; int maxCombo = sliderMaxCombo.Current.Value; @@ -154,33 +177,43 @@ namespace osu.Game.Tests.Visual.Gameplay int currentHits = 0; - double comboPortionMax = 0; for (int i = 0; i < maxCombo; i++) - comboPortionMax += base_score * (1 + (i + 1) / 10.0); + applyHitV2(base_great); - runForAlgorithm("ScoreV2", Color4.OrangeRed, () => + double comboPortionMax = comboPortion; + + comboPortion = 0; + maxBaseScore = 0; + currentBaseScore = 0; + currentHits = 0; + + void applyHitV2(int baseScore) { - maxBaseScore += base_score; - currentBaseScore += base_score; - comboPortion += base_score * (1 + ++currentCombo / 10.0); + maxBaseScore += baseScore; + currentBaseScore += baseScore; + comboPortion += baseScore * (1 + ++currentCombo / 10.0); currentHits++; - }, () => - { - currentHits++; - maxBaseScore += base_score; + } - currentCombo = 0; - }, () => - { - double accuracy = currentBaseScore / maxBaseScore; + runForAlgorithm("ScoreV2", Color4.OrangeRed, + () => applyHitV2(base_great), + () => applyHitV2(base_ok), + () => + { + currentHits++; + maxBaseScore += base_great; + currentCombo = 0; + }, () => + { + double accuracy = currentBaseScore / maxBaseScore; - return (int)Math.Round - ( - 700000 * comboPortion / comboPortionMax + - 300000 * Math.Pow(accuracy, 10) * ((double)currentHits / maxCombo) - ); - }); + return (int)Math.Round + ( + 700000 * comboPortion / comboPortionMax + + 300000 * Math.Pow(accuracy, 10) * ((double)currentHits / maxCombo) + ); + }); } private void runForProcessor(string name, Color4 colour, ScoreProcessor processor) @@ -195,11 +228,12 @@ namespace osu.Game.Tests.Visual.Gameplay runForAlgorithm(name, colour, () => processor.ApplyResult(new OsuJudgementResult(new HitCircle(), new OsuJudgement()) { Type = HitResult.Great }), + () => processor.ApplyResult(new OsuJudgementResult(new HitCircle(), new OsuJudgement()) { Type = HitResult.Ok }), () => processor.ApplyResult(new OsuJudgementResult(new HitCircle(), new OsuJudgement()) { Type = HitResult.Miss }), () => (int)processor.TotalScore.Value); } - private void runForAlgorithm(string name, Color4 colour, Action applyHit, Action applyMiss, Func getTotalScore) + private void runForAlgorithm(string name, Color4 colour, Action applyHit, Action applyNonPerfect, Action applyMiss, Func getTotalScore) { int maxCombo = sliderMaxCombo.Current.Value; @@ -209,6 +243,8 @@ namespace osu.Game.Tests.Visual.Gameplay { if (graphs.MissLocations.Contains(i)) applyMiss(); + else if (graphs.NonPerfectLocations.Contains(i)) + applyNonPerfect(); else applyHit(); @@ -243,6 +279,7 @@ namespace osu.Game.Tests.Visual.Gameplay public class GraphContainer : Container { public readonly BindableList MissLocations = new BindableList(); + public readonly BindableList NonPerfectLocations = new BindableList(); public Bindable MaxCombo = new Bindable(); @@ -287,6 +324,7 @@ namespace osu.Game.Tests.Visual.Gameplay }; MissLocations.BindCollectionChanged((_, _) => updateMissLocations()); + NonPerfectLocations.BindCollectionChanged((_, _) => updateMissLocations()); MaxCombo.BindValueChanged(_ => { @@ -345,6 +383,19 @@ namespace osu.Game.Tests.Visual.Gameplay X = (float)miss / MaxCombo.Value, }); } + + foreach (int miss in NonPerfectLocations) + { + missLines.Add(new Box + { + Colour = Color4.Orange, + Origin = Anchor.TopCentre, + Width = 1, + RelativeSizeAxes = Axes.Y, + RelativePositionAxes = Axes.X, + X = (float)miss / MaxCombo.Value, + }); + } } protected override bool OnHover(HoverEvent e) @@ -365,9 +416,14 @@ namespace osu.Game.Tests.Visual.Gameplay return base.OnMouseMove(e); } - protected override bool OnClick(ClickEvent e) + protected override bool OnMouseDown(MouseDownEvent e) { - MissLocations.Add((int)(e.MousePosition.X / DrawWidth * MaxCombo.Value)); + int combo = (int)(e.MousePosition.X / DrawWidth * MaxCombo.Value); + + if (e.Button == MouseButton.Left) + MissLocations.Add(combo); + else + NonPerfectLocations.Add(combo); return true; } } From d92aca7c22dbd8c6674037ef8078d567f80fad8e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Oct 2022 18:30:18 +0900 Subject: [PATCH 0112/2991] Fix scoreV2 being higher than intended --- osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs index f0deeb118b..7743b44bd4 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs @@ -167,14 +167,12 @@ namespace osu.Game.Tests.Visual.Gameplay private void runScoreV2() { - int currentCombo = 0; - double comboPortion = 0; - int maxCombo = sliderMaxCombo.Current.Value; + int currentCombo = 0; + double comboPortion = 0; double currentBaseScore = 0; double maxBaseScore = 0; - int currentHits = 0; for (int i = 0; i < maxCombo; i++) @@ -182,9 +180,10 @@ namespace osu.Game.Tests.Visual.Gameplay double comboPortionMax = comboPortion; + currentCombo = 0; comboPortion = 0; - maxBaseScore = 0; currentBaseScore = 0; + maxBaseScore = 0; currentHits = 0; void applyHitV2(int baseScore) From d5666ca7179cef03dda84d989918a48ded3cfc82 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Oct 2022 19:01:43 +0900 Subject: [PATCH 0113/2991] Add tooltip display of current values --- .../Visual/Gameplay/TestSceneScoring.cs | 79 +++++++++++++++++-- 1 file changed, 74 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs index 7743b44bd4..ec98d00e68 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs @@ -3,10 +3,12 @@ using System; using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; @@ -20,6 +22,7 @@ using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Scoring; +using osuTK; using osuTK.Graphics; using osuTK.Input; @@ -252,6 +255,7 @@ namespace osu.Game.Tests.Visual.Gameplay graphs.Add(new LineGraph { + Name = name, RelativeSizeAxes = Axes.Both, LineColour = colour, Values = results @@ -275,7 +279,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - public class GraphContainer : Container + public class GraphContainer : Container, IHasCustomTooltip> { public readonly BindableList MissLocations = new BindableList(); public readonly BindableList NonPerfectLocations = new BindableList(); @@ -289,6 +293,8 @@ namespace osu.Game.Tests.Visual.Gameplay private readonly Container missLines; private readonly Container verticalGridLines; + public int CurrentHoverCombo { get; private set; } + public GraphContainer() { InternalChild = new Container @@ -411,19 +417,82 @@ namespace osu.Game.Tests.Visual.Gameplay protected override bool OnMouseMove(MouseMoveEvent e) { + CurrentHoverCombo = (int)(e.MousePosition.X / DrawWidth * MaxCombo.Value); + hoverLine.X = e.MousePosition.X; return base.OnMouseMove(e); } protected override bool OnMouseDown(MouseDownEvent e) { - int combo = (int)(e.MousePosition.X / DrawWidth * MaxCombo.Value); - if (e.Button == MouseButton.Left) - MissLocations.Add(combo); + MissLocations.Add(CurrentHoverCombo); else - NonPerfectLocations.Add(combo); + NonPerfectLocations.Add(CurrentHoverCombo); + return true; } + + private GraphTooltip? tooltip; + + public ITooltip> GetCustomTooltip() => tooltip ??= new GraphTooltip(this); + + public IEnumerable TooltipContent => Content.OfType(); + + public class GraphTooltip : CompositeDrawable, ITooltip> + { + private readonly GraphContainer graphContainer; + + private readonly OsuTextFlowContainer textFlow; + + public GraphTooltip(GraphContainer graphContainer) + { + this.graphContainer = graphContainer; + AutoSizeAxes = Axes.Both; + + Masking = true; + CornerRadius = 10; + + InternalChildren = new Drawable[] + { + new Box + { + Colour = OsuColour.Gray(0.15f), + RelativeSizeAxes = Axes.Both, + }, + textFlow = new OsuTextFlowContainer + { + Colour = Color4.White, + AutoSizeAxes = Axes.Both, + Padding = new MarginPadding(10), + } + }; + } + + private int? lastContentCombo; + + public void SetContent(IEnumerable content) + { + int relevantCombo = graphContainer.CurrentHoverCombo; + + if (lastContentCombo == relevantCombo) + return; + + lastContentCombo = relevantCombo; + textFlow.Clear(); + + textFlow.AddParagraph($"At combo {relevantCombo}:"); + + foreach (var graph in content) + { + float valueAtHover = graph.Values.ElementAt(relevantCombo); + float ofTotal = valueAtHover / graph.Values.Last(); + + textFlow.AddParagraph($"{graph.Name}: {valueAtHover:#,0} ({ofTotal * 100:N0}% of final)\n", st => st.Colour = graph.LineColour); + } + } + + public void Move(Vector2 pos) => this.MoveTo(pos); + } } } From e1a8bfa135a103540ad232555fd7f7f33e3eee45 Mon Sep 17 00:00:00 2001 From: Dario Headley Date: Tue, 18 Oct 2022 13:39:40 +0200 Subject: [PATCH 0114/2991] Fixed approachCircle preempt --- .../Mods/OsuModApproachDifferent.cs | 2 +- .../Mods/OsuModFreezeFrame.cs | 42 +++++++++++++++---- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 2 +- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModApproachDifferent.cs b/osu.Game.Rulesets.Osu/Mods/OsuModApproachDifferent.cs index ec93f19e17..f213d9f193 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModApproachDifferent.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModApproachDifferent.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override double ScoreMultiplier => 1; public override IconUsage? Icon { get; } = FontAwesome.Regular.Circle; - public override Type[] IncompatibleMods => new[] { typeof(IHidesApproachCircles) }; + public override Type[] IncompatibleMods => new[] { typeof(IHidesApproachCircles), typeof(OsuModFreezeFrame) }; [SettingSource("Initial size", "Change the initial size of the approach circle, relative to hit circles.", 0)] public BindableFloat Scale { get; } = new BindableFloat(4) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index a91d7831c3..f2ee93a704 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -1,17 +1,20 @@ // 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.Graphics; using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.Osu.UI; -using osu.Game.Rulesets.UI; +using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModFreezeFrame : Mod, IApplicableToBeatmap, IApplicableToDrawableRuleset + public class OsuModFreezeFrame : Mod, IApplicableToDrawableHitObject, IApplicableToBeatmap + { public override string Name => "Freeze Frame"; @@ -21,16 +24,18 @@ namespace osu.Game.Rulesets.Osu.Mods public override LocalisableString Description => "Burn the notes into your memory."; + //Alters the transforms of the approach circles, breaking the effects of these mods. + public override Type[] IncompatibleMods => new[] { typeof(OsuModApproachDifferent), /*typeof(OsuModHidden)*/ }; + public override ModType Type => ModType.Fun; - public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) - { - (drawableRuleset.Playfield as OsuPlayfield)?.FollowPoints.Hide(); - } + //mod breaks normal approach circle preempt + private double approachCircleTimePreempt; public void ApplyToBeatmap(IBeatmap beatmap) { double lastNewComboTime = 0; + approachCircleTimePreempt = beatmap.HitObjects.OfType().FirstOrDefault()!.TimePreempt; foreach (var obj in beatmap.HitObjects.OfType()) { @@ -58,5 +63,28 @@ namespace osu.Game.Rulesets.Osu.Mods } } } + + public void ApplyToDrawableHitObject(DrawableHitObject drawableObject) + { + drawableObject.ApplyCustomUpdateState += (drawableHitObject, _) => + { + if (drawableHitObject is not DrawableHitCircle drawableHitCircle) return; + + var hitCircle = drawableHitCircle.HitObject; + var approachCircle = drawableHitCircle.ApproachCircle; + + approachCircle.ClearTransforms(); + approachCircle.ScaleTo(4); + approachCircle.FadeTo(0); + + using (drawableHitCircle.ApproachCircle.BeginAbsoluteSequence(hitCircle.StartTime - approachCircleTimePreempt)) + { + //Redo ApproachCircle animation with correct startTime. + approachCircle.LifetimeStart = hitCircle.StartTime - approachCircleTimePreempt; + approachCircle.FadeTo(1, Math.Min(hitCircle.TimeFadeIn * 2, hitCircle.TimePreempt)); + approachCircle.ScaleTo(1, approachCircleTimePreempt).Then().Expire(); + } + }; + } } } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 996ee1cddb..2d7c0c82de 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override LocalisableString Description => @"Play with no approach circles and fading circles/sliders."; public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.06 : 1; - public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn) }; + public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn), typeof(OsuModFreezeFrame) }; public const double FADE_IN_DURATION_MULTIPLIER = 0.4; public const double FADE_OUT_DURATION_MULTIPLIER = 0.3; From acf3498f83a225ddf10bef957370655944f1e2fd Mon Sep 17 00:00:00 2001 From: "D.Headley" Date: Tue, 18 Oct 2022 13:49:10 +0200 Subject: [PATCH 0115/2991] Code Quality --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index f2ee93a704..7395e09d97 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -14,7 +14,6 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Mods { public class OsuModFreezeFrame : Mod, IApplicableToDrawableHitObject, IApplicableToBeatmap - { public override string Name => "Freeze Frame"; From 764bc1948fffea55f1fd0eb13150949fdbf88c83 Mon Sep 17 00:00:00 2001 From: "D.Headley" Date: Tue, 18 Oct 2022 14:59:43 +0200 Subject: [PATCH 0116/2991] remove commented out Incompatible mod --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 7395e09d97..8bf2c89057 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override LocalisableString Description => "Burn the notes into your memory."; //Alters the transforms of the approach circles, breaking the effects of these mods. - public override Type[] IncompatibleMods => new[] { typeof(OsuModApproachDifferent), /*typeof(OsuModHidden)*/ }; + public override Type[] IncompatibleMods => new[] { typeof(OsuModApproachDifferent), typeof(OsuModHidden) }; public override ModType Type => ModType.Fun; From d6ed5612802cbf5b0a5d83e69e6d7fdfe375bcd8 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 19 Oct 2022 00:16:24 +0900 Subject: [PATCH 0117/2991] make EndPlacement virtual --- .../Edit/Blueprints/HitPlacementBlueprint.cs | 1 + osu.Game/Rulesets/Edit/HitObjectComposer.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs index 08e7e57688..863a2c9eac 100644 --- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs @@ -26,6 +26,7 @@ namespace osu.Game.Rulesets.Taiko.Edit.Blueprints Size = new Vector2(TaikoHitObject.DEFAULT_SIZE * TaikoPlayfield.DEFAULT_HEIGHT) }; } + protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 3bed835854..0266317817 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -359,7 +359,7 @@ namespace osu.Game.Rulesets.Edit EditorBeatmap.PlacementObject.Value = hitObject; } - public void EndPlacement(HitObject hitObject, bool commit) + public virtual void EndPlacement(HitObject hitObject, bool commit) { EditorBeatmap.PlacementObject.Value = null; From a76a0397226b844e923b40e3965a4e745bc0c321 Mon Sep 17 00:00:00 2001 From: Joppe27 Date: Tue, 18 Oct 2022 23:40:43 +0200 Subject: [PATCH 0118/2991] Rename KiaiFlashingDrawable and move to osu.Game --- .../Skinning/LegacyKiaiFlashingDrawable.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename osu.Game.Rulesets.Osu/Skinning/Legacy/KiaiFlashingDrawable.cs => osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs (88%) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/KiaiFlashingDrawable.cs b/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs similarity index 88% rename from osu.Game.Rulesets.Osu/Skinning/Legacy/KiaiFlashingDrawable.cs rename to osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs index 152ed5c3d9..c64f322df9 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/KiaiFlashingDrawable.cs +++ b/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs @@ -7,15 +7,15 @@ using osu.Framework.Graphics; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.Containers; -namespace osu.Game.Rulesets.Osu.Skinning.Legacy +namespace osu.Game.Skinning { - internal class KiaiFlashingDrawable : BeatSyncedContainer + public class LegacyKiaiFlashingDrawable : BeatSyncedContainer { private readonly Drawable flashingDrawable; private const float flash_opacity = 0.3f; - public KiaiFlashingDrawable(Func creationFunc) + public LegacyKiaiFlashingDrawable(Func creationFunc) { AutoSizeAxes = Axes.Both; From 2b5f12e4fb67ede5e419596ad3d8bc14642bdb2b Mon Sep 17 00:00:00 2001 From: Joppe27 Date: Tue, 18 Oct 2022 23:47:26 +0200 Subject: [PATCH 0119/2991] Mark existing Drawable test scenes as NUnit for reuse in kiai test scenes --- .../Skinning/TestSceneDrawableDrumRoll.cs | 4 ++-- .../Skinning/TestSceneDrawableHit.cs | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRoll.cs index 2d27e0e40e..e42dc254ac 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRoll.cs @@ -25,8 +25,8 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning TimeRange = { Value = 5000 }, }; - [BackgroundDependencyLoader] - private void load() + [Test] + public void DrumrollTest() { AddStep("Drum roll", () => SetContents(_ => { diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs index d5a97f8f88..8e9c487c2f 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs @@ -4,7 +4,6 @@ #nullable disable using NUnit.Framework; -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; @@ -16,8 +15,8 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning [TestFixture] public class TestSceneDrawableHit : TaikoSkinnableTestScene { - [BackgroundDependencyLoader] - private void load() + [Test] + public void TestHits() { AddStep("Centre hit", () => SetContents(_ => new DrawableHit(createHitAtCurrentTime()) { From bc57ef061ee32f9a507277ba2128cfab3b4eb25c Mon Sep 17 00:00:00 2001 From: Joppe27 Date: Tue, 18 Oct 2022 23:48:50 +0200 Subject: [PATCH 0120/2991] Add tests for DrawableHit and DrawableDrumRoll kiai flashing --- .../Skinning/TestSceneDrawableDrumRollKiai.cs | 30 +++++++++++++++++++ .../Skinning/TestSceneDrawableHitKiai.cs | 30 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRollKiai.cs create mode 100644 osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHitKiai.cs diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRollKiai.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRollKiai.cs new file mode 100644 index 0000000000..53977150e7 --- /dev/null +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRollKiai.cs @@ -0,0 +1,30 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Beatmaps; + +namespace osu.Game.Rulesets.Taiko.Tests.Skinning +{ + [TestFixture] + public class TestSceneDrawableDrumRollKiai : TestSceneDrawableDrumRoll + { + [SetUp] + public void SetUp() => Schedule(() => + { + var controlPointInfo = new ControlPointInfo(); + + controlPointInfo.Add(0, new TimingControlPoint { BeatLength = 500 }); + controlPointInfo.Add(0, new EffectControlPoint { KiaiMode = true }); + + Beatmap.Value = CreateWorkingBeatmap(new Beatmap + { + ControlPointInfo = controlPointInfo + }); + + // track needs to be playing for BeatSyncedContainer to work. + Beatmap.Value.Track.Start(); + }); + } +} diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHitKiai.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHitKiai.cs new file mode 100644 index 0000000000..fac0530749 --- /dev/null +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHitKiai.cs @@ -0,0 +1,30 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; + +namespace osu.Game.Rulesets.Taiko.Tests.Skinning +{ + [TestFixture] + public class TestSceneDrawableHitKiai : TestSceneDrawableHit + { + [SetUp] + public void SetUp() => Schedule(() => + { + var controlPointInfo = new ControlPointInfo(); + + controlPointInfo.Add(0, new TimingControlPoint { BeatLength = 500 }); + controlPointInfo.Add(0, new EffectControlPoint { KiaiMode = true }); + + Beatmap.Value = CreateWorkingBeatmap(new Beatmap + { + ControlPointInfo = controlPointInfo + }); + + // track needs to be playing for BeatSyncedContainer to work. + Beatmap.Value.Track.Start(); + }); + } +} From 59213fc00bd2cf10710e26d674c038c1c99def50 Mon Sep 17 00:00:00 2001 From: Joppe27 Date: Tue, 18 Oct 2022 23:53:12 +0200 Subject: [PATCH 0121/2991] Update LegacyMainCirclePiece to use renamed version of KiaiFlashingDrawable --- .../Skinning/Legacy/LegacyMainCirclePiece.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs index 1b2ab82044..211411591c 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy InternalChildren = new[] { - CircleSprite = new KiaiFlashingDrawable(() => new Sprite { Texture = skin.GetTexture(circleName) }) + CircleSprite = new LegacyKiaiFlashingDrawable(() => new Sprite { Texture = skin.GetTexture(circleName) }) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Child = OverlaySprite = new KiaiFlashingDrawable(() => skin.GetAnimation(@$"{circleName}overlay", true, true, frameLength: 1000 / 2d)) + Child = OverlaySprite = new LegacyKiaiFlashingDrawable(() => skin.GetAnimation(@$"{circleName}overlay", true, true, frameLength: 1000 / 2d)) { Anchor = Anchor.Centre, Origin = Anchor.Centre, From a21acdb5bc70cbf185f2e2e2447da669c0b2e703 Mon Sep 17 00:00:00 2001 From: Joppe27 Date: Tue, 18 Oct 2022 23:55:02 +0200 Subject: [PATCH 0122/2991] Implement kiai flashing for legacy taiko skins --- osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs index 399bd9260d..6bbeb0ed4c 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy } // backgroundLayer is guaranteed to exist due to the pre-check in TaikoLegacySkinTransformer. - AddInternal(backgroundLayer = getDrawableFor("circle")); + AddInternal(backgroundLayer = new LegacyKiaiFlashingDrawable(() => getDrawableFor("circle"))); var foregroundLayer = getDrawableFor("circleoverlay"); if (foregroundLayer != null) From 003e4247f9064e86f2c6bc1aa2eb7baeda7f49ee Mon Sep 17 00:00:00 2001 From: Joppe27 Date: Tue, 18 Oct 2022 23:55:40 +0200 Subject: [PATCH 0123/2991] Implement kiai flashing for "triangles" taiko skin --- .../Skinning/Default/CirclePiece.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs index a7ab1bcd4a..d0eaf9a602 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs @@ -3,6 +3,7 @@ #nullable disable +using System; using osu.Framework.Audio.Track; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -32,6 +33,8 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default private const double pre_beat_transition_time = 80; + private const float flash_opacity = 0.3f; + private Color4 accentColour; /// @@ -157,6 +160,13 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default if (!effectPoint.KiaiMode) return; + FlashBox + // Make sure the hit indicator usage of FlashBox doesn't get faded out prematurely by a kiai flash + .DelayUntilTransformsFinished() + .FadeTo(flash_opacity, 0, Easing.OutQuint) + .Then() + .FadeOut(Math.Max(80, timingPoint.BeatLength - 80), Easing.OutSine); + if (beatIndex % timingPoint.TimeSignature.Numerator != 0) return; From 9b123e7365a777b11e3de8990b21ad5cfb80820b Mon Sep 17 00:00:00 2001 From: Joppe27 Date: Wed, 19 Oct 2022 00:51:44 +0200 Subject: [PATCH 0124/2991] Adjust flash intensity and fade values to feel better --- osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs | 2 +- osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs index d0eaf9a602..70eacbe61d 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs @@ -163,7 +163,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default FlashBox // Make sure the hit indicator usage of FlashBox doesn't get faded out prematurely by a kiai flash .DelayUntilTransformsFinished() - .FadeTo(flash_opacity, 0, Easing.OutQuint) + .FadeTo(flash_opacity) .Then() .FadeOut(Math.Max(80, timingPoint.BeatLength - 80), Easing.OutSine); diff --git a/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs b/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs index c64f322df9..2bcdd5b5a1 100644 --- a/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs +++ b/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs @@ -13,7 +13,7 @@ namespace osu.Game.Skinning { private readonly Drawable flashingDrawable; - private const float flash_opacity = 0.3f; + private const float flash_opacity = 0.55f; public LegacyKiaiFlashingDrawable(Func creationFunc) { @@ -44,7 +44,7 @@ namespace osu.Game.Skinning flashingDrawable .FadeTo(flash_opacity) .Then() - .FadeOut(timingPoint.BeatLength * 0.75f); + .FadeOut(Math.Max(80, timingPoint.BeatLength - 80), Easing.OutSine); } } } From 343c560b1b92e7e8fb603915816f0f8aad2116de Mon Sep 17 00:00:00 2001 From: Alden Wu Date: Tue, 18 Oct 2022 03:33:03 -0700 Subject: [PATCH 0125/2991] Remove smoke point maximum/cap --- .../Skinning/SmokeSegment.cs | 144 +++++++++--------- 1 file changed, 75 insertions(+), 69 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs index aba4d0ff63..6aee9ca2df 100644 --- a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -22,8 +23,6 @@ namespace osu.Game.Rulesets.Osu.Skinning { public abstract class SmokeSegment : Drawable, ITexturedShaderDrawable { - private const int max_point_count = 18_000; - // fade anim values private const double initial_fade_out_duration = 4000; @@ -85,12 +84,6 @@ namespace osu.Game.Rulesets.Osu.Skinning totalDistance = pointInterval; } - private Vector2 nextPointDirection() - { - float angle = RNG.NextSingle(0, 2 * MathF.PI); - return new Vector2(MathF.Sin(angle), -MathF.Cos(angle)); - } - public void AddPosition(Vector2 position, double time) { lastPosition ??= position; @@ -107,33 +100,27 @@ namespace osu.Game.Rulesets.Osu.Skinning Vector2 pointPos = (pointInterval - (totalDistance - delta)) * increment + (Vector2)lastPosition; increment *= pointInterval; - if (SmokePoints.Count > 0 && SmokePoints[^1].Time > time) - { - int index = ~SmokePoints.BinarySearch(new SmokePoint { Time = time }, new SmokePoint.UpperBoundComparer()); - SmokePoints.RemoveRange(index, SmokePoints.Count - index); - } - totalDistance %= pointInterval; - for (int i = 0; i < count; i++) + if (SmokePoints.Count == 0 || SmokePoints[^1].Time <= time) { - SmokePoints.Add(new SmokePoint + for (int i = 0; i < count; i++) { - Position = pointPos, - Time = time, - Direction = nextPointDirection(), - }); + SmokePoints.Add(new SmokePoint + { + Position = pointPos, + Time = time, + Angle = RNG.NextSingle(0, 2 * MathF.PI), + }); - pointPos += increment; + pointPos += increment; + } } Invalidate(Invalidation.DrawNode); } lastPosition = position; - - if (SmokePoints.Count >= max_point_count) - FinishDrawing(time); } public void FinishDrawing(double time) @@ -157,7 +144,7 @@ namespace osu.Game.Rulesets.Osu.Skinning { public Vector2 Position; public double Time; - public Vector2 Direction; + public float Angle; public struct UpperBoundComparer : IComparer { @@ -171,6 +158,17 @@ namespace osu.Game.Rulesets.Osu.Skinning return x.Time > target.Time ? 1 : -1; } } + + public struct LowerBoundComparer : IComparer + { + public int Compare(SmokePoint x, SmokePoint target) + { + // Similar logic as UpperBoundComparer, except returned index will always be + // the first element larger or equal + + return x.Time < target.Time ? -1 : 1; + } + } } protected class SmokeDrawNode : TexturedShaderDrawNode @@ -187,11 +185,11 @@ namespace osu.Game.Rulesets.Osu.Skinning private Vector2 drawSize; private Texture? texture; private int rotationSeed; - private int rotationIndex; + private int firstVisibleIndex; // anim calculation vars (color, scale, direction) private double initialFadeOutDurationTrunc; - private double firstVisiblePointTime; + private double firstVisiblePointTimeAfterSmokeEnded; private double initialFadeOutTime; private double reFadeInTime; @@ -206,9 +204,6 @@ namespace osu.Game.Rulesets.Osu.Skinning { base.ApplyState(); - points.Clear(); - points.AddRange(Source.SmokePoints); - radius = Source.radius; drawSize = Source.DrawSize; texture = Source.Texture; @@ -220,11 +215,18 @@ namespace osu.Game.Rulesets.Osu.Skinning rotationSeed = Source.rotationSeed; initialFadeOutDurationTrunc = Math.Min(initial_fade_out_duration, SmokeEndTime - SmokeStartTime); - firstVisiblePointTime = SmokeEndTime - initialFadeOutDurationTrunc; + firstVisiblePointTimeAfterSmokeEnded = SmokeEndTime - initialFadeOutDurationTrunc; - initialFadeOutTime = CurrentTime; - reFadeInTime = CurrentTime - initialFadeOutDurationTrunc - firstVisiblePointTime * (1 - 1 / re_fade_in_speed); - finalFadeOutTime = CurrentTime - initialFadeOutDurationTrunc - firstVisiblePointTime * (1 - 1 / final_fade_out_speed); + initialFadeOutTime = Math.Min(CurrentTime, SmokeEndTime); + reFadeInTime = CurrentTime - initialFadeOutDurationTrunc - firstVisiblePointTimeAfterSmokeEnded * (1 - 1 / re_fade_in_speed); + finalFadeOutTime = CurrentTime - initialFadeOutDurationTrunc - firstVisiblePointTimeAfterSmokeEnded * (1 - 1 / final_fade_out_speed); + + double firstVisibleTime = Math.Min(SmokeEndTime, CurrentTime) - initialFadeOutDurationTrunc; + firstVisibleIndex = ~Source.SmokePoints.BinarySearch(new SmokePoint { Time = firstVisibleTime }, new SmokePoint.LowerBoundComparer()); + int futureIndex = ~Source.SmokePoints.BinarySearch(new SmokePoint { Time = CurrentTime }, new SmokePoint.UpperBoundComparer()); + + points.Clear(); + points.AddRange(Source.SmokePoints.Skip(firstVisibleIndex).Take(futureIndex - firstVisibleIndex)); } public sealed override void Draw(IRenderer renderer) @@ -234,9 +236,12 @@ namespace osu.Game.Rulesets.Osu.Skinning if (points.Count == 0) return; - rotationIndex = 0; - - quadBatch ??= renderer.CreateQuadBatch(max_point_count / 10, 10); + quadBatch ??= renderer.CreateQuadBatch(200, 4); + if (points.Count > quadBatch.Size * 4 && quadBatch.Size != 10922) + { + int batchSize = Math.Min((int)(quadBatch.Size * 1.5f), 10922); + quadBatch = renderer.CreateQuadBatch(batchSize, 4); + } texture ??= renderer.WhitePixel; RectangleF textureRect = texture.GetTextureRect(); @@ -248,8 +253,8 @@ namespace osu.Game.Rulesets.Osu.Skinning shader.Bind(); texture.Bind(); - foreach (var point in points) - drawPointQuad(point, textureRect); + for (int i = 0; i < points.Count; i++) + drawPointQuad(points[i], textureRect, i + firstVisibleIndex); shader.Unbind(); renderer.PopLocalMatrix(); @@ -263,30 +268,31 @@ namespace osu.Game.Rulesets.Osu.Skinning { var color = Color4.White; - double timeDoingInitialFadeOut = Math.Min(initialFadeOutTime, SmokeEndTime) - point.Time; - - if (timeDoingInitialFadeOut > 0) + double timeDoingFinalFadeOut = finalFadeOutTime - point.Time / final_fade_out_speed; + if (timeDoingFinalFadeOut > 0 && point.Time > firstVisiblePointTimeAfterSmokeEnded) { - float fraction = Math.Clamp((float)(timeDoingInitialFadeOut / initial_fade_out_duration), 0, 1); - color.A = (1 - fraction) * initial_alpha; + float fraction = Math.Clamp((float)(timeDoingFinalFadeOut / final_fade_out_duration), 0, 1); + fraction = MathF.Pow(fraction, 5); + color.A = (1 - fraction) * re_fade_in_alpha; } - - if (color.A > 0) + else { - double timeDoingReFadeIn = reFadeInTime - point.Time / re_fade_in_speed; - double timeDoingFinalFadeOut = finalFadeOutTime - point.Time / final_fade_out_speed; - - if (timeDoingFinalFadeOut > 0) + double timeDoingInitialFadeOut = initialFadeOutTime - point.Time; + if (timeDoingInitialFadeOut > 0) { - float fraction = Math.Clamp((float)(timeDoingFinalFadeOut / final_fade_out_duration), 0, 1); - fraction = MathF.Pow(fraction, 5); - color.A = (1 - fraction) * re_fade_in_alpha; + float fraction = Math.Clamp((float)(timeDoingInitialFadeOut / initial_fade_out_duration), 0, 1); + color.A = (1 - fraction) * initial_alpha; } - else if (timeDoingReFadeIn > 0) + + if (point.Time > firstVisiblePointTimeAfterSmokeEnded) { - float fraction = Math.Clamp((float)(timeDoingReFadeIn / re_fade_in_duration), 0, 1); - fraction = 1 - MathF.Pow(1 - fraction, 5); - color.A = fraction * (re_fade_in_alpha - color.A) + color.A; + double timeDoingReFadeIn = reFadeInTime - point.Time / re_fade_in_speed; + if (timeDoingReFadeIn > 0) + { + float fraction = Math.Clamp((float)(timeDoingReFadeIn / re_fade_in_duration), 0, 1); + fraction = 1 - MathF.Pow(1 - fraction, 5); + color.A = fraction * (re_fade_in_alpha - color.A) + color.A; + } } } @@ -301,33 +307,33 @@ namespace osu.Game.Rulesets.Osu.Skinning return fraction * (final_scale - initial_scale) + initial_scale; } - protected virtual Vector2 PointDirection(SmokePoint point) + protected virtual Vector2 PointDirection(SmokePoint point, int index) { - float initialAngle = MathF.Atan2(point.Direction.Y, point.Direction.X); - float finalAngle = initialAngle + nextRotation(); - double timeDoingRotation = CurrentTime - point.Time; float fraction = Math.Clamp((float)(timeDoingRotation / rotation_duration), 0, 1); fraction = 1 - MathF.Pow(1 - fraction, 5); - float angle = fraction * (finalAngle - initialAngle) + initialAngle; + float angle = fraction * getRotation(index) + point.Angle; return new Vector2(MathF.Sin(angle), -MathF.Cos(angle)); } - private float nextRotation() => max_rotation * (StatelessRNG.NextSingle(rotationSeed, rotationIndex++) * 2 - 1); + private float getRotation(int index) => max_rotation * (StatelessRNG.NextSingle(rotationSeed, index) * 2 - 1); - private void drawPointQuad(SmokePoint point, RectangleF textureRect) + private void drawPointQuad(SmokePoint point, RectangleF textureRect, int index) { Debug.Assert(quadBatch != null); var colour = PointColour(point); - float scale = PointScale(point); - var dir = PointDirection(point); - var ortho = dir.PerpendicularLeft; - - if (colour.A == 0 || scale == 0) + if (colour.A == 0) return; + float scale = PointScale(point); + if (scale == 0) + return; + + var dir = PointDirection(point, index); + var ortho = dir.PerpendicularLeft; + var localTopLeft = point.Position + (radius * scale * (-ortho - dir)); var localTopRight = point.Position + (radius * scale * (-ortho + dir)); var localBotLeft = point.Position + (radius * scale * (ortho - dir)); From a9b8ba94fa923eb54ca4304504f1e2e6cf416f04 Mon Sep 17 00:00:00 2001 From: Alden Wu Date: Tue, 18 Oct 2022 22:59:58 -0700 Subject: [PATCH 0126/2991] Add necessary newlines --- osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs index 6aee9ca2df..5e72f165df 100644 --- a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs @@ -237,11 +237,13 @@ namespace osu.Game.Rulesets.Osu.Skinning return; quadBatch ??= renderer.CreateQuadBatch(200, 4); + if (points.Count > quadBatch.Size * 4 && quadBatch.Size != 10922) { int batchSize = Math.Min((int)(quadBatch.Size * 1.5f), 10922); quadBatch = renderer.CreateQuadBatch(batchSize, 4); } + texture ??= renderer.WhitePixel; RectangleF textureRect = texture.GetTextureRect(); @@ -269,6 +271,7 @@ namespace osu.Game.Rulesets.Osu.Skinning var color = Color4.White; double timeDoingFinalFadeOut = finalFadeOutTime - point.Time / final_fade_out_speed; + if (timeDoingFinalFadeOut > 0 && point.Time > firstVisiblePointTimeAfterSmokeEnded) { float fraction = Math.Clamp((float)(timeDoingFinalFadeOut / final_fade_out_duration), 0, 1); @@ -278,6 +281,7 @@ namespace osu.Game.Rulesets.Osu.Skinning else { double timeDoingInitialFadeOut = initialFadeOutTime - point.Time; + if (timeDoingInitialFadeOut > 0) { float fraction = Math.Clamp((float)(timeDoingInitialFadeOut / initial_fade_out_duration), 0, 1); @@ -287,6 +291,7 @@ namespace osu.Game.Rulesets.Osu.Skinning if (point.Time > firstVisiblePointTimeAfterSmokeEnded) { double timeDoingReFadeIn = reFadeInTime - point.Time / re_fade_in_speed; + if (timeDoingReFadeIn > 0) { float fraction = Math.Clamp((float)(timeDoingReFadeIn / re_fade_in_duration), 0, 1); From 50ab9bff8b8609b1b3438c314d2b957c23578e9d Mon Sep 17 00:00:00 2001 From: Alden Wu Date: Tue, 18 Oct 2022 23:05:09 -0700 Subject: [PATCH 0127/2991] Rename for consistency --- osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs index 5e72f165df..23bfea5240 100644 --- a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs @@ -185,7 +185,7 @@ namespace osu.Game.Rulesets.Osu.Skinning private Vector2 drawSize; private Texture? texture; private int rotationSeed; - private int firstVisibleIndex; + private int firstVisiblePointIndex; // anim calculation vars (color, scale, direction) private double initialFadeOutDurationTrunc; @@ -221,12 +221,12 @@ namespace osu.Game.Rulesets.Osu.Skinning reFadeInTime = CurrentTime - initialFadeOutDurationTrunc - firstVisiblePointTimeAfterSmokeEnded * (1 - 1 / re_fade_in_speed); finalFadeOutTime = CurrentTime - initialFadeOutDurationTrunc - firstVisiblePointTimeAfterSmokeEnded * (1 - 1 / final_fade_out_speed); - double firstVisibleTime = Math.Min(SmokeEndTime, CurrentTime) - initialFadeOutDurationTrunc; - firstVisibleIndex = ~Source.SmokePoints.BinarySearch(new SmokePoint { Time = firstVisibleTime }, new SmokePoint.LowerBoundComparer()); - int futureIndex = ~Source.SmokePoints.BinarySearch(new SmokePoint { Time = CurrentTime }, new SmokePoint.UpperBoundComparer()); + double firstVisiblePointTime = Math.Min(SmokeEndTime, CurrentTime) - initialFadeOutDurationTrunc; + firstVisiblePointIndex = ~Source.SmokePoints.BinarySearch(new SmokePoint { Time = firstVisiblePointTime }, new SmokePoint.LowerBoundComparer()); + int futurePointIndex = ~Source.SmokePoints.BinarySearch(new SmokePoint { Time = CurrentTime }, new SmokePoint.UpperBoundComparer()); points.Clear(); - points.AddRange(Source.SmokePoints.Skip(firstVisibleIndex).Take(futureIndex - firstVisibleIndex)); + points.AddRange(Source.SmokePoints.Skip(firstVisiblePointIndex).Take(futurePointIndex - firstVisiblePointIndex)); } public sealed override void Draw(IRenderer renderer) @@ -256,7 +256,7 @@ namespace osu.Game.Rulesets.Osu.Skinning texture.Bind(); for (int i = 0; i < points.Count; i++) - drawPointQuad(points[i], textureRect, i + firstVisibleIndex); + drawPointQuad(points[i], textureRect, i + firstVisiblePointIndex); shader.Unbind(); renderer.PopLocalMatrix(); @@ -272,7 +272,7 @@ namespace osu.Game.Rulesets.Osu.Skinning double timeDoingFinalFadeOut = finalFadeOutTime - point.Time / final_fade_out_speed; - if (timeDoingFinalFadeOut > 0 && point.Time > firstVisiblePointTimeAfterSmokeEnded) + if (timeDoingFinalFadeOut > 0 && point.Time >= firstVisiblePointTimeAfterSmokeEnded) { float fraction = Math.Clamp((float)(timeDoingFinalFadeOut / final_fade_out_duration), 0, 1); fraction = MathF.Pow(fraction, 5); From 9356a40a394f7afcfa95a1325c3b537c7d8a0f0e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Oct 2022 15:13:20 +0900 Subject: [PATCH 0128/2991] Remove redundant flash layer colour logic In a previous iteration, the flash layer was white on the initial hit, but this seems to have been removed for the final implementation. --- osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs index ffdcba3cdb..ca0d99f2f6 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs @@ -173,11 +173,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon .FadeOut(flash_in_duration); } - // The flash layer starts white to give the wanted brightness, but is almost immediately - // recoloured to the accent colour. This would more correctly be done with two layers (one for the initial flash) - // but works well enough with the colour fade. flash.FadeTo(1, flash_in_duration, Easing.OutQuint); - flash.FlashColour(accentColour.Value, fade_out_time, Easing.OutQuint); this.FadeOut(fade_out_time, Easing.OutQuad); break; From aca0d04834b667bb2893ccb9fbf2f2827fc93254 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Oct 2022 15:52:25 +0900 Subject: [PATCH 0129/2991] Forcefully remove transforms before reapplying to avoid old accent colour getting rewound --- .../Skinning/Argon/ArgonMainCirclePiece.cs | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs index ca0d99f2f6..f5df06f023 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs @@ -108,18 +108,23 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon { base.LoadComplete(); - accentColour.BindValueChanged(colour => - { - outerFill.Colour = innerFill.Colour = colour.NewValue.Darken(4); - outerGradient.Colour = ColourInfo.GradientVertical(colour.NewValue, colour.NewValue.Darken(0.1f)); - innerGradient.Colour = ColourInfo.GradientVertical(colour.NewValue.Darken(0.5f), colour.NewValue.Darken(0.6f)); - flash.Colour = colour.NewValue; - }, true); - indexInCurrentCombo.BindValueChanged(index => number.Text = (index.NewValue + 1).ToString(), true); + accentColour.BindValueChanged(colour => + { + // A colour transform is applied. + // Without removing transforms first, when it is rewound it may apply an old colour. + outerGradient.ClearTransforms(); + outerGradient.Colour = ColourInfo.GradientVertical(colour.NewValue, colour.NewValue.Darken(0.1f)); + + outerFill.Colour = innerFill.Colour = colour.NewValue.Darken(4); + innerGradient.Colour = ColourInfo.GradientVertical(colour.NewValue.Darken(0.5f), colour.NewValue.Darken(0.6f)); + flash.Colour = colour.NewValue; + + updateStateTransforms(drawableObject, drawableObject.State.Value); + }, true); + drawableObject.ApplyCustomUpdateState += updateStateTransforms; - updateStateTransforms(drawableObject, drawableObject.State.Value); } private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state) From 59e2478b0ec8e3a4a0ebaf615489224c88b38fd3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Oct 2022 16:01:07 +0900 Subject: [PATCH 0130/2991] Fix some older beatmaps having missing backgrounds Closes https://github.com/ppy/osu/issues/20824. Note that this will require a reimport of beatmaps as it is baked into the database. Probably not worth making a migration for at this point in time. --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 75500fbc4e..5f5749dc73 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -355,6 +355,14 @@ namespace osu.Game.Beatmaps.Formats switch (type) { + case LegacyEventType.Sprite: + // Generally, the background is the first thing defined in a beatmap file. + // In some older beatmaps, it is not present and replaced by a storyboard-level background instead. + // Allow the first sprite (by file order) to act as the background in such cases. + if (string.IsNullOrEmpty(beatmap.BeatmapInfo.Metadata.BackgroundFile)) + beatmap.BeatmapInfo.Metadata.BackgroundFile = CleanFilename(split[3]); + break; + case LegacyEventType.Background: beatmap.BeatmapInfo.Metadata.BackgroundFile = CleanFilename(split[2]); break; From 830b92d3aebb8a89298504d649baedd27f5e28e7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Oct 2022 20:06:39 +0900 Subject: [PATCH 0131/2991] Add momentary shortcuts to toggle grid/distance snap Matching osu!stable. I use these quite a lot while mapping and I'm sure others do as well. Hold `Shift` = invert grid snap Hold `Alt` = invert distance snap --- .../Edit/CatchHitObjectComposer.cs | 31 ++++++++++++++++ .../Edit/OsuHitObjectComposer.cs | 37 +++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index 54d50b01c4..d40200f2dd 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -26,6 +26,7 @@ using osu.Game.Rulesets.UI; using osu.Game.Screens.Edit.Components.TernaryButtons; using osu.Game.Screens.Edit.Compose.Components; using osuTK; +using osuTK.Input; namespace osu.Game.Rulesets.Catch.Edit { @@ -88,6 +89,36 @@ namespace osu.Game.Rulesets.Catch.Edit updateDistanceSnapGrid(); } + protected override bool OnKeyDown(KeyDownEvent e) + { + if (e.Repeat) + return false; + + if (handleToggleViaKey(e.Key)) + return true; + + return base.OnKeyDown(e); + } + + protected override void OnKeyUp(KeyUpEvent e) + { + handleToggleViaKey(e.Key); + base.OnKeyUp(e); + } + + private bool handleToggleViaKey(Key key) + { + switch (key) + { + case Key.AltLeft: + case Key.AltRight: + distanceSnapToggle.Value = distanceSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; + return true; + } + + return false; + } + public override bool OnPressed(KeyBindingPressEvent e) { switch (e.Action) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 6b4a6e39d9..b9177e9cdd 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -13,6 +13,7 @@ using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Events; using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Edit; @@ -24,6 +25,7 @@ using osu.Game.Rulesets.UI; using osu.Game.Screens.Edit.Components.TernaryButtons; using osu.Game.Screens.Edit.Compose.Components; using osuTK; +using osuTK.Input; namespace osu.Game.Rulesets.Osu.Edit { @@ -229,6 +231,41 @@ namespace osu.Game.Rulesets.Osu.Edit } } + protected override bool OnKeyDown(KeyDownEvent e) + { + if (e.Repeat) + return false; + + if (handleToggleViaKey(e.Key)) + return true; + + return base.OnKeyDown(e); + } + + protected override void OnKeyUp(KeyUpEvent e) + { + handleToggleViaKey(e.Key); + base.OnKeyUp(e); + } + + private bool handleToggleViaKey(Key key) + { + switch (key) + { + case Key.ShiftLeft: + case Key.ShiftRight: + rectangularGridSnapToggle.Value = rectangularGridSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; + return true; + + case Key.AltLeft: + case Key.AltRight: + distanceSnapToggle.Value = distanceSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; + return true; + } + + return false; + } + private DistanceSnapGrid createDistanceSnapGrid(IEnumerable selectedHitObjects) { if (BlueprintContainer.CurrentTool is SpinnerCompositionTool) From bea136ce50fb586619794a3b33f0ccf8337e8942 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Oct 2022 23:56:42 +0900 Subject: [PATCH 0132/2991] Adjust test assert ordering to read better --- osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs index 58b5b41702..1c87eb49c9 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs @@ -161,10 +161,11 @@ namespace osu.Game.Tests.Visual.Editing AddStep("hold alt", () => InputManager.PressKey(Key.LAlt)); AddStep("scroll mouse 5 steps", () => InputManager.ScrollVerticalBy(5)); - AddAssert("distance spacing increased by 0.5", () => editorBeatmap.BeatmapInfo.DistanceSpacing == originalSpacing + 0.5); AddStep("release alt", () => InputManager.ReleaseKey(Key.LAlt)); AddStep("release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + + AddAssert("distance spacing increased by 0.5", () => editorBeatmap.BeatmapInfo.DistanceSpacing == originalSpacing + 0.5); } public class EditorBeatmapContainer : Container From 966dd786ae4460b39ada7d9bf95512114539f261 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Oct 2022 23:59:34 +0900 Subject: [PATCH 0133/2991] Don't consume keys when handling momentary snap toggles --- osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index b9177e9cdd..e46131dd6e 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -236,8 +236,7 @@ namespace osu.Game.Rulesets.Osu.Edit if (e.Repeat) return false; - if (handleToggleViaKey(e.Key)) - return true; + handleToggleViaKey(e.Key); return base.OnKeyDown(e); } @@ -248,22 +247,20 @@ namespace osu.Game.Rulesets.Osu.Edit base.OnKeyUp(e); } - private bool handleToggleViaKey(Key key) + private void handleToggleViaKey(Key key) { switch (key) { case Key.ShiftLeft: case Key.ShiftRight: rectangularGridSnapToggle.Value = rectangularGridSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; - return true; + break; case Key.AltLeft: case Key.AltRight: distanceSnapToggle.Value = distanceSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; - return true; + break; } - - return false; } private DistanceSnapGrid createDistanceSnapGrid(IEnumerable selectedHitObjects) From d83c398b58bdb2d11859dadb96f1c66f6820a890 Mon Sep 17 00:00:00 2001 From: Joppe27 Date: Wed, 19 Oct 2022 23:31:23 +0200 Subject: [PATCH 0134/2991] Apply review: changed DelayUntilTransformsFinished to ArmedState check --- .../Skinning/Default/CirclePiece.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs index 70eacbe61d..36daefbd36 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs @@ -4,6 +4,7 @@ #nullable disable using System; +using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -14,6 +15,7 @@ using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; +using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Objects; using osuTK.Graphics; @@ -155,17 +157,21 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default }; } + [Resolved] + private DrawableHitObject drawableHitObject { get; set; } + protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) { if (!effectPoint.KiaiMode) return; - FlashBox - // Make sure the hit indicator usage of FlashBox doesn't get faded out prematurely by a kiai flash - .DelayUntilTransformsFinished() - .FadeTo(flash_opacity) - .Then() - .FadeOut(Math.Max(80, timingPoint.BeatLength - 80), Easing.OutSine); + if (drawableHitObject.State.Value == ArmedState.Idle) + { + FlashBox + .FadeTo(flash_opacity) + .Then() + .FadeOut(Math.Max(80, timingPoint.BeatLength - 80), Easing.OutSine); + } if (beatIndex % timingPoint.TimeSignature.Numerator != 0) return; From 1852714d2d32a329313b6525eec35381f4dbe6ec Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 20 Oct 2022 01:16:27 +0300 Subject: [PATCH 0135/2991] Fix existing alpha transform cleared on accent colour change Clearing it causes its start value to be lost. --- osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs index f5df06f023..4b5adaa033 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs @@ -114,9 +114,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon { // A colour transform is applied. // Without removing transforms first, when it is rewound it may apply an old colour. - outerGradient.ClearTransforms(); + outerGradient.ClearTransforms(targetMember: nameof(Colour)); outerGradient.Colour = ColourInfo.GradientVertical(colour.NewValue, colour.NewValue.Darken(0.1f)); - outerFill.Colour = innerFill.Colour = colour.NewValue.Darken(4); innerGradient.Colour = ColourInfo.GradientVertical(colour.NewValue.Darken(0.5f), colour.NewValue.Darken(0.6f)); flash.Colour = colour.NewValue; From ba37daa456b5239af39abbf428e638058669c706 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 20 Oct 2022 01:18:07 +0300 Subject: [PATCH 0136/2991] Bring back removed newline --- osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs index 4b5adaa033..36dc8c801d 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs @@ -116,6 +116,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon // Without removing transforms first, when it is rewound it may apply an old colour. outerGradient.ClearTransforms(targetMember: nameof(Colour)); outerGradient.Colour = ColourInfo.GradientVertical(colour.NewValue, colour.NewValue.Darken(0.1f)); + outerFill.Colour = innerFill.Colour = colour.NewValue.Darken(4); innerGradient.Colour = ColourInfo.GradientVertical(colour.NewValue.Darken(0.5f), colour.NewValue.Darken(0.6f)); flash.Colour = colour.NewValue; From 57320074a0f6140bdd17423e416af3db200361c8 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 20 Oct 2022 01:24:36 +0300 Subject: [PATCH 0137/2991] Fix accidental breakage of changelog layout --- .../Overlays/Changelog/ChangelogContent.cs | 13 +++++- .../Changelog/ChangelogSingleBuild.cs | 46 ++++++++----------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogContent.cs b/osu.Game/Overlays/Changelog/ChangelogContent.cs index 1e49efb10e..dca2f3b1b0 100644 --- a/osu.Game/Overlays/Changelog/ChangelogContent.cs +++ b/osu.Game/Overlays/Changelog/ChangelogContent.cs @@ -7,20 +7,29 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Online.API.Requests.Responses; using System; +using osu.Framework.Graphics.Cursor; namespace osu.Game.Overlays.Changelog { - public class ChangelogContent : FillFlowContainer + public class ChangelogContent : PopoverContainer { public Action BuildSelected; public void SelectBuild(APIChangelogBuild build) => BuildSelected?.Invoke(build); + protected override Container Content { get; } + public ChangelogContent() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - Direction = FillDirection.Vertical; + Content = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical + }; + base.Content.Add(Content); } } } diff --git a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs index afdfd0ff68..e4f240f0e7 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs @@ -10,7 +10,6 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; @@ -64,33 +63,28 @@ namespace osu.Game.Overlays.Changelog { CommentsContainer comments; - Child = new PopoverContainer + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] + new ChangelogBuildWithNavigation(build) { SelectBuild = SelectBuild }, + new Box { - new ChangelogBuildWithNavigation(build) { SelectBuild = SelectBuild }, - new Box - { - RelativeSizeAxes = Axes.X, - Height = 2, - Colour = colourProvider.Background6, - Margin = new MarginPadding { Top = 30 }, - }, - new ChangelogSupporterPromo - { - Alpha = api.LocalUser.Value.IsSupporter ? 0 : 1, - }, - new Box - { - RelativeSizeAxes = Axes.X, - Height = 2, - Colour = colourProvider.Background6, - Alpha = api.LocalUser.Value.IsSupporter ? 0 : 1, - }, - comments = new CommentsContainer() - } + RelativeSizeAxes = Axes.X, + Height = 2, + Colour = colourProvider.Background6, + Margin = new MarginPadding { Top = 30 }, + }, + new ChangelogSupporterPromo + { + Alpha = api.LocalUser.Value.IsSupporter ? 0 : 1, + }, + new Box + { + RelativeSizeAxes = Axes.X, + Height = 2, + Colour = colourProvider.Background6, + Alpha = api.LocalUser.Value.IsSupporter ? 0 : 1, + }, + comments = new CommentsContainer() }; comments.ShowComments(CommentableType.Build, build.Id); From 78943a21d81fc6658a5be485f354b7f925b4636e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Oct 2022 08:06:05 +0900 Subject: [PATCH 0138/2991] Update osu.Game/Beatmaps/ControlPoints/IControlPoint.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Beatmaps/ControlPoints/IControlPoint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/ControlPoints/IControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/IControlPoint.cs index 6a287285d8..091e99e029 100644 --- a/osu.Game/Beatmaps/ControlPoints/IControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/IControlPoint.cs @@ -8,6 +8,6 @@ namespace osu.Game.Beatmaps.ControlPoints /// /// The time at which the control point takes effect. /// - public double Time { get; } + double Time { get; } } } From a7d4a74ed660366bce2dd1ddef5065363761f595 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Oct 2022 08:07:56 +0900 Subject: [PATCH 0139/2991] Update osu.Game/Tests/Visual/ScrollingTestContainer.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Tests/Visual/ScrollingTestContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/ScrollingTestContainer.cs b/osu.Game/Tests/Visual/ScrollingTestContainer.cs index 87f4bb3f3b..1817a704b9 100644 --- a/osu.Game/Tests/Visual/ScrollingTestContainer.cs +++ b/osu.Game/Tests/Visual/ScrollingTestContainer.cs @@ -100,7 +100,7 @@ namespace osu.Game.Tests.Visual => implementation.GetLength(startTime, endTime, timeRange, scrollLength); public float PositionAt(double time, double currentTime, double timeRange, float scrollLength, double? originTime = null) - => implementation.PositionAt(time, currentTime, timeRange, scrollLength); + => implementation.PositionAt(time, currentTime, timeRange, scrollLength, originTime); public double TimeAt(float position, double currentTime, double timeRange, float scrollLength) => implementation.TimeAt(position, currentTime, timeRange, scrollLength); From eb386d4bd54cc07957d33a3bd96052d4d68b104a Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 20 Oct 2022 03:29:18 +0300 Subject: [PATCH 0140/2991] Enable slider ball tint in default legacy skin --- osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs | 1 - osu.Game/Skinning/DefaultLegacySkin.cs | 2 ++ osu.Game/Skinning/SkinConfiguration.cs | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs index 306a1e38b9..1c0a62454b 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs @@ -9,7 +9,6 @@ namespace osu.Game.Rulesets.Osu.Skinning { SliderBorderSize, SliderPathRadius, - AllowSliderBallTint, CursorCentre, CursorExpand, CursorRotate, diff --git a/osu.Game/Skinning/DefaultLegacySkin.cs b/osu.Game/Skinning/DefaultLegacySkin.cs index 04f1286dc7..b80275a1e8 100644 --- a/osu.Game/Skinning/DefaultLegacySkin.cs +++ b/osu.Game/Skinning/DefaultLegacySkin.cs @@ -46,6 +46,8 @@ namespace osu.Game.Skinning new Color4(242, 24, 57, 255) }; + Configuration.ConfigDictionary[nameof(SkinConfiguration.LegacySetting.AllowSliderBallTint)] = @"true"; + Configuration.LegacyVersion = 2.7m; } } diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 0b1159f8fd..4e5d96ccb8 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -38,7 +38,8 @@ namespace osu.Game.Skinning HitCirclePrefix, HitCircleOverlap, AnimationFramerate, - LayeredHitSounds + LayeredHitSounds, + AllowSliderBallTint, } public static List DefaultComboColours { get; } = new List From 4bf4938b726c584177b28361e6f198afc8878a3e Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 20 Oct 2022 03:44:58 +0300 Subject: [PATCH 0141/2991] Keep cursor hiding feature to gameplay screens for now --- osu.Game/Graphics/Cursor/MenuCursorContainer.cs | 17 ++++++++++++++++- osu.Game/OsuGame.cs | 2 ++ osu.Game/Screens/IOsuScreen.cs | 5 +++++ osu.Game/Screens/OsuScreen.cs | 5 ++--- osu.Game/Screens/Play/Player.cs | 2 ++ 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursorContainer.cs b/osu.Game/Graphics/Cursor/MenuCursorContainer.cs index 33b0c308cc..a210cd3063 100644 --- a/osu.Game/Graphics/Cursor/MenuCursorContainer.cs +++ b/osu.Game/Graphics/Cursor/MenuCursorContainer.cs @@ -23,6 +23,21 @@ namespace osu.Game.Graphics.Cursor private readonly IBindable screenshotCursorVisibility = new Bindable(true); public override bool IsPresent => screenshotCursorVisibility.Value && base.IsPresent; + private bool hideCursorOnNonMouseInput; + + public bool HideCursorOnNonMouseInput + { + get => hideCursorOnNonMouseInput; + set + { + if (hideCursorOnNonMouseInput == value) + return; + + hideCursorOnNonMouseInput = value; + updateState(); + } + } + protected override Drawable CreateCursor() => activeCursor = new Cursor(); private Cursor activeCursor = null!; @@ -75,7 +90,7 @@ namespace osu.Game.Graphics.Cursor private void updateState() { - bool combinedVisibility = State.Value == Visibility.Visible && lastInputWasMouse.Value && !isIdle.Value; + bool combinedVisibility = State.Value == Visibility.Visible && (lastInputWasMouse.Value || !hideCursorOnNonMouseInput) && !isIdle.Value; if (visible == combinedVisibility) return; diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index b3eaf5cd01..2bdcb57f2a 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1333,6 +1333,8 @@ namespace osu.Game OverlayActivationMode.BindTo(newOsuScreen.OverlayActivationMode); API.Activity.BindTo(newOsuScreen.Activity); + GlobalCursorDisplay.MenuCursor.HideCursorOnNonMouseInput = newOsuScreen.HideMenuCursorOnNonMouseInput; + if (newOsuScreen.HideOverlaysOnEnter) CloseAllOverlays(); else diff --git a/osu.Game/Screens/IOsuScreen.cs b/osu.Game/Screens/IOsuScreen.cs index 7d8657a3df..a5739a41b1 100644 --- a/osu.Game/Screens/IOsuScreen.cs +++ b/osu.Game/Screens/IOsuScreen.cs @@ -41,6 +41,11 @@ namespace osu.Game.Screens /// bool HideOverlaysOnEnter { get; } + /// + /// Whether the menu cursor should be hidden when non-mouse input is received. + /// + bool HideMenuCursorOnNonMouseInput { get; } + /// /// Whether overlays should be able to be opened when this screen is current. /// diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 0678a90f71..6be13bbda3 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -40,11 +40,10 @@ namespace osu.Game.Screens public virtual bool AllowExternalScreenChange => false; - /// - /// Whether all overlays should be hidden when this screen is entered or resumed. - /// public virtual bool HideOverlaysOnEnter => false; + public virtual bool HideMenuCursorOnNonMouseInput => false; + /// /// The initial overlay activation mode to use when this screen is entered for the first time. /// diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 68b623b781..7048f83c09 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -66,6 +66,8 @@ namespace osu.Game.Screens.Play public override bool HideOverlaysOnEnter => true; + public override bool HideMenuCursorOnNonMouseInput => true; + protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.UserTriggered; // We are managing our own adjustments (see OnEntering/OnExiting). From 39650717eaa89e838e60b4776bbfa4c08aae3163 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 20 Oct 2022 03:45:17 +0300 Subject: [PATCH 0142/2991] Improve input detection to not make cursor flicker on combined input --- osu.Game/Graphics/Cursor/MenuCursorContainer.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursorContainer.cs b/osu.Game/Graphics/Cursor/MenuCursorContainer.cs index a210cd3063..af542989ff 100644 --- a/osu.Game/Graphics/Cursor/MenuCursorContainer.cs +++ b/osu.Game/Graphics/Cursor/MenuCursorContainer.cs @@ -277,14 +277,19 @@ namespace osu.Game.Graphics.Cursor { switch (e) { - case MouseEvent: + case MouseDownEvent: + case MouseMoveEvent: lastInputWasMouseSource.Value = true; return false; - default: + case KeyDownEvent keyDown when !keyDown.Repeat: + case JoystickPressEvent: + case MidiDownEvent: lastInputWasMouseSource.Value = false; return false; } + + return false; } } From 7d31eaea549922d3bd8f993f4c3382a19498bee7 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 20 Oct 2022 03:32:04 +0300 Subject: [PATCH 0143/2991] Move ball tinting logic to overwrite `SliderBall` colour --- .../Objects/Drawables/DrawableSlider.cs | 19 ------------------- .../Objects/Drawables/DrawableSliderBall.cs | 10 +--------- .../Skinning/Legacy/LegacySliderBall.cs | 11 +++++++++++ 3 files changed, 12 insertions(+), 28 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index e37f1133aa..785d15c15b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -14,12 +14,10 @@ using osu.Game.Audio; using osu.Game.Graphics.Containers; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Osu.Skinning; using osu.Game.Rulesets.Osu.Skinning.Default; using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; using osuTK; -using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -106,7 +104,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { foreach (var drawableHitObject in NestedHitObjects) drawableHitObject.AccentColour.Value = colour.NewValue; - updateBallTint(); }, true); Tracking.BindValueChanged(updateSlidingSample); @@ -257,22 +254,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables SliderBody?.RecyclePath(); } - protected override void ApplySkin(ISkinSource skin, bool allowFallback) - { - base.ApplySkin(skin, allowFallback); - - updateBallTint(); - } - - private void updateBallTint() - { - if (CurrentSkin == null) - return; - - bool allowBallTint = CurrentSkin.GetConfig(OsuSkinConfiguration.AllowSliderBallTint)?.Value ?? false; - Ball.AccentColour = allowBallTint ? AccentColour.Value : Color4.White; - } - protected override void CheckForResult(bool userTriggered, double timeOffset) { if (userTriggered || Time.Current < HitObject.EndTime) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs index a2fe623897..de6ca7dd38 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs @@ -11,28 +11,20 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; using osu.Framework.Input.Events; -using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Skinning.Default; using osu.Game.Skinning; using osuTK; -using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableSliderBall : CircularContainer, ISliderProgress, IRequireHighFrequencyMousePosition, IHasAccentColour + public class DrawableSliderBall : CircularContainer, ISliderProgress, IRequireHighFrequencyMousePosition { public const float FOLLOW_AREA = 2.4f; public Func GetInitialHitAction; - public Color4 AccentColour - { - get => ball.Colour; - set => ball.Colour = value; - } - private Drawable followCircleReceptor; private DrawableSlider drawableSlider; private Drawable ball; diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBall.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBall.cs index 414879f42d..60d71ae843 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBall.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBall.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; @@ -21,6 +22,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy [Resolved(canBeNull: true)] private DrawableHitObject? parentObject { get; set; } + public Color4 BallColour => animationContent.Colour; + private Sprite layerNd = null!; private Sprite layerSpec = null!; @@ -61,6 +64,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy }; } + private readonly IBindable accentColour = new Bindable(); + protected override void LoadComplete() { base.LoadComplete(); @@ -69,6 +74,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { parentObject.ApplyCustomUpdateState += updateStateTransforms; updateStateTransforms(parentObject, parentObject.State.Value); + + if (skin.GetConfig(SkinConfiguration.LegacySetting.AllowSliderBallTint)?.Value == true) + { + accentColour.BindTo(parentObject.AccentColour); + accentColour.BindValueChanged(a => animationContent.Colour = a.NewValue, true); + } } } From f444bb9ba6a74a0eeb956104ab22d00e2d29e769 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 20 Oct 2022 03:32:33 +0300 Subject: [PATCH 0144/2991] Update existing test case --- .../TestSceneSliderApplication.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderApplication.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderApplication.cs index 0169627867..728aa27da2 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderApplication.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderApplication.cs @@ -14,6 +14,7 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Rulesets.Osu.Skinning.Legacy; using osu.Game.Skinning; using osu.Game.Tests.Visual; using osuTK; @@ -68,10 +69,8 @@ namespace osu.Game.Rulesets.Osu.Tests AddStep("create slider", () => { - var tintingSkin = skinManager.GetSkin(DefaultLegacySkin.CreateInfo()); - tintingSkin.Configuration.ConfigDictionary["AllowSliderBallTint"] = "1"; - - var provider = Ruleset.Value.CreateInstance().CreateSkinTransformer(tintingSkin, Beatmap.Value.Beatmap); + var skin = skinManager.GetSkin(DefaultLegacySkin.CreateInfo()); + var provider = Ruleset.Value.CreateInstance().CreateSkinTransformer(skin, Beatmap.Value.Beatmap); Child = new SkinProvidingContainer(provider) { @@ -92,10 +91,10 @@ namespace osu.Game.Rulesets.Osu.Tests }); AddStep("set accent white", () => dho.AccentColour.Value = Color4.White); - AddAssert("ball is white", () => dho.ChildrenOfType().Single().AccentColour == Color4.White); + AddAssert("ball is white", () => dho.ChildrenOfType().Single().BallColour == Color4.White); AddStep("set accent red", () => dho.AccentColour.Value = Color4.Red); - AddAssert("ball is red", () => dho.ChildrenOfType().Single().AccentColour == Color4.Red); + AddAssert("ball is red", () => dho.ChildrenOfType().Single().BallColour == Color4.Red); } private Slider prepareObject(Slider slider) From 212f15e2d29bfc7435803b5b662fd7a2598dea56 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 20 Oct 2022 04:06:33 +0300 Subject: [PATCH 0145/2991] Update existing test cases --- osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs index 6c0191ae27..75c47f0b1b 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs @@ -178,6 +178,7 @@ namespace osu.Game.Tests.Visual.UserInterface [Test] public void TestKeyboardLocalCursor([Values] bool clickToShow) { + AddStep("Enable cursor hiding", () => globalCursorDisplay.MenuCursor.HideCursorOnNonMouseInput = true); AddStep("Move to purple area", () => InputManager.MoveMouseTo(cursorBoxes[3].ScreenSpaceDrawQuad.Centre + new Vector2(10, 0))); AddAssert("Check purple cursor visible", () => checkVisible(cursorBoxes[3].Cursor)); AddAssert("Check global cursor alpha is 1", () => globalCursorDisplay.MenuCursor.Alpha == 1); @@ -201,6 +202,7 @@ namespace osu.Game.Tests.Visual.UserInterface [Test] public void TestKeyboardUserCursor([Values] bool clickToShow) { + AddStep("Enable cursor hiding", () => globalCursorDisplay.MenuCursor.HideCursorOnNonMouseInput = true); AddStep("Move to green area", () => InputManager.MoveMouseTo(cursorBoxes[0])); AddAssert("Check green cursor visible", () => checkVisible(cursorBoxes[0].Cursor)); AddAssert("Check global cursor alpha is 0", () => !checkVisible(globalCursorDisplay.MenuCursor) && globalCursorDisplay.MenuCursor.ActiveCursor.Alpha == 0); From a754dc6d3b4d4fc2d02b58f7e68284f92710025a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Oct 2022 14:34:07 +0900 Subject: [PATCH 0146/2991] Expose binary search methods publicly Co-authored-by: Dan Balasescu --- osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs index cfe3c671ac..9186685f0c 100644 --- a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs +++ b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs @@ -196,7 +196,7 @@ namespace osu.Game.Beatmaps.ControlPoints /// The time to find the control point at. /// The control point to use when is before any control points. /// The active control point at , or a fallback if none found. - internal static T BinarySearchWithFallback(IReadOnlyList list, double time, T fallback) + public static T BinarySearchWithFallback(IReadOnlyList list, double time, T fallback) where T : class, IControlPoint { return BinarySearch(list, time) ?? fallback; @@ -208,7 +208,7 @@ namespace osu.Game.Beatmaps.ControlPoints /// The list to search. /// The time to find the control point at. /// The active control point at . - internal static T BinarySearch(IReadOnlyList list, double time) + public static T BinarySearch(IReadOnlyList list, double time) where T : class, IControlPoint { if (list == null) From 42bb9dc3e3db17b9cb39da3103ce10820a683db9 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 20 Oct 2022 22:17:26 +0900 Subject: [PATCH 0147/2991] revert EndPlacement change --- .../Edit/TaikoHitObjectComposer.cs | 12 ------------ osu.Game/Rulesets/Edit/HitObjectComposer.cs | 2 +- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs b/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs index 06c982397c..57c45fc074 100644 --- a/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs +++ b/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Tools; @@ -19,16 +17,6 @@ namespace osu.Game.Rulesets.Taiko.Edit { } - public override void EndPlacement(HitObject hitObject, bool commit) - { - EditorBeatmap.PlacementObject.Value = null; - - if (commit) - { - EditorBeatmap.Add(hitObject); - } - } - protected override IReadOnlyList CompositionTools => new HitObjectCompositionTool[] { new HitCompositionTool(), diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 0266317817..3bed835854 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -359,7 +359,7 @@ namespace osu.Game.Rulesets.Edit EditorBeatmap.PlacementObject.Value = hitObject; } - public virtual void EndPlacement(HitObject hitObject, bool commit) + public void EndPlacement(HitObject hitObject, bool commit) { EditorBeatmap.PlacementObject.Value = null; From 26860a903e684db7d3c06241d6889dbcd9186a5a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Oct 2022 22:30:30 +0900 Subject: [PATCH 0148/2991] Refactor implementation to support hitobjects nested multiple levels deep --- .../Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 443a37ab1c..424fc7c44c 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -236,8 +236,10 @@ namespace osu.Game.Rulesets.UI.Scrolling entry.LifetimeStart = Math.Min(entry.HitObject.StartTime - judgementOffset, computedStartTime); } - private void updateLayoutRecursive(DrawableHitObject hitObject) + private void updateLayoutRecursive(DrawableHitObject hitObject, double? parentHitObjectStartTime = null) { + parentHitObjectStartTime ??= hitObject.HitObject.StartTime; + if (hitObject.HitObject is IHasDuration e) { float length = LengthAtTime(hitObject.HitObject.StartTime, e.EndTime); @@ -249,10 +251,10 @@ namespace osu.Game.Rulesets.UI.Scrolling foreach (var obj in hitObject.NestedHitObjects) { - updateLayoutRecursive(obj); + updateLayoutRecursive(obj, parentHitObjectStartTime); // Nested hitobjects don't need to scroll, but they do need accurate positions and start lifetime - updatePosition(obj, hitObject.HitObject.StartTime, hitObject.HitObject.StartTime); + updatePosition(obj, hitObject.HitObject.StartTime, parentHitObjectStartTime); setComputedLifetimeStart(obj.Entry); } } From 5c13c443ff79af12849311737f99ab705b6211ff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Oct 2022 23:08:18 +0900 Subject: [PATCH 0149/2991] Fix incorrect fallback logic Regressed when attempting to share implementation of binary search. --- osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs | 2 +- .../Scrolling/Algorithms/OverlappingScrollAlgorithm.cs | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs index 9186685f0c..422e306450 100644 --- a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs +++ b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs @@ -207,7 +207,7 @@ namespace osu.Game.Beatmaps.ControlPoints /// /// The list to search. /// The time to find the control point at. - /// The active control point at . + /// The active control point at . Will return null if there are no control points, or if the time is before the first control point. public static T BinarySearch(IReadOnlyList list, double time) where T : class, IControlPoint { diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs index 00bc7453d8..54079c7895 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs @@ -4,6 +4,7 @@ #nullable disable using System; +using System.Linq; using osu.Framework.Lists; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Timing; @@ -73,6 +74,13 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms /// /// The time which the should affect. /// The . - private MultiplierControlPoint controlPointAt(double time) => ControlPointInfo.BinarySearch(controlPoints, time) ?? new MultiplierControlPoint(double.NegativeInfinity); + private MultiplierControlPoint controlPointAt(double time) + { + return ControlPointInfo.BinarySearch(controlPoints, time) + // The standard binary search will fail if there's no control points, or if the time is before the first. + // For this method, we want to use the first control point in the latter case. + ?? controlPoints.FirstOrDefault() + ?? new MultiplierControlPoint(double.NegativeInfinity); + } } } From ed39481932a148297c546013987e8fbbccaeaf47 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 20 Oct 2022 18:11:35 +0300 Subject: [PATCH 0150/2991] Use another string for title --- osu.Game/Overlays/Comments/ReportCommentPopover.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index 5214f8a3e3..83b13c8f56 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -42,7 +42,7 @@ namespace osu.Game.Overlays.Comments { Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, - Text = UsersStrings.ReportTitle(comment.Comment.User?.Username ?? comment.Comment.LegacyName!), + Text = ReportStrings.CommentTitle(comment.Comment.User?.Username ?? comment.Comment.LegacyName!), Font = OsuFont.Torus.With(size: 25), Margin = new MarginPadding { Bottom = 10 } }, From 635900085c62854e4b8ec842a2a003cfbaff90e0 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 20 Oct 2022 18:12:20 +0300 Subject: [PATCH 0151/2991] Disable button when there is no text --- .../Overlays/Comments/ReportCommentPopover.cs | 51 ++++++++----------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index 83b13c8f56..14da02f838 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -2,11 +2,11 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; -using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; @@ -19,8 +19,8 @@ namespace osu.Game.Overlays.Comments { private readonly DrawableComment comment; private OsuEnumDropdown reason = null!; - private OsuTextBox info = null!; - private ShakeContainer shaker = null!; + private readonly Bindable commentText = new Bindable(); + private RoundedButton submitButton = null!; public ReportCommentPopover(DrawableComment comment) { @@ -64,48 +64,37 @@ namespace osu.Game.Overlays.Comments Text = UsersStrings.ReportComments, Font = OsuFont.Torus.With(size: 20), }, - info = new OsuTextBox + new OsuTextBox { RelativeSizeAxes = Axes.X, - PlaceholderText = UsersStrings.ReportPlaceholder + PlaceholderText = UsersStrings.ReportPlaceholder, + Current = commentText }, - new Container + submitButton = new RoundedButton { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Child = shaker = new ShakeContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Child = new RoundedButton - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Width = 200, - BackgroundColour = colours.Red3, - Text = UsersStrings.ReportActionsSend, - Action = send, - Margin = new MarginPadding { Bottom = 5, Top = 10 }, - } - } + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Width = 200, + BackgroundColour = colours.Red3, + Text = UsersStrings.ReportActionsSend, + Action = send, + Margin = new MarginPadding { Bottom = 5, Top = 10 }, } } }; + commentText.BindValueChanged(e => + { + submitButton.Enabled.Value = !string.IsNullOrWhiteSpace(e.NewValue); + }, true); } private void send() { - string infoValue = info.Current.Value; - var reasonValue = reason.Current.Value; - - if (string.IsNullOrWhiteSpace(infoValue)) - { - shaker.Shake(); + if (string.IsNullOrWhiteSpace(commentText.Value)) return; - } this.HidePopover(); - comment.ReportComment(reasonValue, infoValue); + comment.ReportComment(reason.Current.Value, commentText.Value); } } } From da4f04ace77929cb1927f4c5aa34ccde189d551f Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 20 Oct 2022 18:22:55 +0300 Subject: [PATCH 0152/2991] Make dropdown not resize --- osu.Game/Overlays/Comments/ReportCommentPopover.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index 14da02f838..202f27777d 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -7,6 +7,7 @@ using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; @@ -30,7 +31,7 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load(OsuColour colours) { - Child = new FillFlowContainer + Child = new ReverseChildIDFillFlowContainer { Direction = FillDirection.Vertical, Width = 500, @@ -53,9 +54,14 @@ namespace osu.Game.Overlays.Comments Text = UsersStrings.ReportReason, Font = OsuFont.Torus.With(size: 20), }, - reason = new OsuEnumDropdown + new Container { - RelativeSizeAxes = Axes.X + RelativeSizeAxes = Axes.X, + Height = 40, + Child = reason = new OsuEnumDropdown + { + RelativeSizeAxes = Axes.X + } }, new OsuSpriteText { From 0ef903230c04e118d8ab94f6f628eba6ccab1ab1 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 20 Oct 2022 18:47:42 +0300 Subject: [PATCH 0153/2991] Make report button a separate component --- osu.Game/Overlays/Comments/DrawableComment.cs | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 75f68782b8..a2b11bfc69 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -34,7 +34,8 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments { - public class DrawableComment : CompositeDrawable, IHasPopover + [Cached] + public class DrawableComment : CompositeDrawable { private const int avatar_size = 40; @@ -64,6 +65,7 @@ namespace osu.Game.Overlays.Comments private ShowRepliesButton showRepliesButton = null!; private ChevronButton chevronButton = null!; private LinkFlowContainer actionsContainer = null!; + private ReportButton? reportButton; private LoadingSpinner actionsLoading = null!; private DeletedCommentsCounter deletedCommentsCounter = null!; private OsuSpriteText deletedLabel = null!; @@ -334,12 +336,12 @@ namespace osu.Game.Overlays.Comments makeDeleted(); actionsContainer.AddLink("Copy link", copyUrl); - actionsContainer.AddArbitraryDrawable(new Container { Width = 10 }); + actionsContainer.AddArbitraryDrawable(Empty().With(d => d.Width = 10)); if (Comment.UserId.HasValue && Comment.UserId.Value == api.LocalUser.Value.Id) actionsContainer.AddLink("Delete", deleteComment); else - actionsContainer.AddLink(UsersStrings.ReportButtonText, this.ShowPopover); + actionsContainer.AddArbitraryDrawable(reportButton = new ReportButton()); if (Comment.IsTopLevel) { @@ -424,6 +426,8 @@ namespace osu.Game.Overlays.Comments request.Success += () => Schedule(() => { actionsLoading.Hide(); + reportButton?.Expire(); + actionsContainer.Show(); onScreenDisplay?.Display(new ReportToast()); }); request.Failure += _ => Schedule(() => @@ -582,8 +586,6 @@ namespace osu.Game.Overlays.Comments } } - public Popover GetPopover() => new ReportCommentPopover(this); - private class ReportToast : Toast { public ReportToast() @@ -591,5 +593,25 @@ namespace osu.Game.Overlays.Comments { } } + + private class ReportButton : LinkFlowContainer, IHasPopover + { + public ReportButton() + : base(s => s.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold)) + { + } + + [Resolved] + private DrawableComment comment { get; set; } = null!; + + [BackgroundDependencyLoader] + private void load() + { + AutoSizeAxes = Axes.Both; + AddLink(UsersStrings.ReportButtonText, this.ShowPopover); + } + + public Popover GetPopover() => new ReportCommentPopover(comment); + } } } From 81bdf716ef41a8b9968cbe6e05b00dace996075b Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 20 Oct 2022 19:56:00 +0300 Subject: [PATCH 0154/2991] Change test --- osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs | 2 +- osu.Game/Overlays/Comments/DrawableComment.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs index 54c135ba15..a2e0c90c4c 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs @@ -276,7 +276,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("Complete request", () => requestLock.Set()); AddUntilStep("Request sent", () => request != null); AddAssert("Request is correct", () => request != null && request.CommentID == 2 && request.Comment == report_text && request.Reason == CommentReportReason.Other); - AddUntilStep("Buttons hidden", () => !targetComment.ChildrenOfType().Single(x => x.Name == @"Actions buttons").IsPresent); + AddUntilStep("Button expired", () => !targetComment.ChildrenOfType().Any()); } private void addTestComments() diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index a2b11bfc69..199f678be1 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -594,7 +594,7 @@ namespace osu.Game.Overlays.Comments } } - private class ReportButton : LinkFlowContainer, IHasPopover + internal class ReportButton : LinkFlowContainer, IHasPopover { public ReportButton() : base(s => s.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold)) From bf4a91f1f00b6fab2208416558e142dba6b10caa Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Thu, 20 Oct 2022 12:48:44 -0700 Subject: [PATCH 0155/2991] Fix skin toolbox component button not playing hover/click sounds --- osu.Game/Skinning/Editor/SkinComponentToolbox.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Skinning/Editor/SkinComponentToolbox.cs b/osu.Game/Skinning/Editor/SkinComponentToolbox.cs index 980dee8601..469657c03c 100644 --- a/osu.Game/Skinning/Editor/SkinComponentToolbox.cs +++ b/osu.Game/Skinning/Editor/SkinComponentToolbox.cs @@ -85,10 +85,6 @@ namespace osu.Game.Skinning.Editor { public Action? RequestPlacement; - protected override bool ShouldBeConsideredForInput(Drawable child) => false; - - public override bool PropagateNonPositionalInputSubTree => false; - private readonly Drawable component; private readonly CompositeDrawable? dependencySource; @@ -177,6 +173,10 @@ namespace osu.Game.Skinning.Editor public class DependencyBorrowingContainer : Container { + protected override bool ShouldBeConsideredForInput(Drawable child) => false; + + public override bool PropagateNonPositionalInputSubTree => false; + private readonly CompositeDrawable? donor; public DependencyBorrowingContainer(CompositeDrawable? donor) From 27ce3d8342e0a239042f1402ca486e44461770c6 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 21 Oct 2022 01:52:19 +0300 Subject: [PATCH 0156/2991] Fix input settings not displaying in visual test browser --- osu.Desktop/OsuGameDesktop.cs | 29 ----------------------------- osu.Game/OsuGameBase.cs | 23 +++++++++++++++++++++++ 2 files changed, 23 insertions(+), 29 deletions(-) diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index 3ee1b3da30..09f7292845 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -18,17 +18,9 @@ using osu.Framework; using osu.Framework.Logging; using osu.Game.Updater; using osu.Desktop.Windows; -using osu.Framework.Input.Handlers; -using osu.Framework.Input.Handlers.Joystick; -using osu.Framework.Input.Handlers.Mouse; -using osu.Framework.Input.Handlers.Tablet; -using osu.Framework.Input.Handlers.Touch; using osu.Framework.Threading; using osu.Game.IO; using osu.Game.IPC; -using osu.Game.Overlays.Settings; -using osu.Game.Overlays.Settings.Sections; -using osu.Game.Overlays.Settings.Sections.Input; using osu.Game.Utils; using SDL2; @@ -148,27 +140,6 @@ namespace osu.Desktop desktopWindow.DragDrop += f => fileDrop(new[] { f }); } - public override SettingsSubsection CreateSettingsSubsectionFor(InputHandler handler) - { - switch (handler) - { - case ITabletHandler th: - return new TabletSettings(th); - - case MouseHandler mh: - return new MouseSettings(mh); - - case JoystickHandler jh: - return new JoystickSettings(jh); - - case TouchHandler th: - return new InputSection.HandlerSection(th); - - default: - return base.CreateSettingsSubsectionFor(handler); - } - } - protected override BatteryInfo CreateBatteryInfo() => new SDL2BatteryInfo(); private readonly List importableFiles = new List(); diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 7d9ed7bf3e..1177f01609 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -21,7 +21,11 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Textures; using osu.Framework.Input; using osu.Framework.Input.Handlers; +using osu.Framework.Input.Handlers.Joystick; using osu.Framework.Input.Handlers.Midi; +using osu.Framework.Input.Handlers.Mouse; +using osu.Framework.Input.Handlers.Tablet; +using osu.Framework.Input.Handlers.Touch; using osu.Framework.IO.Stores; using osu.Framework.Logging; using osu.Framework.Platform; @@ -46,6 +50,7 @@ using osu.Game.Online.Spectator; using osu.Game.Overlays; using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings.Sections; +using osu.Game.Overlays.Settings.Sections.Input; using osu.Game.Resources; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -521,6 +526,24 @@ namespace osu.Game /// Should be overriden per-platform to provide settings for platform-specific handlers. public virtual SettingsSubsection CreateSettingsSubsectionFor(InputHandler handler) { + if (RuntimeInfo.IsDesktop) + { + switch (handler) + { + case ITabletHandler th: + return new TabletSettings(th); + + case MouseHandler mh: + return new MouseSettings(mh); + + case JoystickHandler jh: + return new JoystickSettings(jh); + + case TouchHandler: + return new InputSection.HandlerSection(handler); + } + } + switch (handler) { case MidiHandler: From d441e98af785942277e6172c732f512cee626f07 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2022 15:34:25 +0900 Subject: [PATCH 0157/2991] Adjust kiai flash period in line with stable --- osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs index 36daefbd36..6b5a9ae6d2 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs @@ -3,7 +3,6 @@ #nullable disable -using System; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Extensions.Color4Extensions; @@ -170,7 +169,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default FlashBox .FadeTo(flash_opacity) .Then() - .FadeOut(Math.Max(80, timingPoint.BeatLength - 80), Easing.OutSine); + .FadeOut(timingPoint.BeatLength * 0.75, Easing.OutSine); } if (beatIndex % timingPoint.TimeSignature.Numerator != 0) From 23b7b9013e65f0b9c7828ac5d1cbac4b18d98dc0 Mon Sep 17 00:00:00 2001 From: Alden Wu Date: Thu, 20 Oct 2022 23:37:05 -0700 Subject: [PATCH 0158/2991] Change smoke quadbatch growth factor to 2 from 1.5 --- osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs index 23bfea5240..46c8e7c02a 100644 --- a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs @@ -238,9 +238,9 @@ namespace osu.Game.Rulesets.Osu.Skinning quadBatch ??= renderer.CreateQuadBatch(200, 4); - if (points.Count > quadBatch.Size * 4 && quadBatch.Size != 10922) + if (points.Count > quadBatch.Size && quadBatch.Size != IRenderer.MAX_QUADS) { - int batchSize = Math.Min((int)(quadBatch.Size * 1.5f), 10922); + int batchSize = Math.Min(quadBatch.Size * 2, IRenderer.MAX_QUADS); quadBatch = renderer.CreateQuadBatch(batchSize, 4); } From 6cdfddea6261a293bf54f285ead6c012eddb1cb2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2022 16:10:55 +0900 Subject: [PATCH 0159/2991] Always enable distance spacing when adusting distance space multiplier --- osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index 46a827e03a..feedad7f25 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -111,7 +111,7 @@ namespace osu.Game.Rulesets.Edit { case GlobalAction.EditorIncreaseDistanceSpacing: case GlobalAction.EditorDecreaseDistanceSpacing: - return adjustDistanceSpacing(e.Action, adjust_step); + return AdjustDistanceSpacing(e.Action, adjust_step); } return false; @@ -127,13 +127,13 @@ namespace osu.Game.Rulesets.Edit { case GlobalAction.EditorIncreaseDistanceSpacing: case GlobalAction.EditorDecreaseDistanceSpacing: - return adjustDistanceSpacing(e.Action, e.ScrollAmount * adjust_step); + return AdjustDistanceSpacing(e.Action, e.ScrollAmount * adjust_step); } return false; } - private bool adjustDistanceSpacing(GlobalAction action, float amount) + protected virtual bool AdjustDistanceSpacing(GlobalAction action, float amount) { if (DistanceSpacingMultiplier.Disabled) return false; From ef990c55ca43efec56f378a205a456749f71ba06 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2022 16:11:19 +0900 Subject: [PATCH 0160/2991] Handle distance/grid toggles based on key type, rathern than individual left/right --- .../Edit/OsuHitObjectComposer.cs | 59 ++++++++++++++----- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index e46131dd6e..4eb1cc3513 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -16,6 +16,7 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; +using osu.Game.Input.Bindings; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Mods; @@ -25,7 +26,6 @@ using osu.Game.Rulesets.UI; using osu.Game.Screens.Edit.Components.TernaryButtons; using osu.Game.Screens.Edit.Compose.Components; using osuTK; -using osuTK.Input; namespace osu.Game.Rulesets.Osu.Edit { @@ -236,30 +236,61 @@ namespace osu.Game.Rulesets.Osu.Edit if (e.Repeat) return false; - handleToggleViaKey(e.Key); - + handleToggleViaKey(e); return base.OnKeyDown(e); } protected override void OnKeyUp(KeyUpEvent e) { - handleToggleViaKey(e.Key); + handleToggleViaKey(e); base.OnKeyUp(e); } - private void handleToggleViaKey(Key key) + protected override bool AdjustDistanceSpacing(GlobalAction action, float amount) { - switch (key) - { - case Key.ShiftLeft: - case Key.ShiftRight: - rectangularGridSnapToggle.Value = rectangularGridSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; - break; + // To allow better visualisation, ensure that the spacing grid is visible before adjusting. + distanceSnapToggle.Value = TernaryState.True; - case Key.AltLeft: - case Key.AltRight: + return base.AdjustDistanceSpacing(action, amount); + } + + private TernaryState? gridSnapBeforeMomentary; + private TernaryState? distanceSnapBeforeMomentary; + + private void handleToggleViaKey(KeyboardEvent key) + { + if (key.ShiftPressed) + { + if (gridSnapBeforeMomentary == null) + { + gridSnapBeforeMomentary = rectangularGridSnapToggle.Value; + rectangularGridSnapToggle.Value = rectangularGridSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; + } + } + else + { + if (gridSnapBeforeMomentary != null) + { + rectangularGridSnapToggle.Value = gridSnapBeforeMomentary.Value; + gridSnapBeforeMomentary = null; + } + } + + if (key.AltPressed) + { + if (distanceSnapBeforeMomentary == null) + { + distanceSnapBeforeMomentary = distanceSnapToggle.Value; distanceSnapToggle.Value = distanceSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; - break; + } + } + else + { + if (distanceSnapBeforeMomentary != null) + { + distanceSnapToggle.Value = distanceSnapBeforeMomentary.Value; + distanceSnapBeforeMomentary = null; + } } } From 16f5c2a7c6b90dc54baab5407e3b2a06cbf89653 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2022 17:15:36 +0900 Subject: [PATCH 0161/2991] Apply same fix to osu!catch composer --- .../Edit/CatchHitObjectComposer.cs | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index d40200f2dd..72750fb798 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -94,29 +94,36 @@ namespace osu.Game.Rulesets.Catch.Edit if (e.Repeat) return false; - if (handleToggleViaKey(e.Key)) - return true; - + handleToggleViaKey(e); return base.OnKeyDown(e); } protected override void OnKeyUp(KeyUpEvent e) { - handleToggleViaKey(e.Key); + handleToggleViaKey(e); base.OnKeyUp(e); } - private bool handleToggleViaKey(Key key) - { - switch (key) - { - case Key.AltLeft: - case Key.AltRight: - distanceSnapToggle.Value = distanceSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; - return true; - } + private TernaryState? distanceSnapBeforeMomentary; - return false; + private void handleToggleViaKey(KeyboardEvent key) + { + if (key.AltPressed) + { + if (distanceSnapBeforeMomentary == null) + { + distanceSnapBeforeMomentary = distanceSnapToggle.Value; + distanceSnapToggle.Value = distanceSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; + } + } + else + { + if (distanceSnapBeforeMomentary != null) + { + distanceSnapToggle.Value = distanceSnapBeforeMomentary.Value; + distanceSnapBeforeMomentary = null; + } + } } public override bool OnPressed(KeyBindingPressEvent e) From ca91f9f7160517afebbd17eebb9b7c704fa054a9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2022 17:16:55 +0900 Subject: [PATCH 0162/2991] Don't allow two momentary toggles at the same time to avoid edge cases --- osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 4eb1cc3513..282631bb1a 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -261,7 +261,7 @@ namespace osu.Game.Rulesets.Osu.Edit { if (key.ShiftPressed) { - if (gridSnapBeforeMomentary == null) + if (distanceSnapBeforeMomentary == null && gridSnapBeforeMomentary == null) { gridSnapBeforeMomentary = rectangularGridSnapToggle.Value; rectangularGridSnapToggle.Value = rectangularGridSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; @@ -278,7 +278,7 @@ namespace osu.Game.Rulesets.Osu.Edit if (key.AltPressed) { - if (distanceSnapBeforeMomentary == null) + if (gridSnapBeforeMomentary == null && distanceSnapBeforeMomentary == null) { distanceSnapBeforeMomentary = distanceSnapToggle.Value; distanceSnapToggle.Value = distanceSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; From 7b1edff2b36a728e4ef964ea4bf849d86c37d368 Mon Sep 17 00:00:00 2001 From: Jamie Taylor Date: Fri, 21 Oct 2022 18:06:38 +0900 Subject: [PATCH 0163/2991] Add unique hover/select samples to settings sidebar buttons --- osu.Game/Graphics/UserInterface/HoverSampleSet.cs | 3 +++ osu.Game/Overlays/Settings/SidebarButton.cs | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/HoverSampleSet.cs b/osu.Game/Graphics/UserInterface/HoverSampleSet.cs index 6358317e9d..f0ff76b35d 100644 --- a/osu.Game/Graphics/UserInterface/HoverSampleSet.cs +++ b/osu.Game/Graphics/UserInterface/HoverSampleSet.cs @@ -15,6 +15,9 @@ namespace osu.Game.Graphics.UserInterface [Description("button")] Button, + [Description("button-sidebar")] + ButtonSidebar, + [Description("toolbar")] Toolbar, diff --git a/osu.Game/Overlays/Settings/SidebarButton.cs b/osu.Game/Overlays/Settings/SidebarButton.cs index c6a4cbbcaa..2c4832c68a 100644 --- a/osu.Game/Overlays/Settings/SidebarButton.cs +++ b/osu.Game/Overlays/Settings/SidebarButton.cs @@ -16,6 +16,11 @@ namespace osu.Game.Overlays.Settings [Resolved] protected OverlayColourProvider ColourProvider { get; private set; } + protected SidebarButton() + : base(HoverSampleSet.ButtonSidebar) + { + } + [BackgroundDependencyLoader] private void load() { From af84f708b7b83d87738fecc45982ec13083c9755 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2022 19:01:28 +0900 Subject: [PATCH 0164/2991] Avoid serialising some more properties of `SoloScoreInfo` unless present --- .../Online/API/Requests/Responses/SoloScoreInfo.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs b/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs index 2c9f250028..4469d50acb 100644 --- a/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs +++ b/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs @@ -114,6 +114,7 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty("has_replay")] public bool HasReplay { get; set; } + // These properties are calculated or not relevant to any external usage. public bool ShouldSerializeID() => false; public bool ShouldSerializeUser() => false; public bool ShouldSerializeBeatmap() => false; @@ -122,6 +123,18 @@ namespace osu.Game.Online.API.Requests.Responses public bool ShouldSerializeOnlineID() => false; public bool ShouldSerializeHasReplay() => false; + // These fields only need to be serialised if they hold values. + // Generally this is required because this model may be used by server-side components, but + // we don't want to bother sending these fields in score submission requests, for instance. + public bool ShouldSerializeEndedAt() => EndedAt != default; + public bool ShouldSerializeStartedAt() => StartedAt != default; + public bool ShouldSerializeLegacyScoreId() => LegacyScoreId != null; + public bool ShouldSerializeLegacyTotalScore() => LegacyTotalScore != null; + public bool ShouldSerializeMods() => Mods.Length > 0; + public bool ShouldSerializeUserID() => UserID > 0; + public bool ShouldSerializeBeatmapID() => BeatmapID > 0; + public bool ShouldSerializeBuildID() => BuildID != null; + #endregion public override string ToString() => $"score_id: {ID} user_id: {UserID}"; From 1e09a212791de25c93c7f48183aacff6f369aa46 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2022 19:55:58 +0900 Subject: [PATCH 0165/2991] Remove unused using statement --- osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index 72750fb798..27235bd62e 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -26,7 +26,6 @@ using osu.Game.Rulesets.UI; using osu.Game.Screens.Edit.Components.TernaryButtons; using osu.Game.Screens.Edit.Compose.Components; using osuTK; -using osuTK.Input; namespace osu.Game.Rulesets.Catch.Edit { From 8b74b5807f3f43b7107ed19dd39636afddada643 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2022 20:53:37 +0900 Subject: [PATCH 0166/2991] Update resources --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 3f4c8e2d24..50fb1c4eda 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -51,7 +51,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f1fed6913b..42da129195 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index c79d0e4864..d883ce0045 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -61,7 +61,7 @@ - + From 447d420c997622ec256d7dc8678ee052feb3510c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2022 21:03:39 +0900 Subject: [PATCH 0167/2991] Fix adjusting volume via settings playing tick samples twice --- .../Graphics/UserInterface/OsuSliderBar.cs | 5 +++++ .../Settings/Sections/Audio/VolumeSettings.cs | 18 +++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index 2a8b41fd20..9acb0c7f94 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -44,6 +44,8 @@ namespace osu.Game.Graphics.UserInterface public virtual LocalisableString TooltipText { get; private set; } + public bool PlaySamplesOnAdjust { get; set; } = true; + /// /// Whether to format the tooltip as a percentage or the actual value. /// @@ -187,6 +189,9 @@ namespace osu.Game.Graphics.UserInterface private void playSample(T value) { + if (!PlaySamplesOnAdjust) + return; + if (Clock == null || Clock.CurrentTime - lastSampleTime <= 30) return; diff --git a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs index cea8fdd733..8f188f04d9 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs @@ -8,6 +8,7 @@ using osu.Framework.Audio; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Configuration; +using osu.Game.Graphics.UserInterface; using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Audio @@ -21,7 +22,7 @@ namespace osu.Game.Overlays.Settings.Sections.Audio { Children = new Drawable[] { - new SettingsSlider + new VolumeAdjustSlider { LabelText = AudioSettingsStrings.MasterVolume, Current = audio.Volume, @@ -35,14 +36,15 @@ namespace osu.Game.Overlays.Settings.Sections.Audio KeyboardStep = 0.01f, DisplayAsPercentage = true }, - new SettingsSlider + new VolumeAdjustSlider { LabelText = AudioSettingsStrings.EffectVolume, Current = audio.VolumeSample, KeyboardStep = 0.01f, DisplayAsPercentage = true }, - new SettingsSlider + + new VolumeAdjustSlider { LabelText = AudioSettingsStrings.MusicVolume, Current = audio.VolumeTrack, @@ -51,5 +53,15 @@ namespace osu.Game.Overlays.Settings.Sections.Audio }, }; } + + private class VolumeAdjustSlider : SettingsSlider + { + protected override Drawable CreateControl() + { + var sliderBar = (OsuSliderBar)base.CreateControl(); + sliderBar.PlaySamplesOnAdjust = false; + return sliderBar; + } + } } } From 7dc03097ffa73297def50e96b8c7609db4ee1246 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2022 21:51:17 +0900 Subject: [PATCH 0168/2991] Change distance snap to never account for slider velocity This is a nuanced detail that was implemented incorrectly from the outset. When mapping, generally a mapper chooses the distance spacing with no regard to the SV. It has always been common to have a lower or higher distance spacing than SV, but with the way the lazer editor has worked, the SV was multiplied into the distance snap grid display, incorectly changing its spacing depending on the "reference object" (which is usually the previous hitobject chronologically). --- osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index 46a827e03a..d23d8ad438 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -148,7 +148,7 @@ namespace osu.Game.Rulesets.Edit public virtual float GetBeatSnapDistanceAt(HitObject referenceObject) { - return (float)(100 * EditorBeatmap.Difficulty.SliderMultiplier * referenceObject.DifficultyControlPoint.SliderVelocity / BeatSnapProvider.BeatDivisor); + return (float)(100 * EditorBeatmap.Difficulty.SliderMultiplier * 1 / BeatSnapProvider.BeatDivisor); } public virtual float DurationToDistance(HitObject referenceObject, double duration) From bace3df4cae732e0b34d518cc0cb3a7cbea1c488 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2022 22:58:10 +0900 Subject: [PATCH 0169/2991] Update test assertions in line with change --- .../Editing/TestSceneHitObjectComposerDistanceSnapping.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index 1e87ed27df..a98f931e7a 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -71,9 +71,9 @@ namespace osu.Game.Tests.Editing [TestCase(1)] [TestCase(2)] - public void TestSpeedMultiplier(float multiplier) + public void TestSpeedMultiplierDoesNotChangeDistanceSnap(float multiplier) { - assertSnapDistance(100 * multiplier, new HitObject + assertSnapDistance(100, new HitObject { DifficultyControlPoint = new DifficultyControlPoint { From 645a84b1d633973d5e360aec52d4f1693a91baf8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2022 22:58:36 +0900 Subject: [PATCH 0170/2991] Display current distance snap and add button to update to use it --- .../Edit/CatchHitObjectComposer.cs | 6 ++ .../Edit/OsuHitObjectComposer.cs | 8 ++ .../Edit/DistancedHitObjectComposer.cs | 74 ++++++++++++++++++- osu.Game/Rulesets/Edit/ExpandableButton.cs | 36 +++++++++ 4 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 osu.Game/Rulesets/Edit/ExpandableButton.cs diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index 54d50b01c4..f2eaebbfe5 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -81,6 +81,12 @@ namespace osu.Game.Rulesets.Catch.Edit inputManager = GetContainingInputManager(); } + protected override double ReadCurrentDistanceSnap(HitObject before, HitObject after) + { + // TODO: catch lol + return 1; + } + protected override void Update() { base.Update(); diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 6b4a6e39d9..58d0005ab7 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -112,6 +112,14 @@ namespace osu.Game.Rulesets.Osu.Edit private RectangularPositionSnapGrid rectangularPositionSnapGrid; + protected override double ReadCurrentDistanceSnap(HitObject before, HitObject after) + { + float expectedDistance = DurationToDistance(before, after.StartTime - before.GetEndTime()); + float actualDistance = Vector2.Distance(((OsuHitObject)before).EndPosition, ((OsuHitObject)after).Position); + + return actualDistance / expectedDistance; + } + protected override void Update() { base.Update(); diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index d23d8ad438..10be00ac55 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -3,6 +3,8 @@ #nullable disable +using System.Diagnostics; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions; @@ -13,7 +15,9 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Localisation; +using osu.Framework.Utils; using osu.Game.Configuration; +using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Input.Bindings; using osu.Game.Overlays; @@ -32,7 +36,7 @@ namespace osu.Game.Rulesets.Edit { private const float adjust_step = 0.1f; - public Bindable DistanceSpacingMultiplier { get; } = new BindableDouble(1.0) + public BindableDouble DistanceSpacingMultiplier { get; } = new BindableDouble(1.0) { MinValue = 0.1, MaxValue = 6.0, @@ -44,6 +48,9 @@ namespace osu.Game.Rulesets.Edit protected ExpandingToolboxContainer RightSideToolboxContainer { get; private set; } private ExpandableSlider> distanceSpacingSlider; + private ExpandableButton readCurrentButton; + + private OsuSpriteText currentDistanceSpacingDisplay; [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } @@ -74,10 +81,29 @@ namespace osu.Game.Rulesets.Edit Alpha = DistanceSpacingMultiplier.Disabled ? 0 : 1, Child = new EditorToolboxGroup("snapping") { - Child = distanceSpacingSlider = new ExpandableSlider> + Children = new Drawable[] { - Current = { BindTarget = DistanceSpacingMultiplier }, - KeyboardStep = adjust_step, + distanceSpacingSlider = new ExpandableSlider> + { + Current = { BindTarget = DistanceSpacingMultiplier }, + KeyboardStep = adjust_step, + }, + currentDistanceSpacingDisplay = new OsuSpriteText + { + }, + readCurrentButton = new ExpandableButton + { + Text = "Use current", + Action = () => + { + (HitObject before, HitObject after)? objects = getObjectsOnEitherSideOfCurrentTime(); + + Debug.Assert(objects != null); + + DistanceSpacingMultiplier.Value = ReadCurrentDistanceSnap(objects.Value.before, objects.Value.after); + }, + RelativeSizeAxes = Axes.X, + } } } } @@ -85,6 +111,46 @@ namespace osu.Game.Rulesets.Edit }); } + private (HitObject before, HitObject after)? getObjectsOnEitherSideOfCurrentTime() + { + HitObject lastBefore = Playfield.HitObjectContainer.AliveObjects.LastOrDefault(h => h.HitObject.GetEndTime() <= EditorClock.CurrentTime)?.HitObject; + + if (lastBefore == null) + return null; + + HitObject firstAfter = Playfield.HitObjectContainer.AliveObjects.FirstOrDefault(h => h.HitObject.StartTime >= EditorClock.CurrentTime)?.HitObject; + + if (firstAfter == null) + return null; + + if (lastBefore == firstAfter) + return null; + + return (lastBefore, firstAfter); + } + + protected abstract double ReadCurrentDistanceSnap(HitObject before, HitObject after); + + protected override void Update() + { + base.Update(); + + (HitObject before, HitObject after)? objects = getObjectsOnEitherSideOfCurrentTime(); + + if (objects != null) + { + double currentSnap = ReadCurrentDistanceSnap(objects.Value.before, objects.Value.after); + readCurrentButton.Enabled.Value = Precision.AlmostEquals(currentSnap, DistanceSpacingMultiplier.Value, DistanceSpacingMultiplier.Precision); + + currentDistanceSpacingDisplay.Text = $"Current {currentSnap:N1}x"; + } + else + { + readCurrentButton.Enabled.Value = false; + currentDistanceSpacingDisplay.Text = "Current: -"; + } + } + protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game/Rulesets/Edit/ExpandableButton.cs b/osu.Game/Rulesets/Edit/ExpandableButton.cs new file mode 100644 index 0000000000..32885c1a1c --- /dev/null +++ b/osu.Game/Rulesets/Edit/ExpandableButton.cs @@ -0,0 +1,36 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterfaceV2; + +namespace osu.Game.Rulesets.Edit +{ + internal class ExpandableButton : RoundedButton, IExpandable + { + public BindableBool Expanded { get; } = new BindableBool(); + + [Resolved(canBeNull: true)] + private IExpandingContainer? expandingContainer { get; set; } + + protected override void LoadComplete() + { + base.LoadComplete(); + + expandingContainer?.Expanded.BindValueChanged(containerExpanded => + { + Expanded.Value = containerExpanded.NewValue; + }, true); + + Expanded.BindValueChanged(expanded => + { + if (expanded.NewValue) + Show(); + else + Hide(); + }, true); + } + } +} From f6de366766b1d22fbc10650ec0feb24aebac71d4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2022 23:21:07 +0900 Subject: [PATCH 0171/2991] Combine display and button into one control --- .../Edit/DistancedHitObjectComposer.cs | 22 +++--- osu.Game/Rulesets/Edit/ExpandableButton.cs | 69 ++++++++++++++++++- 2 files changed, 76 insertions(+), 15 deletions(-) diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index 10be00ac55..9ef8480b25 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -17,7 +17,6 @@ using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Framework.Utils; using osu.Game.Configuration; -using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Input.Bindings; using osu.Game.Overlays; @@ -48,9 +47,7 @@ namespace osu.Game.Rulesets.Edit protected ExpandingToolboxContainer RightSideToolboxContainer { get; private set; } private ExpandableSlider> distanceSpacingSlider; - private ExpandableButton readCurrentButton; - - private OsuSpriteText currentDistanceSpacingDisplay; + private ExpandableButton currentDistanceSpacingButton; [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } @@ -88,12 +85,8 @@ namespace osu.Game.Rulesets.Edit Current = { BindTarget = DistanceSpacingMultiplier }, KeyboardStep = adjust_step, }, - currentDistanceSpacingDisplay = new OsuSpriteText + currentDistanceSpacingButton = new ExpandableButton { - }, - readCurrentButton = new ExpandableButton - { - Text = "Use current", Action = () => { (HitObject before, HitObject after)? objects = getObjectsOnEitherSideOfCurrentTime(); @@ -140,14 +133,17 @@ namespace osu.Game.Rulesets.Edit if (objects != null) { double currentSnap = ReadCurrentDistanceSnap(objects.Value.before, objects.Value.after); - readCurrentButton.Enabled.Value = Precision.AlmostEquals(currentSnap, DistanceSpacingMultiplier.Value, DistanceSpacingMultiplier.Precision); - currentDistanceSpacingDisplay.Text = $"Current {currentSnap:N1}x"; + currentDistanceSpacingButton.Enabled.Value = currentDistanceSpacingButton.Expanded.Value + && !Precision.AlmostEquals(currentSnap, DistanceSpacingMultiplier.Value, DistanceSpacingMultiplier.Precision / 2); + currentDistanceSpacingButton.ContractedLabelText = $"(current {currentSnap:N2}x)"; + currentDistanceSpacingButton.ExpandedLabelText = $"Use current ({currentSnap:N2}x)"; } else { - readCurrentButton.Enabled.Value = false; - currentDistanceSpacingDisplay.Text = "Current: -"; + currentDistanceSpacingButton.Enabled.Value = false; + currentDistanceSpacingButton.ContractedLabelText = "Current N/A"; + currentDistanceSpacingButton.ExpandedLabelText = "Use current (N/A)"; } } diff --git a/osu.Game/Rulesets/Edit/ExpandableButton.cs b/osu.Game/Rulesets/Edit/ExpandableButton.cs index 32885c1a1c..572ae19a03 100644 --- a/osu.Game/Rulesets/Edit/ExpandableButton.cs +++ b/osu.Game/Rulesets/Edit/ExpandableButton.cs @@ -3,6 +3,9 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Localisation; +using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterfaceV2; @@ -10,6 +13,54 @@ namespace osu.Game.Rulesets.Edit { internal class ExpandableButton : RoundedButton, IExpandable { + private float actualHeight; + + public override float Height + { + get => base.Height; + set => base.Height = actualHeight = value; + } + + private LocalisableString contractedLabelText; + + /// + /// The label text to display when this slider is in a contracted state. + /// + public LocalisableString ContractedLabelText + { + get => contractedLabelText; + set + { + if (value == contractedLabelText) + return; + + contractedLabelText = value; + + if (!Expanded.Value) + Text = value; + } + } + + private LocalisableString expandedLabelText; + + /// + /// The label text to display when this slider is in an expanded state. + /// + public LocalisableString ExpandedLabelText + { + get => expandedLabelText; + set + { + if (value == expandedLabelText) + return; + + expandedLabelText = value; + + if (Expanded.Value) + Text = value; + } + } + public BindableBool Expanded { get; } = new BindableBool(); [Resolved(canBeNull: true)] @@ -26,10 +77,24 @@ namespace osu.Game.Rulesets.Edit Expanded.BindValueChanged(expanded => { + Text = expanded.NewValue ? expandedLabelText : contractedLabelText; + if (expanded.NewValue) - Show(); + { + SpriteText.Anchor = Anchor.Centre; + SpriteText.Origin = Anchor.Centre; + SpriteText.Font = OsuFont.GetFont(weight: FontWeight.Bold); + base.Height = actualHeight; + Background.Show(); + } else - Hide(); + { + SpriteText.Anchor = Anchor.CentreLeft; + SpriteText.Origin = Anchor.CentreLeft; + SpriteText.Font = OsuFont.GetFont(weight: FontWeight.Regular); + base.Height = SpriteText.DrawHeight; + Background.Hide(); + } }, true); } } From 15aeb4a137c91274b9e7d964917db3d0df576938 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 21 Oct 2022 17:25:41 +0300 Subject: [PATCH 0172/2991] Display text in buttons flow instead of toast --- .../Visual/Online/TestSceneCommentActions.cs | 1 - osu.Game/Overlays/Comments/DrawableComment.cs | 19 ++++++++----------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs index a2e0c90c4c..b4ffcd42b5 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs @@ -276,7 +276,6 @@ namespace osu.Game.Tests.Visual.Online AddStep("Complete request", () => requestLock.Set()); AddUntilStep("Request sent", () => request != null); AddAssert("Request is correct", () => request != null && request.CommentID == 2 && request.Comment == report_text && request.Reason == CommentReportReason.Other); - AddUntilStep("Button expired", () => !targetComment.ChildrenOfType().Any()); } private void addTestComments() diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 199f678be1..4d4ed06200 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -24,7 +24,6 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Framework.Platform; using osu.Game.Graphics.UserInterface; -using osu.Game.Localisation; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Comments.Buttons; @@ -426,9 +425,8 @@ namespace osu.Game.Overlays.Comments request.Success += () => Schedule(() => { actionsLoading.Hide(); - reportButton?.Expire(); + reportButton?.MarkReported(); actionsContainer.Show(); - onScreenDisplay?.Display(new ReportToast()); }); request.Failure += _ => Schedule(() => { @@ -586,14 +584,6 @@ namespace osu.Game.Overlays.Comments } } - private class ReportToast : Toast - { - public ReportToast() - : base(UserInterfaceStrings.GeneralHeader, UsersStrings.ReportThanks, "") - { - } - } - internal class ReportButton : LinkFlowContainer, IHasPopover { public ReportButton() @@ -611,6 +601,13 @@ namespace osu.Game.Overlays.Comments AddLink(UsersStrings.ReportButtonText, this.ShowPopover); } + public void MarkReported() + { + Clear(true); + AddText(UsersStrings.ReportThanks); + this.Delay(3000).Then().FadeOut(2000); + } + public Popover GetPopover() => new ReportCommentPopover(comment); } } From bb921ff9a76e2e608e97b1d6c571454337c00ab6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2022 23:35:47 +0900 Subject: [PATCH 0173/2991] Fix incorrect current DS value when inside a slider --- osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index 9ef8480b25..4a7e0828cd 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -106,7 +106,7 @@ namespace osu.Game.Rulesets.Edit private (HitObject before, HitObject after)? getObjectsOnEitherSideOfCurrentTime() { - HitObject lastBefore = Playfield.HitObjectContainer.AliveObjects.LastOrDefault(h => h.HitObject.GetEndTime() <= EditorClock.CurrentTime)?.HitObject; + HitObject lastBefore = Playfield.HitObjectContainer.AliveObjects.LastOrDefault(h => h.HitObject.StartTime <= EditorClock.CurrentTime)?.HitObject; if (lastBefore == null) return null; From f516e32949d2b4c24bad95b2c57c2f95f5ef20dd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2022 23:35:53 +0900 Subject: [PATCH 0174/2991] Improve UI a bit --- .../Rulesets/Edit/DistancedHitObjectComposer.cs | 15 +++++++++------ osu.Game/Rulesets/Edit/ExpandableButton.cs | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index 4a7e0828cd..9a65570e72 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -94,6 +94,7 @@ namespace osu.Game.Rulesets.Edit Debug.Assert(objects != null); DistanceSpacingMultiplier.Value = ReadCurrentDistanceSnap(objects.Value.before, objects.Value.after); + // TODO: This should probably also force distance spacing grid on. }, RelativeSizeAxes = Axes.X, } @@ -130,20 +131,22 @@ namespace osu.Game.Rulesets.Edit (HitObject before, HitObject after)? objects = getObjectsOnEitherSideOfCurrentTime(); - if (objects != null) - { - double currentSnap = ReadCurrentDistanceSnap(objects.Value.before, objects.Value.after); + double currentSnap = objects == null + ? 0 + : ReadCurrentDistanceSnap(objects.Value.before, objects.Value.after); + if (currentSnap > DistanceSpacingMultiplier.MinValue) + { currentDistanceSpacingButton.Enabled.Value = currentDistanceSpacingButton.Expanded.Value && !Precision.AlmostEquals(currentSnap, DistanceSpacingMultiplier.Value, DistanceSpacingMultiplier.Precision / 2); - currentDistanceSpacingButton.ContractedLabelText = $"(current {currentSnap:N2}x)"; + currentDistanceSpacingButton.ContractedLabelText = $"current {currentSnap:N2}x"; currentDistanceSpacingButton.ExpandedLabelText = $"Use current ({currentSnap:N2}x)"; } else { currentDistanceSpacingButton.Enabled.Value = false; - currentDistanceSpacingButton.ContractedLabelText = "Current N/A"; - currentDistanceSpacingButton.ExpandedLabelText = "Use current (N/A)"; + currentDistanceSpacingButton.ContractedLabelText = string.Empty; + currentDistanceSpacingButton.ExpandedLabelText = "Use current (unavailable)"; } } diff --git a/osu.Game/Rulesets/Edit/ExpandableButton.cs b/osu.Game/Rulesets/Edit/ExpandableButton.cs index 572ae19a03..5b60a2536d 100644 --- a/osu.Game/Rulesets/Edit/ExpandableButton.cs +++ b/osu.Game/Rulesets/Edit/ExpandableButton.cs @@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Edit SpriteText.Anchor = Anchor.CentreLeft; SpriteText.Origin = Anchor.CentreLeft; SpriteText.Font = OsuFont.GetFont(weight: FontWeight.Regular); - base.Height = SpriteText.DrawHeight; + base.Height = actualHeight / 2; Background.Hide(); } }, true); From c1ed775deb3a14a4344bc0b177b65baaa99f2d4e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2022 23:36:16 +0900 Subject: [PATCH 0175/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 50fb1c4eda..b036d3d177 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 42da129195..b64d135ab8 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index d883ce0045..06fac451ad 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From 678bfb2caa67d779d052ae70d61401d66bb912bf Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 21 Oct 2022 20:56:18 +0300 Subject: [PATCH 0176/2991] Ban `char.ToLower()`/`char.ToUpper()` as well for better safety --- CodeAnalysis/BannedSymbols.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CodeAnalysis/BannedSymbols.txt b/CodeAnalysis/BannedSymbols.txt index 022da0a2ea..03fd21829d 100644 --- a/CodeAnalysis/BannedSymbols.txt +++ b/CodeAnalysis/BannedSymbols.txt @@ -15,6 +15,8 @@ M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Collections.Gen M:System.Threading.Tasks.Task.Wait();Don't use Task.Wait. Use Task.WaitSafely() to ensure we avoid deadlocks. P:System.Threading.Tasks.Task`1.Result;Don't use Task.Result. Use Task.GetResultSafely() to ensure we avoid deadlocks. M:System.Threading.ManualResetEventSlim.Wait();Specify a timeout to avoid waiting forever. +M:System.Char.ToLower(System.Char);char.ToLower() changes behaviour depending on CultureInfo.CurrentCulture. Use char.ToLowerInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture. +M:System.Char.ToUpper(System.Char);char.ToUpper() changes behaviour depending on CultureInfo.CurrentCulture. Use char.ToUpperInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture. M:System.String.ToLower();string.ToLower() changes behaviour depending on CultureInfo.CurrentCulture. Use string.ToLowerInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture or use LocalisableString. M:System.String.ToUpper();string.ToUpper() changes behaviour depending on CultureInfo.CurrentCulture. Use string.ToUpperInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture or use LocalisableString. M:Humanizer.InflectorExtensions.Pascalize(System.String);Humanizer's .Pascalize() extension method changes behaviour depending on CultureInfo.CurrentCulture. Use StringDehumanizeExtensions.ToPascalCase() instead. From 081cf1cc47c5ad775840ab1227bbb85808477ad1 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 22 Oct 2022 02:45:28 +0300 Subject: [PATCH 0177/2991] Adjust comment report popover design --- osu.Game/Overlays/Comments/ReportCommentPopover.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index 202f27777d..f3d6e319bf 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -39,6 +39,13 @@ namespace osu.Game.Overlays.Comments Spacing = new Vector2(7), Children = new Drawable[] { + new SpriteIcon + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Icon = FontAwesome.Solid.ExclamationTriangle, + Size = new Vector2(36), + }, new OsuSpriteText { Origin = Anchor.TopCentre, @@ -52,7 +59,6 @@ namespace osu.Game.Overlays.Comments Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, Text = UsersStrings.ReportReason, - Font = OsuFont.Torus.With(size: 20), }, new Container { @@ -68,7 +74,6 @@ namespace osu.Game.Overlays.Comments Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, Text = UsersStrings.ReportComments, - Font = OsuFont.Torus.With(size: 20), }, new OsuTextBox { From 9b5e35d5992985722ddf8576500c6d69040c3998 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 22 Oct 2022 02:45:06 +0300 Subject: [PATCH 0178/2991] Remove dependency on `DrawableComment` from report popover and simplify logic Allows for testing the button and popover in isolation. --- .../Overlays/Comments/ReportCommentPopover.cs | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index f3d6e319bf..39fd52aa2a 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -1,16 +1,18 @@ // 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.Allocation; -using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Resources.Localisation.Web; using osuTK; @@ -18,12 +20,15 @@ namespace osu.Game.Overlays.Comments { public class ReportCommentPopover : OsuPopover { - private readonly DrawableComment comment; - private OsuEnumDropdown reason = null!; - private readonly Bindable commentText = new Bindable(); + public Action? Action; + + private readonly Comment? comment; + + private OsuEnumDropdown reasonDropdown = null!; + private OsuTextBox commentsTextBox = null!; private RoundedButton submitButton = null!; - public ReportCommentPopover(DrawableComment comment) + public ReportCommentPopover(Comment? comment) { this.comment = comment; } @@ -50,7 +55,7 @@ namespace osu.Game.Overlays.Comments { Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, - Text = ReportStrings.CommentTitle(comment.Comment.User?.Username ?? comment.Comment.LegacyName!), + Text = ReportStrings.CommentTitle(comment?.User?.Username ?? comment?.LegacyName ?? @"Someone"), Font = OsuFont.Torus.With(size: 25), Margin = new MarginPadding { Bottom = 10 } }, @@ -64,7 +69,7 @@ namespace osu.Game.Overlays.Comments { RelativeSizeAxes = Axes.X, Height = 40, - Child = reason = new OsuEnumDropdown + Child = reasonDropdown = new OsuEnumDropdown { RelativeSizeAxes = Axes.X } @@ -75,11 +80,10 @@ namespace osu.Game.Overlays.Comments Anchor = Anchor.TopCentre, Text = UsersStrings.ReportComments, }, - new OsuTextBox + commentsTextBox = new OsuTextBox { RelativeSizeAxes = Axes.X, PlaceholderText = UsersStrings.ReportPlaceholder, - Current = commentText }, submitButton = new RoundedButton { @@ -88,24 +92,20 @@ namespace osu.Game.Overlays.Comments Width = 200, BackgroundColour = colours.Red3, Text = UsersStrings.ReportActionsSend, - Action = send, + Action = () => + { + Action?.Invoke(reasonDropdown.Current.Value, commentsTextBox.Text); + this.HidePopover(); + }, Margin = new MarginPadding { Bottom = 5, Top = 10 }, } } }; - commentText.BindValueChanged(e => + + commentsTextBox.Current.BindValueChanged(e => { submitButton.Enabled.Value = !string.IsNullOrWhiteSpace(e.NewValue); }, true); } - - private void send() - { - if (string.IsNullOrWhiteSpace(commentText.Value)) - return; - - this.HidePopover(); - comment.ReportComment(reason.Current.Value, commentText.Value); - } } } From 6c82bc36ed703bbfb6a4567baeea669375bfed0c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 22 Oct 2022 02:47:11 +0300 Subject: [PATCH 0179/2991] Encapsulate report logic inside button implementation Avoids complicating the `DrawableComment` class, and allows for isolated testability. --- .../Overlays/Comments/CommentReportButton.cs | 91 +++++++++++++++++++ osu.Game/Overlays/Comments/DrawableComment.cs | 51 +---------- 2 files changed, 92 insertions(+), 50 deletions(-) create mode 100644 osu.Game/Overlays/Comments/CommentReportButton.cs diff --git a/osu.Game/Overlays/Comments/CommentReportButton.cs b/osu.Game/Overlays/Comments/CommentReportButton.cs new file mode 100644 index 0000000000..4f5c5c6dcf --- /dev/null +++ b/osu.Game/Overlays/Comments/CommentReportButton.cs @@ -0,0 +1,91 @@ +// 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.Allocation; +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Resources.Localisation.Web; +using osuTK; + +namespace osu.Game.Overlays.Comments +{ + public class CommentReportButton : CompositeDrawable, IHasPopover + { + private readonly Comment comment; + + private LinkFlowContainer link = null!; + private LoadingSpinner loading = null!; + + [Resolved] + private IAPIProvider api { get; set; } = null!; + + [Resolved] + private OverlayColourProvider? colourProvider { get; set; } + + public CommentReportButton(Comment comment) + { + this.comment = comment; + } + + [BackgroundDependencyLoader] + private void load() + { + AutoSizeAxes = Axes.Both; + + InternalChildren = new Drawable[] + { + link = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold)) + { + AutoSizeAxes = Axes.Both, + }, + loading = new LoadingSpinner + { + Size = new Vector2(12f), + } + }; + + link.AddLink(UsersStrings.ReportButtonText, this.ShowPopover); + } + + private void report(CommentReportReason reason, string comments) + { + var request = new CommentReportRequest(comment.Id, reason, comments); + + link.Hide(); + loading.Show(); + + request.Success += () => Schedule(() => + { + loading.Hide(); + + link.Clear(true); + link.AddText(UsersStrings.ReportThanks, s => s.Colour = colourProvider?.Content2 ?? Colour4.White); + link.Show(); + + this.FadeOut(2000, Easing.InQuint).Expire(); + }); + + request.Failure += _ => Schedule(() => + { + loading.Hide(); + link.Show(); + }); + + api.Queue(request); + } + + public Popover GetPopover() => new ReportCommentPopover(comment) + { + Action = report + }; + } +} diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 4d4ed06200..aa08de798c 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -19,8 +19,6 @@ using System; using osu.Framework.Graphics.Shapes; using osu.Framework.Extensions.IEnumerableExtensions; using System.Collections.Specialized; -using osu.Framework.Extensions; -using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Framework.Platform; using osu.Game.Graphics.UserInterface; @@ -64,7 +62,6 @@ namespace osu.Game.Overlays.Comments private ShowRepliesButton showRepliesButton = null!; private ChevronButton chevronButton = null!; private LinkFlowContainer actionsContainer = null!; - private ReportButton? reportButton; private LoadingSpinner actionsLoading = null!; private DeletedCommentsCounter deletedCommentsCounter = null!; private OsuSpriteText deletedLabel = null!; @@ -340,7 +337,7 @@ namespace osu.Game.Overlays.Comments if (Comment.UserId.HasValue && Comment.UserId.Value == api.LocalUser.Value.Id) actionsContainer.AddLink("Delete", deleteComment); else - actionsContainer.AddArbitraryDrawable(reportButton = new ReportButton()); + actionsContainer.AddArbitraryDrawable(new CommentReportButton(Comment)); if (Comment.IsTopLevel) { @@ -417,25 +414,6 @@ namespace osu.Game.Overlays.Comments api.Queue(request); } - public void ReportComment(CommentReportReason reason, string comment) - { - actionsContainer.Hide(); - actionsLoading.Show(); - var request = new CommentReportRequest(Comment.Id, reason, comment); - request.Success += () => Schedule(() => - { - actionsLoading.Hide(); - reportButton?.MarkReported(); - actionsContainer.Show(); - }); - request.Failure += _ => Schedule(() => - { - actionsLoading.Hide(); - actionsContainer.Show(); - }); - api.Queue(request); - } - private void copyUrl() { host.GetClipboard()?.SetText($@"{api.APIEndpointUrl}/comments/{Comment.Id}"); @@ -583,32 +561,5 @@ namespace osu.Game.Overlays.Comments return parentComment.HasMessage ? parentComment.Message : parentComment.IsDeleted ? "deleted" : string.Empty; } } - - internal class ReportButton : LinkFlowContainer, IHasPopover - { - public ReportButton() - : base(s => s.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold)) - { - } - - [Resolved] - private DrawableComment comment { get; set; } = null!; - - [BackgroundDependencyLoader] - private void load() - { - AutoSizeAxes = Axes.Both; - AddLink(UsersStrings.ReportButtonText, this.ShowPopover); - } - - public void MarkReported() - { - Clear(true); - AddText(UsersStrings.ReportThanks); - this.Delay(3000).Then().FadeOut(2000); - } - - public Popover GetPopover() => new ReportCommentPopover(comment); - } } } From 90a9961a69655de48b05ecef8de33146c09c564d Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 22 Oct 2022 02:47:23 +0300 Subject: [PATCH 0180/2991] Add visual test case for report button Makes it much easier to test button/popover design changes --- .../Online/TestSceneCommentReportButton.cs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneCommentReportButton.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentReportButton.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentReportButton.cs new file mode 100644 index 0000000000..fb56a41507 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentReportButton.cs @@ -0,0 +1,46 @@ +// 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.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Testing; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays.Comments; +using osu.Game.Tests.Visual.UserInterface; +using osuTK; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneCommentReportButton : ThemeComparisonTestScene + { + [SetUpSteps] + public void SetUpSteps() + { + AddStep("setup API", () => ((DummyAPIAccess)API).HandleRequest += req => + { + switch (req) + { + case CommentReportRequest report: + Scheduler.AddDelayed(report.TriggerSuccess, 1000); + return true; + } + + return false; + }); + } + + protected override Drawable CreateContent() => new PopoverContainer + { + RelativeSizeAxes = Axes.Both, + Child = new CommentReportButton(new Comment { User = new APIUser { Username = "Someone" } }) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Scale = new Vector2(2f), + }.With(b => Schedule(b.ShowPopover)), + }; + } +} From b0a4cd4f30e65ce7e04884f986c9d2c8f2501912 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 22 Oct 2022 03:43:14 +0300 Subject: [PATCH 0181/2991] Inline content creation in base add method --- osu.Game/Overlays/Changelog/ChangelogContent.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogContent.cs b/osu.Game/Overlays/Changelog/ChangelogContent.cs index dca2f3b1b0..2b54df7226 100644 --- a/osu.Game/Overlays/Changelog/ChangelogContent.cs +++ b/osu.Game/Overlays/Changelog/ChangelogContent.cs @@ -23,13 +23,13 @@ namespace osu.Game.Overlays.Changelog { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - Content = new FillFlowContainer + + base.Content.Add(Content = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical - }; - base.Content.Add(Content); + }); } } } From 3d37a67590f866bc43a26c69a2be15ca1938279e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 22 Oct 2022 14:15:17 +0900 Subject: [PATCH 0182/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index b036d3d177..152e050805 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b64d135ab8..bd8c915f5f 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 06fac451ad..1a3f9dbe67 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From 9155fcf3cb8cb71eaae196b8962f136c54fc8bd7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 22 Oct 2022 23:25:08 +0900 Subject: [PATCH 0183/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 152e050805..f251e8ee71 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index bd8c915f5f..e0561d9b21 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 1a3f9dbe67..cf70b65578 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From a74e873b983678993ca7d3c4c6d20468d052e9b7 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 23 Oct 2022 01:13:29 +0900 Subject: [PATCH 0184/2991] remove useless using --- osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs b/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs index 57c45fc074..161799c980 100644 --- a/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs +++ b/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Tools; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Screens.Edit.Compose.Components; From f14d871f97375bdff5f1eada82facd6b5e8ea6f3 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 23 Oct 2022 01:32:22 +0900 Subject: [PATCH 0185/2991] let TaikoSpan show in timeline before placed --- .../Edit/Blueprints/TaikoSpanPlacementBlueprint.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs index 23a005190a..70364cabf1 100644 --- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs @@ -52,6 +52,12 @@ namespace osu.Game.Rulesets.Taiko.Edit.Blueprints private double originalStartTime; private Vector2 originalPosition; + protected override void LoadComplete() + { + base.LoadComplete(); + BeginPlacement(); + } + protected override bool OnMouseDown(MouseDownEvent e) { if (e.Button != MouseButton.Left) From f4db2c1ff421588f3896f8e26bcb43da082179a7 Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Sat, 22 Oct 2022 22:38:04 +0200 Subject: [PATCH 0186/2991] Add test --- .../TestSceneControlPointConversion.cs | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko.Tests/TestSceneControlPointConversion.cs diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneControlPointConversion.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneControlPointConversion.cs new file mode 100644 index 0000000000..e2ec41ce21 --- /dev/null +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneControlPointConversion.cs @@ -0,0 +1,38 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.Objects; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Taiko.Tests +{ + public class TestSceneControlPointConversion : OsuTestScene + { + [Test] + public void TestSceneScrollSpeedConversion() + { + const double start_time = 1000; + const double slider_velocity = 10; + + var beatmap = new Beatmap + { + HitObjects = + { + new HitObject + { + StartTime = start_time, + DifficultyControlPoint = new DifficultyControlPoint { SliderVelocity = slider_velocity } + } + }, + BeatmapInfo = { Ruleset = { OnlineID = 0 } }, + }; + + var convertedBeatmap = new TaikoRuleset().CreateBeatmapConverter(beatmap).Convert(); + + AddAssert("effect point generated", () => convertedBeatmap.ControlPointInfo.EffectPointAt(start_time).ScrollSpeed == slider_velocity); + } + } +} From e8960ba53b25c33dae8822598180c3fb189397e8 Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Sat, 22 Oct 2022 22:46:19 +0200 Subject: [PATCH 0187/2991] whitespace removal --- .../TestSceneControlPointConversion.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneControlPointConversion.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneControlPointConversion.cs index e2ec41ce21..72763421cc 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneControlPointConversion.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneControlPointConversion.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Taiko.Tests }; var convertedBeatmap = new TaikoRuleset().CreateBeatmapConverter(beatmap).Convert(); - + AddAssert("effect point generated", () => convertedBeatmap.ControlPointInfo.EffectPointAt(start_time).ScrollSpeed == slider_velocity); } } From a35026d537faf39e902a541f5b6ed284e507aba1 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Sat, 22 Oct 2022 23:29:44 +0200 Subject: [PATCH 0188/2991] Downgrade AutoMapper to fix Android startup crash --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index e0561d9b21..22474c0592 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,7 +18,7 @@ - + From 889c2978d7a95ea864c584db8bd61d81dc615f04 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 24 Oct 2022 13:13:40 +0900 Subject: [PATCH 0189/2991] Fix point conversion not using invariant culture This was only the case in a fallback path (ie. when the user provides a `json` file with an old or computed format from an external source). Closes #20844. --- osu.Game.Tournament/JsonPointConverter.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tournament/JsonPointConverter.cs b/osu.Game.Tournament/JsonPointConverter.cs index db48c36c99..d3b40a3526 100644 --- a/osu.Game.Tournament/JsonPointConverter.cs +++ b/osu.Game.Tournament/JsonPointConverter.cs @@ -6,6 +6,7 @@ using System; using System.Diagnostics; using System.Drawing; +using System.Globalization; using Newtonsoft.Json; namespace osu.Game.Tournament @@ -31,7 +32,9 @@ namespace osu.Game.Tournament Debug.Assert(str != null); - return new PointConverter().ConvertFromString(str) as Point? ?? new Point(); + // Null check suppression is required due to .NET standard expecting a non-null context. + // Seems to work fine at a runtime level (and the parameter is nullable in .NET 6+). + return new PointConverter().ConvertFromString(null!, CultureInfo.InvariantCulture, str) as Point? ?? new Point(); } var point = new Point(); From e9b3048a8bca903f35bf483a02a4972c64934fc1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 24 Oct 2022 13:58:00 +0900 Subject: [PATCH 0190/2991] Change the order of global bindings to give overlays lowest priority --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index ad53f6d90f..4a233e5bf3 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -31,14 +31,17 @@ namespace osu.Game.Input.Bindings parentInputManager = GetContainingInputManager(); } - // IMPORTANT: Do not change the order of key bindings in this list. - // It is used to decide the order of precedence (see note in DatabasedKeyBindingContainer). + // IMPORTANT: Take care when changing order of the items in the enumerable. + // It is used to decide the order of precedence, with the earlier items having higher precedence. public override IEnumerable DefaultKeyBindings => GlobalKeyBindings - .Concat(OverlayKeyBindings) .Concat(EditorKeyBindings) .Concat(InGameKeyBindings) .Concat(SongSelectKeyBindings) - .Concat(AudioControlKeyBindings); + .Concat(AudioControlKeyBindings) + // Overlay bindings may conflict with more local cases like the editor so they are checked last. + // It has generally been agreed on that local screens like the editor should have priority, + // based on such usages potentially requiring a lot more key bindings that may be "shared" with global ones. + .Concat(OverlayKeyBindings); public IEnumerable GlobalKeyBindings => new[] { From e72a71a28e9d25f0133592a8a24af3fe29fe3318 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 24 Oct 2022 13:58:11 +0900 Subject: [PATCH 0191/2991] Add simple editor "duplicate objects" key binding --- .../Input/Bindings/GlobalActionContainer.cs | 4 ++++ .../GlobalActionKeyBindingStrings.cs | 5 ++++ osu.Game/Screens/Edit/Editor.cs | 23 ++++++++++++++++++- 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 4a233e5bf3..476fda81b7 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -90,6 +90,7 @@ namespace osu.Game.Input.Bindings new KeyBinding(new[] { InputKey.F3 }, GlobalAction.EditorTimingMode), new KeyBinding(new[] { InputKey.F4 }, GlobalAction.EditorSetupMode), new KeyBinding(new[] { InputKey.Control, InputKey.Shift, InputKey.A }, GlobalAction.EditorVerifyMode), + new KeyBinding(new[] { InputKey.Control, InputKey.D }, GlobalAction.EditorDuplicateSelection), new KeyBinding(new[] { InputKey.J }, GlobalAction.EditorNudgeLeft), new KeyBinding(new[] { InputKey.K }, GlobalAction.EditorNudgeRight), new KeyBinding(new[] { InputKey.G }, GlobalAction.EditorCycleGridDisplayMode), @@ -346,5 +347,8 @@ namespace osu.Game.Input.Bindings [LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.ToggleProfile))] ToggleProfile, + + [LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.EditorDuplicateSelection))] + EditorDuplicateSelection } } diff --git a/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs b/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs index 172818c1c0..403fa8017a 100644 --- a/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs +++ b/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs @@ -184,6 +184,11 @@ namespace osu.Game.Localisation /// public static LocalisableString EditorTapForBPM => new TranslatableString(getKey(@"editor_tap_for_bpm"), @"Tap for BPM"); + /// + /// "Duplicate selection" + /// + public static LocalisableString EditorDuplicateSelection => new TranslatableString(getKey(@"editor_duplicate_selection"), @"Duplicate selection"); + /// /// "Cycle grid display mode" /// diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 3dfc7010f3..51f2ca16c2 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -304,6 +304,7 @@ namespace osu.Game.Screens.Edit cutMenuItem = new EditorMenuItem("Cut", MenuItemType.Standard, Cut), copyMenuItem = new EditorMenuItem("Copy", MenuItemType.Standard, Copy), pasteMenuItem = new EditorMenuItem("Paste", MenuItemType.Standard, Paste), + duplicateMenuItem = new EditorMenuItem("Duplicate", MenuItemType.Standard, Duplicate), } }, new MenuItem("View") @@ -575,6 +576,10 @@ namespace osu.Game.Screens.Edit this.Exit(); return true; + case GlobalAction.EditorDuplicateSelection: + Duplicate(); + return true; + case GlobalAction.EditorComposeMode: Mode.Value = EditorScreenMode.Compose; return true; @@ -741,6 +746,7 @@ namespace osu.Game.Screens.Edit private EditorMenuItem cutMenuItem; private EditorMenuItem copyMenuItem; + private EditorMenuItem duplicateMenuItem; private EditorMenuItem pasteMenuItem; private readonly BindableWithCurrent canCut = new BindableWithCurrent(); @@ -750,7 +756,11 @@ namespace osu.Game.Screens.Edit private void setUpClipboardActionAvailability() { canCut.Current.BindValueChanged(cut => cutMenuItem.Action.Disabled = !cut.NewValue, true); - canCopy.Current.BindValueChanged(copy => copyMenuItem.Action.Disabled = !copy.NewValue, true); + canCopy.Current.BindValueChanged(copy => + { + copyMenuItem.Action.Disabled = !copy.NewValue; + duplicateMenuItem.Action.Disabled = !copy.NewValue; + }, true); canPaste.Current.BindValueChanged(paste => pasteMenuItem.Action.Disabled = !paste.NewValue, true); } @@ -765,6 +775,17 @@ namespace osu.Game.Screens.Edit protected void Copy() => currentScreen?.Copy(); + protected void Duplicate() + { + // This is an initial implementation just to get an idea of how people used this function. + // There are a couple of differences from osu!stable's implementation which will require more work to match: + // - The "clipboard" is not populated during the duplication process. + // - The duplicated hitobjects are inserted after the original pattern (add one beat_length and then quantize using beat snap). + // - The duplicated hitobjects are selected (but this is also applied for all paste operations so should be changed there). + Copy(); + Paste(); + } + protected void Paste() => currentScreen?.Paste(); #endregion From d0e6bda9ef52dbf0a53d4c9685cc8c7c35535ad5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 24 Oct 2022 15:19:36 +0900 Subject: [PATCH 0192/2991] Stop `HitObjectComposer` from handling `Shift`+`Number` keys --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 3bed835854..520fcb0290 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -238,7 +238,7 @@ namespace osu.Game.Rulesets.Edit protected override bool OnKeyDown(KeyDownEvent e) { - if (e.ControlPressed || e.AltPressed || e.SuperPressed) + if (e.ControlPressed || e.AltPressed || e.SuperPressed || e.ShiftPressed) return false; if (checkLeftToggleFromKey(e.Key, out int leftIndex)) From 1d5df150272056da2780dd6ab06ad8923da5e5ae Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 24 Oct 2022 15:20:15 +0900 Subject: [PATCH 0193/2991] Add ability to use `Shift`+`Number` to set current beat divisor in editor --- osu.Game/Screens/Edit/BindableBeatDivisor.cs | 20 ++++++++++++++++ .../Compose/Components/BeatDivisorControl.cs | 23 ++++++++++--------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Edit/BindableBeatDivisor.cs b/osu.Game/Screens/Edit/BindableBeatDivisor.cs index a7faf961cf..aa8e202e22 100644 --- a/osu.Game/Screens/Edit/BindableBeatDivisor.cs +++ b/osu.Game/Screens/Edit/BindableBeatDivisor.cs @@ -25,6 +25,26 @@ namespace osu.Game.Screens.Edit BindValueChanged(_ => ensureValidDivisor()); } + /// + /// Set a divisor, updating the valid divisor range appropriately. + /// + /// The intended divisor. + public void SetArbitraryDivisor(int divisor) + { + // If the current valid divisor range doesn't contain the proposed value, attempt to find one which does. + if (!ValidDivisors.Value.Presets.Contains(divisor)) + { + if (BeatDivisorPresetCollection.COMMON.Presets.Contains(divisor)) + ValidDivisors.Value = BeatDivisorPresetCollection.COMMON; + else if (BeatDivisorPresetCollection.TRIPLETS.Presets.Contains(divisor)) + ValidDivisors.Value = BeatDivisorPresetCollection.TRIPLETS; + else + ValidDivisors.Value = BeatDivisorPresetCollection.Custom(divisor); + } + + Value = divisor; + } + private void updateBindableProperties() { ensureValidDivisor(); diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs index 19ea2162a3..6dca799549 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs @@ -209,6 +209,17 @@ namespace osu.Game.Screens.Edit.Compose.Components } } + protected override bool OnKeyDown(KeyDownEvent e) + { + if (e.ShiftPressed && e.Key >= Key.Number1 && e.Key <= Key.Number9) + { + beatDivisor.SetArbitraryDivisor(e.Key - Key.Number0); + return true; + } + + return base.OnKeyDown(e); + } + internal class DivisorDisplay : OsuAnimatedButton, IHasPopover { public BindableBeatDivisor BeatDivisor { get; } = new BindableBeatDivisor(); @@ -306,17 +317,7 @@ namespace osu.Game.Screens.Edit.Compose.Components return; } - if (!BeatDivisor.ValidDivisors.Value.Presets.Contains(divisor)) - { - if (BeatDivisorPresetCollection.COMMON.Presets.Contains(divisor)) - BeatDivisor.ValidDivisors.Value = BeatDivisorPresetCollection.COMMON; - else if (BeatDivisorPresetCollection.TRIPLETS.Presets.Contains(divisor)) - BeatDivisor.ValidDivisors.Value = BeatDivisorPresetCollection.TRIPLETS; - else - BeatDivisor.ValidDivisors.Value = BeatDivisorPresetCollection.Custom(divisor); - } - - BeatDivisor.Value = divisor; + BeatDivisor.SetArbitraryDivisor(divisor); this.HidePopover(); } From f08270f6b06945f6f86655d36861ed7bf54aaef5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 24 Oct 2022 15:54:09 +0900 Subject: [PATCH 0194/2991] Fix incorrect `maxBaseScore` accounting due to silly oversight --- osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs index ec98d00e68..f8b5085a70 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs @@ -191,7 +191,7 @@ namespace osu.Game.Tests.Visual.Gameplay void applyHitV2(int baseScore) { - maxBaseScore += baseScore; + maxBaseScore += base_great; currentBaseScore += baseScore; comboPortion += baseScore * (1 + ++currentCombo / 10.0); From 14704fd07cdaa6fe51482ceb56a29f7ae33c5a2d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 24 Oct 2022 16:08:49 +0900 Subject: [PATCH 0195/2991] Fix crash when exiting seeding editor too soon Closes https://github.com/ppy/osu/issues/20783. --- .../Screens/Editors/SeedingEditorScreen.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs index 1bc929604d..348661e2a3 100644 --- a/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs @@ -239,17 +239,17 @@ namespace osu.Game.Tournament.Screens.Editors var req = new GetBeatmapRequest(new APIBeatmap { OnlineID = Model.ID }); - req.Success += res => + req.Success += res => Schedule(() => { Model.Beatmap = new TournamentBeatmap(res); updatePanel(); - }; + }); - req.Failure += _ => + req.Failure += _ => Schedule(() => { Model.Beatmap = null; updatePanel(); - }; + }); API.Queue(req); }, true); From de881cc5cb44829ce9fdc1f468f28000869081bd Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Mon, 24 Oct 2022 23:17:28 +0900 Subject: [PATCH 0196/2991] useless #nullable disable --- osu.Game/Screens/Edit/Components/Menus/DifficultyMenuItem.cs | 2 -- osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs | 2 -- osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs | 2 -- osu.Game/Screens/Edit/Components/Menus/EditorMenuItemSpacer.cs | 2 -- 4 files changed, 8 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/Menus/DifficultyMenuItem.cs b/osu.Game/Screens/Edit/Components/Menus/DifficultyMenuItem.cs index e14354222b..6af3ba908d 100644 --- a/osu.Game/Screens/Edit/Components/Menus/DifficultyMenuItem.cs +++ b/osu.Game/Screens/Edit/Components/Menus/DifficultyMenuItem.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs index 8321fde171..20b8bba6da 100644 --- a/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.UserInterface; diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs b/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs index 1085f2c277..0a2c073dcd 100644 --- a/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs +++ b/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Game.Graphics.UserInterface; diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorMenuItemSpacer.cs b/osu.Game/Screens/Edit/Components/Menus/EditorMenuItemSpacer.cs index 6af3b99017..4e75a92e19 100644 --- a/osu.Game/Screens/Edit/Components/Menus/EditorMenuItemSpacer.cs +++ b/osu.Game/Screens/Edit/Components/Menus/EditorMenuItemSpacer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Screens.Edit.Components.Menus { public class EditorMenuItemSpacer : EditorMenuItem From a2682b3ce39ddf9fc3e6c311206520c4e4d8472b Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Mon, 24 Oct 2022 23:18:34 +0900 Subject: [PATCH 0197/2991] background dim settings for editor View -> Background Dim follow `DimLevel` and `BlurLevel` Co-Authored-By: Dead_Bush_Sanpai --- osu.Game/Configuration/OsuConfigManager.cs | 2 ++ osu.Game/Screens/Edit/Editor.cs | 23 +++++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 1378e1691a..f8c851757e 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -122,6 +122,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.PositionalHitsoundsLevel, 0.2f, 0, 1); SetDefault(OsuSetting.DimLevel, 0.7, 0, 1, 0.01); SetDefault(OsuSetting.BlurLevel, 0, 0, 1, 0.01); + SetDefault(OsuSetting.EditorUseDim, false); SetDefault(OsuSetting.LightenDuringBreaks, true); SetDefault(OsuSetting.HitLighting, true); @@ -292,6 +293,7 @@ namespace osu.Game.Configuration GameplayCursorDuringTouch, DimLevel, BlurLevel, + EditorUseDim, LightenDuringBreaks, ShowStoryboard, KeyOverlay, diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 3dfc7010f3..9cfd1badd1 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -176,6 +176,8 @@ namespace osu.Game.Screens.Edit [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } + private Bindable useUserDim; + public Editor(EditorLoader loader = null) { this.loader = loader; @@ -260,6 +262,9 @@ namespace osu.Game.Screens.Edit OsuMenuItem undoMenuItem; OsuMenuItem redoMenuItem; + TernaryStateRadioMenuItem backgroundDim; + useUserDim = config.GetBindable(OsuSetting.EditorUseDim); + AddInternal(new OsuContextMenuContainer { RelativeSizeAxes = Axes.Both, @@ -311,6 +316,7 @@ namespace osu.Game.Screens.Edit Items = new MenuItem[] { new WaveformOpacityMenuItem(config.GetBindable(OsuSetting.EditorWaveformOpacity)), + backgroundDim = new TernaryStateRadioMenuItem("Background Dim", MenuItemType.Standard, _ => useUserDim.Value = !useUserDim.Value), } } } @@ -330,6 +336,13 @@ namespace osu.Game.Screens.Edit changeHandler?.CanUndo.BindValueChanged(v => undoMenuItem.Action.Disabled = !v.NewValue, true); changeHandler?.CanRedo.BindValueChanged(v => redoMenuItem.Action.Disabled = !v.NewValue, true); + + useUserDim.BindValueChanged(s => + { + dimBackground(); + backgroundDim.State.Value = s.NewValue ? TernaryState.True : TernaryState.False; + }); + backgroundDim.State.Value = useUserDim.Value ? TernaryState.True : TernaryState.False; } [Resolved] @@ -626,9 +639,9 @@ namespace osu.Game.Screens.Edit ApplyToBackground(b => { // todo: temporary. we want to be applying dim using the UserDimContainer eventually. - b.FadeColour(Color4.DarkGray, 500); + if (!useUserDim.Value) b.FadeColour(Color4.DarkGray, 500); - b.IgnoreUserSettings.Value = true; + b.IgnoreUserSettings.Value = !useUserDim.Value; b.BlurAmount.Value = 0; }); } @@ -656,7 +669,11 @@ namespace osu.Game.Screens.Edit } } - ApplyToBackground(b => b.FadeColour(Color4.White, 500)); + ApplyToBackground(b => + { + b.FadeColour(Color4.White, 500); + b.IgnoreUserSettings.Value = true; + }); resetTrack(); refetchBeatmap(); From 9def12c60bceb6c75a92f74be14aafd1d10b8fe6 Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Mon, 24 Oct 2022 22:50:56 +0300 Subject: [PATCH 0198/2991] Write new tests --- .../SongSelect/TestSceneBeatmapCarousel.cs | 103 ++++++++++-------- 1 file changed, 57 insertions(+), 46 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 0e72463d1e..303af61d20 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -827,6 +827,63 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep("remove single ruleset set", () => carousel.RemoveBeatmapSet(testSingle)); } + [Test] + public void TestCarouselSelectsNextWhenPreviousIsFiltered() + { + List sets = new List(); + + // 10 sets that go osu! -> taiko -> catch -> osu! -> ... + for (int i = 0; i < 10; i++) + { + var rulesetInfo = rulesets.AvailableRulesets.ElementAt(i % 3); + sets.Add(TestResources.CreateTestBeatmapSetInfo(5, new[] { rulesetInfo })); + } + + // Sort mode is important to keep the ruleset order + loadBeatmaps(sets, () => new FilterCriteria { Sort = SortMode.Title }); + setSelected(1, 1); + + for (int i = 1; i < 10; i++) + { + var rulesetInfo = rulesets.AvailableRulesets.ElementAt(i % 3); + AddStep($"Set ruleset to {rulesetInfo.ShortName}", () => + { + carousel.Filter(new FilterCriteria { Ruleset = rulesetInfo, Sort = SortMode.Title }, false); + }); + waitForSelection(i + 1, 1); + } + } + + [Test] + public void TestCarouselSelectsBackwardsWhenDistanceIsShorter() + { + List sets = new List(); + + // 10 sets that go taiko, osu!, osu!, osu!, taiko, osu!, osu!, osu!, ... + for (int i = 0; i < 10; i++) + { + var rulesetInfo = rulesets.AvailableRulesets.ElementAt(i % 4 == 0 ? 1 : 0); + sets.Add(TestResources.CreateTestBeatmapSetInfo(5, new[] { rulesetInfo })); + } + + // Sort mode is important to keep the ruleset order + loadBeatmaps(sets, () => new FilterCriteria { Sort = SortMode.Title }); + + for (int i = 2; i < 10; i += 4) + { + setSelected(i, 1); + AddStep("Set ruleset to taiko", () => + { + carousel.Filter(new FilterCriteria { Ruleset = rulesets.AvailableRulesets.ElementAt(1), Sort = SortMode.Title }, false); + }); + waitForSelection(i - 1, 1); + AddStep("Remove ruleset filter", () => + { + carousel.Filter(new FilterCriteria { Sort = SortMode.Title }, false); + }); + } + } + [Test] public void TestCarouselRemembersSelection() { @@ -862,52 +919,6 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("Selection was remembered", () => eagerSelectedIDs.Count == 1); } - [Test] - public void TestRandomFallbackOnNonMatchingPrevious() - { - List manySets = new List(); - - AddStep("populate maps", () => - { - manySets.Clear(); - - for (int i = 0; i < 10; i++) - { - manySets.Add(TestResources.CreateTestBeatmapSetInfo(3, new[] - { - // all taiko except for first - rulesets.GetRuleset(i > 0 ? 1 : 0) - })); - } - }); - - loadBeatmaps(manySets); - - for (int i = 0; i < 10; i++) - { - AddStep("Reset filter", () => carousel.Filter(new FilterCriteria(), false)); - - AddStep("select first beatmap", () => carousel.SelectBeatmap(manySets.First().Beatmaps.First())); - - AddStep("Toggle non-matching filter", () => - { - carousel.Filter(new FilterCriteria { SearchText = Guid.NewGuid().ToString() }, false); - }); - - AddAssert("selection lost", () => carousel.SelectedBeatmapInfo == null); - - AddStep("Restore different ruleset filter", () => - { - carousel.Filter(new FilterCriteria { Ruleset = rulesets.GetRuleset(1) }, false); - eagerSelectedIDs.Add(carousel.SelectedBeatmapSet!.ID); - }); - - AddAssert("selection changed", () => !carousel.SelectedBeatmapInfo!.Equals(manySets.First().Beatmaps.First())); - } - - AddAssert("Selection was random", () => eagerSelectedIDs.Count > 2); - } - [Test] public void TestFilteringByUserStarDifficulty() { From b95091fbb0a79bbb4d42a173c30354aabfb864a0 Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Mon, 24 Oct 2022 22:55:09 +0300 Subject: [PATCH 0199/2991] Move test to improve diff readability --- .../SongSelect/TestSceneBeatmapCarousel.cs | 114 +++++++++--------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 303af61d20..eacaf7f92e 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -827,63 +827,6 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep("remove single ruleset set", () => carousel.RemoveBeatmapSet(testSingle)); } - [Test] - public void TestCarouselSelectsNextWhenPreviousIsFiltered() - { - List sets = new List(); - - // 10 sets that go osu! -> taiko -> catch -> osu! -> ... - for (int i = 0; i < 10; i++) - { - var rulesetInfo = rulesets.AvailableRulesets.ElementAt(i % 3); - sets.Add(TestResources.CreateTestBeatmapSetInfo(5, new[] { rulesetInfo })); - } - - // Sort mode is important to keep the ruleset order - loadBeatmaps(sets, () => new FilterCriteria { Sort = SortMode.Title }); - setSelected(1, 1); - - for (int i = 1; i < 10; i++) - { - var rulesetInfo = rulesets.AvailableRulesets.ElementAt(i % 3); - AddStep($"Set ruleset to {rulesetInfo.ShortName}", () => - { - carousel.Filter(new FilterCriteria { Ruleset = rulesetInfo, Sort = SortMode.Title }, false); - }); - waitForSelection(i + 1, 1); - } - } - - [Test] - public void TestCarouselSelectsBackwardsWhenDistanceIsShorter() - { - List sets = new List(); - - // 10 sets that go taiko, osu!, osu!, osu!, taiko, osu!, osu!, osu!, ... - for (int i = 0; i < 10; i++) - { - var rulesetInfo = rulesets.AvailableRulesets.ElementAt(i % 4 == 0 ? 1 : 0); - sets.Add(TestResources.CreateTestBeatmapSetInfo(5, new[] { rulesetInfo })); - } - - // Sort mode is important to keep the ruleset order - loadBeatmaps(sets, () => new FilterCriteria { Sort = SortMode.Title }); - - for (int i = 2; i < 10; i += 4) - { - setSelected(i, 1); - AddStep("Set ruleset to taiko", () => - { - carousel.Filter(new FilterCriteria { Ruleset = rulesets.AvailableRulesets.ElementAt(1), Sort = SortMode.Title }, false); - }); - waitForSelection(i - 1, 1); - AddStep("Remove ruleset filter", () => - { - carousel.Filter(new FilterCriteria { Sort = SortMode.Title }, false); - }); - } - } - [Test] public void TestCarouselRemembersSelection() { @@ -966,6 +909,63 @@ namespace osu.Game.Tests.Visual.SongSelect checkVisibleItemCount(true, 15); } + [Test] + public void TestCarouselSelectsNextWhenPreviousIsFiltered() + { + List sets = new List(); + + // 10 sets that go osu! -> taiko -> catch -> osu! -> ... + for (int i = 0; i < 10; i++) + { + var rulesetInfo = rulesets.AvailableRulesets.ElementAt(i % 3); + sets.Add(TestResources.CreateTestBeatmapSetInfo(5, new[] { rulesetInfo })); + } + + // Sort mode is important to keep the ruleset order + loadBeatmaps(sets, () => new FilterCriteria { Sort = SortMode.Title }); + setSelected(1, 1); + + for (int i = 1; i < 10; i++) + { + var rulesetInfo = rulesets.AvailableRulesets.ElementAt(i % 3); + AddStep($"Set ruleset to {rulesetInfo.ShortName}", () => + { + carousel.Filter(new FilterCriteria { Ruleset = rulesetInfo, Sort = SortMode.Title }, false); + }); + waitForSelection(i + 1, 1); + } + } + + [Test] + public void TestCarouselSelectsBackwardsWhenDistanceIsShorter() + { + List sets = new List(); + + // 10 sets that go taiko, osu!, osu!, osu!, taiko, osu!, osu!, osu!, ... + for (int i = 0; i < 10; i++) + { + var rulesetInfo = rulesets.AvailableRulesets.ElementAt(i % 4 == 0 ? 1 : 0); + sets.Add(TestResources.CreateTestBeatmapSetInfo(5, new[] { rulesetInfo })); + } + + // Sort mode is important to keep the ruleset order + loadBeatmaps(sets, () => new FilterCriteria { Sort = SortMode.Title }); + + for (int i = 2; i < 10; i += 4) + { + setSelected(i, 1); + AddStep("Set ruleset to taiko", () => + { + carousel.Filter(new FilterCriteria { Ruleset = rulesets.AvailableRulesets.ElementAt(1), Sort = SortMode.Title }, false); + }); + waitForSelection(i - 1, 1); + AddStep("Remove ruleset filter", () => + { + carousel.Filter(new FilterCriteria { Sort = SortMode.Title }, false); + }); + } + } + private void loadBeatmaps(List beatmapSets = null, Func initialCriteria = null, Action carouselAdjust = null, int? count = null, bool randomDifficulties = false) { From da74690ec9363c3be62d5a9a5e5c76b8f0f63033 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 11:38:58 +0900 Subject: [PATCH 0200/2991] Add test coverage of clone operations --- .../Editing/TestSceneEditorClipboard.cs | 31 +++++++++++++++++++ osu.Game/Tests/Visual/EditorTestScene.cs | 2 ++ 2 files changed, 33 insertions(+) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs index 23e137865c..9fa3b2db1a 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs @@ -155,6 +155,20 @@ namespace osu.Game.Tests.Visual.Editing AddUntilStep("composer selection box is visible", () => Editor.ChildrenOfType().First().ChildrenOfType().First().Alpha > 0); } + [Test] + public void TestClone() + { + var addedObject = new HitCircle { StartTime = 1000 }; + AddStep("add hitobject", () => EditorBeatmap.Add(addedObject)); + AddStep("select added object", () => EditorBeatmap.SelectedHitObjects.Add(addedObject)); + + AddAssert("is one object", () => EditorBeatmap.HitObjects.Count == 1); + AddStep("clone", () => Editor.Duplicate()); + AddAssert("is two objects", () => EditorBeatmap.HitObjects.Count == 2); + AddStep("clone", () => Editor.Duplicate()); + AddAssert("is three objects", () => EditorBeatmap.HitObjects.Count == 3); + } + [Test] public void TestCutNothing() { @@ -175,5 +189,22 @@ namespace osu.Game.Tests.Visual.Editing AddStep("paste hitobject", () => Editor.Paste()); AddAssert("are no objects", () => EditorBeatmap.HitObjects.Count == 0); } + + [Test] + public void TestCloneNothing() + { + // Add arbitrary object and copy to clipboard. + // This is tested to ensure that clone doesn't incorrectly read from the clipboard when no selection is made. + var addedObject = new HitCircle { StartTime = 1000 }; + AddStep("add hitobject", () => EditorBeatmap.Add(addedObject)); + AddStep("select added object", () => EditorBeatmap.SelectedHitObjects.Add(addedObject)); + AddStep("copy hitobject", () => Editor.Copy()); + + AddStep("deselect all objects", () => EditorBeatmap.SelectedHitObjects.Clear()); + + AddAssert("is one object", () => EditorBeatmap.HitObjects.Count == 1); + AddStep("clone", () => Editor.Duplicate()); + AddAssert("still one object", () => EditorBeatmap.HitObjects.Count == 1); + } } } diff --git a/osu.Game/Tests/Visual/EditorTestScene.cs b/osu.Game/Tests/Visual/EditorTestScene.cs index ced72aa593..0e24c5c47a 100644 --- a/osu.Game/Tests/Visual/EditorTestScene.cs +++ b/osu.Game/Tests/Visual/EditorTestScene.cs @@ -110,6 +110,8 @@ namespace osu.Game.Tests.Visual public new void Paste() => base.Paste(); + public new void Duplicate() => base.Duplicate(); + public new void SwitchToDifficulty(BeatmapInfo beatmapInfo) => base.SwitchToDifficulty(beatmapInfo); public new void CreateNewDifficulty(RulesetInfo rulesetInfo) => base.CreateNewDifficulty(rulesetInfo); From 1e579e06f8079e82f0694db8af6faa8ade586a08 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 11:42:12 +0900 Subject: [PATCH 0201/2991] Fix duplicate working incorrectly if there is no selection currently made --- osu.Game/Screens/Edit/Editor.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 51f2ca16c2..cc551c3262 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -777,6 +777,10 @@ namespace osu.Game.Screens.Edit protected void Duplicate() { + // Avoid attempting to clone if copying is not available (as it may result in pasting something unexpected). + if (!canCopy.Value) + return; + // This is an initial implementation just to get an idea of how people used this function. // There are a couple of differences from osu!stable's implementation which will require more work to match: // - The "clipboard" is not populated during the duplication process. From 4d4f6e25bab755fe8de9d90909a3beec2a22590c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 11:43:23 +0900 Subject: [PATCH 0202/2991] Rename to "clone" instead of "duplicate" --- osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs | 6 +++--- osu.Game/Input/Bindings/GlobalActionContainer.cs | 6 +++--- osu.Game/Localisation/GlobalActionKeyBindingStrings.cs | 4 ++-- osu.Game/Screens/Edit/Editor.cs | 8 ++++---- osu.Game/Tests/Visual/EditorTestScene.cs | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs index 9fa3b2db1a..0a5a1febe4 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs @@ -163,9 +163,9 @@ namespace osu.Game.Tests.Visual.Editing AddStep("select added object", () => EditorBeatmap.SelectedHitObjects.Add(addedObject)); AddAssert("is one object", () => EditorBeatmap.HitObjects.Count == 1); - AddStep("clone", () => Editor.Duplicate()); + AddStep("clone", () => Editor.Clone()); AddAssert("is two objects", () => EditorBeatmap.HitObjects.Count == 2); - AddStep("clone", () => Editor.Duplicate()); + AddStep("clone", () => Editor.Clone()); AddAssert("is three objects", () => EditorBeatmap.HitObjects.Count == 3); } @@ -203,7 +203,7 @@ namespace osu.Game.Tests.Visual.Editing AddStep("deselect all objects", () => EditorBeatmap.SelectedHitObjects.Clear()); AddAssert("is one object", () => EditorBeatmap.HitObjects.Count == 1); - AddStep("clone", () => Editor.Duplicate()); + AddStep("clone", () => Editor.Clone()); AddAssert("still one object", () => EditorBeatmap.HitObjects.Count == 1); } } diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 476fda81b7..a58c6723ef 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -90,7 +90,7 @@ namespace osu.Game.Input.Bindings new KeyBinding(new[] { InputKey.F3 }, GlobalAction.EditorTimingMode), new KeyBinding(new[] { InputKey.F4 }, GlobalAction.EditorSetupMode), new KeyBinding(new[] { InputKey.Control, InputKey.Shift, InputKey.A }, GlobalAction.EditorVerifyMode), - new KeyBinding(new[] { InputKey.Control, InputKey.D }, GlobalAction.EditorDuplicateSelection), + new KeyBinding(new[] { InputKey.Control, InputKey.D }, GlobalAction.EditorCloneSelection), new KeyBinding(new[] { InputKey.J }, GlobalAction.EditorNudgeLeft), new KeyBinding(new[] { InputKey.K }, GlobalAction.EditorNudgeRight), new KeyBinding(new[] { InputKey.G }, GlobalAction.EditorCycleGridDisplayMode), @@ -348,7 +348,7 @@ namespace osu.Game.Input.Bindings [LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.ToggleProfile))] ToggleProfile, - [LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.EditorDuplicateSelection))] - EditorDuplicateSelection + [LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.EditorCloneSelection))] + EditorCloneSelection } } diff --git a/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs b/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs index 403fa8017a..14e0bbbced 100644 --- a/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs +++ b/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs @@ -185,9 +185,9 @@ namespace osu.Game.Localisation public static LocalisableString EditorTapForBPM => new TranslatableString(getKey(@"editor_tap_for_bpm"), @"Tap for BPM"); /// - /// "Duplicate selection" + /// "Clone selection" /// - public static LocalisableString EditorDuplicateSelection => new TranslatableString(getKey(@"editor_duplicate_selection"), @"Duplicate selection"); + public static LocalisableString EditorCloneSelection => new TranslatableString(getKey(@"editor_clone_selection"), @"Clone selection"); /// /// "Cycle grid display mode" diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index cc551c3262..c2899bc1ec 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -304,7 +304,7 @@ namespace osu.Game.Screens.Edit cutMenuItem = new EditorMenuItem("Cut", MenuItemType.Standard, Cut), copyMenuItem = new EditorMenuItem("Copy", MenuItemType.Standard, Copy), pasteMenuItem = new EditorMenuItem("Paste", MenuItemType.Standard, Paste), - duplicateMenuItem = new EditorMenuItem("Duplicate", MenuItemType.Standard, Duplicate), + duplicateMenuItem = new EditorMenuItem("Clone", MenuItemType.Standard, Clone), } }, new MenuItem("View") @@ -576,8 +576,8 @@ namespace osu.Game.Screens.Edit this.Exit(); return true; - case GlobalAction.EditorDuplicateSelection: - Duplicate(); + case GlobalAction.EditorCloneSelection: + Clone(); return true; case GlobalAction.EditorComposeMode: @@ -775,7 +775,7 @@ namespace osu.Game.Screens.Edit protected void Copy() => currentScreen?.Copy(); - protected void Duplicate() + protected void Clone() { // Avoid attempting to clone if copying is not available (as it may result in pasting something unexpected). if (!canCopy.Value) diff --git a/osu.Game/Tests/Visual/EditorTestScene.cs b/osu.Game/Tests/Visual/EditorTestScene.cs index 0e24c5c47a..0e7bb72162 100644 --- a/osu.Game/Tests/Visual/EditorTestScene.cs +++ b/osu.Game/Tests/Visual/EditorTestScene.cs @@ -110,7 +110,7 @@ namespace osu.Game.Tests.Visual public new void Paste() => base.Paste(); - public new void Duplicate() => base.Duplicate(); + public new void Clone() => base.Clone(); public new void SwitchToDifficulty(BeatmapInfo beatmapInfo) => base.SwitchToDifficulty(beatmapInfo); From 1b42f5ec6ec79ce7d73dcbd917fd33f5a518a21a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 11:51:31 +0900 Subject: [PATCH 0203/2991] Add test coverage of `BeatDivisorControl` key bindings --- .../Editing/TestSceneBeatDivisorControl.cs | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneBeatDivisorControl.cs b/osu.Game.Tests/Visual/Editing/TestSceneBeatDivisorControl.cs index ecd7732862..f2d27b9117 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneBeatDivisorControl.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneBeatDivisorControl.cs @@ -106,6 +106,49 @@ namespace osu.Game.Tests.Visual.Editing assertBeatSnap(16); } + [Test] + public void TestKeyboardNavigation() + { + pressKey(1); + assertBeatSnap(1); + assertPreset(BeatDivisorType.Common); + + pressKey(2); + assertBeatSnap(2); + assertPreset(BeatDivisorType.Common); + + pressKey(3); + assertBeatSnap(3); + assertPreset(BeatDivisorType.Triplets); + + pressKey(4); + assertBeatSnap(4); + assertPreset(BeatDivisorType.Common); + + pressKey(5); + assertBeatSnap(5); + assertPreset(BeatDivisorType.Custom, 5); + + pressKey(6); + assertBeatSnap(6); + assertPreset(BeatDivisorType.Triplets); + + pressKey(7); + assertBeatSnap(7); + assertPreset(BeatDivisorType.Custom, 7); + + pressKey(8); + assertBeatSnap(8); + assertPreset(BeatDivisorType.Common); + + void pressKey(int key) => AddStep($"press shift+{key}", () => + { + InputManager.PressKey(Key.ShiftLeft); + InputManager.Key(Key.Number0 + key); + InputManager.ReleaseKey(Key.ShiftLeft); + }); + } + [Test] public void TestBeatPresetNavigation() { From 8e4f5381e3cba926282ea72d52621cca6be6a52e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 12:03:46 +0900 Subject: [PATCH 0204/2991] Add top level test coverage of editor shortcuts --- .../Visual/Editing/TestSceneEditorBindings.cs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 osu.Game.Tests/Visual/Editing/TestSceneEditorBindings.cs diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorBindings.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorBindings.cs new file mode 100644 index 0000000000..5771d64775 --- /dev/null +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorBindings.cs @@ -0,0 +1,32 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Osu; +using osuTK.Input; + +namespace osu.Game.Tests.Visual.Editing +{ + /// + /// Test editor hotkeys at a high level to ensure they all work well together. + /// + public class TestSceneEditorBindings : EditorTestScene + { + protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); + + [Test] + public void TestBeatDivisorChangeHotkeys() + { + AddStep("hold shift", () => InputManager.PressKey(Key.LShift)); + + AddStep("press 4", () => InputManager.Key(Key.Number4)); + AddAssert("snap updated to 4", () => EditorBeatmap.BeatmapInfo.BeatDivisor, () => Is.EqualTo(4)); + + AddStep("press 6", () => InputManager.Key(Key.Number6)); + AddAssert("snap updated to 6", () => EditorBeatmap.BeatmapInfo.BeatDivisor, () => Is.EqualTo(6)); + + AddStep("release shift", () => InputManager.ReleaseKey(Key.LShift)); + } + } +} From 2456a18bc1be49d23b3beb0e1ca2fed087f148d2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 12:48:17 +0900 Subject: [PATCH 0205/2991] Rewrite implementation to avoid duplicated LINQ returns --- .../Carousel/CarouselGroupEagerSelect.cs | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs index 2c1ccebfab..a96d768ff9 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs @@ -115,26 +115,24 @@ namespace osu.Game.Screens.Select.Carousel protected virtual CarouselItem GetNextToSelect() { int forwardsIndex = lastSelectedIndex; + bool hasForwards; + int backwardsIndex = lastSelectedIndex; + bool hasBackwards; - while (true) + while ((hasBackwards = backwardsIndex >= 0) | (hasForwards = forwardsIndex < Items.Count)) { - // check if a direction has been exhausted and an item (or null) from the other direction should be returned - if (forwardsIndex >= Items.Count) - return Items.Reverse().Skip(Items.Count - backwardsIndex - 1).FirstOrDefault(item => !item.Filtered.Value); - if (backwardsIndex < 0) - return Items.Skip(forwardsIndex).FirstOrDefault(item => !item.Filtered.Value); - - // check if an unfiltered item has been reached - if (!Items[forwardsIndex].Filtered.Value) + if (hasForwards && !Items[forwardsIndex].Filtered.Value) return Items[forwardsIndex]; - if (!Items[backwardsIndex].Filtered.Value) + + if (hasBackwards && !Items[backwardsIndex].Filtered.Value) return Items[backwardsIndex]; - // increment the indices forwardsIndex++; backwardsIndex--; } + + return null; } protected virtual void PerformSelection() From f9c61904262f30b9f6297bcee9737cc13c691021 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Tue, 25 Oct 2022 13:00:53 +0900 Subject: [PATCH 0206/2991] Add DimAmount for UserDimContainer --- osu.Game/Graphics/Containers/UserDimContainer.cs | 5 ++++- osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index d52fb7c60a..296855522b 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -48,13 +48,15 @@ namespace osu.Game.Graphics.Containers protected Bindable UserDimLevel { get; private set; } + public Bindable DimAmount { get; set; } = new Bindable(); + protected Bindable LightenDuringBreaks { get; private set; } protected Bindable ShowStoryboard { get; private set; } private float breakLightening => LightenDuringBreaks.Value && IsBreakTime.Value ? BREAK_LIGHTEN_AMOUNT : 0; - protected float DimLevel => Math.Max(!IgnoreUserSettings.Value ? (float)UserDimLevel.Value - breakLightening : 0, 0); + protected float DimLevel => Math.Max(!IgnoreUserSettings.Value ? (float)UserDimLevel.Value - breakLightening : DimAmount.Value, 0); protected override Container Content => dimContent; @@ -76,6 +78,7 @@ namespace osu.Game.Graphics.Containers ShowStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); UserDimLevel.ValueChanged += _ => UpdateVisuals(); + DimAmount.ValueChanged += _ => UpdateVisuals(); LightenDuringBreaks.ValueChanged += _ => UpdateVisuals(); IsBreakTime.ValueChanged += _ => UpdateVisuals(); ShowStoryboard.ValueChanged += _ => UpdateVisuals(); diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs index ca05c8af46..053bcf2387 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs @@ -43,6 +43,8 @@ namespace osu.Game.Screens.Backgrounds /// public readonly Bindable BlurAmount = new BindableFloat(); + public readonly Bindable DimAmount = new Bindable(); + internal readonly IBindable IsBreakTime = new Bindable(); private readonly DimmableBackground dimmable; @@ -58,6 +60,7 @@ namespace osu.Game.Screens.Backgrounds dimmable.IgnoreUserSettings.BindTo(IgnoreUserSettings); dimmable.IsBreakTime.BindTo(IsBreakTime); dimmable.BlurAmount.BindTo(BlurAmount); + dimmable.DimAmount.BindTo(DimAmount); StoryboardReplacesBackground.BindTo(dimmable.StoryboardReplacesBackground); } From 3d72ff28c3e09b1e1be93917ceaf2957e34d1adc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 13:25:38 +0900 Subject: [PATCH 0207/2991] Add test scene for "Freeze Frame" mod --- .../Mods/TestSceneOsuModFreezeFrame.cs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs new file mode 100644 index 0000000000..7d7b2d9071 --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs @@ -0,0 +1,22 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Rulesets.Osu.Mods; + +namespace osu.Game.Rulesets.Osu.Tests.Mods +{ + public class TestSceneOsuModFreezeFrame : OsuModTestScene + { + [Test] + public void TestFreezeFrame() + { + CreateModTest(new ModTestData + { + Mod = new OsuModFreezeFrame(), + PassCondition = () => true, + Autoplay = false, + }); + } + } +} From 588fc750cdeac7b2b915506f62eb168adb960687 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 13:26:32 +0900 Subject: [PATCH 0208/2991] Change approach circles to all appear at the same time, but don't adjust AR --- .../Mods/OsuModFreezeFrame.cs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 8bf2c89057..2187d33a49 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -29,12 +29,17 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Fun; //mod breaks normal approach circle preempt - private double approachCircleTimePreempt; + private double originalPreempt; public void ApplyToBeatmap(IBeatmap beatmap) { + var firstHitObject = beatmap.HitObjects.OfType().FirstOrDefault(); + if (firstHitObject == null) + return; + double lastNewComboTime = 0; - approachCircleTimePreempt = beatmap.HitObjects.OfType().FirstOrDefault()!.TimePreempt; + + originalPreempt = firstHitObject.TimePreempt; foreach (var obj in beatmap.HitObjects.OfType()) { @@ -72,17 +77,12 @@ namespace osu.Game.Rulesets.Osu.Mods var hitCircle = drawableHitCircle.HitObject; var approachCircle = drawableHitCircle.ApproachCircle; - approachCircle.ClearTransforms(); - approachCircle.ScaleTo(4); - approachCircle.FadeTo(0); + // Reapply scale, ensuring the AR isn't changes due to the new preempt. + approachCircle.ClearTransforms(targetMember: nameof(approachCircle.Scale)); + approachCircle.ScaleTo(4 * (float)(hitCircle.TimePreempt / originalPreempt)); - using (drawableHitCircle.ApproachCircle.BeginAbsoluteSequence(hitCircle.StartTime - approachCircleTimePreempt)) - { - //Redo ApproachCircle animation with correct startTime. - approachCircle.LifetimeStart = hitCircle.StartTime - approachCircleTimePreempt; - approachCircle.FadeTo(1, Math.Min(hitCircle.TimeFadeIn * 2, hitCircle.TimePreempt)); - approachCircle.ScaleTo(1, approachCircleTimePreempt).Then().Expire(); - } + using (drawableHitCircle.ApproachCircle.BeginAbsoluteSequence(hitCircle.StartTime - hitCircle.TimePreempt)) + approachCircle.ScaleTo(1, hitCircle.TimePreempt).Then().Expire(); }; } } From 279ef556e3c4eb818d40d837809739cf7a8eb8ca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 13:27:26 +0900 Subject: [PATCH 0209/2991] Fix typon in comment --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 2187d33a49..20d75ab019 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Osu.Mods var hitCircle = drawableHitCircle.HitObject; var approachCircle = drawableHitCircle.ApproachCircle; - // Reapply scale, ensuring the AR isn't changes due to the new preempt. + // Reapply scale, ensuring the AR isn't changed due to the new preempt. approachCircle.ClearTransforms(targetMember: nameof(approachCircle.Scale)); approachCircle.ScaleTo(4 * (float)(hitCircle.TimePreempt / originalPreempt)); From 22ea9a8ab4f2d4c07820935f3c3dc823c8c1b65b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 13:34:21 +0900 Subject: [PATCH 0210/2991] Add early return of carousel group has no items --- osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs index a96d768ff9..6a53f8f527 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs @@ -114,6 +114,9 @@ namespace osu.Game.Screens.Select.Carousel /// An unfiltered item nearest to the last selected one or null if all items are filtered protected virtual CarouselItem GetNextToSelect() { + if (Items.Count == 0) + return null; + int forwardsIndex = lastSelectedIndex; bool hasForwards; From 02a3f8c17fb14bdd2c699c20a1416d0563aec045 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 14:09:22 +0900 Subject: [PATCH 0211/2991] Allow both distance snap and grid snap to be applied at the same time --- .../Edit/OsuHitObjectComposer.cs | 27 +++++++------------ 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 6b4a6e39d9..67061bdaf2 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -80,19 +80,7 @@ namespace osu.Game.Rulesets.Osu.Edit placementObject = EditorBeatmap.PlacementObject.GetBoundCopy(); placementObject.ValueChanged += _ => updateDistanceSnapGrid(); - distanceSnapToggle.ValueChanged += _ => - { - updateDistanceSnapGrid(); - - if (distanceSnapToggle.Value == TernaryState.True) - rectangularGridSnapToggle.Value = TernaryState.False; - }; - - rectangularGridSnapToggle.ValueChanged += _ => - { - if (rectangularGridSnapToggle.Value == TernaryState.True) - distanceSnapToggle.Value = TernaryState.False; - }; + distanceSnapToggle.ValueChanged += _ => updateDistanceSnapGrid(); // we may be entering the screen with a selection already active updateDistanceSnapGrid(); @@ -134,22 +122,27 @@ namespace osu.Game.Rulesets.Osu.Edit if (snapType.HasFlagFast(SnapType.NearbyObjects) && snapToVisibleBlueprints(screenSpacePosition, out var snapResult)) return snapResult; + SnapResult result = base.FindSnappedPositionAndTime(screenSpacePosition, snapType); + if (snapType.HasFlagFast(SnapType.Grids)) { if (distanceSnapToggle.Value == TernaryState.True && distanceSnapGrid != null) { (Vector2 pos, double time) = distanceSnapGrid.GetSnappedPosition(distanceSnapGrid.ToLocalSpace(screenSpacePosition)); - return new SnapResult(distanceSnapGrid.ToScreenSpace(pos), time, PlayfieldAtScreenSpacePosition(screenSpacePosition)); + + result.ScreenSpacePosition = distanceSnapGrid.ToScreenSpace(pos); + result.Time = time; } if (rectangularGridSnapToggle.Value == TernaryState.True) { - Vector2 pos = rectangularPositionSnapGrid.GetSnappedPosition(rectangularPositionSnapGrid.ToLocalSpace(screenSpacePosition)); - return new SnapResult(rectangularPositionSnapGrid.ToScreenSpace(pos), null, PlayfieldAtScreenSpacePosition(screenSpacePosition)); + Vector2 pos = rectangularPositionSnapGrid.GetSnappedPosition(rectangularPositionSnapGrid.ToLocalSpace(result.ScreenSpacePosition)); + + result.ScreenSpacePosition = rectangularPositionSnapGrid.ToScreenSpace(pos); } } - return base.FindSnappedPositionAndTime(screenSpacePosition, snapType); + return result; } private bool snapToVisibleBlueprints(Vector2 screenSpacePosition, out SnapResult snapResult) From 2f0283e4d4b6d547a2c7a04387a514a115142988 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 14:22:28 +0900 Subject: [PATCH 0212/2991] Simplify logic with new multi-grid snap support --- .../Edit/CatchHitObjectComposer.cs | 21 +++------- .../Edit/OsuHitObjectComposer.cs | 42 ++++++------------- 2 files changed, 18 insertions(+), 45 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index 27235bd62e..9ba17c89ff 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -103,25 +103,16 @@ namespace osu.Game.Rulesets.Catch.Edit base.OnKeyUp(e); } - private TernaryState? distanceSnapBeforeMomentary; + private bool distanceSnapMomentary; private void handleToggleViaKey(KeyboardEvent key) { - if (key.AltPressed) + bool altPressed = key.AltPressed; + + if (altPressed != distanceSnapMomentary) { - if (distanceSnapBeforeMomentary == null) - { - distanceSnapBeforeMomentary = distanceSnapToggle.Value; - distanceSnapToggle.Value = distanceSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; - } - } - else - { - if (distanceSnapBeforeMomentary != null) - { - distanceSnapToggle.Value = distanceSnapBeforeMomentary.Value; - distanceSnapBeforeMomentary = null; - } + distanceSnapMomentary = altPressed; + distanceSnapToggle.Value = distanceSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; } } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 838f18bad5..bf7cddd099 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -247,43 +247,25 @@ namespace osu.Game.Rulesets.Osu.Edit return base.AdjustDistanceSpacing(action, amount); } - private TernaryState? gridSnapBeforeMomentary; - private TernaryState? distanceSnapBeforeMomentary; + private bool distanceSnapMomentary; + private bool gridSnapMomentary; private void handleToggleViaKey(KeyboardEvent key) { - if (key.ShiftPressed) + bool altPressed = key.AltPressed; + + if (altPressed != distanceSnapMomentary) { - if (distanceSnapBeforeMomentary == null && gridSnapBeforeMomentary == null) - { - gridSnapBeforeMomentary = rectangularGridSnapToggle.Value; - rectangularGridSnapToggle.Value = rectangularGridSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; - } - } - else - { - if (gridSnapBeforeMomentary != null) - { - rectangularGridSnapToggle.Value = gridSnapBeforeMomentary.Value; - gridSnapBeforeMomentary = null; - } + distanceSnapMomentary = altPressed; + distanceSnapToggle.Value = distanceSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; } - if (key.AltPressed) + bool shiftPressed = key.ShiftPressed; + + if (shiftPressed != gridSnapMomentary) { - if (gridSnapBeforeMomentary == null && distanceSnapBeforeMomentary == null) - { - distanceSnapBeforeMomentary = distanceSnapToggle.Value; - distanceSnapToggle.Value = distanceSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; - } - } - else - { - if (distanceSnapBeforeMomentary != null) - { - distanceSnapToggle.Value = distanceSnapBeforeMomentary.Value; - distanceSnapBeforeMomentary = null; - } + gridSnapMomentary = shiftPressed; + rectangularGridSnapToggle.Value = rectangularGridSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; } } From a9755295e44445e25c5aeebec212f5baa83b89df Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 14:32:08 +0900 Subject: [PATCH 0213/2991] Update tests in line with new behaviour --- .../Editor/TestSceneOsuEditorGrids.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs index 1e73885540..479687c496 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs @@ -20,20 +20,27 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); [Test] - public void TestGridExclusivity() + public void TestGridToggles() { AddStep("enable distance snap grid", () => InputManager.Key(Key.T)); AddStep("select second object", () => EditorBeatmap.SelectedHitObjects.Add(EditorBeatmap.HitObjects.ElementAt(1))); + AddUntilStep("distance snap grid visible", () => this.ChildrenOfType().Any()); rectangularGridActive(false); AddStep("enable rectangular grid", () => InputManager.Key(Key.Y)); - AddUntilStep("distance snap grid hidden", () => !this.ChildrenOfType().Any()); + + AddStep("select second object", () => EditorBeatmap.SelectedHitObjects.Add(EditorBeatmap.HitObjects.ElementAt(1))); + AddUntilStep("distance snap grid still visible", () => this.ChildrenOfType().Any()); rectangularGridActive(true); - AddStep("enable distance snap grid", () => InputManager.Key(Key.T)); + AddStep("disable distance snap grid", () => InputManager.Key(Key.T)); + AddUntilStep("distance snap grid hidden", () => !this.ChildrenOfType().Any()); AddStep("select second object", () => EditorBeatmap.SelectedHitObjects.Add(EditorBeatmap.HitObjects.ElementAt(1))); - AddUntilStep("distance snap grid visible", () => this.ChildrenOfType().Any()); + rectangularGridActive(true); + + AddStep("disable rectangular grid", () => InputManager.Key(Key.Y)); + AddUntilStep("distance snap grid still hidden", () => !this.ChildrenOfType().Any()); rectangularGridActive(false); } From 16ef0b09e8a86eb33b0bce3ca2a230ab24c840bc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 14:36:35 +0900 Subject: [PATCH 0214/2991] Add test coverage of momentary toggles --- .../Editor/TestSceneOsuEditorGrids.cs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs index 479687c496..f6d3512fe6 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs @@ -44,6 +44,28 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor rectangularGridActive(false); } + [Test] + public void TestDistanceSnapMomentaryToggle() + { + AddStep("select second object", () => EditorBeatmap.SelectedHitObjects.Add(EditorBeatmap.HitObjects.ElementAt(1))); + + AddUntilStep("distance snap grid hidden", () => !this.ChildrenOfType().Any()); + AddStep("hold alt", () => InputManager.PressKey(Key.AltLeft)); + AddUntilStep("distance snap grid visible", () => this.ChildrenOfType().Any()); + AddStep("release alt", () => InputManager.ReleaseKey(Key.AltLeft)); + AddUntilStep("distance snap grid hidden", () => !this.ChildrenOfType().Any()); + } + + [Test] + public void TestGridSnapMomentaryToggle() + { + rectangularGridActive(false); + AddStep("hold shift", () => InputManager.PressKey(Key.ShiftLeft)); + rectangularGridActive(true); + AddStep("release shift", () => InputManager.ReleaseKey(Key.ShiftLeft)); + rectangularGridActive(false); + } + private void rectangularGridActive(bool active) { AddStep("choose placement tool", () => InputManager.Key(Key.Number2)); From da93849b8084b7bc0fb057704ee1a7a1606bf82f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 14:55:33 +0900 Subject: [PATCH 0215/2991] Rename some pieces and better document `SampleBankInfo` --- .../Objects/Legacy/ConvertHitObjectParser.cs | 44 ++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index b289299a63..930ee0448f 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -199,8 +199,8 @@ namespace osu.Game.Rulesets.Objects.Legacy if (stringAddBank == @"none") stringAddBank = null; - bankInfo.Normal = stringBank; - bankInfo.Add = string.IsNullOrEmpty(stringAddBank) ? stringBank : stringAddBank; + bankInfo.BankForNormal = stringBank; + bankInfo.BankForAdditions = string.IsNullOrEmpty(stringAddBank) ? stringBank : stringAddBank; if (split.Length > 2) bankInfo.CustomSampleBank = Parsing.ParseInt(split[2]); @@ -447,32 +447,54 @@ namespace osu.Game.Rulesets.Objects.Legacy var soundTypes = new List { - new LegacyHitSampleInfo(HitSampleInfo.HIT_NORMAL, bankInfo.Normal, bankInfo.Volume, bankInfo.CustomSampleBank, + new LegacyHitSampleInfo(HitSampleInfo.HIT_NORMAL, bankInfo.BankForNormal, bankInfo.Volume, bankInfo.CustomSampleBank, // if the sound type doesn't have the Normal flag set, attach it anyway as a layered sample. // None also counts as a normal non-layered sample: https://osu.ppy.sh/help/wiki/osu!_File_Formats/Osu_(file_format)#hitsounds type != LegacyHitSoundType.None && !type.HasFlagFast(LegacyHitSoundType.Normal)) }; if (type.HasFlagFast(LegacyHitSoundType.Finish)) - soundTypes.Add(new LegacyHitSampleInfo(HitSampleInfo.HIT_FINISH, bankInfo.Add, bankInfo.Volume, bankInfo.CustomSampleBank)); + soundTypes.Add(new LegacyHitSampleInfo(HitSampleInfo.HIT_FINISH, bankInfo.BankForAdditions, bankInfo.Volume, bankInfo.CustomSampleBank)); if (type.HasFlagFast(LegacyHitSoundType.Whistle)) - soundTypes.Add(new LegacyHitSampleInfo(HitSampleInfo.HIT_WHISTLE, bankInfo.Add, bankInfo.Volume, bankInfo.CustomSampleBank)); + soundTypes.Add(new LegacyHitSampleInfo(HitSampleInfo.HIT_WHISTLE, bankInfo.BankForAdditions, bankInfo.Volume, bankInfo.CustomSampleBank)); if (type.HasFlagFast(LegacyHitSoundType.Clap)) - soundTypes.Add(new LegacyHitSampleInfo(HitSampleInfo.HIT_CLAP, bankInfo.Add, bankInfo.Volume, bankInfo.CustomSampleBank)); + soundTypes.Add(new LegacyHitSampleInfo(HitSampleInfo.HIT_CLAP, bankInfo.BankForAdditions, bankInfo.Volume, bankInfo.CustomSampleBank)); return soundTypes; } private class SampleBankInfo { + /// + /// An optional overriding filename which causes all bank/sample specifications to be ignored. + /// public string Filename; - public string Normal; - public string Add; + /// + /// The bank identifier to use for the base ("hitnormal") sample. + /// Transferred to when appropriate. + /// + public string BankForNormal; + + /// + /// The bank identifier to use for additions ("hitwhistle", "hitfinish", "hitclap"). + /// Transferred to when appropriate. + /// + public string BankForAdditions; + + /// + /// Hit sample volume (0-100). + /// See . + /// public int Volume; + /// + /// The index of the custom sample bank. Is only used if 2 or above for "reasons". + /// This will add a suffix to lookups, allowing extended bank lookups (ie. "normal-hitnormal-2"). + /// See . + /// public int CustomSampleBank; public SampleBankInfo Clone() => (SampleBankInfo)MemberwiseClone(); @@ -503,7 +525,8 @@ namespace osu.Game.Rulesets.Objects.Legacy public sealed override HitSampleInfo With(Optional newName = default, Optional newBank = default, Optional newSuffix = default, Optional newVolume = default) => With(newName, newBank, newVolume); - public virtual LegacyHitSampleInfo With(Optional newName = default, Optional newBank = default, Optional newVolume = default, Optional newCustomSampleBank = default, + public virtual LegacyHitSampleInfo With(Optional newName = default, Optional newBank = default, Optional newVolume = default, + Optional newCustomSampleBank = default, Optional newIsLayered = default) => new LegacyHitSampleInfo(newName.GetOr(Name), newBank.GetOr(Bank), newVolume.GetOr(Volume), newCustomSampleBank.GetOr(CustomSampleBank), newIsLayered.GetOr(IsLayered)); @@ -537,7 +560,8 @@ namespace osu.Game.Rulesets.Objects.Legacy Path.ChangeExtension(Filename, null) }; - public sealed override LegacyHitSampleInfo With(Optional newName = default, Optional newBank = default, Optional newVolume = default, Optional newCustomSampleBank = default, + public sealed override LegacyHitSampleInfo With(Optional newName = default, Optional newBank = default, Optional newVolume = default, + Optional newCustomSampleBank = default, Optional newIsLayered = default) => new FileHitSampleInfo(Filename, newVolume.GetOr(Volume)); From f4aae9138bf98ec4475ce14d709dae20be4ca001 Mon Sep 17 00:00:00 2001 From: "D.Headley" Date: Tue, 25 Oct 2022 08:48:45 +0200 Subject: [PATCH 0216/2991] Remove Incompatibility with HD --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index 20d75ab019..bea5d4f5d9 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override LocalisableString Description => "Burn the notes into your memory."; //Alters the transforms of the approach circles, breaking the effects of these mods. - public override Type[] IncompatibleMods => new[] { typeof(OsuModApproachDifferent), typeof(OsuModHidden) }; + public override Type[] IncompatibleMods => new[] { typeof(OsuModApproachDifferent) }; public override ModType Type => ModType.Fun; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 2d7c0c82de..996ee1cddb 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override LocalisableString Description => @"Play with no approach circles and fading circles/sliders."; public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.06 : 1; - public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn), typeof(OsuModFreezeFrame) }; + public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn) }; public const double FADE_IN_DURATION_MULTIPLIER = 0.4; public const double FADE_OUT_DURATION_MULTIPLIER = 0.3; From cf3bf41b4902f754d64344bda326928190dd3ff7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Oct 2022 18:57:15 +0900 Subject: [PATCH 0217/2991] Harden and simplify logic to avoid weird issues --- .../Select/Carousel/CarouselGroupEagerSelect.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs index 6a53f8f527..34865c7f51 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs @@ -118,13 +118,16 @@ namespace osu.Game.Screens.Select.Carousel return null; int forwardsIndex = lastSelectedIndex; - bool hasForwards; - int backwardsIndex = lastSelectedIndex; - bool hasBackwards; - while ((hasBackwards = backwardsIndex >= 0) | (hasForwards = forwardsIndex < Items.Count)) + while (true) { + bool hasBackwards = backwardsIndex >= 0 && backwardsIndex < Items.Count; + bool hasForwards = forwardsIndex < Items.Count; + + if (!hasBackwards && !hasForwards) + return null; + if (hasForwards && !Items[forwardsIndex].Filtered.Value) return Items[forwardsIndex]; @@ -134,8 +137,6 @@ namespace osu.Game.Screens.Select.Carousel forwardsIndex++; backwardsIndex--; } - - return null; } protected virtual void PerformSelection() From 92ab39f5c2d94c34964b7c22894f3914c7aa8311 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Tue, 25 Oct 2022 19:16:23 +0900 Subject: [PATCH 0218/2991] Fix hold note disappear instantly --- osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 48647f9f5f..14dbc432ff 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -69,6 +69,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// private double? releaseTime; + public override double MaximumJudgementOffset => Tail.MaximumJudgementOffset; + public DrawableHoldNote() : this(null) { @@ -260,7 +262,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables tick.MissForcefully(); } - ApplyResult(r => r.Type = r.Judgement.MaxResult); + ApplyResult(r => r.Type = Tail.IsHit ? r.Judgement.MaxResult : r.Judgement.MinResult); endHold(); } From 0b8b3223222d4cfe3311e65707bd5fe3d59ad7d5 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Tue, 25 Oct 2022 19:48:33 +0900 Subject: [PATCH 0219/2991] Fix tests --- osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs | 2 +- osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs index 8f776ff507..0296303867 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs @@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Mania.Tests assertHeadJudgement(HitResult.Miss); assertTickJudgement(HitResult.LargeTickMiss); assertTailJudgement(HitResult.Miss); - assertNoteJudgement(HitResult.IgnoreHit); + assertNoteJudgement(HitResult.IgnoreMiss); } /// diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs index 1f139b5b78..464dbecee5 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs @@ -76,8 +76,8 @@ namespace osu.Game.Rulesets.Mania.Tests performTest(objects, new List()); - addJudgementAssert(objects[0], HitResult.IgnoreHit); - addJudgementAssert(objects[1], HitResult.IgnoreHit); + addJudgementAssert(objects[0], HitResult.IgnoreMiss); + addJudgementAssert(objects[1], HitResult.IgnoreMiss); } [Test] From 242f80b8b31a670032048d305469302aa7afd123 Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Tue, 25 Oct 2022 15:49:14 +0200 Subject: [PATCH 0220/2991] Set scrollspeed directly at beatmap decode --- .../TestSceneControlPointConversion.cs | 38 ------------------- .../Beatmaps/TaikoBeatmapConverter.cs | 23 ----------- .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 7 +--- 3 files changed, 1 insertion(+), 67 deletions(-) delete mode 100644 osu.Game.Rulesets.Taiko.Tests/TestSceneControlPointConversion.cs diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneControlPointConversion.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneControlPointConversion.cs deleted file mode 100644 index 72763421cc..0000000000 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneControlPointConversion.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using NUnit.Framework; -using osu.Game.Beatmaps; -using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Rulesets.Objects; -using osu.Game.Tests.Visual; - -namespace osu.Game.Rulesets.Taiko.Tests -{ - public class TestSceneControlPointConversion : OsuTestScene - { - [Test] - public void TestSceneScrollSpeedConversion() - { - const double start_time = 1000; - const double slider_velocity = 10; - - var beatmap = new Beatmap - { - HitObjects = - { - new HitObject - { - StartTime = start_time, - DifficultyControlPoint = new DifficultyControlPoint { SliderVelocity = slider_velocity } - } - }, - BeatmapInfo = { Ruleset = { OnlineID = 0 } }, - }; - - var convertedBeatmap = new TaikoRuleset().CreateBeatmapConverter(beatmap).Convert(); - - AddAssert("effect point generated", () => convertedBeatmap.ControlPointInfo.EffectPointAt(start_time).ScrollSpeed == slider_velocity); - } - } -} diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index c1e1052569..524565a863 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -57,29 +57,6 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps Beatmap converted = base.ConvertBeatmap(original, cancellationToken); - if (original.BeatmapInfo.Ruleset.OnlineID == 0) - { - // Post processing step to transform standard slider velocity changes into scroll speed changes - double lastScrollSpeed = 1; - - foreach (HitObject hitObject in original.HitObjects) - { - double nextScrollSpeed = hitObject.DifficultyControlPoint.SliderVelocity; - - if (!Precision.AlmostEquals(lastScrollSpeed, nextScrollSpeed)) - { - EffectControlPoint currentControlPoint = converted.ControlPointInfo.EffectPointAt(hitObject.StartTime); - - if (Precision.AlmostEquals(currentControlPoint.Time, hitObject.StartTime)) - currentControlPoint.ScrollSpeed = nextScrollSpeed; - else - converted.ControlPointInfo.Add(hitObject.StartTime, new EffectControlPoint { ScrollSpeed = nextScrollSpeed }); - - lastScrollSpeed = nextScrollSpeed; - } - } - } - if (original.BeatmapInfo.Ruleset.OnlineID == 3) { // Post processing step to transform mania hit objects with the same start time into strong hits diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 75500fbc4e..2d9320d9c4 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -438,14 +438,9 @@ namespace osu.Game.Beatmaps.Formats { KiaiMode = kiaiMode, OmitFirstBarLine = omitFirstBarSignature, + ScrollSpeed = speedMultiplier, }; - int onlineRulesetID = beatmap.BeatmapInfo.Ruleset.OnlineID; - - // osu!taiko and osu!mania use effect points rather than difficulty points for scroll speed adjustments. - if (onlineRulesetID == 1 || onlineRulesetID == 3) - effectPoint.ScrollSpeed = speedMultiplier; - addControlPoint(time, effectPoint, timingChange); addControlPoint(time, new LegacySampleControlPoint From aae5359b2e5e33cb37404dda1e580a3ee77691b1 Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Tue, 25 Oct 2022 17:47:51 +0200 Subject: [PATCH 0221/2991] Update Tests --- .../Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 2 +- osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index fdd0167ed3..d9bbe7a51e 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -175,7 +175,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(4, controlPoints.TimingPoints.Count); Assert.AreEqual(5, controlPoints.DifficultyPoints.Count); Assert.AreEqual(34, controlPoints.SamplePoints.Count); - Assert.AreEqual(8, controlPoints.EffectPoints.Count); + Assert.AreEqual(13, controlPoints.EffectPoints.Count); var timingPoint = controlPoints.TimingPointAt(0); Assert.AreEqual(956, timingPoint.Time); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs b/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs index 03c184c27d..e93382cc9b 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs @@ -67,8 +67,8 @@ namespace osu.Game.Tests.Visual.Editing InputManager.Click(MouseButton.Left); }); - AddUntilStep("Selection changed", () => timingScreen.SelectedGroup.Value.Time == 54670); - AddUntilStep("Ensure seeked to correct time", () => EditorClock.CurrentTimeAccurate == 54670); + AddUntilStep("Selection changed", () => timingScreen.SelectedGroup.Value.Time == 37560); + AddUntilStep("Ensure seeked to correct time", () => EditorClock.CurrentTimeAccurate == 37560); AddStep("Seek to just before next point", () => EditorClock.Seek(69000)); AddStep("Start clock", () => EditorClock.Start()); @@ -85,8 +85,8 @@ namespace osu.Game.Tests.Visual.Editing InputManager.Click(MouseButton.Left); }); - AddUntilStep("Selection changed", () => timingScreen.SelectedGroup.Value.Time == 54670); - AddUntilStep("Ensure seeked to correct time", () => EditorClock.CurrentTimeAccurate == 54670); + AddUntilStep("Selection changed", () => timingScreen.SelectedGroup.Value.Time == 37560); + AddUntilStep("Ensure seeked to correct time", () => EditorClock.CurrentTimeAccurate == 37560); AddStep("Seek to later", () => EditorClock.Seek(80000)); AddUntilStep("Selection changed", () => timingScreen.SelectedGroup.Value.Time == 69670); From d2b0a413da43e15ea6964fa6650a15ec89d068a7 Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Tue, 25 Oct 2022 18:18:25 +0200 Subject: [PATCH 0222/2991] Always encode scroll speed as slider velocity in the legacy encoder --- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 03c63ff4f2..c9ee63424c 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -185,19 +185,12 @@ namespace osu.Game.Beatmaps.Formats SampleControlPoint lastRelevantSamplePoint = null; DifficultyControlPoint lastRelevantDifficultyPoint = null; - // In osu!taiko and osu!mania, a scroll speed is stored as "slider velocity" in legacy formats. - // In that case, a scrolling speed change is a global effect and per-hit object difficulty control points are ignored. - bool scrollSpeedEncodedAsSliderVelocity = onlineRulesetID == 1 || onlineRulesetID == 3; - // iterate over hitobjects and pull out all required sample and difficulty changes extractDifficultyControlPoints(beatmap.HitObjects); extractSampleControlPoints(beatmap.HitObjects); - if (scrollSpeedEncodedAsSliderVelocity) - { - foreach (var point in legacyControlPoints.EffectPoints) - legacyControlPoints.Add(point.Time, new DifficultyControlPoint { SliderVelocity = point.ScrollSpeed }); - } + foreach (var point in legacyControlPoints.EffectPoints) + legacyControlPoints.Add(point.Time, new DifficultyControlPoint { SliderVelocity = point.ScrollSpeed }); foreach (var group in legacyControlPoints.Groups) { @@ -244,9 +237,6 @@ namespace osu.Game.Beatmaps.Formats IEnumerable collectDifficultyControlPoints(IEnumerable hitObjects) { - if (scrollSpeedEncodedAsSliderVelocity) - yield break; - foreach (var hitObject in hitObjects) yield return hitObject.DifficultyControlPoint; } From 93e9b4a2c5329a46668b6f4261680abfb763a7c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 25 Oct 2022 19:53:05 +0200 Subject: [PATCH 0223/2991] Add failing test case --- .../Mods/TestSceneTaikoModFlashlight.cs | 36 +++++++++++++++++++ .../Mods/TaikoModFlashlight.cs | 8 ++--- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModFlashlight.cs b/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModFlashlight.cs index 417b59f5d2..d55ce17e6c 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModFlashlight.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModFlashlight.cs @@ -1,8 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; using NUnit.Framework; +using osu.Framework.Testing; using osu.Game.Rulesets.Taiko.Mods; +using osu.Game.Rulesets.Taiko.UI; +using osuTK; namespace osu.Game.Rulesets.Taiko.Tests.Mods { @@ -16,5 +20,37 @@ namespace osu.Game.Rulesets.Taiko.Tests.Mods [Test] public void TestComboBasedSize([Values] bool comboBasedSize) => CreateModTest(new ModTestData { Mod = new TaikoModFlashlight { ComboBasedSize = { Value = comboBasedSize } }, PassCondition = () => true }); + + [Test] + public void TestFlashlightAlwaysHasNonZeroSize() + { + bool failed = false; + + CreateModTest(new ModTestData + { + Mod = new TestTaikoModFlashlight { ComboBasedSize = { Value = true } }, + Autoplay = false, + PassCondition = () => + { + failed |= this.ChildrenOfType().SingleOrDefault()?.FlashlightSize.Y == 0; + return !failed; + } + }); + } + + private class TestTaikoModFlashlight : TaikoModFlashlight + { + protected override Flashlight CreateFlashlight() => new TestTaikoFlashlight(this, Playfield); + + public class TestTaikoFlashlight : TaikoFlashlight + { + public TestTaikoFlashlight(TaikoModFlashlight modFlashlight, TaikoPlayfield taikoPlayfield) + : base(modFlashlight, taikoPlayfield) + { + } + + public new Vector2 FlashlightSize => base.FlashlightSize; + } + } } } diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs index 98f954ad29..d5b0b64036 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs @@ -27,17 +27,17 @@ namespace osu.Game.Rulesets.Taiko.Mods public override float DefaultFlashlightSize => 200; - protected override Flashlight CreateFlashlight() => new TaikoFlashlight(this, playfield); + protected override Flashlight CreateFlashlight() => new TaikoFlashlight(this, Playfield); - private TaikoPlayfield playfield = null!; + protected TaikoPlayfield Playfield { get; private set; } = null!; public override void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { - playfield = (TaikoPlayfield)drawableRuleset.Playfield; + Playfield = (TaikoPlayfield)drawableRuleset.Playfield; base.ApplyToDrawableRuleset(drawableRuleset); } - private class TaikoFlashlight : Flashlight + public class TaikoFlashlight : Flashlight { private readonly LayoutValue flashlightProperties = new LayoutValue(Invalidation.RequiredParentSizeToFit | Invalidation.DrawInfo); private readonly TaikoPlayfield taikoPlayfield; From e3bc1126d75e204b08a85059b6f818c4c292d60d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 25 Oct 2022 20:03:22 +0200 Subject: [PATCH 0224/2991] Fix invalid flashlight size calculation This regressed in #20714. One usage of `getSizeFor(0)` was replaced by `adjustSize(GetSize())`, but another usage of `getSizeFor(Combo.Value)` was replaced by `adjustSize(Combo.Value)`, which is not correct, since `adjustSize()` is expecting to receive a combo-based size, rather than a combo value directly. --- osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs index d5b0b64036..2b3dc799ab 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs @@ -75,7 +75,7 @@ namespace osu.Game.Rulesets.Taiko.Mods FlashlightPosition = ToLocalSpace(taikoPlayfield.HitTarget.ScreenSpaceDrawQuad.Centre); ClearTransforms(targetMember: nameof(FlashlightSize)); - FlashlightSize = adjustSize(Combo.Value); + FlashlightSize = adjustSize(GetSize()); flashlightProperties.Validate(); } From 974f22dd97a4f79fc9709a5431c2f1ecae73549f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 25 Oct 2022 20:11:29 +0200 Subject: [PATCH 0225/2991] Attempt to make flashlight code slightly more legible --- .../Mods/TaikoModFlashlight.cs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs index 2b3dc799ab..46569c2495 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs @@ -47,21 +47,28 @@ namespace osu.Game.Rulesets.Taiko.Mods { this.taikoPlayfield = taikoPlayfield; - FlashlightSize = adjustSize(GetSize()); + FlashlightSize = adjustSizeForPlayfieldAspectRatio(GetSize()); FlashlightSmoothness = 1.4f; AddLayout(flashlightProperties); } - private Vector2 adjustSize(float size) + /// + /// Returns the aspect ratio-adjusted size of the flashlight. + /// This ensures that the size of the flashlight remains independent of taiko-specific aspect ratio adjustments. + /// + /// + /// The size of the flashlight. + /// The value provided here should always come from . + /// + private Vector2 adjustSizeForPlayfieldAspectRatio(float size) { - // Preserve flashlight size through the playfield's aspect adjustment. return new Vector2(0, size * taikoPlayfield.DrawHeight / TaikoPlayfield.DEFAULT_HEIGHT); } protected override void UpdateFlashlightSize(float size) { - this.TransformTo(nameof(FlashlightSize), adjustSize(size), FLASHLIGHT_FADE_DURATION); + this.TransformTo(nameof(FlashlightSize), adjustSizeForPlayfieldAspectRatio(size), FLASHLIGHT_FADE_DURATION); } protected override string FragmentShader => "CircularFlashlight"; @@ -75,7 +82,7 @@ namespace osu.Game.Rulesets.Taiko.Mods FlashlightPosition = ToLocalSpace(taikoPlayfield.HitTarget.ScreenSpaceDrawQuad.Centre); ClearTransforms(targetMember: nameof(FlashlightSize)); - FlashlightSize = adjustSize(GetSize()); + FlashlightSize = adjustSizeForPlayfieldAspectRatio(GetSize()); flashlightProperties.Validate(); } From f5ca447b8e289712a9ffe8c6ff164f2d36aa87e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 25 Oct 2022 21:34:41 +0200 Subject: [PATCH 0226/2991] Rename one more "{duplicate -> clone}" reference --- osu.Game/Screens/Edit/Editor.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index c2899bc1ec..912681e114 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -304,7 +304,7 @@ namespace osu.Game.Screens.Edit cutMenuItem = new EditorMenuItem("Cut", MenuItemType.Standard, Cut), copyMenuItem = new EditorMenuItem("Copy", MenuItemType.Standard, Copy), pasteMenuItem = new EditorMenuItem("Paste", MenuItemType.Standard, Paste), - duplicateMenuItem = new EditorMenuItem("Clone", MenuItemType.Standard, Clone), + cloneMenuItem = new EditorMenuItem("Clone", MenuItemType.Standard, Clone), } }, new MenuItem("View") @@ -746,7 +746,7 @@ namespace osu.Game.Screens.Edit private EditorMenuItem cutMenuItem; private EditorMenuItem copyMenuItem; - private EditorMenuItem duplicateMenuItem; + private EditorMenuItem cloneMenuItem; private EditorMenuItem pasteMenuItem; private readonly BindableWithCurrent canCut = new BindableWithCurrent(); @@ -759,7 +759,7 @@ namespace osu.Game.Screens.Edit canCopy.Current.BindValueChanged(copy => { copyMenuItem.Action.Disabled = !copy.NewValue; - duplicateMenuItem.Action.Disabled = !copy.NewValue; + cloneMenuItem.Action.Disabled = !copy.NewValue; }, true); canPaste.Current.BindValueChanged(paste => pasteMenuItem.Action.Disabled = !paste.NewValue, true); } From 8505848b1a0efaf3682a7b703b94f95f95d902c2 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 25 Oct 2022 18:06:49 -0700 Subject: [PATCH 0227/2991] Scroll beatmap listing to top when searching via tags/source --- osu.Game/Overlays/BeatmapListingOverlay.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index 2be328427b..c73936da8a 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -115,6 +115,7 @@ namespace osu.Game.Overlays { filterControl.Search(query); Show(); + ScrollFlow.ScrollToStart(); } protected override BeatmapListingHeader CreateHeader() => new BeatmapListingHeader(); From d9d083752aeac9d1342084f63d6495d5a0e78a8b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 11:03:11 +0900 Subject: [PATCH 0228/2991] Clamp backwards index to total current items to fix edge case of item removal --- osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs index 34865c7f51..6366fc8050 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs @@ -118,7 +118,7 @@ namespace osu.Game.Screens.Select.Carousel return null; int forwardsIndex = lastSelectedIndex; - int backwardsIndex = lastSelectedIndex; + int backwardsIndex = Math.Min(lastSelectedIndex, Items.Count - 1); while (true) { From cbcebfa130f342f3900b86542e72ed8c2098a287 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 12:18:54 +0900 Subject: [PATCH 0229/2991] Remove switch back to selection tool to simplify test flow --- osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs index f6d3512fe6..f9cea5761b 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs @@ -79,8 +79,6 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddAssert("placement blueprint at (0, 0)", () => Precision.AlmostEquals(Editor.ChildrenOfType().Single().HitObject.Position, new Vector2(0, 0))); else AddAssert("placement blueprint at (1, 1)", () => Precision.AlmostEquals(Editor.ChildrenOfType().Single().HitObject.Position, new Vector2(1, 1))); - - AddStep("choose selection tool", () => InputManager.Key(Key.Number1)); } [Test] From 5f10b81af1dfaf0f717858961780538a1fc2498d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 12:55:59 +0900 Subject: [PATCH 0230/2991] Move distance snap grid test cursor behind grid to better visualise centre-points --- .../Editor/TestSceneOsuDistanceSnapGrid.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs index dc74d38cdc..f880739950 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs @@ -88,8 +88,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor RelativeSizeAxes = Axes.Both, Colour = Color4.SlateGray }, + new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position }, grid = new OsuDistanceSnapGrid(new HitCircle { Position = grid_position }), - new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position } }; }); @@ -166,8 +166,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor RelativeSizeAxes = Axes.Both, Colour = Color4.SlateGray }, + new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position }, grid = new OsuDistanceSnapGrid(new HitCircle { Position = grid_position }, new HitCircle { StartTime = 200 }), - new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position } }; }); From cab9a1c01203236748b6a72077dec351286d5d34 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 13:08:19 +0900 Subject: [PATCH 0231/2991] Add test coverage of distance snap grid failing visually --- .../Editor/TestSceneOsuDistanceSnapGrid.cs | 43 +++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs index f880739950..1b67fc2ca9 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs @@ -4,12 +4,15 @@ #nullable disable using System; +using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Input; +using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Overlays; @@ -52,6 +55,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor }; private OsuDistanceSnapGrid grid; + private SnappingCursorContainer cursor; public TestSceneOsuDistanceSnapGrid() { @@ -88,7 +92,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor RelativeSizeAxes = Axes.Both, Colour = Color4.SlateGray }, - new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position }, + cursor = new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position }, grid = new OsuDistanceSnapGrid(new HitCircle { Position = grid_position }), }; }); @@ -154,6 +158,37 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertSnappedDistance(expectedDistance); } + [Test] + public void TestReferenceObjectNotOnSnapGrid() + { + AddStep("create grid", () => + { + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.SlateGray + }, + cursor = new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position }, + grid = new OsuDistanceSnapGrid(new HitCircle + { + Position = grid_position, + // This is important. It sets the reference object to a point in time that isn't on the current snap divisor's grid. + // We are testing that the grid's display is offset correctly. + StartTime = 40, + }), + }; + }); + + AddStep("move mouse to point", () => InputManager.MoveMouseTo(grid.ToScreenSpace(grid_position + new Vector2(beat_length, 0) * 2))); + + AddAssert("Ensure cursor is on a grid line", () => + { + return grid.ChildrenOfType().Any(p => Precision.AlmostEquals(p.ScreenSpaceDrawQuad.TopRight.X, grid.ToScreenSpace(cursor.LastSnappedPosition).X)); + }); + } + [Test] public void TestLimitedDistance() { @@ -166,7 +201,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor RelativeSizeAxes = Axes.Both, Colour = Color4.SlateGray }, - new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position }, + cursor = new SnappingCursorContainer { GetSnapPosition = v => grid.GetSnappedPosition(grid.ToLocalSpace(v)).position }, grid = new OsuDistanceSnapGrid(new HitCircle { Position = grid_position }, new HitCircle { StartTime = 200 }), }; }); @@ -186,6 +221,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor { public Func GetSnapPosition; + public Vector2 LastSnappedPosition { get; private set; } + private readonly Drawable cursor; private InputManager inputManager; @@ -214,7 +251,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor protected override void Update() { base.Update(); - cursor.Position = GetSnapPosition.Invoke(inputManager.CurrentState.Mouse.Position); + cursor.Position = LastSnappedPosition = GetSnapPosition.Invoke(inputManager.CurrentState.Mouse.Position); } } } From 2016d330553bc1dc4ebbe3135011e71454590b8e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 13:10:39 +0900 Subject: [PATCH 0232/2991] Offset start of distance snap grid drawing if reference object's start time doesn't align Closes #20938. --- .../Edit/Compose/Components/CircularDistanceSnapGrid.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/CircularDistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/CircularDistanceSnapGrid.cs index 98079116cd..6e54e98740 100644 --- a/osu.Game/Screens/Edit/Compose/Components/CircularDistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/CircularDistanceSnapGrid.cs @@ -53,9 +53,16 @@ namespace osu.Game.Screens.Edit.Compose.Components float maxDistance = new Vector2(dx, dy).Length; int requiredCircles = Math.Min(MaxIntervals, (int)(maxDistance / DistanceBetweenTicks)); + // We need to offset the drawn lines to the next valid snap for the currently selected divisor. + // + // Picture the scenario where the user has just placed an object on a 1/2 snap, then changes to + // 1/3 snap and expects to be able to place the next object on a valid 1/3 snap, regardless of the + // fact that the 1/2 snap reference object is not valid for 1/3 snapping. + float offset = SnapProvider.FindSnappedDistance(ReferenceObject, 0); + for (int i = 0; i < requiredCircles; i++) { - float diameter = (i + 1) * DistanceBetweenTicks * 2; + float diameter = (offset + (i + 1) * DistanceBetweenTicks) * 2; AddInternal(new Ring(ReferenceObject, GetColourForIndexFromPlacement(i)) { From 8d9a85e9e588b1cc964ecc6514ed1d105b713c10 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 13:14:12 +0900 Subject: [PATCH 0233/2991] Fix typos in xmldoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Rulesets/Edit/ExpandableButton.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Edit/ExpandableButton.cs b/osu.Game/Rulesets/Edit/ExpandableButton.cs index 5b60a2536d..a66600bd58 100644 --- a/osu.Game/Rulesets/Edit/ExpandableButton.cs +++ b/osu.Game/Rulesets/Edit/ExpandableButton.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Edit private LocalisableString contractedLabelText; /// - /// The label text to display when this slider is in a contracted state. + /// The label text to display when this button is in a contracted state. /// public LocalisableString ContractedLabelText { @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Edit private LocalisableString expandedLabelText; /// - /// The label text to display when this slider is in an expanded state. + /// The label text to display when this button is in an expanded state. /// public LocalisableString ExpandedLabelText { From 54ae16badc5eeeb5c5f63cc59a3b3a48832da203 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 13:27:23 +0900 Subject: [PATCH 0234/2991] Move distance snap toggle button implementation to `DistancedHitObjectComposer` --- .../Edit/CatchHitObjectComposer.cs | 39 +------------------ .../Edit/OsuHitObjectComposer.cs | 19 ++------- .../Edit/DistancedHitObjectComposer.cs | 39 +++++++++++++++++++ 3 files changed, 44 insertions(+), 53 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index 9ba17c89ff..721ef64dc0 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -10,7 +10,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Sprites; using osu.Framework.Input; using osu.Framework.Input.Events; using osu.Game.Beatmaps; @@ -23,7 +22,6 @@ using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.UI; -using osu.Game.Screens.Edit.Components.TernaryButtons; using osu.Game.Screens.Edit.Compose.Components; using osuTK; @@ -35,8 +33,6 @@ namespace osu.Game.Rulesets.Catch.Edit private CatchDistanceSnapGrid distanceSnapGrid; - private readonly Bindable distanceSnapToggle = new Bindable(); - private InputManager inputManager; private readonly BindableDouble timeRangeMultiplier = new BindableDouble(1) @@ -88,34 +84,6 @@ namespace osu.Game.Rulesets.Catch.Edit updateDistanceSnapGrid(); } - protected override bool OnKeyDown(KeyDownEvent e) - { - if (e.Repeat) - return false; - - handleToggleViaKey(e); - return base.OnKeyDown(e); - } - - protected override void OnKeyUp(KeyUpEvent e) - { - handleToggleViaKey(e); - base.OnKeyUp(e); - } - - private bool distanceSnapMomentary; - - private void handleToggleViaKey(KeyboardEvent key) - { - bool altPressed = key.AltPressed; - - if (altPressed != distanceSnapMomentary) - { - distanceSnapMomentary = altPressed; - distanceSnapToggle.Value = distanceSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; - } - } - public override bool OnPressed(KeyBindingPressEvent e) { switch (e.Action) @@ -148,11 +116,6 @@ namespace osu.Game.Rulesets.Catch.Edit new BananaShowerCompositionTool() }; - protected override IEnumerable CreateTernaryButtons() => base.CreateTernaryButtons().Concat(new[] - { - new TernaryButton(distanceSnapToggle, "Distance Snap", () => new SpriteIcon { Icon = FontAwesome.Solid.Ruler }) - }); - public override SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition, SnapType snapType = SnapType.All) { var result = base.FindSnappedPositionAndTime(screenSpacePosition, snapType); @@ -224,7 +187,7 @@ namespace osu.Game.Rulesets.Catch.Edit private void updateDistanceSnapGrid() { - if (distanceSnapToggle.Value != TernaryState.True) + if (DistanceSnapToggle.Value != TernaryState.True) { distanceSnapGrid.Hide(); return; diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index bf7cddd099..a543cb62fa 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -46,12 +46,10 @@ namespace osu.Game.Rulesets.Osu.Edit new SpinnerCompositionTool() }; - private readonly Bindable distanceSnapToggle = new Bindable(); private readonly Bindable rectangularGridSnapToggle = new Bindable(); protected override IEnumerable CreateTernaryButtons() => base.CreateTernaryButtons().Concat(new[] { - new TernaryButton(distanceSnapToggle, "Distance Snap", () => new SpriteIcon { Icon = FontAwesome.Solid.Ruler }), new TernaryButton(rectangularGridSnapToggle, "Grid Snap", () => new SpriteIcon { Icon = FontAwesome.Solid.Th }) }); @@ -82,7 +80,7 @@ namespace osu.Game.Rulesets.Osu.Edit placementObject = EditorBeatmap.PlacementObject.GetBoundCopy(); placementObject.ValueChanged += _ => updateDistanceSnapGrid(); - distanceSnapToggle.ValueChanged += _ => updateDistanceSnapGrid(); + DistanceSnapToggle.ValueChanged += _ => updateDistanceSnapGrid(); // we may be entering the screen with a selection already active updateDistanceSnapGrid(); @@ -128,7 +126,7 @@ namespace osu.Game.Rulesets.Osu.Edit if (snapType.HasFlagFast(SnapType.Grids)) { - if (distanceSnapToggle.Value == TernaryState.True && distanceSnapGrid != null) + if (DistanceSnapToggle.Value == TernaryState.True && distanceSnapGrid != null) { (Vector2 pos, double time) = distanceSnapGrid.GetSnappedPosition(distanceSnapGrid.ToLocalSpace(screenSpacePosition)); @@ -197,7 +195,7 @@ namespace osu.Game.Rulesets.Osu.Edit distanceSnapGridCache.Invalidate(); distanceSnapGrid = null; - if (distanceSnapToggle.Value != TernaryState.True) + if (DistanceSnapToggle.Value != TernaryState.True) return; switch (BlueprintContainer.CurrentTool) @@ -242,24 +240,15 @@ namespace osu.Game.Rulesets.Osu.Edit protected override bool AdjustDistanceSpacing(GlobalAction action, float amount) { // To allow better visualisation, ensure that the spacing grid is visible before adjusting. - distanceSnapToggle.Value = TernaryState.True; + DistanceSnapToggle.Value = TernaryState.True; return base.AdjustDistanceSpacing(action, amount); } - private bool distanceSnapMomentary; private bool gridSnapMomentary; private void handleToggleViaKey(KeyboardEvent key) { - bool altPressed = key.AltPressed; - - if (altPressed != distanceSnapMomentary) - { - distanceSnapMomentary = altPressed; - distanceSnapToggle.Value = distanceSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; - } - bool shiftPressed = key.ShiftPressed; if (shiftPressed != gridSnapMomentary) diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index 449996131d..cd7c25509c 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -3,6 +3,8 @@ #nullable disable +using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions; @@ -10,6 +12,7 @@ using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Localisation; @@ -20,6 +23,7 @@ using osu.Game.Overlays; using osu.Game.Overlays.OSD; using osu.Game.Overlays.Settings.Sections; using osu.Game.Rulesets.Objects; +using osu.Game.Screens.Edit.Components.TernaryButtons; namespace osu.Game.Rulesets.Edit { @@ -48,6 +52,10 @@ namespace osu.Game.Rulesets.Edit [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } + protected readonly Bindable DistanceSnapToggle = new Bindable(); + + private bool distanceSnapMomentary; + protected DistancedHitObjectComposer(Ruleset ruleset) : base(ruleset) { @@ -105,6 +113,37 @@ namespace osu.Game.Rulesets.Edit } } + protected override IEnumerable CreateTernaryButtons() => base.CreateTernaryButtons().Concat(new[] + { + new TernaryButton(DistanceSnapToggle, "Distance Snap", () => new SpriteIcon { Icon = FontAwesome.Solid.Ruler }) + }); + + protected override bool OnKeyDown(KeyDownEvent e) + { + if (e.Repeat) + return false; + + handleToggleViaKey(e); + return base.OnKeyDown(e); + } + + protected override void OnKeyUp(KeyUpEvent e) + { + handleToggleViaKey(e); + base.OnKeyUp(e); + } + + private void handleToggleViaKey(KeyboardEvent key) + { + bool altPressed = key.AltPressed; + + if (altPressed != distanceSnapMomentary) + { + distanceSnapMomentary = altPressed; + DistanceSnapToggle.Value = DistanceSnapToggle.Value == TernaryState.False ? TernaryState.True : TernaryState.False; + } + } + public virtual bool OnPressed(KeyBindingPressEvent e) { switch (e.Action) From 6b53ea3400511e74b8c108189f0014a73eaa4f63 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 13:37:01 +0900 Subject: [PATCH 0235/2991] Enable distance snapping when DS value is changed via user interaction --- .../Rulesets/Edit/DistancedHitObjectComposer.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index ab320af902..ca7ca79813 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -89,8 +89,9 @@ namespace osu.Game.Rulesets.Edit { distanceSpacingSlider = new ExpandableSlider> { - Current = { BindTarget = DistanceSpacingMultiplier }, KeyboardStep = adjust_step, + // Manual binding in LoadComplete to handle one-way event flow. + Current = DistanceSpacingMultiplier.GetUnboundCopy(), }, currentDistanceSpacingButton = new ExpandableButton { @@ -101,6 +102,7 @@ namespace osu.Game.Rulesets.Edit Debug.Assert(objects != null); DistanceSpacingMultiplier.Value = ReadCurrentDistanceSnap(objects.Value.before, objects.Value.after); + DistanceSnapToggle.Value = TernaryState.True; }, RelativeSizeAxes = Axes.X, } @@ -173,6 +175,14 @@ namespace osu.Game.Rulesets.Edit EditorBeatmap.BeatmapInfo.DistanceSpacing = multiplier.NewValue; }, true); + + // Manual binding to handle enabling distance spacing when the slider is interacted with. + distanceSpacingSlider.Current.BindValueChanged(spacing => + { + DistanceSpacingMultiplier.Value = spacing.NewValue; + DistanceSnapToggle.Value = TernaryState.True; + }); + DistanceSpacingMultiplier.BindValueChanged(spacing => distanceSpacingSlider.Current.Value = spacing.NewValue); } } @@ -245,6 +255,7 @@ namespace osu.Game.Rulesets.Edit else if (action == GlobalAction.EditorDecreaseDistanceSpacing) DistanceSpacingMultiplier.Value -= amount; + DistanceSnapToggle.Value = TernaryState.True; return true; } From f8a4af5e0e400067471fb0a301cf945fcdaba023 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 13:45:06 +0900 Subject: [PATCH 0236/2991] Add osu!catch read-distance-spacing implementation --- .../Edit/CatchHitObjectComposer.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index 004919e807..220bc49203 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -3,6 +3,7 @@ #nullable disable +using System; using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; @@ -79,8 +80,15 @@ namespace osu.Game.Rulesets.Catch.Edit protected override double ReadCurrentDistanceSnap(HitObject before, HitObject after) { - // TODO: catch lol - return 1; + // osu!catch's distance snap implementation is limited, in that a custom spacing cannot be specified. + // Therefore this functionality is not currently used. + // + // The implementation below is probably correct but should be checked if/when exposed via controls. + + float expectedDistance = DurationToDistance(before, after.StartTime - before.GetEndTime()); + float actualDistance = Math.Abs(((CatchHitObject)before).EffectiveX - ((CatchHitObject)after).EffectiveX); + + return actualDistance / expectedDistance; } protected override void Update() From d03161ec013ad0a1b670aad474158c3349e85352 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 14:39:39 +0900 Subject: [PATCH 0237/2991] Apply distance snap time component even when nearby object snap kicks in --- .../Edit/OsuHitObjectComposer.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 67061bdaf2..f9a952c2fb 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -13,6 +13,7 @@ using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; +using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Edit; @@ -120,7 +121,24 @@ namespace osu.Game.Rulesets.Osu.Edit public override SnapResult FindSnappedPositionAndTime(Vector2 screenSpacePosition, SnapType snapType = SnapType.All) { if (snapType.HasFlagFast(SnapType.NearbyObjects) && snapToVisibleBlueprints(screenSpacePosition, out var snapResult)) + { + // In the case of snapping to nearby objects, a time value is not provided. + // This matches the stable editor (which also uses current time), but with the introduction of time-snapping distance snap + // this could result in unexpected behaviour when distance snapping is turned on an a user attempts to place an object that is + // BOTH on a valid distance snap ring, and also at the same position as a previous object. + // + // We want to ensure that in this particular case, the time-snapping component of distance snap is still applied. + // The easiest way to ensure this is to attempt application of distance snap after a nearby object is found, and copy over + // the time value if the proposed positions are roughly the same. + if (snapType.HasFlagFast(SnapType.Grids) && distanceSnapToggle.Value == TernaryState.True && distanceSnapGrid != null) + { + (Vector2 distanceSnappedPosition, double distanceSnappedTime) = distanceSnapGrid.GetSnappedPosition(distanceSnapGrid.ToLocalSpace(snapResult.ScreenSpacePosition)); + if (Precision.AlmostEquals(distanceSnapGrid.ToScreenSpace(distanceSnappedPosition), snapResult.ScreenSpacePosition, 1)) + snapResult.Time = distanceSnappedTime; + } + return snapResult; + } SnapResult result = base.FindSnappedPositionAndTime(screenSpacePosition, snapType); From 6991195d69b6a444ec4aad8b5e915fc105ce6d99 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Tue, 25 Oct 2022 13:01:24 +0900 Subject: [PATCH 0238/2991] let editor dim different from gameplay dim --- .../Editing/TestSceneEditorTestGameplay.cs | 15 ++++-- osu.Game/Configuration/OsuConfigManager.cs | 4 +- .../Screens/Edit/BackgroundDimMenuItem.cs | 46 +++++++++++++++++++ osu.Game/Screens/Edit/Editor.cs | 25 ++++------ 4 files changed, 68 insertions(+), 22 deletions(-) create mode 100644 osu.Game/Screens/Edit/BackgroundDimMenuItem.cs diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs index a5d115331d..9722c60cba 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs @@ -7,10 +7,12 @@ using System; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Screens; using osu.Framework.Testing; using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; @@ -21,7 +23,6 @@ using osu.Game.Screens.Edit.GameplayTest; using osu.Game.Screens.Play; using osu.Game.Storyboards; using osu.Game.Tests.Beatmaps.IO; -using osuTK.Graphics; using osuTK.Input; namespace osu.Game.Tests.Visual.Editing @@ -40,6 +41,14 @@ namespace osu.Game.Tests.Visual.Editing private BeatmapSetInfo importedBeatmapSet; + private Bindable editorDim; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + editorDim = config.GetBindable(OsuSetting.EditorDim); + } + public override void SetUpSteps() { AddStep("import test beatmap", () => importedBeatmapSet = BeatmapImportHelper.LoadOszIntoOsu(game).GetResultSafely()); @@ -77,7 +86,7 @@ namespace osu.Game.Tests.Visual.Editing // this test cares about checking the background belonging to the editor specifically, so check that using reference equality // (as `.Equals()` cannot discern between the two, as they technically share the same database GUID). var background = this.ChildrenOfType().Single(b => ReferenceEquals(b.Beatmap.BeatmapInfo, EditorBeatmap.BeatmapInfo)); - return background.Colour == Color4.DarkGray && background.BlurAmount.Value == 0; + return background.DimAmount.Value == editorDim.Value && background.BlurAmount.Value == 0; }); AddAssert("no mods selected", () => SelectedMods.Value.Count == 0); } @@ -110,7 +119,7 @@ namespace osu.Game.Tests.Visual.Editing // this test cares about checking the background belonging to the editor specifically, so check that using reference equality // (as `.Equals()` cannot discern between the two, as they technically share the same database GUID). var background = this.ChildrenOfType().Single(b => ReferenceEquals(b.Beatmap.BeatmapInfo, EditorBeatmap.BeatmapInfo)); - return background.Colour == Color4.DarkGray && background.BlurAmount.Value == 0; + return background.DimAmount.Value == editorDim.Value && background.BlurAmount.Value == 0; }); AddStep("start track", () => EditorClock.Start()); diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index f8c851757e..30299eb062 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -122,7 +122,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.PositionalHitsoundsLevel, 0.2f, 0, 1); SetDefault(OsuSetting.DimLevel, 0.7, 0, 1, 0.01); SetDefault(OsuSetting.BlurLevel, 0, 0, 1, 0.01); - SetDefault(OsuSetting.EditorUseDim, false); + SetDefault(OsuSetting.EditorDim, 0.25f); SetDefault(OsuSetting.LightenDuringBreaks, true); SetDefault(OsuSetting.HitLighting, true); @@ -293,7 +293,7 @@ namespace osu.Game.Configuration GameplayCursorDuringTouch, DimLevel, BlurLevel, - EditorUseDim, + EditorDim, LightenDuringBreaks, ShowStoryboard, KeyOverlay, diff --git a/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs b/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs new file mode 100644 index 0000000000..b8644ed690 --- /dev/null +++ b/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs @@ -0,0 +1,46 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Framework.Bindables; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Edit +{ + internal class BackgroundDimMenuItem : MenuItem + { + private readonly Bindable backgroudDim; + + private readonly Dictionary menuItemLookup = new Dictionary(); + + public BackgroundDimMenuItem(Bindable backgroudDim) + : base("Background dim") + { + Items = new[] + { + createMenuItem(0f), + createMenuItem(0.25f), + createMenuItem(0.5f), + createMenuItem(0.75f), + createMenuItem(1f), + }; + + this.backgroudDim = backgroudDim; + backgroudDim.BindValueChanged(dim => + { + foreach (var kvp in menuItemLookup) + kvp.Value.State.Value = kvp.Key == dim.NewValue ? TernaryState.True : TernaryState.False; + }, true); + } + + private TernaryStateRadioMenuItem createMenuItem(float dim) + { + var item = new TernaryStateRadioMenuItem($"{dim * 100}%", MenuItemType.Standard, _ => updateOpacity(dim)); + menuItemLookup[dim] = item; + return item; + } + + private void updateOpacity(float dim) => backgroudDim.Value = dim; + } +} diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 9cfd1badd1..3c91d302ae 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -51,7 +51,6 @@ using osu.Game.Screens.Edit.Timing; using osu.Game.Screens.Edit.Verify; using osu.Game.Screens.Play; using osu.Game.Users; -using osuTK.Graphics; using osuTK.Input; using CommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings; @@ -176,7 +175,7 @@ namespace osu.Game.Screens.Edit [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } - private Bindable useUserDim; + private Bindable editorDim; public Editor(EditorLoader loader = null) { @@ -262,8 +261,7 @@ namespace osu.Game.Screens.Edit OsuMenuItem undoMenuItem; OsuMenuItem redoMenuItem; - TernaryStateRadioMenuItem backgroundDim; - useUserDim = config.GetBindable(OsuSetting.EditorUseDim); + editorDim = config.GetBindable(OsuSetting.EditorDim); AddInternal(new OsuContextMenuContainer { @@ -316,7 +314,7 @@ namespace osu.Game.Screens.Edit Items = new MenuItem[] { new WaveformOpacityMenuItem(config.GetBindable(OsuSetting.EditorWaveformOpacity)), - backgroundDim = new TernaryStateRadioMenuItem("Background Dim", MenuItemType.Standard, _ => useUserDim.Value = !useUserDim.Value), + new BackgroundDimMenuItem(editorDim), } } } @@ -337,12 +335,7 @@ namespace osu.Game.Screens.Edit changeHandler?.CanUndo.BindValueChanged(v => undoMenuItem.Action.Disabled = !v.NewValue, true); changeHandler?.CanRedo.BindValueChanged(v => redoMenuItem.Action.Disabled = !v.NewValue, true); - useUserDim.BindValueChanged(s => - { - dimBackground(); - backgroundDim.State.Value = s.NewValue ? TernaryState.True : TernaryState.False; - }); - backgroundDim.State.Value = useUserDim.Value ? TernaryState.True : TernaryState.False; + editorDim.BindValueChanged(_ => dimBackground()); } [Resolved] @@ -638,10 +631,8 @@ namespace osu.Game.Screens.Edit { ApplyToBackground(b => { - // todo: temporary. we want to be applying dim using the UserDimContainer eventually. - if (!useUserDim.Value) b.FadeColour(Color4.DarkGray, 500); - - b.IgnoreUserSettings.Value = !useUserDim.Value; + b.IgnoreUserSettings.Value = true; + b.DimAmount.Value = editorDim.Value; b.BlurAmount.Value = 0; }); } @@ -671,8 +662,8 @@ namespace osu.Game.Screens.Edit ApplyToBackground(b => { - b.FadeColour(Color4.White, 500); - b.IgnoreUserSettings.Value = true; + //b.DimAmount.UnbindAll(); + b.DimAmount.Value = 0; }); resetTrack(); From 614011d612b760d94b97f6d23df360a75b6649d8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 15:25:50 +0900 Subject: [PATCH 0239/2991] Update `TestSceneObjectOrderedHitPolicy` to provide better output --- osu.Game.Rulesets.Osu.Tests/TestSceneObjectOrderedHitPolicy.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneObjectOrderedHitPolicy.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneObjectOrderedHitPolicy.cs index 1665c40b40..ed1891b7d9 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneObjectOrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneObjectOrderedHitPolicy.cs @@ -377,7 +377,7 @@ namespace osu.Game.Rulesets.Osu.Tests private void addJudgementAssert(OsuHitObject hitObject, HitResult result) { AddAssert($"({hitObject.GetType().ReadableName()} @ {hitObject.StartTime}) judgement is {result}", - () => judgementResults.Single(r => r.HitObject == hitObject).Type == result); + () => judgementResults.Single(r => r.HitObject == hitObject).Type, () => Is.EqualTo(result)); } private void addJudgementAssert(string name, Func hitObject, HitResult result) From 674ae9e7427e06dfbffb9287a0c5f7a39fa11f3a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 15:26:20 +0900 Subject: [PATCH 0240/2991] Refactor `DrawableSliderHead` to never update the drawable position Slider heads are guaranteed to always be drawn at (0,0). This fixes weird behaviour in the editor, but also simplifies things in the process. Win-win. Closes #20644. --- .../Objects/Drawables/DrawableHitCircle.cs | 9 +++++++-- .../Objects/Drawables/DrawableSliderHead.cs | 19 +++++-------------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index 23db29b9a6..841a52da7b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -102,8 +102,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Size = HitArea.DrawSize; - PositionBindable.BindValueChanged(_ => Position = HitObject.StackedPosition); - StackHeightBindable.BindValueChanged(_ => Position = HitObject.StackedPosition); + PositionBindable.BindValueChanged(_ => UpdatePosition()); + StackHeightBindable.BindValueChanged(_ => UpdatePosition()); ScaleBindable.BindValueChanged(scale => scaleContainer.Scale = new Vector2(scale.NewValue)); } @@ -134,6 +134,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } } + protected virtual void UpdatePosition() + { + Position = HitObject.StackedPosition; + } + public override void Shake() => shakeContainer.Shake(); protected override void CheckForResult(bool userTriggered, double timeOffset) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs index 80b9544e5b..d1d749d7e2 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs @@ -6,7 +6,6 @@ using System; using System.Diagnostics; using JetBrains.Annotations; -using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Scoring; @@ -43,13 +42,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { } - [BackgroundDependencyLoader] - private void load() - { - PositionBindable.BindValueChanged(_ => updatePosition()); - pathVersion.BindValueChanged(_ => updatePosition()); - } - protected override void OnFree() { base.OnFree(); @@ -57,6 +49,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables pathVersion.UnbindFrom(DrawableSlider.PathVersion); } + protected override void UpdatePosition() + { + // Slider head is always drawn at (0,0). + } + protected override void OnApply() { base.OnApply(); @@ -100,11 +97,5 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables base.Shake(); DrawableSlider.Shake(); } - - private void updatePosition() - { - if (Slider != null) - Position = HitObject.Position - Slider.Position; - } } } From 81bb00c25829fca1d394775961bb8e10e28cec2e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 24 Oct 2022 16:57:45 +0900 Subject: [PATCH 0241/2991] Add argon transformer for osu!catch (and basic new catcher design) --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 4 + .../Skinning/Argon/ArgonCatcher.cs | 86 ++++++++ .../Skinning/Argon/ArgonJudgementPiece.cs | 193 ++++++++++++++++++ .../Argon/CatchArgonSkinTransformer.cs | 34 +++ 4 files changed, 317 insertions(+) create mode 100644 osu.Game.Rulesets.Catch/Skinning/Argon/ArgonCatcher.cs create mode 100644 osu.Game.Rulesets.Catch/Skinning/Argon/ArgonJudgementPiece.cs create mode 100644 osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 5c9c95827a..e0f7820262 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -17,6 +17,7 @@ using osu.Game.Rulesets.Catch.Edit; using osu.Game.Rulesets.Catch.Mods; using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Catch.Scoring; +using osu.Game.Rulesets.Catch.Skinning.Argon; using osu.Game.Rulesets.Catch.Skinning.Legacy; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Difficulty; @@ -188,6 +189,9 @@ namespace osu.Game.Rulesets.Catch { case LegacySkin: return new CatchLegacySkinTransformer(skin); + + case ArgonSkin: + return new CatchArgonSkinTransformer(skin); } return null; diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonCatcher.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonCatcher.cs new file mode 100644 index 0000000000..4e3439cb2b --- /dev/null +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonCatcher.cs @@ -0,0 +1,86 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Catch.UI; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Catch.Skinning.Argon +{ + public class ArgonCatcher : CompositeDrawable + { + [Resolved] + private Bindable currentState { get; set; } = null!; + + [BackgroundDependencyLoader] + private void load() + { + RelativeSizeAxes = Axes.Both; + + InternalChildren = new Drawable[] + { + new Container + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + Height = 10, + Children = new Drawable[] + { + new Circle + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + }, + new Box + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreRight, + Colour = Color4.White, + Alpha = 0.25f, + RelativeSizeAxes = Axes.X, + X = -2, + Width = 20, + Height = 1.8f, + }, + new Circle + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreRight, + Colour = Color4.White, + RelativeSizeAxes = Axes.X, + X = -2, + Width = 15 / 170f, + Height = 4, + }, + new Box + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreLeft, + Colour = Color4.White, + Alpha = 0.25f, + RelativeSizeAxes = Axes.X, + X = 2, + Width = 20, + Height = 1.8f, + }, + new Circle + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreLeft, + Colour = Color4.White, + X = 2, + RelativeSizeAxes = Axes.X, + Width = 15 / 170f, + Height = 4, + }, + } + }, + }; + } + } +} diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonJudgementPiece.cs new file mode 100644 index 0000000000..59e8b5a0b3 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonJudgementPiece.cs @@ -0,0 +1,193 @@ +// 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.Allocation; +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Utils; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Scoring; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Catch.Skinning.Argon +{ + public class ArgonJudgementPiece : CompositeDrawable, IAnimatableJudgement + { + protected readonly HitResult Result; + + protected SpriteText JudgementText { get; private set; } = null!; + + private RingExplosion? ringExplosion; + + [Resolved] + private OsuColour colours { get; set; } = null!; + + public ArgonJudgementPiece(HitResult result) + { + Result = result; + Origin = Anchor.Centre; + Y = 160; + } + + [BackgroundDependencyLoader] + private void load() + { + AutoSizeAxes = Axes.Both; + + InternalChildren = new Drawable[] + { + JudgementText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Text = Result.GetDescription().ToUpperInvariant(), + Colour = colours.ForHitResult(Result), + Blending = BlendingParameters.Additive, + Spacing = new Vector2(10, 0), + Font = OsuFont.Default.With(size: 28, weight: FontWeight.Regular), + }, + }; + + if (Result.IsHit()) + { + AddInternal(ringExplosion = new RingExplosion(Result) + { + Colour = colours.ForHitResult(Result), + }); + } + } + + /// + /// Plays the default animation for this judgement piece. + /// + /// + /// The base implementation only handles fade (for all result types) and misses. + /// Individual rulesets are recommended to implement their appropriate hit animations. + /// + public virtual void PlayAnimation() + { + switch (Result) + { + default: + JudgementText + .ScaleTo(Vector2.One) + .ScaleTo(new Vector2(1.4f), 1800, Easing.OutQuint); + break; + + case HitResult.Miss: + this.ScaleTo(1.6f); + this.ScaleTo(1, 100, Easing.In); + + this.MoveTo(Vector2.Zero); + this.MoveToOffset(new Vector2(0, 100), 800, Easing.InQuint); + + this.RotateTo(0); + this.RotateTo(40, 800, Easing.InQuint); + break; + } + + this.FadeOutFromOne(800); + + ringExplosion?.PlayAnimation(); + } + + public Drawable? GetAboveHitObjectsProxiedContent() => null; + + private class RingExplosion : CompositeDrawable + { + private readonly float travel = 52; + + public RingExplosion(HitResult result) + { + const float thickness = 4; + + const float small_size = 9; + const float large_size = 14; + + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + Blending = BlendingParameters.Additive; + + int countSmall = 0; + int countLarge = 0; + + switch (result) + { + case HitResult.Meh: + countSmall = 3; + travel *= 0.3f; + break; + + case HitResult.Ok: + case HitResult.Good: + countSmall = 4; + travel *= 0.6f; + break; + + case HitResult.Great: + case HitResult.Perfect: + countSmall = 4; + countLarge = 4; + break; + } + + for (int i = 0; i < countSmall; i++) + AddInternal(new RingPiece(thickness) { Size = new Vector2(small_size) }); + + for (int i = 0; i < countLarge; i++) + AddInternal(new RingPiece(thickness) { Size = new Vector2(large_size) }); + } + + public void PlayAnimation() + { + foreach (var c in InternalChildren) + { + const float start_position_ratio = 0.3f; + + float direction = RNG.NextSingle(0, 360); + float distance = RNG.NextSingle(travel / 2, travel); + + c.MoveTo(new Vector2( + MathF.Cos(direction) * distance * start_position_ratio, + MathF.Sin(direction) * distance * start_position_ratio + )); + + c.MoveTo(new Vector2( + MathF.Cos(direction) * distance, + MathF.Sin(direction) * distance + ), 600, Easing.OutQuint); + } + + this.FadeOutFromOne(1000, Easing.OutQuint); + } + + public class RingPiece : CircularContainer + { + public RingPiece(float thickness = 9) + { + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + Masking = true; + BorderThickness = thickness; + BorderColour = Color4.White; + + Child = new Box + { + AlwaysPresent = true, + Alpha = 0, + RelativeSizeAxes = Axes.Both + }; + } + } + } + } +} diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs new file mode 100644 index 0000000000..764f3c6cbd --- /dev/null +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs @@ -0,0 +1,34 @@ +// 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.Graphics; +using osu.Game.Skinning; + +namespace osu.Game.Rulesets.Catch.Skinning.Argon +{ + public class CatchArgonSkinTransformer : SkinTransformer + { + public CatchArgonSkinTransformer(ISkin skin) + : base(skin) + { + } + + public override Drawable? GetDrawableComponent(ISkinComponent component) + { + switch (component) + { + case CatchSkinComponent osuComponent: + // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. + switch (osuComponent.Component) + { + case CatchSkinComponents.Catcher: + return new ArgonCatcher(); + } + + break; + } + + return base.GetDrawableComponent(component); + } + } +} From 4ff4de00b3f7eff901ff318ee26f0a1ed160af88 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 16:08:01 +0900 Subject: [PATCH 0242/2991] Add argon fruit design --- .../Skinning/Argon/ArgonFruitPiece.cs | 104 ++++++++++++++++++ .../Argon/CatchArgonSkinTransformer.cs | 3 + .../Skinning/Default/CatchHitObjectPiece.cs | 3 +- .../Skinning/Default/DropletPiece.cs | 2 +- .../Skinning/Default/FruitPiece.cs | 4 +- 5 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs new file mode 100644 index 0000000000..7a59254028 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs @@ -0,0 +1,104 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Framework.Utils; +using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Catch.Skinning.Default; +using osu.Game.Rulesets.Catch.UI; +using osuTK; + +namespace osu.Game.Rulesets.Catch.Skinning.Argon +{ + internal class ArgonFruitPiece : CatchHitObjectPiece + { + public readonly Bindable VisualRepresentation = new Bindable(); + + protected override Drawable HyperBorderPiece => hyperBorderPiece; + + private Drawable hyperBorderPiece = null!; + + private Container layers = null!; + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + RelativeSizeAxes = Axes.Both; + + Texture largeTexture = getTexture("A"); + + InternalChildren = new[] + { + new Circle + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(20), + }, + layers = new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Sprite + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Blending = BlendingParameters.Additive, + Alpha = 0.15f, + Texture = largeTexture + }, + new Sprite + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Blending = BlendingParameters.Additive, + Alpha = 0.5f, + Texture = getTexture("B") + }, + new Sprite + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Blending = BlendingParameters.Additive, + Texture = getTexture("C") + }, + } + }, + hyperBorderPiece = new Sprite + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Colour = Catcher.DEFAULT_HYPER_DASH_COLOUR, + Blending = BlendingParameters.Additive, + Alpha = 0.15f, + Texture = largeTexture, + }, + }; + + Texture getTexture(string type) => textures.Get($"Gameplay/catch/blob-{type}{RNG.Next(1, 7)}"); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + IndexInBeatmap.BindValueChanged(index => + { + VisualRepresentation.Value = Fruit.GetVisualRepresentation(index.NewValue); + }, true); + + AccentColour.BindValueChanged(colour => + { + foreach (var sprite in layers) + sprite.Colour = colour.NewValue; + }, true); + } + } +} diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs index 764f3c6cbd..621a71b1d1 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs @@ -23,6 +23,9 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon { case CatchSkinComponents.Catcher: return new ArgonCatcher(); + + case CatchSkinComponents.Fruit: + return new ArgonFruitPiece(); } break; diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs index 6cc5220699..fd1047f27e 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs @@ -7,6 +7,7 @@ using System; using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Catch.Objects.Drawables; using osuTK.Graphics; @@ -32,7 +33,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default /// A part of this piece that will be only visible when is true. /// [CanBeNull] - protected virtual HyperBorderPiece HyperBorderPiece => null; + protected virtual Drawable HyperBorderPiece => null; protected override void LoadComplete() { diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs index 6b7f25eed1..e4c2f04476 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs @@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default { public class DropletPiece : CatchHitObjectPiece { - protected override HyperBorderPiece HyperBorderPiece { get; } + protected override Drawable HyperBorderPiece { get; } public DropletPiece() { diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs index 8fb5c8f84a..9dce0e9129 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs @@ -19,13 +19,13 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default public readonly Bindable VisualRepresentation = new Bindable(); protected override BorderPiece BorderPiece { get; } - protected override HyperBorderPiece HyperBorderPiece { get; } + protected override Drawable HyperBorderPiece { get; } public FruitPiece() { RelativeSizeAxes = Axes.Both; - InternalChildren = new Drawable[] + InternalChildren = new[] { new FruitPulpFormation { From a475ca848d188d9ac490d4b3a6f6edc3c5250f5d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 16:31:40 +0900 Subject: [PATCH 0243/2991] Add rotation to fruit pieces --- .../Skinning/Argon/ArgonFruitPiece.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs index 7a59254028..9561659792 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs @@ -26,6 +26,8 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon private Container layers = null!; + private float rotationRandomness; + [BackgroundDependencyLoader] private void load(TextureStore textures) { @@ -99,6 +101,24 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon foreach (var sprite in layers) sprite.Colour = colour.NewValue; }, true); + + rotationRandomness = RNG.NextSingle(0.2f, 1) * (RNG.NextBool() ? -1 : 1); + } + + protected override void Update() + { + base.Update(); + + for (int i = 0; i < layers.Count; i++) + { + layers[i].Rotation += + // Layers are ordered from largest to smallest. Smaller layers should rotate more. + (i * 2) + * (float)Clock.ElapsedFrameTime + * 0.02f * rotationRandomness + // Each layer should alternate rotation direction. + * (i % 2 == 1 ? 1 : -1); + } } } } From 0a8a13f52915e90f30b60a62aecc048378cad645 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 17:01:58 +0900 Subject: [PATCH 0244/2991] Add argon banana piece --- .../Skinning/Argon/ArgonBananaPiece.cs | 82 +++++++++++++++++++ .../Argon/CatchArgonSkinTransformer.cs | 3 + 2 files changed, 85 insertions(+) create mode 100644 osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs new file mode 100644 index 0000000000..49edc80770 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs @@ -0,0 +1,82 @@ +// 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.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics.Containers; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Catch.Skinning.Argon +{ + internal class ArgonBananaPiece : ArgonFruitPiece + { + [BackgroundDependencyLoader] + private void load() + { + AddInternal(new UprightAspectMaintainingContainer + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Children = new Drawable[] + { + new Circle + { + Colour = Color4.White.Opacity(0.4f), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Blending = BlendingParameters.Additive, + Size = new Vector2(8), + Scale = new Vector2(30, 1), + }, + new Box + { + Colour = ColourInfo.GradientHorizontal(Color4.White.Opacity(0), Color4.White), + RelativeSizeAxes = Axes.X, + Blending = BlendingParameters.Additive, + Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + Width = 1.6f, + Height = 2, + }, + new Box + { + Colour = ColourInfo.GradientHorizontal(Color4.White, Color4.White.Opacity(0)), + RelativeSizeAxes = Axes.X, + Blending = BlendingParameters.Additive, + Anchor = Anchor.Centre, + Origin = Anchor.CentreLeft, + Width = 1.6f, + Height = 2, + }, + new Circle + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(1.2f), + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Hollow = false, + Colour = Color4.White.Opacity(0.1f), + Radius = 50, + }, + Child = + { + Alpha = 0, + AlwaysPresent = true, + }, + BorderColour = Color4.White.Opacity(0.1f), + BorderThickness = 3, + }, + } + }); + } + } +} diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs index 621a71b1d1..b55706b6d0 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs @@ -26,6 +26,9 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon case CatchSkinComponents.Fruit: return new ArgonFruitPiece(); + + case CatchSkinComponents.Banana: + return new ArgonBananaPiece(); } break; From 2deaae270c19d991e7b12fc1280146efa3c11b2c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 17:12:20 +0900 Subject: [PATCH 0245/2991] Fix catcher not consdiering allowable catch range --- .../Skinning/Argon/ArgonCatcher.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonCatcher.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonCatcher.cs index 4e3439cb2b..ffd99aff4a 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonCatcher.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonCatcher.cs @@ -34,48 +34,51 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon new Circle { RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, Colour = Color4.White, + Width = Catcher.ALLOWED_CATCH_RANGE, }, new Box { + Name = "long line left", Anchor = Anchor.CentreLeft, Origin = Anchor.CentreRight, Colour = Color4.White, Alpha = 0.25f, RelativeSizeAxes = Axes.X, - X = -2, Width = 20, Height = 1.8f, }, new Circle { + Name = "bumper left", Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreRight, + Origin = Anchor.CentreLeft, Colour = Color4.White, RelativeSizeAxes = Axes.X, - X = -2, - Width = 15 / 170f, + Width = (1 - Catcher.ALLOWED_CATCH_RANGE) / 2, Height = 4, }, new Box { + Name = "long line right", Anchor = Anchor.CentreRight, Origin = Anchor.CentreLeft, Colour = Color4.White, Alpha = 0.25f, RelativeSizeAxes = Axes.X, - X = 2, Width = 20, Height = 1.8f, }, new Circle { + Name = "bumper right", Anchor = Anchor.CentreRight, - Origin = Anchor.CentreLeft, + Origin = Anchor.CentreRight, Colour = Color4.White, - X = 2, RelativeSizeAxes = Axes.X, - Width = 15 / 170f, + Width = (1 - Catcher.ALLOWED_CATCH_RANGE) / 2, Height = 4, }, } From 14a4fad6f1c21e14c7d72ec52461524ebb3b5bbc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 17:16:38 +0900 Subject: [PATCH 0246/2991] Remove unused `VisualRepresentation` --- .../Skinning/Argon/ArgonFruitPiece.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs index 9561659792..2412de7dbe 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs @@ -2,14 +2,12 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.Utils; -using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Skinning.Default; using osu.Game.Rulesets.Catch.UI; using osuTK; @@ -18,8 +16,6 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon { internal class ArgonFruitPiece : CatchHitObjectPiece { - public readonly Bindable VisualRepresentation = new Bindable(); - protected override Drawable HyperBorderPiece => hyperBorderPiece; private Drawable hyperBorderPiece = null!; @@ -91,11 +87,6 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon { base.LoadComplete(); - IndexInBeatmap.BindValueChanged(index => - { - VisualRepresentation.Value = Fruit.GetVisualRepresentation(index.NewValue); - }, true); - AccentColour.BindValueChanged(colour => { foreach (var sprite in layers) From 8a513003ce38f4212e9f40f90c21ec1555ca1c0d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 17:32:26 +0900 Subject: [PATCH 0247/2991] Add argon droplet --- .../Skinning/Argon/ArgonDropletPiece.cs | 118 ++++++++++++++++++ .../Argon/CatchArgonSkinTransformer.cs | 3 + .../Skinning/Default/DropletPiece.cs | 2 +- 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Catch/Skinning/Argon/ArgonDropletPiece.cs diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonDropletPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonDropletPiece.cs new file mode 100644 index 0000000000..c607b96729 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonDropletPiece.cs @@ -0,0 +1,118 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Framework.Utils; +using osu.Game.Rulesets.Catch.Skinning.Default; +using osu.Game.Rulesets.Catch.UI; +using osuTK; + +namespace osu.Game.Rulesets.Catch.Skinning.Argon +{ + internal class ArgonDropletPiece : CatchHitObjectPiece + { + protected override Drawable HyperBorderPiece => hyperBorderPiece; + + private Drawable hyperBorderPiece = null!; + + private Container layers = null!; + + private float rotationRandomness; + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + RelativeSizeAxes = Axes.Both; + + const float droplet_scale_down = 0.5f; + + InternalChildren = new[] + { + new Circle + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(20), + }, + layers = new Container + { + Scale = new Vector2(droplet_scale_down), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Sprite + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Blending = BlendingParameters.Additive, + Alpha = 0.15f, + Texture = getTexture("A") + }, + new Sprite + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Blending = BlendingParameters.Additive, + Alpha = 0.5f, + Scale = new Vector2(0.8f), + Texture = getTexture("A") + }, + } + }, + hyperBorderPiece = new Sprite + { + Scale = new Vector2(droplet_scale_down), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Colour = Catcher.DEFAULT_HYPER_DASH_COLOUR, + Blending = BlendingParameters.Additive, + Alpha = 0.15f, + Texture = getTexture("A"), + }, + }; + + Texture getTexture(string type) => textures.Get($"Gameplay/catch/blob-{type}{RNG.Next(1, 7)}"); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + AccentColour.BindValueChanged(colour => + { + foreach (var sprite in layers) + sprite.Colour = colour.NewValue; + }, true); + + rotationRandomness = RNG.NextSingle(0.2f, 1); + } + + protected override void Update() + { + base.Update(); + + // Note that droplets are rotated at a higher level, so this is mostly just to create more + // random arrangements of the multiple layers than actually rotate. + // + // Because underlying rotation is always clockwise, we apply anti-clockwise resistance to avoid + // making things spin too fast. + for (int i = 0; i < layers.Count; i++) + { + layers[i].Rotation -= + // Layers are ordered from largest to smallest. Smaller layers should rotate more. + (i * 4) + * (float)Clock.ElapsedFrameTime + * 0.2f * rotationRandomness + // Each layer should alternate rotation direction. + * (i % 2 == 1 ? 0.5f : 1); + } + } + } +} diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs index b55706b6d0..76a5b221fd 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs @@ -29,6 +29,9 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon case CatchSkinComponents.Banana: return new ArgonBananaPiece(); + + case CatchSkinComponents.Droplet: + return new ArgonDropletPiece(); } break; diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs index e4c2f04476..b8ae062382 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default { Size = new Vector2(CatchHitObject.OBJECT_RADIUS / 2); - InternalChildren = new Drawable[] + InternalChildren = new[] { new Pulp { From 44f55ed152d21be35ddbf36393d0a919172060de Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 18:20:45 +0900 Subject: [PATCH 0248/2991] Add argon osu!catch hit explosion --- .../Skinning/Argon/ArgonHitExplosion.cs | 112 ++++++++++++++++++ .../Argon/CatchArgonSkinTransformer.cs | 3 + 2 files changed, 115 insertions(+) create mode 100644 osu.Game.Rulesets.Catch/Skinning/Argon/ArgonHitExplosion.cs diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonHitExplosion.cs new file mode 100644 index 0000000000..90dca49dfd --- /dev/null +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonHitExplosion.cs @@ -0,0 +1,112 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Utils; +using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Catch.UI; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Catch.Skinning.Argon +{ + public class ArgonHitExplosion : CompositeDrawable, IHitExplosion + { + public override bool RemoveWhenNotAlive => true; + + private Container tallExplosion = null!; + private Container largeFaint = null!; + + private readonly Bindable accentColour = new Bindable(); + + public ArgonHitExplosion() + { + Size = new Vector2(20); + Anchor = Anchor.BottomCentre; + Origin = Anchor.BottomCentre; + } + + [BackgroundDependencyLoader] + private void load() + { + InternalChildren = new Drawable[] + { + tallExplosion = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Masking = true, + Width = 0.1f, + Child = new Box + { + AlwaysPresent = true, + Alpha = 0, + RelativeSizeAxes = Axes.Both, + }, + }, + largeFaint = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Masking = true, + Child = new Box + { + AlwaysPresent = true, + Alpha = 0, + RelativeSizeAxes = Axes.Both, + }, + }, + }; + + accentColour.BindValueChanged(colour => + { + tallExplosion.EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = colour.NewValue, + Hollow = false, + Roundness = 15, + Radius = 15, + }; + + largeFaint.EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = Interpolation.ValueAt(0.2f, colour.NewValue, Color4.White, 0, 1), + Hollow = false, + Radius = 50, + }; + }, true); + } + + public void Animate(HitExplosionEntry entry) + { + X = entry.Position; + Scale = new Vector2(entry.HitObject.Scale); + accentColour.Value = entry.ObjectColour; + + using (BeginAbsoluteSequence(entry.LifetimeStart)) + { + this.FadeOutFromOne(400); + + if (!(entry.HitObject is Droplet)) + { + float scale = Math.Clamp(entry.JudgementResult.ComboAtJudgement / 200f, 0.35f, 1.125f); + + tallExplosion + .ScaleTo(new Vector2(1.1f, 20 * scale), 200, Easing.OutQuint) + .Then() + .ScaleTo(new Vector2(1.1f, 1), 600, Easing.In); + } + } + } + } +} diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs index 76a5b221fd..30542187f2 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs @@ -21,6 +21,9 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. switch (osuComponent.Component) { + case CatchSkinComponents.HitExplosion: + return new ArgonHitExplosion(); + case CatchSkinComponents.Catcher: return new ArgonCatcher(); From 8a80cb55bd4741f34d891c6aa0ece5bfa57e583c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Oct 2022 18:55:00 +0900 Subject: [PATCH 0249/2991] Remove unused catcher animation state for now --- osu.Game.Rulesets.Catch/Skinning/Argon/ArgonCatcher.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonCatcher.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonCatcher.cs index ffd99aff4a..4db0df4a34 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonCatcher.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonCatcher.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -13,9 +12,6 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon { public class ArgonCatcher : CompositeDrawable { - [Resolved] - private Bindable currentState { get; set; } = null!; - [BackgroundDependencyLoader] private void load() { From dffebdf7eda6e68045c6e3c99d868507ea06a3dc Mon Sep 17 00:00:00 2001 From: nullium21 Date: Wed, 26 Oct 2022 13:31:32 +0300 Subject: [PATCH 0250/2991] Only use 0-9A-Za-z-_()[] characters in filenames --- osu.Game/Extensions/ModelExtensions.cs | 31 ++++++++++++++++++-------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/osu.Game/Extensions/ModelExtensions.cs b/osu.Game/Extensions/ModelExtensions.cs index b10071bb45..51bea02726 100644 --- a/osu.Game/Extensions/ModelExtensions.cs +++ b/osu.Game/Extensions/ModelExtensions.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.IO; -using System.Linq; using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.IO; @@ -137,20 +136,34 @@ namespace osu.Game.Extensions return instance.OnlineID.Equals(other.OnlineID); } - private static readonly char[] invalid_filename_characters = Path.GetInvalidFileNameChars() - // Backslash is added to avoid issues when exporting to zip. - // See SharpCompress filename normalisation https://github.com/adamhathcock/sharpcompress/blob/a1e7c0068db814c9aa78d86a94ccd1c761af74bd/src/SharpCompress/Writers/Zip/ZipWriter.cs#L143. - .Append('\\') - .ToArray(); + private static bool isValidFilenameChar(this char ch) + { + if (ch >= '0' && ch <= '9') + return true; + + if (ch >= 'A' && ch <= 'Z') + return true; + + if (ch >= 'a' && ch <= 'z') + return true; + + return "-_()[]".Contains(ch); + } /// /// Get a valid filename for use inside a zip file. Avoids backslashes being incorrectly converted to directories. /// public static string GetValidArchiveContentFilename(this string filename) { - foreach (char c in invalid_filename_characters) - filename = filename.Replace(c, '_'); - return filename; + char[] resultData = filename.ToCharArray(); + + for (int i = 0; i < resultData.Length; i++) + { + if (!isValidFilenameChar(resultData[i])) + resultData[i] = '_'; + } + + return new string(resultData); } } } From e4f25fc4d49bfd0d91f764c4b54a68c4671404d6 Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Wed, 26 Oct 2022 16:42:00 +0200 Subject: [PATCH 0251/2991] Don't overwrite special precision legacy difficulty points --- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index c9ee63424c..b1383c9e85 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -10,6 +10,7 @@ using System.IO; using System.Linq; using System.Text; using JetBrains.Annotations; +using osu.Framework.Utils; using osu.Game.Audio; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Legacy; @@ -190,7 +191,14 @@ namespace osu.Game.Beatmaps.Formats extractSampleControlPoints(beatmap.HitObjects); foreach (var point in legacyControlPoints.EffectPoints) + { + DifficultyControlPoint difficultyPoint = legacyControlPoints.DifficultyPointAt(point.Time); + + if (Precision.AlmostEquals(difficultyPoint.SliderVelocity, point.ScrollSpeed, acceptableDifference: point.ScrollSpeedBindable.Precision)) + continue; + legacyControlPoints.Add(point.Time, new DifficultyControlPoint { SliderVelocity = point.ScrollSpeed }); + } foreach (var group in legacyControlPoints.Groups) { From 77dcd0fae284eff1a556ae28fc18498db961426d Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 26 Oct 2022 17:21:20 +0200 Subject: [PATCH 0252/2991] Create BezierConverter.cs --- osu.Game/Rulesets/Objects/BezierConverter.cs | 352 +++++++++++++++++++ 1 file changed, 352 insertions(+) create mode 100644 osu.Game/Rulesets/Objects/BezierConverter.cs diff --git a/osu.Game/Rulesets/Objects/BezierConverter.cs b/osu.Game/Rulesets/Objects/BezierConverter.cs new file mode 100644 index 0000000000..414341641f --- /dev/null +++ b/osu.Game/Rulesets/Objects/BezierConverter.cs @@ -0,0 +1,352 @@ +// 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 osu.Framework.Utils; +using osu.Game.Rulesets.Objects.Types; +using osuTK; + +namespace osu.Game.Rulesets.Objects +{ + public static class BezierConverter + { + private struct CircleBezierPreset + { + public readonly double ArcLength; + public readonly Vector2d[] ControlPoints; + + public CircleBezierPreset(double arcLength, Vector2d[] controlPoints) + { + ArcLength = arcLength; + ControlPoints = controlPoints; + } + } + + // Extremely accurate a bezier anchor positions for approximating circles of several arc lengths + private static readonly CircleBezierPreset[] circle_presets = + { + new CircleBezierPreset(0.4993379862754501, + new[] { new Vector2d(1, 0), new Vector2d(1, 0.2549893626632736f), new Vector2d(0.8778997558480327f, 0.47884446188920726f) }), + new CircleBezierPreset(1.7579419829169447, + new[] { new Vector2d(1, 0), new Vector2d(1, 0.6263026f), new Vector2d(0.42931178f, 1.0990661f), new Vector2d(-0.18605515f, 0.9825393f) }), + new CircleBezierPreset(3.1385246920140215, + new[] { new Vector2d(1, 0), new Vector2d(1, 0.87084764f), new Vector2d(0.002304826f, 1.5033062f), new Vector2d(-0.9973236f, 0.8739115f), new Vector2d(-0.9999953f, 0.0030679568f) }), + new CircleBezierPreset(5.69720464620727, + new[] { new Vector2d(1, 0), new Vector2d(1, 1.4137783f), new Vector2d(-1.4305235f, 2.0779421f), new Vector2d(-2.3410065f, -0.94017583f), new Vector2d(0.05132711f, -1.7309346f), new Vector2d(0.8331702f, -0.5530167f) }), + new CircleBezierPreset(2 * Math.PI, + new[] { new Vector2d(1, 0), new Vector2d(1, 1.2447058f), new Vector2d(-0.8526471f, 2.118367f), new Vector2d(-2.6211002f, 7.854936e-06f), new Vector2d(-0.8526448f, -2.118357f), new Vector2d(1, -1.2447058f), new Vector2d(1, 0) }) + }; + + #region CircularArcProperties + + //TODO: Get this from osu!framework instead + public readonly struct CircularArcProperties + { + public readonly bool IsValid; + public readonly double ThetaStart; + public readonly double ThetaRange; + public readonly double Direction; + public readonly float Radius; + public readonly Vector2 Centre; + + public double ThetaEnd => ThetaStart + ThetaRange * Direction; + + public CircularArcProperties(double thetaStart, double thetaRange, double direction, float radius, Vector2 centre) + { + IsValid = true; + ThetaStart = thetaStart; + ThetaRange = thetaRange; + Direction = direction; + Radius = radius; + Centre = centre; + } + } + + /// + /// Computes various properties that can be used to approximate the circular arc. + /// + /// Three distinct points on the arc. + private static CircularArcProperties circularArcProperties(ReadOnlySpan controlPoints) + { + Vector2 a = controlPoints[0]; + Vector2 b = controlPoints[1]; + Vector2 c = controlPoints[2]; + + // If we have a degenerate triangle where a side-length is almost zero, then give up and fallback to a more numerically stable method. + if (Precision.AlmostEquals(0, (b.Y - a.Y) * (c.X - a.X) - (b.X - a.X) * (c.Y - a.Y))) + return default; // Implicitly sets `IsValid` to false + + // See: https://en.wikipedia.org/wiki/Circumscribed_circle#Cartesian_coordinates_2 + float d = 2 * (a.X * (b - c).Y + b.X * (c - a).Y + c.X * (a - b).Y); + float aSq = a.LengthSquared; + float bSq = b.LengthSquared; + float cSq = c.LengthSquared; + + Vector2 centre = new Vector2( + aSq * (b - c).Y + bSq * (c - a).Y + cSq * (a - b).Y, + aSq * (c - b).X + bSq * (a - c).X + cSq * (b - a).X) / d; + + Vector2 dA = a - centre; + Vector2 dC = c - centre; + + float r = dA.Length; + + double thetaStart = Math.Atan2(dA.Y, dA.X); + double thetaEnd = Math.Atan2(dC.Y, dC.X); + + while (thetaEnd < thetaStart) + thetaEnd += 2 * Math.PI; + + double dir = 1; + double thetaRange = thetaEnd - thetaStart; + + // Decide in which direction to draw the circle, depending on which side of + // AC B lies. + Vector2 orthoAtoC = c - a; + orthoAtoC = new Vector2(orthoAtoC.Y, -orthoAtoC.X); + + if (Vector2.Dot(orthoAtoC, b - a) < 0) + { + dir = -dir; + thetaRange = 2 * Math.PI - thetaRange; + } + + return new CircularArcProperties(thetaStart, thetaRange, dir, r, centre); + } + + #endregion + + public static IEnumerable ConvertToLegacyBezier(IList controlPoints, Vector2 position) + { + Vector2[] vertices = new Vector2[controlPoints.Count]; + for (int i = 0; i < controlPoints.Count; i++) + vertices[i] = controlPoints[i].Position; + + var result = new List(); + int start = 0; + + for (int i = 0; i < controlPoints.Count; i++) + { + if (controlPoints[i].Type == null && i < controlPoints.Count - 1) + continue; + + // The current vertex ends the segment + var segmentVertices = vertices.AsSpan().Slice(start, i - start + 1); + var segmentType = controlPoints[start].Type ?? PathType.Linear; + + switch (segmentType) + { + case PathType.Catmull: + result.AddRange(from segment in ConvertCatmullToBezierAnchors(segmentVertices) from v in segment select v + position); + + break; + + case PathType.Linear: + result.AddRange(from segment in ConvertLinearToBezierAnchors(segmentVertices) from v in segment select v + position); + + break; + + case PathType.PerfectCurve: + result.AddRange(ConvertCircleToBezierAnchors(segmentVertices).Select(v => v + position)); + + break; + + default: + foreach (Vector2 v in segmentVertices) + { + result.Add(v + position); + } + + break; + } + + // Start the new segment at the current vertex + start = i; + } + + return result; + } + + public static List ConvertToModernBezier(IList controlPoints) + { + Vector2[] vertices = new Vector2[controlPoints.Count]; + for (int i = 0; i < controlPoints.Count; i++) + vertices[i] = controlPoints[i].Position; + + var result = new List(); + int start = 0; + + for (int i = 0; i < controlPoints.Count; i++) + { + if (controlPoints[i].Type == null && i < controlPoints.Count - 1) + continue; + + // The current vertex ends the segment + var segmentVertices = vertices.AsSpan().Slice(start, i - start + 1); + var segmentType = controlPoints[start].Type ?? PathType.Linear; + + switch (segmentType) + { + case PathType.Catmull: + foreach (var segment in ConvertCatmullToBezierAnchors(segmentVertices)) + { + for (int j = 0; j < segment.Length - 1; j++) + { + result.Add(new PathControlPoint(segment[j], j == 0 ? PathType.Bezier : null)); + } + } + + break; + + case PathType.Linear: + foreach (var segment in ConvertLinearToBezierAnchors(segmentVertices)) + { + for (int j = 0; j < segment.Length - 1; j++) + { + result.Add(new PathControlPoint(segment[j], j == 0 ? PathType.Bezier : null)); + } + } + + break; + + case PathType.PerfectCurve: + var circleResult = ConvertCircleToBezierAnchors(segmentVertices); + + for (int j = 0; j < circleResult.Length - 1; j++) + { + result.Add(new PathControlPoint(circleResult[j], j == 0 ? PathType.Bezier : null)); + } + + break; + + default: + for (int j = 0; j < segmentVertices.Length - 1; j++) + { + result.Add(new PathControlPoint(segmentVertices[j], j == 0 ? PathType.Bezier : null)); + } + + break; + } + + // Start the new segment at the current vertex + start = i; + } + + result.Add(new PathControlPoint(controlPoints[^1].Position)); + + return result; + } + + /// + /// Converts perfect curve anchors to bezier anchors. + /// + /// The control point positions to convert. + public static Vector2[] ConvertCircleToBezierAnchors(ReadOnlySpan controlPoints) + { + var pr = circularArcProperties(controlPoints); + if (!pr.IsValid) + return controlPoints.ToArray(); + + CircleBezierPreset preset = circle_presets.Last(); + + foreach (CircleBezierPreset cbp in circle_presets) + { + if (cbp.ArcLength < pr.ThetaRange) continue; + + preset = cbp; + break; + } + + double arcLength = preset.ArcLength; + var arc = new Vector2d[preset.ControlPoints.Length]; + preset.ControlPoints.CopyTo(arc, 0); + + // Converge on arcLength of thetaRange + int n = arc.Length - 1; + double tf = pr.ThetaRange / arcLength; + + while (Math.Abs(tf - 1) > 1E-7) + { + for (int j = 0; j < n; j++) + { + for (int i = n; i > j; i--) + { + arc[i] = arc[i] * tf + arc[i - 1] * (1 - tf); + } + } + + arcLength = Math.Atan2(arc.Last()[1], arc.Last()[0]); + + if (arcLength < 0) + { + arcLength += 2 * Math.PI; + } + + tf = pr.ThetaRange / arcLength; + } + + // Adjust rotation, radius, and position + var result = new Vector2[arc.Length]; + + for (int i = 0; i < arc.Length; i++) + { + result[i] = new Vector2( + (float)((Math.Cos(pr.ThetaStart) * arc[i].X + -Math.Sin(pr.ThetaStart) * pr.Direction * arc[i].Y) * pr.Radius + pr.Centre.X), + (float)((Math.Sin(pr.ThetaStart) * arc[i].X + Math.Cos(pr.ThetaStart) * pr.Direction * arc[i].Y) * pr.Radius + pr.Centre.Y)); + } + + return result; + } + + /// + /// Converts catmull anchors to bezier anchors. + /// + /// The control point positions to convert. + public static Vector2[][] ConvertCatmullToBezierAnchors(ReadOnlySpan controlPoints) + { + int iLen = controlPoints.Length; + var bezier = new Vector2[iLen - 1][]; + + for (int i = 0; i < iLen - 1; i++) + { + var v1 = i > 0 ? controlPoints[i - 1] : controlPoints[i]; + var v2 = controlPoints[i]; + var v3 = i < iLen - 1 ? controlPoints[i + 1] : v2 + v2 - v1; + var v4 = i < iLen - 2 ? controlPoints[i + 2] : v3 + v3 - v2; + + bezier[i] = new[] + { + v2, + (-v1 + 6 * v2 + v3) / 6, + (-v4 + 6 * v3 + v2) / 6, + v3 + }; + } + + return bezier; + } + + /// + /// Converts linear anchors to bezier anchors. + /// + /// The control point positions to convert. + public static Vector2[][] ConvertLinearToBezierAnchors(ReadOnlySpan controlPoints) + { + int iLen = controlPoints.Length; + var bezier = new Vector2[iLen - 1][]; + + for (int i = 0; i < iLen - 1; i++) + { + bezier[i] = new[] + { + controlPoints[i], + controlPoints[i + 1] + }; + } + + return bezier; + } + } +} From 86d5fcc26d6a86f7a57bf87285cb53d04da54959 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 26 Oct 2022 19:30:42 +0200 Subject: [PATCH 0253/2991] Added tests --- .../Gameplay/TestSceneBezierConverter.cs | 172 ++++++++++++++++++ osu.Game/Rulesets/Objects/BezierConverter.cs | 3 + 2 files changed, 175 insertions(+) create mode 100644 osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs new file mode 100644 index 0000000000..c915ae0054 --- /dev/null +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs @@ -0,0 +1,172 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable disable + +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Lines; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; +using osuTK; + +namespace osu.Game.Tests.Visual.Gameplay +{ + public class TestSceneBezierConverter : OsuTestScene + { + private readonly SmoothPath drawablePath; + private readonly SmoothPath controlPointDrawablePath; + private readonly SmoothPath convertedDrawablePath; + private readonly SmoothPath convertedControlPointDrawablePath; + private SliderPath path; + private SliderPath convertedPath; + + public TestSceneBezierConverter() + { + Children = new Drawable[] + { + new Container + { + Children = + new Drawable[] + { + drawablePath = new SmoothPath(), + controlPointDrawablePath = new SmoothPath + { + Colour = Colour4.Magenta, + PathRadius = 1f + } + }, + Position = new Vector2(100) + }, + new Container + { + Children = + new Drawable[] + { + convertedDrawablePath = new SmoothPath(), + convertedControlPointDrawablePath = new SmoothPath + { + Colour = Colour4.Magenta, + PathRadius = 1f + } + }, + Position = new Vector2(100, 300) + } + }; + } + + [SetUp] + public void Setup() => Schedule(() => + { + path = new SliderPath(); + convertedPath = new SliderPath(); + + path.Version.ValueChanged += getConvertedControlPoints; + }); + + private void getConvertedControlPoints(ValueChangedEvent obj) + { + convertedPath.ControlPoints.Clear(); + convertedPath.ControlPoints.AddRange(BezierConverter.ConvertToModernBezier(path.ControlPoints)); + } + + protected override void Update() + { + base.Update(); + + if (path != null) + { + List vertices = new List(); + path.GetPathToProgress(vertices, 0, 1); + + drawablePath.Vertices = vertices; + controlPointDrawablePath.Vertices = path.ControlPoints.Select(o => o.Position).ToList(); + if (controlPointDrawablePath.Vertices.Count > 0) + controlPointDrawablePath.Position = drawablePath.PositionInBoundingBox(drawablePath.Vertices[0]) - controlPointDrawablePath.PositionInBoundingBox(controlPointDrawablePath.Vertices[0]); + } + + if (convertedPath != null) + { + List vertices = new List(); + convertedPath.GetPathToProgress(vertices, 0, 1); + + convertedDrawablePath.Vertices = vertices; + convertedControlPointDrawablePath.Vertices = convertedPath.ControlPoints.Select(o => o.Position).ToList(); + if (convertedControlPointDrawablePath.Vertices.Count > 0) + convertedControlPointDrawablePath.Position = convertedDrawablePath.PositionInBoundingBox(convertedDrawablePath.Vertices[0]) - convertedControlPointDrawablePath.PositionInBoundingBox(convertedControlPointDrawablePath.Vertices[0]); + } + } + + [Test] + public void TestEmptyPath() + { + } + + [TestCase(PathType.Linear)] + [TestCase(PathType.Bezier)] + [TestCase(PathType.Catmull)] + [TestCase(PathType.PerfectCurve)] + public void TestSingleSegment(PathType type) + => AddStep("create path", () => path.ControlPoints.AddRange(createSegment(type, Vector2.Zero, new Vector2(0, 100), new Vector2(100)))); + + [TestCase(PathType.Linear)] + [TestCase(PathType.Bezier)] + [TestCase(PathType.Catmull)] + [TestCase(PathType.PerfectCurve)] + public void TestMultipleSegment(PathType type) + { + AddStep("create path", () => + { + path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero)); + path.ControlPoints.AddRange(createSegment(type, new Vector2(0, 100), new Vector2(100), Vector2.Zero)); + }); + } + + [TestCase(0, 100)] + [TestCase(1, 100)] + [TestCase(5, 100)] + [TestCase(10, 100)] + [TestCase(30, 100)] + [TestCase(50, 100)] + [TestCase(100, 100)] + [TestCase(100, 1)] + public void TestPerfectCurveAngles(float height, float width) + { + AddStep("create path", () => + { + path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, Vector2.Zero, new Vector2(width / 2, height), new Vector2(width, 0))); + }); + } + + [TestCase(2)] + [TestCase(4)] + public void TestPerfectCurveFallbackScenarios(int points) + { + AddStep("create path", () => + { + switch (points) + { + case 2: + path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, Vector2.Zero, new Vector2(0, 100))); + break; + + case 4: + path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, Vector2.Zero, new Vector2(0, 100), new Vector2(100), new Vector2(100, 0))); + break; + } + }); + } + + private List createSegment(PathType type, params Vector2[] controlPoints) + { + var points = controlPoints.Select(p => new PathControlPoint { Position = p }).ToList(); + points[0].Type = type; + return points; + } + } +} diff --git a/osu.Game/Rulesets/Objects/BezierConverter.cs b/osu.Game/Rulesets/Objects/BezierConverter.cs index 414341641f..9220993559 100644 --- a/osu.Game/Rulesets/Objects/BezierConverter.cs +++ b/osu.Game/Rulesets/Objects/BezierConverter.cs @@ -245,6 +245,9 @@ namespace osu.Game.Rulesets.Objects /// The control point positions to convert. public static Vector2[] ConvertCircleToBezierAnchors(ReadOnlySpan controlPoints) { + if (controlPoints.Length != 3) + return controlPoints.ToArray(); + var pr = circularArcProperties(controlPoints); if (!pr.IsValid) return controlPoints.ToArray(); From 8b8d0c2293056405941d5b444cb43b7ec5f88ce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 26 Oct 2022 23:30:14 +0200 Subject: [PATCH 0254/2991] Fix typo in comment --- osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index f9a952c2fb..1675d11896 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -124,7 +124,7 @@ namespace osu.Game.Rulesets.Osu.Edit { // In the case of snapping to nearby objects, a time value is not provided. // This matches the stable editor (which also uses current time), but with the introduction of time-snapping distance snap - // this could result in unexpected behaviour when distance snapping is turned on an a user attempts to place an object that is + // this could result in unexpected behaviour when distance snapping is turned on and a user attempts to place an object that is // BOTH on a valid distance snap ring, and also at the same position as a previous object. // // We want to ensure that in this particular case, the time-snapping component of distance snap is still applied. From 0efbae6e70d0190ba42c54c140a4aaecc66be84e Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Wed, 26 Oct 2022 18:33:07 -0700 Subject: [PATCH 0255/2991] Fix osu! logo drag area being a square --- osu.Game/Screens/Menu/OsuLogo.cs | 33 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index e9b50f94f7..3efd74d2c8 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -113,7 +113,7 @@ namespace osu.Game.Screens.Menu AutoSizeAxes = Axes.Both, Children = new Drawable[] { - logoBounceContainer = new DragContainer + logoBounceContainer = new Container { AutoSizeAxes = Axes.Both, Children = new Drawable[] @@ -407,27 +407,24 @@ namespace osu.Game.Screens.Menu impactContainer.ScaleTo(1.12f, 250); } - private class DragContainer : Container + public override bool DragBlocksClick => false; + + protected override bool OnDragStart(DragStartEvent e) => true; + + protected override void OnDrag(DragEvent e) { - public override bool DragBlocksClick => false; + Vector2 change = e.MousePosition - e.MouseDownPosition; - protected override bool OnDragStart(DragStartEvent e) => true; + // Diminish the drag distance as we go further to simulate "rubber band" feeling. + change *= change.Length <= 0 ? 0 : MathF.Pow(change.Length, 0.6f) / change.Length; - protected override void OnDrag(DragEvent e) - { - Vector2 change = e.MousePosition - e.MouseDownPosition; + logoBounceContainer.MoveTo(change); + } - // Diminish the drag distance as we go further to simulate "rubber band" feeling. - change *= change.Length <= 0 ? 0 : MathF.Pow(change.Length, 0.6f) / change.Length; - - this.MoveTo(change); - } - - protected override void OnDragEnd(DragEndEvent e) - { - this.MoveTo(Vector2.Zero, 800, Easing.OutElastic); - base.OnDragEnd(e); - } + protected override void OnDragEnd(DragEndEvent e) + { + logoBounceContainer.MoveTo(Vector2.Zero, 800, Easing.OutElastic); + base.OnDragEnd(e); } } } From 14c7cbde38ce4bada24f6a99076833873026b6a1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Oct 2022 11:40:59 +0900 Subject: [PATCH 0256/2991] Fix toggle mute (and volume meter traversal) handling repeat key presses Closes #20953. --- osu.Game/Overlays/Volume/VolumeControlReceptor.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Volume/VolumeControlReceptor.cs b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs index f2b637c104..624be0b25c 100644 --- a/osu.Game/Overlays/Volume/VolumeControlReceptor.cs +++ b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs @@ -23,10 +23,14 @@ namespace osu.Game.Overlays.Volume { case GlobalAction.DecreaseVolume: case GlobalAction.IncreaseVolume: + ActionRequested?.Invoke(e.Action); + return true; + case GlobalAction.ToggleMute: case GlobalAction.NextVolumeMeter: case GlobalAction.PreviousVolumeMeter: - ActionRequested?.Invoke(e.Action); + if (!e.Repeat) + ActionRequested?.Invoke(e.Action); return true; } From 93ffe3d7adcac60168368a458e8920c667ca26d1 Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Thu, 27 Oct 2022 07:25:50 +0200 Subject: [PATCH 0257/2991] Revert to first approach --- .../Beatmaps/TaikoBeatmapConverter.cs | 23 +++++++++++++++++++ .../Formats/LegacyBeatmapDecoderTest.cs | 2 +- .../Visual/Editing/TestSceneTimingScreen.cs | 8 +++---- .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 7 +++++- .../Beatmaps/Formats/LegacyBeatmapEncoder.cs | 18 ++++++++------- 5 files changed, 44 insertions(+), 14 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 524565a863..c1e1052569 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -57,6 +57,29 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps Beatmap converted = base.ConvertBeatmap(original, cancellationToken); + if (original.BeatmapInfo.Ruleset.OnlineID == 0) + { + // Post processing step to transform standard slider velocity changes into scroll speed changes + double lastScrollSpeed = 1; + + foreach (HitObject hitObject in original.HitObjects) + { + double nextScrollSpeed = hitObject.DifficultyControlPoint.SliderVelocity; + + if (!Precision.AlmostEquals(lastScrollSpeed, nextScrollSpeed)) + { + EffectControlPoint currentControlPoint = converted.ControlPointInfo.EffectPointAt(hitObject.StartTime); + + if (Precision.AlmostEquals(currentControlPoint.Time, hitObject.StartTime)) + currentControlPoint.ScrollSpeed = nextScrollSpeed; + else + converted.ControlPointInfo.Add(hitObject.StartTime, new EffectControlPoint { ScrollSpeed = nextScrollSpeed }); + + lastScrollSpeed = nextScrollSpeed; + } + } + } + if (original.BeatmapInfo.Ruleset.OnlineID == 3) { // Post processing step to transform mania hit objects with the same start time into strong hits diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index d9bbe7a51e..fdd0167ed3 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -175,7 +175,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(4, controlPoints.TimingPoints.Count); Assert.AreEqual(5, controlPoints.DifficultyPoints.Count); Assert.AreEqual(34, controlPoints.SamplePoints.Count); - Assert.AreEqual(13, controlPoints.EffectPoints.Count); + Assert.AreEqual(8, controlPoints.EffectPoints.Count); var timingPoint = controlPoints.TimingPointAt(0); Assert.AreEqual(956, timingPoint.Time); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs b/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs index e93382cc9b..03c184c27d 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs @@ -67,8 +67,8 @@ namespace osu.Game.Tests.Visual.Editing InputManager.Click(MouseButton.Left); }); - AddUntilStep("Selection changed", () => timingScreen.SelectedGroup.Value.Time == 37560); - AddUntilStep("Ensure seeked to correct time", () => EditorClock.CurrentTimeAccurate == 37560); + AddUntilStep("Selection changed", () => timingScreen.SelectedGroup.Value.Time == 54670); + AddUntilStep("Ensure seeked to correct time", () => EditorClock.CurrentTimeAccurate == 54670); AddStep("Seek to just before next point", () => EditorClock.Seek(69000)); AddStep("Start clock", () => EditorClock.Start()); @@ -85,8 +85,8 @@ namespace osu.Game.Tests.Visual.Editing InputManager.Click(MouseButton.Left); }); - AddUntilStep("Selection changed", () => timingScreen.SelectedGroup.Value.Time == 37560); - AddUntilStep("Ensure seeked to correct time", () => EditorClock.CurrentTimeAccurate == 37560); + AddUntilStep("Selection changed", () => timingScreen.SelectedGroup.Value.Time == 54670); + AddUntilStep("Ensure seeked to correct time", () => EditorClock.CurrentTimeAccurate == 54670); AddStep("Seek to later", () => EditorClock.Seek(80000)); AddUntilStep("Selection changed", () => timingScreen.SelectedGroup.Value.Time == 69670); diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index c38510aeef..9c50c06cb7 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -448,9 +448,14 @@ namespace osu.Game.Beatmaps.Formats { KiaiMode = kiaiMode, OmitFirstBarLine = omitFirstBarSignature, - ScrollSpeed = speedMultiplier, }; + int onlineRulesetID = beatmap.BeatmapInfo.Ruleset.OnlineID; + + // osu!taiko and osu!mania use effect points rather than difficulty points for scroll speed adjustments. + if (onlineRulesetID == 1 || onlineRulesetID == 3) + effectPoint.ScrollSpeed = speedMultiplier; + addControlPoint(time, effectPoint, timingChange); addControlPoint(time, new LegacySampleControlPoint diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index b1383c9e85..03c63ff4f2 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -10,7 +10,6 @@ using System.IO; using System.Linq; using System.Text; using JetBrains.Annotations; -using osu.Framework.Utils; using osu.Game.Audio; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Legacy; @@ -186,18 +185,18 @@ namespace osu.Game.Beatmaps.Formats SampleControlPoint lastRelevantSamplePoint = null; DifficultyControlPoint lastRelevantDifficultyPoint = null; + // In osu!taiko and osu!mania, a scroll speed is stored as "slider velocity" in legacy formats. + // In that case, a scrolling speed change is a global effect and per-hit object difficulty control points are ignored. + bool scrollSpeedEncodedAsSliderVelocity = onlineRulesetID == 1 || onlineRulesetID == 3; + // iterate over hitobjects and pull out all required sample and difficulty changes extractDifficultyControlPoints(beatmap.HitObjects); extractSampleControlPoints(beatmap.HitObjects); - foreach (var point in legacyControlPoints.EffectPoints) + if (scrollSpeedEncodedAsSliderVelocity) { - DifficultyControlPoint difficultyPoint = legacyControlPoints.DifficultyPointAt(point.Time); - - if (Precision.AlmostEquals(difficultyPoint.SliderVelocity, point.ScrollSpeed, acceptableDifference: point.ScrollSpeedBindable.Precision)) - continue; - - legacyControlPoints.Add(point.Time, new DifficultyControlPoint { SliderVelocity = point.ScrollSpeed }); + foreach (var point in legacyControlPoints.EffectPoints) + legacyControlPoints.Add(point.Time, new DifficultyControlPoint { SliderVelocity = point.ScrollSpeed }); } foreach (var group in legacyControlPoints.Groups) @@ -245,6 +244,9 @@ namespace osu.Game.Beatmaps.Formats IEnumerable collectDifficultyControlPoints(IEnumerable hitObjects) { + if (scrollSpeedEncodedAsSliderVelocity) + yield break; + foreach (var hitObject in hitObjects) yield return hitObject.DifficultyControlPoint; } From d5c88cca8c5ba9bde038cf5c5a47fab70293000f Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Thu, 27 Oct 2022 07:29:36 +0200 Subject: [PATCH 0258/2991] Fix result of merge conflict --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 9c50c06cb7..5f0a2a0824 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -450,8 +450,6 @@ namespace osu.Game.Beatmaps.Formats OmitFirstBarLine = omitFirstBarSignature, }; - int onlineRulesetID = beatmap.BeatmapInfo.Ruleset.OnlineID; - // osu!taiko and osu!mania use effect points rather than difficulty points for scroll speed adjustments. if (onlineRulesetID == 1 || onlineRulesetID == 3) effectPoint.ScrollSpeed = speedMultiplier; From 4127aaa9882c3b2007849e982b9fcc1d0b551ec4 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Thu, 27 Oct 2022 14:34:24 +0900 Subject: [PATCH 0259/2991] Extract general elements from HubClientConnector into SocketClientConnector --- osu.Game/Online/HubClient.cs | 28 ++++ osu.Game/Online/HubClientConnector.cs | 161 +------------------- osu.Game/Online/SocketClient.cs | 24 +++ osu.Game/Online/SocketClientConnector.cs | 183 +++++++++++++++++++++++ 4 files changed, 242 insertions(+), 154 deletions(-) create mode 100644 osu.Game/Online/HubClient.cs create mode 100644 osu.Game/Online/SocketClient.cs create mode 100644 osu.Game/Online/SocketClientConnector.cs diff --git a/osu.Game/Online/HubClient.cs b/osu.Game/Online/HubClient.cs new file mode 100644 index 0000000000..262e298f34 --- /dev/null +++ b/osu.Game/Online/HubClient.cs @@ -0,0 +1,28 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.SignalR.Client; + +namespace osu.Game.Online +{ + public class HubClient : SocketClient + { + public readonly HubConnection Connection; + + public HubClient(HubConnection connection) + { + Connection = connection; + Connection.Closed += InvokeClosed; + } + + public override Task StartAsync(CancellationToken cancellationToken) => Connection.StartAsync(cancellationToken); + + public override async ValueTask DisposeAsync() + { + await base.DisposeAsync().ConfigureAwait(false); + await Connection.DisposeAsync().ConfigureAwait(false); + } + } +} diff --git a/osu.Game/Online/HubClientConnector.cs b/osu.Game/Online/HubClientConnector.cs index 6bfe09e911..33e9f92817 100644 --- a/osu.Game/Online/HubClientConnector.cs +++ b/osu.Game/Online/HubClientConnector.cs @@ -10,13 +10,11 @@ using Microsoft.AspNetCore.SignalR.Client; using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using osu.Framework; -using osu.Framework.Bindables; -using osu.Framework.Logging; using osu.Game.Online.API; namespace osu.Game.Online { - public class HubClientConnector : IHubClientConnector + public class HubClientConnector : SocketClientConnector, IHubClientConnector { public const string SERVER_SHUTDOWN_MESSAGE = "Server is shutting down."; @@ -25,7 +23,6 @@ namespace osu.Game.Online /// public Action? ConfigureConnection { get; set; } - private readonly string clientName; private readonly string endpoint; private readonly string versionHash; private readonly bool preferMessagePack; @@ -34,18 +31,7 @@ namespace osu.Game.Online /// /// The current connection opened by this connector. /// - public HubConnection? CurrentConnection { get; private set; } - - /// - /// Whether this is connected to the hub, use to access the connection, if this is true. - /// - public IBindable IsConnected => isConnected; - - private readonly Bindable isConnected = new Bindable(); - private readonly SemaphoreSlim connectionLock = new SemaphoreSlim(1); - private CancellationTokenSource connectCancelSource = new CancellationTokenSource(); - - private readonly IBindable apiState = new Bindable(); + public new HubConnection? CurrentConnection => ((HubClient?)base.CurrentConnection)?.Connection; /// /// Constructs a new . @@ -56,99 +42,16 @@ namespace osu.Game.Online /// The hash representing the current game version, used for verification purposes. /// Whether to use MessagePack for serialisation if available on this platform. public HubClientConnector(string clientName, string endpoint, IAPIProvider api, string versionHash, bool preferMessagePack = true) + : base(api) { - this.clientName = clientName; + ClientName = clientName; this.endpoint = endpoint; this.api = api; this.versionHash = versionHash; this.preferMessagePack = preferMessagePack; - - apiState.BindTo(api.State); - apiState.BindValueChanged(_ => Task.Run(connectIfPossible), true); } - public Task Reconnect() - { - Logger.Log($"{clientName} reconnecting...", LoggingTarget.Network); - return Task.Run(connectIfPossible); - } - - private async Task connectIfPossible() - { - switch (apiState.Value) - { - case APIState.Failing: - case APIState.Offline: - await disconnect(true); - break; - - case APIState.Online: - await connect(); - break; - } - } - - private async Task connect() - { - cancelExistingConnect(); - - if (!await connectionLock.WaitAsync(10000).ConfigureAwait(false)) - throw new TimeoutException("Could not obtain a lock to connect. A previous attempt is likely stuck."); - - try - { - while (apiState.Value == APIState.Online) - { - // ensure any previous connection was disposed. - // this will also create a new cancellation token source. - await disconnect(false).ConfigureAwait(false); - - // this token will be valid for the scope of this connection. - // if cancelled, we can be sure that a disconnect or reconnect is handled elsewhere. - var cancellationToken = connectCancelSource.Token; - - cancellationToken.ThrowIfCancellationRequested(); - - Logger.Log($"{clientName} connecting...", LoggingTarget.Network); - - try - { - // importantly, rebuild the connection each attempt to get an updated access token. - CurrentConnection = buildConnection(cancellationToken); - - await CurrentConnection.StartAsync(cancellationToken).ConfigureAwait(false); - - Logger.Log($"{clientName} connected!", LoggingTarget.Network); - isConnected.Value = true; - return; - } - catch (OperationCanceledException) - { - //connection process was cancelled. - throw; - } - catch (Exception e) - { - await handleErrorAndDelay(e, cancellationToken).ConfigureAwait(false); - } - } - } - finally - { - connectionLock.Release(); - } - } - - /// - /// Handles an exception and delays an async flow. - /// - private async Task handleErrorAndDelay(Exception exception, CancellationToken cancellationToken) - { - Logger.Log($"{clientName} connect attempt failed: {exception.Message}", LoggingTarget.Network); - await Task.Delay(5000, cancellationToken).ConfigureAwait(false); - } - - private HubConnection buildConnection(CancellationToken cancellationToken) + protected override Task BuildConnectionAsync(CancellationToken cancellationToken) { var builder = new HubConnectionBuilder() .WithUrl(endpoint, options => @@ -188,59 +91,9 @@ namespace osu.Game.Online ConfigureConnection?.Invoke(newConnection); - newConnection.Closed += ex => onConnectionClosed(ex, cancellationToken); - return newConnection; + return Task.FromResult((SocketClient)new HubClient(newConnection)); } - private async Task onConnectionClosed(Exception? ex, CancellationToken cancellationToken) - { - isConnected.Value = false; - - if (ex != null) - await handleErrorAndDelay(ex, cancellationToken).ConfigureAwait(false); - else - Logger.Log($"{clientName} disconnected", LoggingTarget.Network); - - // make sure a disconnect wasn't triggered (and this is still the active connection). - if (!cancellationToken.IsCancellationRequested) - await Task.Run(connect, default).ConfigureAwait(false); - } - - private async Task disconnect(bool takeLock) - { - cancelExistingConnect(); - - if (takeLock) - { - if (!await connectionLock.WaitAsync(10000).ConfigureAwait(false)) - throw new TimeoutException("Could not obtain a lock to disconnect. A previous attempt is likely stuck."); - } - - try - { - if (CurrentConnection != null) - await CurrentConnection.DisposeAsync().ConfigureAwait(false); - } - finally - { - CurrentConnection = null; - if (takeLock) - connectionLock.Release(); - } - } - - private void cancelExistingConnect() - { - connectCancelSource.Cancel(); - connectCancelSource = new CancellationTokenSource(); - } - - public override string ToString() => $"Connector for {clientName} ({(IsConnected.Value ? "connected" : "not connected")}"; - - public void Dispose() - { - apiState.UnbindAll(); - cancelExistingConnect(); - } + protected override string ClientName { get; } } } diff --git a/osu.Game/Online/SocketClient.cs b/osu.Game/Online/SocketClient.cs new file mode 100644 index 0000000000..3b4aa1b49b --- /dev/null +++ b/osu.Game/Online/SocketClient.cs @@ -0,0 +1,24 @@ +// 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.Threading; +using System.Threading.Tasks; + +namespace osu.Game.Online +{ + public abstract class SocketClient : IAsyncDisposable + { + public event Func? Closed; + + protected Task InvokeClosed(Exception? exception) => Closed?.Invoke(exception) ?? Task.CompletedTask; + + public abstract Task StartAsync(CancellationToken cancellationToken); + + public virtual ValueTask DisposeAsync() + { + Closed = null; + return new ValueTask(Task.CompletedTask); + } + } +} diff --git a/osu.Game/Online/SocketClientConnector.cs b/osu.Game/Online/SocketClientConnector.cs new file mode 100644 index 0000000000..823e724ef9 --- /dev/null +++ b/osu.Game/Online/SocketClientConnector.cs @@ -0,0 +1,183 @@ +// 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.Threading; +using System.Threading.Tasks; +using osu.Framework.Bindables; +using osu.Framework.Extensions.TypeExtensions; +using osu.Framework.Graphics; +using osu.Framework.Logging; +using osu.Game.Online.API; + +namespace osu.Game.Online +{ + public abstract class SocketClientConnector : Component + { + /// + /// Whether this is connected to the hub, use to access the connection, if this is true. + /// + public IBindable IsConnected => isConnected; + + /// + /// The current connection opened by this connector. + /// + public SocketClient? CurrentConnection { get; private set; } + + private readonly Bindable isConnected = new Bindable(); + private readonly SemaphoreSlim connectionLock = new SemaphoreSlim(1); + private CancellationTokenSource connectCancelSource = new CancellationTokenSource(); + + private readonly IBindable apiState = new Bindable(); + + /// + /// Constructs a new . + /// + /// An API provider used to react to connection state changes. + protected SocketClientConnector(IAPIProvider api) + { + apiState.BindTo(api.State); + apiState.BindValueChanged(_ => Task.Run(connectIfPossible), true); + } + + public Task Reconnect() + { + Logger.Log($"{ClientName} reconnecting...", LoggingTarget.Network); + return Task.Run(connectIfPossible); + } + + private async Task connectIfPossible() + { + switch (apiState.Value) + { + case APIState.Failing: + case APIState.Offline: + await disconnect(true); + break; + + case APIState.Online: + await connect(); + break; + } + } + + private async Task connect() + { + cancelExistingConnect(); + + if (!await connectionLock.WaitAsync(10000).ConfigureAwait(false)) + throw new TimeoutException("Could not obtain a lock to connect. A previous attempt is likely stuck."); + + try + { + while (apiState.Value == APIState.Online) + { + // ensure any previous connection was disposed. + // this will also create a new cancellation token source. + await disconnect(false).ConfigureAwait(false); + + // this token will be valid for the scope of this connection. + // if cancelled, we can be sure that a disconnect or reconnect is handled elsewhere. + var cancellationToken = connectCancelSource.Token; + + cancellationToken.ThrowIfCancellationRequested(); + + Logger.Log($"{ClientName} connecting...", LoggingTarget.Network); + + try + { + // importantly, rebuild the connection each attempt to get an updated access token. + CurrentConnection = await BuildConnectionAsync(cancellationToken).ConfigureAwait(false); + CurrentConnection.Closed += ex => onConnectionClosed(ex, cancellationToken); + + cancellationToken.ThrowIfCancellationRequested(); + + await CurrentConnection.StartAsync(cancellationToken).ConfigureAwait(false); + + Logger.Log($"{ClientName} connected!", LoggingTarget.Network); + isConnected.Value = true; + return; + } + catch (OperationCanceledException) + { + //connection process was cancelled. + throw; + } + catch (Exception e) + { + await handleErrorAndDelay(e, cancellationToken).ConfigureAwait(false); + } + } + } + finally + { + connectionLock.Release(); + } + } + + /// + /// Handles an exception and delays an async flow. + /// + private async Task handleErrorAndDelay(Exception exception, CancellationToken cancellationToken) + { + Logger.Log($"{ClientName} connect attempt failed: {exception.Message}", LoggingTarget.Network); + await Task.Delay(5000, cancellationToken).ConfigureAwait(false); + } + + protected abstract Task BuildConnectionAsync(CancellationToken cancellationToken); + + private async Task onConnectionClosed(Exception? ex, CancellationToken cancellationToken) + { + isConnected.Value = false; + + if (ex != null) + await handleErrorAndDelay(ex, cancellationToken).ConfigureAwait(false); + else + Logger.Log($"{ClientName} disconnected", LoggingTarget.Network); + + // make sure a disconnect wasn't triggered (and this is still the active connection). + if (!cancellationToken.IsCancellationRequested) + await Task.Run(connect, default).ConfigureAwait(false); + } + + private async Task disconnect(bool takeLock) + { + cancelExistingConnect(); + + if (takeLock) + { + if (!await connectionLock.WaitAsync(10000).ConfigureAwait(false)) + throw new TimeoutException("Could not obtain a lock to disconnect. A previous attempt is likely stuck."); + } + + try + { + if (CurrentConnection != null) + await CurrentConnection.DisposeAsync().ConfigureAwait(false); + } + finally + { + CurrentConnection = null; + if (takeLock) + connectionLock.Release(); + } + } + + private void cancelExistingConnect() + { + connectCancelSource.Cancel(); + connectCancelSource = new CancellationTokenSource(); + } + + protected virtual string ClientName => GetType().ReadableName(); + + public override string ToString() => $"{ClientName} ({(IsConnected.Value ? "connected" : "not connected")})"; + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + apiState.UnbindAll(); + cancelExistingConnect(); + } + } +} From 097d310d7464056893d2baba9c1a23a3dac0ccfa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Oct 2022 14:40:14 +0900 Subject: [PATCH 0260/2991] Only draw path visualiser when hovered or single slider is selected --- .../Sliders/SliderSelectionBlueprint.cs | 51 +++++++++++++++---- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 265a1d21b1..9716f2820f 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -59,6 +59,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders private readonly BindableList controlPoints = new BindableList(); private readonly IBindable pathVersion = new Bindable(); + private BindableList selectedObjects; public SliderSelectionBlueprint(Slider slider) : base(slider) @@ -86,6 +87,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders pathVersion.BindValueChanged(_ => editorBeatmap?.Update(HitObject)); BodyPiece.UpdateFrom(HitObject); + + selectedObjects = editorBeatmap.SelectedHitObjects.GetBoundCopy(); + selectedObjects.BindCollectionChanged((_, _) => updateVisualDefinition()); } public override bool HandleQuickDeletion() @@ -108,14 +112,21 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders BodyPiece.UpdateFrom(HitObject); } + protected override bool OnHover(HoverEvent e) + { + updateVisualDefinition(); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + updateVisualDefinition(); + base.OnHoverLost(e); + } + protected override void OnSelected() { - AddInternal(ControlPointVisualiser = new PathControlPointVisualiser(HitObject, true) - { - RemoveControlPointsRequested = removeControlPoints, - SplitControlPointsRequested = splitControlPoints - }); - + updateVisualDefinition(); base.OnSelected(); } @@ -123,13 +134,33 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders { base.OnDeselected(); - // throw away frame buffers on deselection. - ControlPointVisualiser?.Expire(); - ControlPointVisualiser = null; - + updateVisualDefinition(); BodyPiece.RecyclePath(); } + private void updateVisualDefinition() + { + bool hasSingleObjectSelected = editorBeatmap.SelectedHitObjects.Count == 1; + + // To reduce overhead of drawing these blueprints, only add extra detail when hovered or when only this slider is selected. + if (IsSelected && (hasSingleObjectSelected || IsHovered)) + { + if (ControlPointVisualiser == null) + { + AddInternal(ControlPointVisualiser = new PathControlPointVisualiser(HitObject, true) + { + RemoveControlPointsRequested = removeControlPoints, + SplitControlPointsRequested = splitControlPoints + }); + } + } + else + { + ControlPointVisualiser?.Expire(); + ControlPointVisualiser = null; + } + } + private Vector2 rightClickPosition; protected override bool OnMouseDown(MouseDownEvent e) From 2f172b66cf80290ee3b9bfd3d4c8d971f342d05c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Oct 2022 14:52:46 +0900 Subject: [PATCH 0261/2991] Block hover if a multi-selection is made to avoid overlapping path visualisers --- .../Blueprints/Sliders/SliderSelectionBlueprint.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 9716f2820f..ab164028b1 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -104,6 +104,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders return true; } + private bool hasSingleObjectSelected => editorBeatmap.SelectedHitObjects.Count == 1; + protected override void Update() { base.Update(); @@ -115,7 +117,11 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders protected override bool OnHover(HoverEvent e) { updateVisualDefinition(); - return base.OnHover(e); + + // In the case more than a single object is selected, block hover from arriving at sliders behind this one. + // Without doing this, the path visualisers of potentially hundreds of sliders will render, which is not only + // visually noisy but also functionally useless. + return !hasSingleObjectSelected; } protected override void OnHoverLost(HoverLostEvent e) @@ -140,8 +146,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders private void updateVisualDefinition() { - bool hasSingleObjectSelected = editorBeatmap.SelectedHitObjects.Count == 1; - // To reduce overhead of drawing these blueprints, only add extra detail when hovered or when only this slider is selected. if (IsSelected && (hasSingleObjectSelected || IsHovered)) { From 6cca3a3dc82cb2b7972c8232d00aa6dcf119be96 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Thu, 27 Oct 2022 14:55:24 +0900 Subject: [PATCH 0262/2991] Add new API requests --- .../Online/API/Requests/ChatAckRequest.cs | 21 +++++++++++ .../API/Requests/GetNotificationsRequest.cs | 12 ++++++ .../API/Requests/Responses/APINotification.cs | 37 +++++++++++++++++++ .../Responses/APINotificationsBundle.cs | 20 ++++++++++ .../API/Requests/Responses/ChatAckResponse.cs | 15 ++++++++ .../API/Requests/Responses/ChatSilence.cs | 17 +++++++++ 6 files changed, 122 insertions(+) create mode 100644 osu.Game/Online/API/Requests/ChatAckRequest.cs create mode 100644 osu.Game/Online/API/Requests/GetNotificationsRequest.cs create mode 100644 osu.Game/Online/API/Requests/Responses/APINotification.cs create mode 100644 osu.Game/Online/API/Requests/Responses/APINotificationsBundle.cs create mode 100644 osu.Game/Online/API/Requests/Responses/ChatAckResponse.cs create mode 100644 osu.Game/Online/API/Requests/Responses/ChatSilence.cs diff --git a/osu.Game/Online/API/Requests/ChatAckRequest.cs b/osu.Game/Online/API/Requests/ChatAckRequest.cs new file mode 100644 index 0000000000..f09df4908e --- /dev/null +++ b/osu.Game/Online/API/Requests/ChatAckRequest.cs @@ -0,0 +1,21 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Net.Http; +using osu.Framework.IO.Network; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Online.API.Requests +{ + public class ChatAckRequest : APIRequest + { + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + req.Method = HttpMethod.Post; + return req; + } + + protected override string Target => "chat/ack"; + } +} diff --git a/osu.Game/Online/API/Requests/GetNotificationsRequest.cs b/osu.Game/Online/API/Requests/GetNotificationsRequest.cs new file mode 100644 index 0000000000..e419807a85 --- /dev/null +++ b/osu.Game/Online/API/Requests/GetNotificationsRequest.cs @@ -0,0 +1,12 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Online.API.Requests +{ + public class GetNotificationsRequest : APIRequest + { + protected override string Target => "notifications"; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APINotification.cs b/osu.Game/Online/API/Requests/Responses/APINotification.cs new file mode 100644 index 0000000000..e1f0fa7221 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APINotification.cs @@ -0,0 +1,37 @@ +// 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 Newtonsoft.Json; + +namespace osu.Game.Online.API.Requests.Responses +{ + [JsonObject(MemberSerialization.OptIn)] + public class APINotification + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("name")] + public string Name { get; set; } = null!; + + [JsonProperty("created_at")] + public DateTimeOffset? CreatedAt { get; set; } + + [JsonProperty("object_type")] + public string ObjectType { get; set; } = null!; + + [JsonProperty("object_id")] + public string ObjectId { get; set; } = null!; + + [JsonProperty("source_user_id")] + public long? SourceUserId { get; set; } + + [JsonProperty("is_read")] + public bool IsRead { get; set; } + + [JsonProperty("details")] + public Dictionary? Details { get; set; } + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APINotificationsBundle.cs b/osu.Game/Online/API/Requests/Responses/APINotificationsBundle.cs new file mode 100644 index 0000000000..067f1066b3 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APINotificationsBundle.cs @@ -0,0 +1,20 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Newtonsoft.Json; + +namespace osu.Game.Online.API.Requests.Responses +{ + [JsonObject(MemberSerialization.OptIn)] + public class APINotificationsBundle + { + [JsonProperty("has_more")] + public bool HasMore { get; set; } + + [JsonProperty("notifications")] + public APINotification[] Notifications { get; set; } = null!; + + [JsonProperty("notification_endpoint")] + public string Endpoint { get; set; } = null!; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/ChatAckResponse.cs b/osu.Game/Online/API/Requests/Responses/ChatAckResponse.cs new file mode 100644 index 0000000000..6ed22a19b2 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/ChatAckResponse.cs @@ -0,0 +1,15 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace osu.Game.Online.API.Requests.Responses +{ + [JsonObject(MemberSerialization.OptIn)] + public class ChatAckResponse + { + [JsonProperty("silences")] + public List Silences { get; set; } = null!; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/ChatSilence.cs b/osu.Game/Online/API/Requests/Responses/ChatSilence.cs new file mode 100644 index 0000000000..45fd6e1ba3 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/ChatSilence.cs @@ -0,0 +1,17 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Newtonsoft.Json; + +namespace osu.Game.Online.API.Requests.Responses +{ + [JsonObject(MemberSerialization.OptIn)] + public class ChatSilence + { + [JsonProperty("id")] + public uint Id { get; set; } + + [JsonProperty("user_id")] + public uint UserId { get; set; } + } +} From 0c7672e1248b190686a2d69b58e9f3612f1884e3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Oct 2022 16:02:04 +0900 Subject: [PATCH 0263/2991] Avoid unnecessarily refreshing `SliderBodyPiece`'s path --- .../Sliders/Components/SliderBodyPiece.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs index bb967a0a76..da2a6ced67 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs @@ -40,16 +40,23 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components body.BorderColour = colours.Yellow; } + private int? lastVersion; + public override void UpdateFrom(Slider hitObject) { base.UpdateFrom(hitObject); body.PathRadius = hitObject.Scale * OsuHitObject.OBJECT_RADIUS; - var vertices = new List(); - hitObject.Path.GetPathToProgress(vertices, 0, 1); + if (lastVersion != hitObject.Path.Version.Value) + { + lastVersion = hitObject.Path.Version.Value; - body.SetVertices(vertices); + var vertices = new List(); + hitObject.Path.GetPathToProgress(vertices, 0, 1); + + body.SetVertices(vertices); + } Size = body.Size; OriginPosition = body.PathOffset; From 39e0362db13a96bed21f265bcb5ae94c87e28097 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Oct 2022 16:15:22 +0900 Subject: [PATCH 0264/2991] Reduce size of spinner blueprint to better represent gameplay size --- .../Spinners/Components/SpinnerPiece.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs index 28690ee0b7..2b1bb5185c 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs @@ -16,8 +16,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners.Components { public class SpinnerPiece : BlueprintPiece { - private readonly CircularContainer circle; - private readonly RingPiece ring; + private readonly Circle circle; + private readonly Circle ring; public SpinnerPiece() { @@ -25,18 +25,21 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners.Components RelativeSizeAxes = Axes.Both; FillMode = FillMode.Fit; - Size = new Vector2(1.3f); + Size = new Vector2(1); InternalChildren = new Drawable[] { - circle = new CircularContainer + circle = new Circle { RelativeSizeAxes = Axes.Both, - Masking = true, Alpha = 0.5f, - Child = new Box { RelativeSizeAxes = Axes.Both } }, - ring = new RingPiece() + ring = new Circle + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(OsuHitObject.OBJECT_RADIUS), + }, }; } From 68d1febe6e9b5939f1f32a112b4c81f1567b1771 Mon Sep 17 00:00:00 2001 From: nullium21 Date: Thu, 27 Oct 2022 10:33:50 +0300 Subject: [PATCH 0265/2991] Use a regex for matching invalid characters instead What the regex does is it matches everything except alphanumeric and [_()[] -], excluding EOL since regex101 seems to also match it, and we probably don't want that to happen. --- osu.Game/Extensions/ModelExtensions.cs | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/osu.Game/Extensions/ModelExtensions.cs b/osu.Game/Extensions/ModelExtensions.cs index 51bea02726..8acc079805 100644 --- a/osu.Game/Extensions/ModelExtensions.cs +++ b/osu.Game/Extensions/ModelExtensions.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.IO; +using System.Text.RegularExpressions; using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.IO; @@ -136,34 +137,14 @@ namespace osu.Game.Extensions return instance.OnlineID.Equals(other.OnlineID); } - private static bool isValidFilenameChar(this char ch) - { - if (ch >= '0' && ch <= '9') - return true; - - if (ch >= 'A' && ch <= 'Z') - return true; - - if (ch >= 'a' && ch <= 'z') - return true; - - return "-_()[]".Contains(ch); - } + private static Regex invalid_filename_chars = new(@"(?!$)[^A-Za-z0-9_()[\] -]", RegexOptions.Compiled); /// /// Get a valid filename for use inside a zip file. Avoids backslashes being incorrectly converted to directories. /// public static string GetValidArchiveContentFilename(this string filename) { - char[] resultData = filename.ToCharArray(); - - for (int i = 0; i < resultData.Length; i++) - { - if (!isValidFilenameChar(resultData[i])) - resultData[i] = '_'; - } - - return new string(resultData); + return invalid_filename_chars.Replace(filename, "_"); } } } From d48f95cf7c0f317c6b532e9d455b592e9a521fb0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Oct 2022 13:16:15 +0900 Subject: [PATCH 0266/2991] Use shader based implementation instead of sprites --- .../Skinning/Argon/ArgonDropletPiece.cs | 37 ++++++++++--------- .../Skinning/Argon/ArgonFruitPiece.cs | 36 ++++++++++-------- 2 files changed, 41 insertions(+), 32 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonDropletPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonDropletPiece.cs index c607b96729..63a41edaf7 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonDropletPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonDropletPiece.cs @@ -5,8 +5,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Utils; using osu.Game.Rulesets.Catch.Skinning.Default; using osu.Game.Rulesets.Catch.UI; @@ -25,11 +24,13 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon private float rotationRandomness; [BackgroundDependencyLoader] - private void load(TextureStore textures) + private void load() { RelativeSizeAxes = Axes.Both; - const float droplet_scale_down = 0.5f; + const float droplet_scale_down = 0.7f; + + int largeBlobSeed = RNG.Next(); InternalChildren = new[] { @@ -47,38 +48,42 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - new Sprite + new CircularBlob { Anchor = Anchor.Centre, Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, Blending = BlendingParameters.Additive, + InnerRadius = 0.5f, Alpha = 0.15f, - Texture = getTexture("A") + Seed = largeBlobSeed }, - new Sprite + new CircularBlob { Anchor = Anchor.Centre, Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, Blending = BlendingParameters.Additive, + InnerRadius = 0.4f, Alpha = 0.5f, - Scale = new Vector2(0.8f), - Texture = getTexture("A") + Scale = new Vector2(0.7f), + Seed = RNG.Next() }, } }, - hyperBorderPiece = new Sprite + hyperBorderPiece = new CircularBlob { Scale = new Vector2(droplet_scale_down), Anchor = Anchor.Centre, Origin = Anchor.Centre, Colour = Catcher.DEFAULT_HYPER_DASH_COLOUR, + RelativeSizeAxes = Axes.Both, Blending = BlendingParameters.Additive, + InnerRadius = 0.5f, Alpha = 0.15f, - Texture = getTexture("A"), + Seed = largeBlobSeed }, }; - - Texture getTexture(string type) => textures.Get($"Gameplay/catch/blob-{type}{RNG.Next(1, 7)}"); } protected override void LoadComplete() @@ -106,10 +111,8 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon for (int i = 0; i < layers.Count; i++) { layers[i].Rotation -= - // Layers are ordered from largest to smallest. Smaller layers should rotate more. - (i * 4) - * (float)Clock.ElapsedFrameTime - * 0.2f * rotationRandomness + (float)Clock.ElapsedFrameTime + * 0.4f * rotationRandomness // Each layer should alternate rotation direction. * (i % 2 == 1 ? 0.5f : 1); } diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs index 2412de7dbe..28538d48b3 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs @@ -5,8 +5,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Utils; using osu.Game.Rulesets.Catch.Skinning.Default; using osu.Game.Rulesets.Catch.UI; @@ -25,11 +24,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon private float rotationRandomness; [BackgroundDependencyLoader] - private void load(TextureStore textures) + private void load() { RelativeSizeAxes = Axes.Both; - Texture largeTexture = getTexture("A"); + int largeBlobSeed = RNG.Next(); InternalChildren = new[] { @@ -44,43 +43,50 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - new Sprite + new CircularBlob { Anchor = Anchor.Centre, Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, Blending = BlendingParameters.Additive, Alpha = 0.15f, - Texture = largeTexture + InnerRadius = 0.5f, + Size = new Vector2(1.1f), + Seed = largeBlobSeed, }, - new Sprite + new CircularBlob { Anchor = Anchor.Centre, Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, Blending = BlendingParameters.Additive, + InnerRadius = 0.2f, Alpha = 0.5f, - Texture = getTexture("B") + Seed = RNG.Next(), }, - new Sprite + new CircularBlob { Anchor = Anchor.Centre, Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, Blending = BlendingParameters.Additive, - Texture = getTexture("C") + InnerRadius = 0.05f, + Seed = RNG.Next(), }, } }, - hyperBorderPiece = new Sprite + hyperBorderPiece = new CircularBlob { Anchor = Anchor.Centre, Origin = Anchor.Centre, Colour = Catcher.DEFAULT_HYPER_DASH_COLOUR, + RelativeSizeAxes = Axes.Both, Blending = BlendingParameters.Additive, - Alpha = 0.15f, - Texture = largeTexture, + InnerRadius = 0.08f, + Size = new Vector2(1.15f), + Seed = largeBlobSeed }, }; - - Texture getTexture(string type) => textures.Get($"Gameplay/catch/blob-{type}{RNG.Next(1, 7)}"); } protected override void LoadComplete() From 6fe8298152db01184197632997a2c0247fd90ac0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Oct 2022 19:02:01 +0900 Subject: [PATCH 0267/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index f251e8ee71..5d6c32cea8 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 22474c0592..5d1a834b0e 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index cf70b65578..bf218f856a 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From 3c4ba6e9fcd596a6fa0d894c47d8ee5d92f073bf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Oct 2022 19:02:32 +0900 Subject: [PATCH 0268/2991] Fix `SoloScoreInfo.Rank` not being serialised if rank is `D` --- osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs b/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs index 4469d50acb..2095b2c700 100644 --- a/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs +++ b/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Converters; @@ -45,6 +46,9 @@ namespace osu.Game.Online.API.Requests.Responses [JsonConverter(typeof(StringEnumConverter))] [JsonProperty("rank")] + // ScoreRank is aligned to make 0 equal D. We still want to serialise this (even when DefaultValueHandling.Ignore is used), + // so set the default to an impossible value. + [DefaultValue(null)] public ScoreRank Rank { get; set; } [JsonProperty("started_at")] From 361153f598c34072b009cd91860dc2470917925a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Oct 2022 19:05:50 +0900 Subject: [PATCH 0269/2991] Fix nullref in tests due to missing `EditorBeatmap` dependency --- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index ab164028b1..0b0a76cce0 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -104,7 +104,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders return true; } - private bool hasSingleObjectSelected => editorBeatmap.SelectedHitObjects.Count == 1; + private bool hasSingleObjectSelected => editorBeatmap == null || editorBeatmap.SelectedHitObjects.Count == 1; protected override void Update() { From e582d9d5a8720928e03a792a9b92dc91fbd54baf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 01:17:09 +0900 Subject: [PATCH 0270/2991] Remove unused using statements --- .../Edit/Blueprints/Spinners/Components/SpinnerPiece.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs index 2b1bb5185c..b5a13a22ce 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs @@ -5,11 +5,9 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.Osu.Skinning.Default; using osuTK; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners.Components From 7faf5cd1f6f7962002162dafc463037e0e2011e3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 01:20:17 +0900 Subject: [PATCH 0271/2991] Fix one more null edge case --- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 0b0a76cce0..b5b04823a7 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -59,7 +59,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders private readonly BindableList controlPoints = new BindableList(); private readonly IBindable pathVersion = new Bindable(); - private BindableList selectedObjects; + private readonly BindableList selectedObjects = new BindableList(); public SliderSelectionBlueprint(Slider slider) : base(slider) @@ -88,7 +88,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders BodyPiece.UpdateFrom(HitObject); - selectedObjects = editorBeatmap.SelectedHitObjects.GetBoundCopy(); + if (editorBeatmap != null) + selectedObjects.BindTo(editorBeatmap.SelectedHitObjects); selectedObjects.BindCollectionChanged((_, _) => updateVisualDefinition()); } @@ -104,7 +105,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders return true; } - private bool hasSingleObjectSelected => editorBeatmap == null || editorBeatmap.SelectedHitObjects.Count == 1; + private bool hasSingleObjectSelected => editorBeatmap == null || selectedObjects.Count == 1; protected override void Update() { From dcff8a193cf1f206d614cb59e8092801b0d050c9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 01:26:10 +0900 Subject: [PATCH 0272/2991] Use better method of forcing serialisation --- osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs b/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs index 2095b2c700..57586e3d77 100644 --- a/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs +++ b/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.ComponentModel; using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Converters; @@ -45,10 +44,8 @@ namespace osu.Game.Online.API.Requests.Responses public int MaxCombo { get; set; } [JsonConverter(typeof(StringEnumConverter))] - [JsonProperty("rank")] - // ScoreRank is aligned to make 0 equal D. We still want to serialise this (even when DefaultValueHandling.Ignore is used), - // so set the default to an impossible value. - [DefaultValue(null)] + // ScoreRank is aligned to make 0 equal D. We still want to serialise this (even when DefaultValueHandling.Ignore is used). + [JsonProperty("rank", DefaultValueHandling = DefaultValueHandling.Include)] public ScoreRank Rank { get; set; } [JsonProperty("started_at")] From 446a9c1b05d5c98e89d85c699afa82338f9f7810 Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Thu, 27 Oct 2022 23:41:17 +0200 Subject: [PATCH 0273/2991] Make added effect points inherit previous effect point settings --- .../Beatmaps/TaikoBeatmapConverter.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index c1e1052569..3cc47deed0 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -65,17 +65,16 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps foreach (HitObject hitObject in original.HitObjects) { double nextScrollSpeed = hitObject.DifficultyControlPoint.SliderVelocity; + EffectControlPoint currentEffectPoint = converted.ControlPointInfo.EffectPointAt(hitObject.StartTime); - if (!Precision.AlmostEquals(lastScrollSpeed, nextScrollSpeed)) + if (!Precision.AlmostEquals(lastScrollSpeed, nextScrollSpeed, acceptableDifference: currentEffectPoint.ScrollSpeedBindable.Precision)) { - EffectControlPoint currentControlPoint = converted.ControlPointInfo.EffectPointAt(hitObject.StartTime); - - if (Precision.AlmostEquals(currentControlPoint.Time, hitObject.StartTime)) - currentControlPoint.ScrollSpeed = nextScrollSpeed; - else - converted.ControlPointInfo.Add(hitObject.StartTime, new EffectControlPoint { ScrollSpeed = nextScrollSpeed }); - - lastScrollSpeed = nextScrollSpeed; + converted.ControlPointInfo.Add(hitObject.StartTime, new EffectControlPoint + { + KiaiMode = currentEffectPoint.KiaiMode, + OmitFirstBarLine = currentEffectPoint.OmitFirstBarLine, + ScrollSpeed = lastScrollSpeed = nextScrollSpeed, + }); } } } From 9969c00ead98ccd88a3eb5f88d7c2357628a495c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 10:19:53 +0900 Subject: [PATCH 0274/2991] Apply two minor fixes from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game.Rulesets.Catch/Skinning/Argon/ArgonDropletPiece.cs | 2 +- .../Skinning/Argon/CatchArgonSkinTransformer.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonDropletPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonDropletPiece.cs index 63a41edaf7..267f8a06a3 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonDropletPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonDropletPiece.cs @@ -113,7 +113,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon layers[i].Rotation -= (float)Clock.ElapsedFrameTime * 0.4f * rotationRandomness - // Each layer should alternate rotation direction. + // Each layer should alternate rotation speed. * (i % 2 == 1 ? 0.5f : 1); } } diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs index 30542187f2..8dae0a2b78 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs @@ -17,9 +17,9 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon { switch (component) { - case CatchSkinComponent osuComponent: + case CatchSkinComponent catchComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. - switch (osuComponent.Component) + switch (catchComponent.Component) { case CatchSkinComponents.HitExplosion: return new ArgonHitExplosion(); From 71970d83cf658add8dbe68cf15390da4f305d489 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 12:47:44 +0900 Subject: [PATCH 0275/2991] Remove obsoleted `ShowProgressGraph` global setting This was moved to the component itself. --- osu.Game/Configuration/OsuConfigManager.cs | 3 -- .../Screens/Play/HUD/DefaultSongProgress.cs | 48 ------------------- 2 files changed, 51 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 1378e1691a..825c345c0a 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -127,7 +127,6 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.HitLighting, true); SetDefault(OsuSetting.HUDVisibilityMode, HUDVisibilityMode.Always); - SetDefault(OsuSetting.ShowProgressGraph, true); SetDefault(OsuSetting.ShowHealthDisplayWhenCantFail, true); SetDefault(OsuSetting.FadePlayfieldWhenHealthLow, true); SetDefault(OsuSetting.KeyOverlay, false); @@ -302,8 +301,6 @@ namespace osu.Game.Configuration FloatingComments, HUDVisibilityMode, - // This has been migrated to the component itself. can be removed 20221027. - ShowProgressGraph, ShowHealthDisplayWhenCantFail, FadePlayfieldWhenHealthLow, MouseDisableButtons, diff --git a/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs b/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs index 30b420441c..45d0cf8462 100644 --- a/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs +++ b/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs @@ -9,7 +9,6 @@ using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.UI; -using osu.Game.Skinning; using osuTK; namespace osu.Game.Screens.Play.HUD @@ -45,12 +44,6 @@ namespace osu.Game.Screens.Play.HUD [Resolved] private DrawableRuleset? drawableRuleset { get; set; } - [Resolved] - private OsuConfigManager config { get; set; } = null!; - - [Resolved] - private SkinManager skinManager { get; set; } = null!; - public DefaultSongProgress() { RelativeSizeAxes = Axes.X; @@ -100,47 +93,6 @@ namespace osu.Game.Screens.Play.HUD { AllowSeeking.BindValueChanged(_ => updateBarVisibility(), true); ShowGraph.BindValueChanged(_ => updateGraphVisibility(), true); - - migrateSettingFromConfig(); - } - - /// - /// This setting has been migrated to a per-component level. - /// Only take the value from the config if it is in a non-default state (then reset it to default so it only applies once). - /// - /// Can be removed 20221027. - /// - private void migrateSettingFromConfig() - { - Bindable configShowGraph = config.GetBindable(OsuSetting.ShowProgressGraph); - - if (!configShowGraph.IsDefault) - { - ShowGraph.Value = configShowGraph.Value; - - // This is pretty ugly, but the only way to make this stick... - var skinnableTarget = this.FindClosestParent(); - - if (skinnableTarget != null) - { - // If the skin is not mutable, a mutable instance will be created, causing this migration logic to run again on the correct skin. - // Therefore we want to avoid resetting the config value on this invocation. - if (skinManager.EnsureMutableSkin()) - return; - - // If `EnsureMutableSkin` actually changed the skin, default layout may take a frame to apply. - // See `SkinnableTargetComponentsContainer`'s use of ScheduleAfterChildren. - ScheduleAfterChildren(() => - { - var skin = skinManager.CurrentSkin.Value; - skin.UpdateDrawableTarget(skinnableTarget); - - skinManager.Save(skin); - }); - - configShowGraph.SetDefault(); - } - } } protected override void PopIn() From 29f504ecc031e8f930e639da5c8d4d7197fdc986 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 13:00:39 +0900 Subject: [PATCH 0276/2991] Remove obsoleted tournament migration flow --- .../NonVisual/CustomTourneyDirectoryTest.cs | 79 +----------------- ...eManager.cs => TournamentConfigManager.cs} | 13 ++- osu.Game.Tournament/IO/TournamentStorage.cs | 80 ++----------------- 3 files changed, 19 insertions(+), 153 deletions(-) rename osu.Game.Tournament/Configuration/{TournamentStorageManager.cs => TournamentConfigManager.cs} (55%) diff --git a/osu.Game.Tournament.Tests/NonVisual/CustomTourneyDirectoryTest.cs b/osu.Game.Tournament.Tests/NonVisual/CustomTourneyDirectoryTest.cs index d314f40c30..f778e67f58 100644 --- a/osu.Game.Tournament.Tests/NonVisual/CustomTourneyDirectoryTest.cs +++ b/osu.Game.Tournament.Tests/NonVisual/CustomTourneyDirectoryTest.cs @@ -49,7 +49,7 @@ namespace osu.Game.Tournament.Tests.NonVisual // manual cleaning so we can prepare a config file. storage.DeleteDirectory(string.Empty); - using (var storageConfig = new TournamentStorageManager(storage)) + using (var storageConfig = new TournamentConfigManager(storage)) storageConfig.SetValue(StorageConfig.CurrentTournament, custom_tournament); try @@ -66,82 +66,5 @@ namespace osu.Game.Tournament.Tests.NonVisual } } } - - [Test] - public void TestMigration() - { - using (HeadlessGameHost host = new TestRunHeadlessGameHost(nameof(TestMigration), null)) // don't use clean run as we are writing test files for migration. - { - string osuRoot = Path.Combine(host.UserStoragePaths.First(), nameof(TestMigration)); - string configFile = Path.Combine(osuRoot, "tournament.ini"); - - if (File.Exists(configFile)) - File.Delete(configFile); - - // Recreate the old setup that uses "tournament" as the base path. - string oldPath = Path.Combine(osuRoot, "tournament"); - - string videosPath = Path.Combine(oldPath, "Videos"); - string modsPath = Path.Combine(oldPath, "Mods"); - string flagsPath = Path.Combine(oldPath, "Flags"); - - Directory.CreateDirectory(videosPath); - Directory.CreateDirectory(modsPath); - Directory.CreateDirectory(flagsPath); - - // Define testing files corresponding to the specific file migrations that are needed - string bracketFile = Path.Combine(osuRoot, TournamentGameBase.BRACKET_FILENAME); - - string drawingsConfig = Path.Combine(osuRoot, "drawings.ini"); - string drawingsFile = Path.Combine(osuRoot, "drawings.txt"); - string drawingsResult = Path.Combine(osuRoot, "drawings_results.txt"); - - // Define sample files to test recursive copying - string videoFile = Path.Combine(videosPath, "video.mp4"); - string modFile = Path.Combine(modsPath, "mod.png"); - string flagFile = Path.Combine(flagsPath, "flag.png"); - - File.WriteAllText(bracketFile, "{}"); - File.WriteAllText(drawingsConfig, "test"); - File.WriteAllText(drawingsFile, "test"); - File.WriteAllText(drawingsResult, "test"); - File.WriteAllText(videoFile, "test"); - File.WriteAllText(modFile, "test"); - File.WriteAllText(flagFile, "test"); - - try - { - var osu = LoadTournament(host); - - var storage = osu.Dependencies.Get(); - - string migratedPath = Path.Combine(host.Storage.GetFullPath("."), "tournaments", "default"); - - videosPath = Path.Combine(migratedPath, "Videos"); - modsPath = Path.Combine(migratedPath, "Mods"); - flagsPath = Path.Combine(migratedPath, "Flags"); - - videoFile = Path.Combine(videosPath, "video.mp4"); - modFile = Path.Combine(modsPath, "mod.png"); - flagFile = Path.Combine(flagsPath, "flag.png"); - - Assert.That(storage.GetFullPath("."), Is.EqualTo(migratedPath)); - - Assert.True(storage.Exists(TournamentGameBase.BRACKET_FILENAME)); - Assert.True(storage.Exists("drawings.txt")); - Assert.True(storage.Exists("drawings_results.txt")); - - Assert.True(storage.Exists("drawings.ini")); - - Assert.True(storage.Exists(videoFile)); - Assert.True(storage.Exists(modFile)); - Assert.True(storage.Exists(flagFile)); - } - finally - { - host.Exit(); - } - } - } } } diff --git a/osu.Game.Tournament/Configuration/TournamentStorageManager.cs b/osu.Game.Tournament/Configuration/TournamentConfigManager.cs similarity index 55% rename from osu.Game.Tournament/Configuration/TournamentStorageManager.cs rename to osu.Game.Tournament/Configuration/TournamentConfigManager.cs index 0b9a556296..8f256ba9c3 100644 --- a/osu.Game.Tournament/Configuration/TournamentStorageManager.cs +++ b/osu.Game.Tournament/Configuration/TournamentConfigManager.cs @@ -8,14 +8,23 @@ using osu.Framework.Platform; namespace osu.Game.Tournament.Configuration { - public class TournamentStorageManager : IniConfigManager + public class TournamentConfigManager : IniConfigManager { protected override string Filename => "tournament.ini"; - public TournamentStorageManager(Storage storage) + private const string default_tournament = "default"; + + public TournamentConfigManager(Storage storage) : base(storage) { } + + protected override void InitialiseDefaults() + { + base.InitialiseDefaults(); + + SetDefault(StorageConfig.CurrentTournament, default_tournament); + } } public enum StorageConfig diff --git a/osu.Game.Tournament/IO/TournamentStorage.cs b/osu.Game.Tournament/IO/TournamentStorage.cs index bd52b6dfed..e59f90a45e 100644 --- a/osu.Game.Tournament/IO/TournamentStorage.cs +++ b/osu.Game.Tournament/IO/TournamentStorage.cs @@ -1,10 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; -using System.IO; using osu.Framework.Bindables; using osu.Framework.Logging; using osu.Framework.Platform; @@ -13,35 +10,28 @@ using osu.Game.Tournament.Configuration; namespace osu.Game.Tournament.IO { - public class TournamentStorage : MigratableStorage + public class TournamentStorage : WrappedStorage { - private const string default_tournament = "default"; - private readonly Storage storage; - /// /// The storage where all tournaments are located. /// public readonly Storage AllTournaments; - private readonly TournamentStorageManager storageConfig; public readonly Bindable CurrentTournament; + protected TournamentConfigManager TournamentConfigManager { get; } + public TournamentStorage(Storage storage) : base(storage.GetStorageForDirectory("tournaments"), string.Empty) { - this.storage = storage; AllTournaments = UnderlyingStorage; - storageConfig = new TournamentStorageManager(storage); + TournamentConfigManager = new TournamentConfigManager(storage); - if (storage.Exists("tournament.ini")) - { - ChangeTargetStorage(AllTournaments.GetStorageForDirectory(storageConfig.Get(StorageConfig.CurrentTournament))); - } - else - Migrate(AllTournaments.GetStorageForDirectory(default_tournament)); + CurrentTournament = TournamentConfigManager.GetBindable(StorageConfig.CurrentTournament); + + ChangeTargetStorage(AllTournaments.GetStorageForDirectory(CurrentTournament.Value)); - CurrentTournament = storageConfig.GetBindable(StorageConfig.CurrentTournament); Logger.Log("Using tournament storage: " + GetFullPath(string.Empty)); CurrentTournament.BindValueChanged(updateTournament); @@ -53,62 +43,6 @@ namespace osu.Game.Tournament.IO Logger.Log("Changing tournament storage: " + GetFullPath(string.Empty)); } - protected override void ChangeTargetStorage(Storage newStorage) - { - // due to an unfortunate oversight, on OSes that are sensitive to pathname casing - // the custom flags directory needed to be named `Flags` (uppercase), - // while custom mods and videos directories needed to be named `mods` and `videos` respectively (lowercase). - // to unify handling to uppercase, move any non-compliant directories automatically for the user to migrate. - // can be removed 20220528 - if (newStorage.ExistsDirectory("flags")) - AttemptOperation(() => Directory.Move(newStorage.GetFullPath("flags"), newStorage.GetFullPath("Flags"))); - if (newStorage.ExistsDirectory("mods")) - AttemptOperation(() => Directory.Move(newStorage.GetFullPath("mods"), newStorage.GetFullPath("Mods"))); - if (newStorage.ExistsDirectory("videos")) - AttemptOperation(() => Directory.Move(newStorage.GetFullPath("videos"), newStorage.GetFullPath("Videos"))); - - base.ChangeTargetStorage(newStorage); - } - public IEnumerable ListTournaments() => AllTournaments.GetDirectories(string.Empty); - - public override bool Migrate(Storage newStorage) - { - // this migration only happens once on moving to the per-tournament storage system. - // listed files are those known at that point in time. - // this can be removed at some point in the future (6 months obsoletion would mean 2021-04-19) - - var source = new DirectoryInfo(storage.GetFullPath("tournament")); - var destination = new DirectoryInfo(newStorage.GetFullPath(".")); - - if (source.Exists) - { - Logger.Log("Migrating tournament assets to default tournament storage."); - CopyRecursive(source, destination); - DeleteRecursive(source); - } - - moveFileIfExists(TournamentGameBase.BRACKET_FILENAME, destination); - moveFileIfExists("drawings.txt", destination); - moveFileIfExists("drawings_results.txt", destination); - moveFileIfExists("drawings.ini", destination); - - ChangeTargetStorage(newStorage); - storageConfig.SetValue(StorageConfig.CurrentTournament, default_tournament); - storageConfig.Save(); - - return true; - } - - private void moveFileIfExists(string file, DirectoryInfo destination) - { - if (!storage.Exists(file)) - return; - - Logger.Log($"Migrating {file} to default tournament storage."); - var fileInfo = new System.IO.FileInfo(storage.GetFullPath(file)); - AttemptOperation(() => fileInfo.CopyTo(Path.Combine(destination.FullName, fileInfo.Name), true)); - fileInfo.Delete(); - } } } From 707b9eaa502368e085702387f90943780879db4e Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 28 Oct 2022 13:07:44 +0900 Subject: [PATCH 0277/2991] Remove unnecessary null-forgiving --- .../Difficulty/Evaluators/ColourEvaluator.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs index 36f8babc6b..9f63e84867 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs @@ -55,11 +55,11 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators double difficulty = 0.0d; if (colour.MonoStreak?.FirstHitObject == hitObject) // Difficulty for MonoStreak - difficulty += EvaluateDifficultyOf(colour.MonoStreak!); + difficulty += EvaluateDifficultyOf(colour.MonoStreak); if (colour.AlternatingMonoPattern?.FirstHitObject == hitObject) // Difficulty for AlternatingMonoPattern - difficulty += EvaluateDifficultyOf(colour.AlternatingMonoPattern!); + difficulty += EvaluateDifficultyOf(colour.AlternatingMonoPattern); if (colour.RepeatingHitPattern?.FirstHitObject == hitObject) // Difficulty for RepeatingHitPattern - difficulty += EvaluateDifficultyOf(colour.RepeatingHitPattern!); + difficulty += EvaluateDifficultyOf(colour.RepeatingHitPattern); return difficulty; } From 08832ae593b558c764af7bbfc5de636a965b1e34 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 13:09:28 +0900 Subject: [PATCH 0278/2991] Remove obsoleted `PositionalHitsounds` global setting --- osu.Game/Configuration/OsuConfigManager.cs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 825c345c0a..80034744de 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -118,7 +118,6 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.Prefer24HourTime, CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern.Contains(@"tt")); // Gameplay - SetDefault(OsuSetting.PositionalHitsounds, true); // replaced by level setting below, can be removed 20220703. SetDefault(OsuSetting.PositionalHitsoundsLevel, 0.2f, 0, 1); SetDefault(OsuSetting.DimLevel, 0.7, 0, 1, 0.01); SetDefault(OsuSetting.BlurLevel, 0, 0, 1, 0.01); @@ -202,14 +201,11 @@ namespace osu.Game.Configuration if (!int.TryParse(pieces[0], out int year)) return; if (!int.TryParse(pieces[1], out int monthDay)) return; + // ReSharper disable once UnusedVariable int combined = (year * 10000) + monthDay; - if (combined < 20220103) - { - var positionalHitsoundsEnabled = GetBindable(OsuSetting.PositionalHitsounds); - if (!positionalHitsoundsEnabled.Value) - SetValue(OsuSetting.PositionalHitsoundsLevel, 0); - } + // migrations can be added here using a condition like: + // if (combined < 20220103) { performMigration() } } public override TrackedSettings CreateTrackedSettings() @@ -295,7 +291,6 @@ namespace osu.Game.Configuration ShowStoryboard, KeyOverlay, GameplayLeaderboard, - PositionalHitsounds, PositionalHitsoundsLevel, AlwaysPlayFirstComboBreak, FloatingComments, From 21f8a91efbd0bcd065e430314f065ab5e21ea16c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 13:12:18 +0900 Subject: [PATCH 0279/2991] Remove obsoleted `int` parsing logic of configuration ruleset --- osu.Game/OsuGame.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 2bdcb57f2a..0a5dd02cbd 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -280,10 +280,7 @@ namespace osu.Game configRuleset = LocalConfig.GetBindable(OsuSetting.Ruleset); uiScale = LocalConfig.GetBindable(OsuSetting.UIScale); - var preferredRuleset = int.TryParse(configRuleset.Value, out int rulesetId) - // int parsing can be removed 20220522 - ? RulesetStore.GetRuleset(rulesetId) - : RulesetStore.GetRuleset(configRuleset.Value); + var preferredRuleset = RulesetStore.GetRuleset(configRuleset.Value); try { From 42eafe318c132813b1abfbeac8126704fdd2d4fd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 13:07:47 +0900 Subject: [PATCH 0280/2991] Remove various simple obsoletions --- osu.Game/Beatmaps/BeatmapInfo.cs | 8 --- osu.Game/Beatmaps/Formats/IHasComboColours.cs | 7 --- osu.Game/Beatmaps/Timing/TimeSignatures.cs | 20 -------- osu.Game/Configuration/DatabasedSetting.cs | 51 ------------------- osu.Game/Database/RealmAccess.cs | 12 +---- .../Mods/IApplicableToDrawableHitObjects.cs | 18 ------- osu.Game/Rulesets/Mods/ICreateReplay.cs | 22 -------- osu.Game/Rulesets/Mods/Mod.cs | 3 -- osu.Game/Rulesets/Mods/ModAutoplay.cs | 13 +---- .../Objects/Drawables/DrawableHitObject.cs | 12 ----- .../Ranking/Statistics/StatisticItem.cs | 6 --- osu.Game/Skinning/SkinConfiguration.cs | 2 - osu.Game/Skinning/SkinImporter.cs | 49 ------------------ 13 files changed, 2 insertions(+), 221 deletions(-) delete mode 100644 osu.Game/Beatmaps/Timing/TimeSignatures.cs delete mode 100644 osu.Game/Configuration/DatabasedSetting.cs delete mode 100644 osu.Game/Rulesets/Mods/IApplicableToDrawableHitObjects.cs delete mode 100644 osu.Game/Rulesets/Mods/ICreateReplay.cs diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 6f9df1ba7f..3208598f56 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -238,14 +238,6 @@ namespace osu.Game.Beatmaps #region Compatibility properties - [Ignored] - [Obsolete("Use BeatmapInfo.Difficulty instead.")] // can be removed 20220719 - public BeatmapDifficulty BaseDifficulty - { - get => Difficulty; - set => Difficulty = value; - } - [Ignored] public string? Path => File?.Filename; diff --git a/osu.Game/Beatmaps/Formats/IHasComboColours.cs b/osu.Game/Beatmaps/Formats/IHasComboColours.cs index d5e96da246..1d9cc0be65 100644 --- a/osu.Game/Beatmaps/Formats/IHasComboColours.cs +++ b/osu.Game/Beatmaps/Formats/IHasComboColours.cs @@ -3,7 +3,6 @@ #nullable disable -using System; using System.Collections.Generic; using osuTK.Graphics; @@ -22,11 +21,5 @@ namespace osu.Game.Beatmaps.Formats /// if empty, will fall back to default combo colours. /// List CustomComboColours { get; } - - /// - /// Adds combo colours to the list. - /// - [Obsolete("Use CustomComboColours directly.")] // can be removed 20220215 - void AddComboColours(params Color4[] colours); } } diff --git a/osu.Game/Beatmaps/Timing/TimeSignatures.cs b/osu.Game/Beatmaps/Timing/TimeSignatures.cs deleted file mode 100644 index 95c971eebf..0000000000 --- a/osu.Game/Beatmaps/Timing/TimeSignatures.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -#nullable disable - -using System; -using System.ComponentModel; - -namespace osu.Game.Beatmaps.Timing -{ - [Obsolete("Use osu.Game.Beatmaps.Timing.TimeSignature instead.")] - public enum TimeSignatures // can be removed 20220722 - { - [Description("4/4")] - SimpleQuadruple = 4, - - [Description("3/4")] - SimpleTriple = 3 - } -} diff --git a/osu.Game/Configuration/DatabasedSetting.cs b/osu.Game/Configuration/DatabasedSetting.cs deleted file mode 100644 index 0c1b4021a1..0000000000 --- a/osu.Game/Configuration/DatabasedSetting.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -#nullable disable - -using System.ComponentModel.DataAnnotations.Schema; -using osu.Game.Database; - -namespace osu.Game.Configuration -{ - [Table("Settings")] - public class DatabasedSetting : IHasPrimaryKey // can be removed 20220315. - { - public int ID { get; set; } - - public bool IsManaged => ID > 0; - - public int? RulesetID { get; set; } - - public int? Variant { get; set; } - - public int? SkinInfoID { get; set; } - - [Column("Key")] - public string Key { get; set; } - - [Column("Value")] - public string StringValue - { - get => Value.ToString(); - set => Value = value; - } - - public object Value; - - public DatabasedSetting(string key, object value) - { - Key = key; - Value = value; - } - - /// - /// Constructor for derived classes that may require serialisation. - /// - public DatabasedSetting() - { - } - - public override string ToString() => $"{Key}=>{Value}"; - } -} diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs index edcd020226..1a938c12e5 100644 --- a/osu.Game/Database/RealmAccess.cs +++ b/osu.Game/Database/RealmAccess.cs @@ -857,17 +857,7 @@ namespace osu.Game.Database if (legacyCollectionImporter.GetAvailableCount(storage).GetResultSafely() > 0) { - legacyCollectionImporter.ImportFromStorage(storage).ContinueWith(task => - { - if (task.Exception != null) - { - // can be removed 20221027 (just for initial safety). - Logger.Error(task.Exception.InnerException, "Collections could not be migrated to realm. Please provide your \"collection.db\" to the dev team."); - return; - } - - storage.Move("collection.db", "collection.db.migrated"); - }); + legacyCollectionImporter.ImportFromStorage(storage).ContinueWith(_ => storage.Move("collection.db", "collection.db.migrated")); } break; diff --git a/osu.Game/Rulesets/Mods/IApplicableToDrawableHitObjects.cs b/osu.Game/Rulesets/Mods/IApplicableToDrawableHitObjects.cs deleted file mode 100644 index 7f926dd8b8..0000000000 --- a/osu.Game/Rulesets/Mods/IApplicableToDrawableHitObjects.cs +++ /dev/null @@ -1,18 +0,0 @@ -// 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 osu.Framework.Extensions.IEnumerableExtensions; -using osu.Game.Rulesets.Objects.Drawables; - -namespace osu.Game.Rulesets.Mods -{ - [Obsolete(@"Use the singular version IApplicableToDrawableHitObject instead.")] // Can be removed 20211216 - public interface IApplicableToDrawableHitObjects : IApplicableToDrawableHitObject - { - void ApplyToDrawableHitObjects(IEnumerable drawables); - - void IApplicableToDrawableHitObject.ApplyToDrawableHitObject(DrawableHitObject drawable) => ApplyToDrawableHitObjects(drawable.Yield()); - } -} diff --git a/osu.Game/Rulesets/Mods/ICreateReplay.cs b/osu.Game/Rulesets/Mods/ICreateReplay.cs deleted file mode 100644 index 1e5eeca92c..0000000000 --- a/osu.Game/Rulesets/Mods/ICreateReplay.cs +++ /dev/null @@ -1,22 +0,0 @@ -// 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 osu.Game.Beatmaps; -using osu.Game.Scoring; - -namespace osu.Game.Rulesets.Mods -{ - [Obsolete("Use ICreateReplayData instead")] // Can be removed 20220929 - public interface ICreateReplay : ICreateReplayData - { - public Score CreateReplayScore(IBeatmap beatmap, IReadOnlyList mods); - - ModReplayData ICreateReplayData.CreateReplayData(IBeatmap beatmap, IReadOnlyList mods) - { - var replayScore = CreateReplayScore(beatmap, mods); - return new ModReplayData(replayScore.Replay, new ModCreatedUser { Username = replayScore.ScoreInfo.User.Username }); - } - } -} diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index e4c91d3037..98df540de4 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -101,9 +101,6 @@ namespace osu.Game.Rulesets.Mods [JsonIgnore] public virtual bool ValidForMultiplayerAsFreeMod => true; - [Obsolete("Going forward, the concept of \"ranked\" doesn't exist. The only exceptions are automation mods, which should now override and set UserPlayable to false.")] // Can be removed 20211009 - public virtual bool Ranked => false; - /// /// Whether this mod requires configuration to apply changes to the game. /// diff --git a/osu.Game/Rulesets/Mods/ModAutoplay.cs b/osu.Game/Rulesets/Mods/ModAutoplay.cs index 6cafe0716d..83afda3a28 100644 --- a/osu.Game/Rulesets/Mods/ModAutoplay.cs +++ b/osu.Game/Rulesets/Mods/ModAutoplay.cs @@ -8,7 +8,6 @@ using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Replays; -using osu.Game.Scoring; namespace osu.Game.Rulesets.Mods { @@ -33,16 +32,6 @@ namespace osu.Game.Rulesets.Mods public override bool HasImplementation => GetType().GenericTypeArguments.Length == 0; - [Obsolete("Override CreateReplayData(IBeatmap, IReadOnlyList) instead")] // Can be removed 20220929 - public virtual Score CreateReplayScore(IBeatmap beatmap, IReadOnlyList mods) => new Score { Replay = new Replay() }; - - public virtual ModReplayData CreateReplayData(IBeatmap beatmap, IReadOnlyList mods) - { -#pragma warning disable CS0618 - var replayScore = CreateReplayScore(beatmap, mods); -#pragma warning restore CS0618 - - return new ModReplayData(replayScore.Replay, new ModCreatedUser { Username = replayScore.ScoreInfo.User.Username }); - } + public virtual ModReplayData CreateReplayData(IBeatmap beatmap, IReadOnlyList mods) => new ModReplayData(new Replay(), new ModCreatedUser { Username = @"autoplay" }); } } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index dec68a6c22..d624164013 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -196,18 +196,6 @@ namespace osu.Game.Rulesets.Objects.Drawables updateState(State.Value, true); } - /// - /// Applies a hit object to be represented by this . - /// - [Obsolete("Use either overload of Apply that takes a single argument of type HitObject or HitObjectLifetimeEntry")] // Can be removed 20211021. - public void Apply([NotNull] HitObject hitObject, [CanBeNull] HitObjectLifetimeEntry lifetimeEntry) - { - if (lifetimeEntry != null) - Apply(lifetimeEntry); - else - Apply(hitObject); - } - /// /// Applies a new to be represented by this . /// A new is automatically created and applied to this . diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticItem.cs b/osu.Game/Screens/Ranking/Statistics/StatisticItem.cs index e3ac054d1b..5bbd260d3f 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticItem.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticItem.cs @@ -36,12 +36,6 @@ namespace osu.Game.Screens.Ranking.Statistics /// public readonly bool RequiresHitEvents; - [Obsolete("Use constructor which takes creation function instead.")] // Can be removed 20220803. - public StatisticItem([NotNull] string name, [NotNull] Drawable content, [CanBeNull] Dimension dimension = null) - : this(name, () => content, true, dimension) - { - } - /// /// Creates a new , to be displayed inside a in the results screen. /// diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index 4e5d96ccb8..a9f660312e 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -66,8 +66,6 @@ namespace osu.Game.Skinning } } - void IHasComboColours.AddComboColours(params Color4[] colours) => CustomComboColours.AddRange(colours); - public Dictionary CustomColours { get; } = new Dictionary(); public readonly Dictionary ConfigDictionary = new Dictionary(); diff --git a/osu.Game/Skinning/SkinImporter.cs b/osu.Game/Skinning/SkinImporter.cs index 701dcdfc2d..f594a7b2d2 100644 --- a/osu.Game/Skinning/SkinImporter.cs +++ b/osu.Game/Skinning/SkinImporter.cs @@ -4,11 +4,9 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text; using System.Threading; using Newtonsoft.Json; -using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Database; @@ -33,9 +31,6 @@ namespace osu.Game.Skinning this.skinResources = skinResources; modelManager = new ModelManager(storage, realm); - - // can be removed 20220420. - populateMissingHashes(); } public override IEnumerable HandledExtensions => new[] { ".osk" }; @@ -158,18 +153,6 @@ namespace osu.Game.Skinning } modelManager.ReplaceFile(existingFile, stream, realm); - - // can be removed 20220502. - if (!ensureIniWasUpdated(item)) - { - Logger.Log($"Skin {item}'s skin.ini had issues and has been removed. Please report this and provide the problematic skin.", LoggingTarget.Database, LogLevel.Important); - - var existingIni = item.GetFile(@"skin.ini"); - if (existingIni != null) - item.Files.Remove(existingIni); - - writeNewSkinIni(); - } } } @@ -194,38 +177,6 @@ namespace osu.Game.Skinning } } - private bool ensureIniWasUpdated(SkinInfo item) - { - // This is a final consistency check to ensure that hash computation doesn't enter an infinite loop. - // With other changes to the surrounding code this should never be hit, but until we are 101% sure that there - // are no other cases let's avoid a hard startup crash by bailing and alerting. - - var instance = createInstance(item); - - return instance.Configuration.SkinInfo.Name == item.Name; - } - - private void populateMissingHashes() - { - Realm.Run(realm => - { - var skinsWithoutHashes = realm.All().Where(i => !i.Protected && string.IsNullOrEmpty(i.Hash)).ToArray(); - - foreach (SkinInfo skin in skinsWithoutHashes) - { - try - { - realm.Write(_ => skin.Hash = ComputeHash(skin)); - } - catch (Exception e) - { - modelManager.Delete(skin); - Logger.Error(e, $"Existing skin {skin} has been deleted during hash recomputation due to being invalid"); - } - } - }); - } - private Skin createInstance(SkinInfo item) => item.CreateInstance(skinResources); public void Save(Skin skin) From f9d2c30c3eb65fdf4074ac862f837ea94e639898 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 13:52:45 +0900 Subject: [PATCH 0281/2991] Add user toggle for application of safe areas --- .../TestSceneSafeAreaHandling.cs | 11 ++++++++++ osu.Game/Configuration/OsuConfigManager.cs | 4 +++- .../Graphics/Containers/ScalingContainer.cs | 11 ++++++++-- osu.Game/OsuGame.cs | 5 +++++ osu.Game/OsuGameBase.cs | 4 +++- .../Sections/Graphics/LayoutSettings.cs | 20 +++++++++++++++---- 6 files changed, 47 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSafeAreaHandling.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSafeAreaHandling.cs index 2ba0fa36c3..90365ec939 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSafeAreaHandling.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSafeAreaHandling.cs @@ -8,6 +8,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Configuration; using osu.Game.Overlays.Settings; using osuTK.Graphics; @@ -24,6 +25,8 @@ namespace osu.Game.Tests.Visual.UserInterface private readonly Bindable safeAreaPaddingLeft = new BindableFloat { MinValue = 0, MaxValue = 200 }; private readonly Bindable safeAreaPaddingRight = new BindableFloat { MinValue = 0, MaxValue = 200 }; + private readonly Bindable applySafeAreaConsiderations = new Bindable(true); + protected override void LoadComplete() { base.LoadComplete(); @@ -84,6 +87,11 @@ namespace osu.Game.Tests.Visual.UserInterface Current = safeAreaPaddingRight, LabelText = "Right" }, + new SettingsCheckbox + { + LabelText = "Apply", + Current = applySafeAreaConsiderations, + }, } } } @@ -93,6 +101,7 @@ namespace osu.Game.Tests.Visual.UserInterface safeAreaPaddingBottom.BindValueChanged(_ => updateSafeArea()); safeAreaPaddingLeft.BindValueChanged(_ => updateSafeArea()); safeAreaPaddingRight.BindValueChanged(_ => updateSafeArea()); + applySafeAreaConsiderations.BindValueChanged(_ => updateSafeArea()); }); base.SetUpSteps(); @@ -107,6 +116,8 @@ namespace osu.Game.Tests.Visual.UserInterface Left = safeAreaPaddingLeft.Value, Right = safeAreaPaddingRight.Value, }; + + Game.LocalConfig.SetValue(OsuSetting.SafeAreaConsiderations, applySafeAreaConsiderations.Value); } [Test] diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 1378e1691a..e449837c92 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -154,6 +154,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.SongSelectRightMouseScroll, false); SetDefault(OsuSetting.Scaling, ScalingMode.Off); + SetDefault(OsuSetting.SafeAreaConsiderations, true); SetDefault(OsuSetting.ScalingSizeX, 0.8f, 0.2f, 1f); SetDefault(OsuSetting.ScalingSizeY, 0.8f, 0.2f, 1f); @@ -370,6 +371,7 @@ namespace osu.Game.Configuration DiscordRichPresence, AutomaticallyDownloadWhenSpectating, ShowOnlineExplicitContent, - LastProcessedMetadataId + LastProcessedMetadataId, + SafeAreaConsiderations, } } diff --git a/osu.Game/Graphics/Containers/ScalingContainer.cs b/osu.Game/Graphics/Containers/ScalingContainer.cs index 17c51129a7..11e57d4be3 100644 --- a/osu.Game/Graphics/Containers/ScalingContainer.cs +++ b/osu.Game/Graphics/Containers/ScalingContainer.cs @@ -29,6 +29,7 @@ namespace osu.Game.Graphics.Containers private Bindable sizeY; private Bindable posX; private Bindable posY; + private Bindable applySafeAreaPadding; private Bindable safeAreaPadding; @@ -132,6 +133,9 @@ namespace osu.Game.Graphics.Containers posY = config.GetBindable(OsuSetting.ScalingPositionY); posY.ValueChanged += _ => Scheduler.AddOnce(updateSize); + applySafeAreaPadding = config.GetBindable(OsuSetting.SafeAreaConsiderations); + applySafeAreaPadding.BindValueChanged(_ => Scheduler.AddOnce(updateSize)); + safeAreaPadding = safeArea.SafeAreaPadding.GetBoundCopy(); safeAreaPadding.BindValueChanged(_ => Scheduler.AddOnce(updateSize)); } @@ -192,7 +196,7 @@ namespace osu.Game.Graphics.Containers bool requiresMasking = targetRect.Size != Vector2.One // For the top level scaling container, for now we apply masking if safe areas are in use. // In the future this can likely be removed as more of the actual UI supports overflowing into the safe areas. - || (targetMode == ScalingMode.Everything && safeAreaPadding.Value.Total != Vector2.Zero); + || (targetMode == ScalingMode.Everything && (applySafeAreaPadding.Value && safeAreaPadding.Value.Total != Vector2.Zero)); if (requiresMasking) sizableContainer.Masking = true; @@ -225,6 +229,9 @@ namespace osu.Game.Graphics.Containers [Resolved] private ISafeArea safeArea { get; set; } + [Resolved] + private OsuConfigManager config { get; set; } + private readonly bool confineHostCursor; private readonly LayoutValue cursorRectCache = new LayoutValue(Invalidation.RequiredParentSizeToFit); @@ -259,7 +266,7 @@ namespace osu.Game.Graphics.Containers { if (host.Window == null) return; - bool coversWholeScreen = Size == Vector2.One && safeArea.SafeAreaPadding.Value.Total == Vector2.Zero; + bool coversWholeScreen = Size == Vector2.One && (!config.Get(OsuSetting.SafeAreaConsiderations) || safeArea.SafeAreaPadding.Value.Total == Vector2.Zero); host.Window.CursorConfineRect = coversWholeScreen ? null : ToScreenSpace(DrawRectangle).AABBFloat; } } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 2bdcb57f2a..b3009fb85f 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -179,6 +179,8 @@ namespace osu.Game private Bindable configRuleset; + private Bindable applySafeAreaConsiderations; + private Bindable uiScale; private Bindable configSkin; @@ -312,6 +314,9 @@ namespace osu.Game SelectedMods.BindValueChanged(modsChanged); Beatmap.BindValueChanged(beatmapChanged, true); + + applySafeAreaConsiderations = LocalConfig.GetBindable(OsuSetting.SafeAreaConsiderations); + applySafeAreaConsiderations.BindValueChanged(apply => SafeAreaContainer.SafeAreaOverrideEdges = apply.NewValue ? SafeAreaOverrideEdges : Edges.All); } private ExternalLinkOpener externalLinkOpener; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 7d9ed7bf3e..4c31158597 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -189,6 +189,8 @@ namespace osu.Game private RealmAccess realm; + protected SafeAreaContainer SafeAreaContainer { get; private set; } + /// /// For now, this is used as a source specifically for beat synced components. /// Going forward, it could potentially be used as the single source-of-truth for beatmap timing. @@ -341,7 +343,7 @@ namespace osu.Game GlobalActionContainer globalBindings; - base.Content.Add(new SafeAreaContainer + base.Content.Add(SafeAreaContainer = new SafeAreaContainer { SafeAreaOverrideEdges = SafeAreaOverrideEdges, RelativeSizeAxes = Axes.Both, diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 59b56522a4..f77e1bfc6a 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -20,6 +20,7 @@ using osu.Game.Configuration; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Localisation; +using osuTK; using osuTK.Graphics; namespace osu.Game.Overlays.Settings.Sections.Graphics @@ -50,6 +51,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics private SettingsDropdown resolutionDropdown = null!; private SettingsDropdown displayDropdown = null!; private SettingsDropdown windowModeDropdown = null!; + private SettingsCheckbox safeAreaConsiderationsCheckbox = null!; private Bindable scalingPositionX = null!; private Bindable scalingPositionY = null!; @@ -101,6 +103,11 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics ItemSource = resolutions, Current = sizeFullscreen }, + safeAreaConsiderationsCheckbox = new SettingsCheckbox + { + LabelText = "Shrink game to avoid cameras and notches", + Current = osuConfig.GetBindable(OsuSetting.SafeAreaConsiderations), + }, new SettingsSlider { LabelText = GraphicsSettingsStrings.UIScaling, @@ -166,7 +173,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics windowModeDropdown.Current.BindValueChanged(_ => { - updateDisplayModeDropdowns(); + updateDisplaySettingsVisibility(); updateScreenModeWarning(); }, true); @@ -191,7 +198,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics .Distinct()); } - updateDisplayModeDropdowns(); + updateDisplaySettingsVisibility(); }), true); scalingMode.BindValueChanged(_ => @@ -221,11 +228,11 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics Scheduler.AddOnce(d => { displayDropdown.Items = d; - updateDisplayModeDropdowns(); + updateDisplaySettingsVisibility(); }, displays); } - private void updateDisplayModeDropdowns() + private void updateDisplaySettingsVisibility() { if (resolutions.Count > 1 && windowModeDropdown.Current.Value == WindowMode.Fullscreen) resolutionDropdown.Show(); @@ -236,6 +243,11 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics displayDropdown.Show(); else displayDropdown.Hide(); + + if (host.Window.SafeAreaPadding.Value.Total != Vector2.Zero) + safeAreaConsiderationsCheckbox.Show(); + else + safeAreaConsiderationsCheckbox.Hide(); } private void updateScreenModeWarning() From 10c658e4408d565fca826f8ad7afe29bc6435f3f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 14:34:24 +0900 Subject: [PATCH 0282/2991] Ensure `updateVisualDefinition` is called once on load MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index b5b04823a7..6fd1546d30 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders if (editorBeatmap != null) selectedObjects.BindTo(editorBeatmap.SelectedHitObjects); - selectedObjects.BindCollectionChanged((_, _) => updateVisualDefinition()); + selectedObjects.BindCollectionChanged((_, _) => updateVisualDefinition(), true); } public override bool HandleQuickDeletion() From 300ffbb500e0b51ef3eebd363ea25904da109f74 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 14:35:55 +0900 Subject: [PATCH 0283/2991] Don't bother checking for null `editorBeatmap` --- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 6fd1546d30..36ee7c2460 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders return true; } - private bool hasSingleObjectSelected => editorBeatmap == null || selectedObjects.Count == 1; + private bool hasSingleObjectSelected => selectedObjects.Count == 1; protected override void Update() { From b3219526a57e415e870082ff176a03e65610cf27 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 28 Oct 2022 14:42:42 +0900 Subject: [PATCH 0284/2991] Populate beatmap ruleset in SoloScoreInfo.ToScoreInfo() --- .../API/Requests/Responses/SoloScoreInfo.cs | 62 ++++++++++++------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs b/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs index 57586e3d77..77dcfd39e3 100644 --- a/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs +++ b/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs @@ -154,10 +154,8 @@ namespace osu.Game.Online.API.Requests.Responses var mods = Mods.Select(apiMod => apiMod.ToMod(rulesetInstance)).ToArray(); - var scoreInfo = ToScoreInfo(mods); - + var scoreInfo = ToScoreInfo(mods, beatmap); scoreInfo.Ruleset = ruleset; - if (beatmap != null) scoreInfo.BeatmapInfo = beatmap; return scoreInfo; } @@ -166,25 +164,47 @@ namespace osu.Game.Online.API.Requests.Responses /// Create a from an API score instance. /// /// The mod instances, resolved from a ruleset. - /// - public ScoreInfo ToScoreInfo(Mod[] mods) => new ScoreInfo + /// The object to populate the scores' beatmap with. + /// + /// If this is a type, then the score will be fully populated with the given object. + /// Otherwise, if this is an type (e.g. ), then only the beatmap ruleset will be populated. + /// Otherwise, if this is null, then the beatmap ruleset will not be populated. + /// The online beatmap ID is populated in all cases. + /// + /// + /// The populated . + public ScoreInfo ToScoreInfo(Mod[] mods, IBeatmapInfo? beatmap = null) { - OnlineID = OnlineID, - User = User ?? new APIUser { Id = UserID }, - BeatmapInfo = new BeatmapInfo { OnlineID = BeatmapID }, - Ruleset = new RulesetInfo { OnlineID = RulesetID }, - Passed = Passed, - TotalScore = TotalScore, - Accuracy = Accuracy, - MaxCombo = MaxCombo, - Rank = Rank, - Statistics = Statistics, - MaximumStatistics = MaximumStatistics, - Date = EndedAt, - Hash = HasReplay ? "online" : string.Empty, // TODO: temporary? - Mods = mods, - PP = PP, - }; + var score = new ScoreInfo + { + OnlineID = OnlineID, + User = User ?? new APIUser { Id = UserID }, + BeatmapInfo = new BeatmapInfo { OnlineID = BeatmapID }, + Ruleset = new RulesetInfo { OnlineID = RulesetID }, + Passed = Passed, + TotalScore = TotalScore, + Accuracy = Accuracy, + MaxCombo = MaxCombo, + Rank = Rank, + Statistics = Statistics, + MaximumStatistics = MaximumStatistics, + Date = EndedAt, + Hash = HasReplay ? "online" : string.Empty, // TODO: temporary? + Mods = mods, + PP = PP, + }; + + if (beatmap is BeatmapInfo realmBeatmap) + score.BeatmapInfo = realmBeatmap; + else if (beatmap != null) + { + score.BeatmapInfo.Ruleset.OnlineID = beatmap.Ruleset.OnlineID; + score.BeatmapInfo.Ruleset.Name = beatmap.Ruleset.Name; + score.BeatmapInfo.Ruleset.ShortName = beatmap.Ruleset.ShortName; + } + + return score; + } /// /// Creates a from a local score for score submission. From c1e9398c19d3e74850c9f7fe546d8fefdabefa2f Mon Sep 17 00:00:00 2001 From: nullium21 Date: Fri, 28 Oct 2022 09:19:34 +0300 Subject: [PATCH 0285/2991] Fix regex by allowing file extensions + typed new Apparently, the _whole_ filename was checked with GetValidArchiveContentFilename, not just the stem. --- osu.Game/Extensions/ModelExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Extensions/ModelExtensions.cs b/osu.Game/Extensions/ModelExtensions.cs index 8acc079805..73a87c7003 100644 --- a/osu.Game/Extensions/ModelExtensions.cs +++ b/osu.Game/Extensions/ModelExtensions.cs @@ -137,7 +137,7 @@ namespace osu.Game.Extensions return instance.OnlineID.Equals(other.OnlineID); } - private static Regex invalid_filename_chars = new(@"(?!$)[^A-Za-z0-9_()[\] -]", RegexOptions.Compiled); + private static Regex invalid_filename_chars = new Regex(@"(?!$)[^A-Za-z0-9_()[\]. -]", RegexOptions.Compiled); /// /// Get a valid filename for use inside a zip file. Avoids backslashes being incorrectly converted to directories. From 6901ed997d353628005b524ad553d7eed9c83cde Mon Sep 17 00:00:00 2001 From: nullium21 Date: Fri, 28 Oct 2022 09:21:47 +0300 Subject: [PATCH 0286/2991] One more little change Damn, i forgor. Sorry, CI runners. --- osu.Game/Extensions/ModelExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Extensions/ModelExtensions.cs b/osu.Game/Extensions/ModelExtensions.cs index 73a87c7003..f8db5f4e88 100644 --- a/osu.Game/Extensions/ModelExtensions.cs +++ b/osu.Game/Extensions/ModelExtensions.cs @@ -137,7 +137,7 @@ namespace osu.Game.Extensions return instance.OnlineID.Equals(other.OnlineID); } - private static Regex invalid_filename_chars = new Regex(@"(?!$)[^A-Za-z0-9_()[\]. -]", RegexOptions.Compiled); + private static readonly Regex invalid_filename_chars = new Regex(@"(?!$)[^A-Za-z0-9_()[\]. \-]", RegexOptions.Compiled); /// /// Get a valid filename for use inside a zip file. Avoids backslashes being incorrectly converted to directories. From 87328dd1f535ec4f5c799b73ac8207ed439b1596 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Thu, 27 Oct 2022 23:36:30 -0700 Subject: [PATCH 0287/2991] Fix bar hit error meter labels not clearing when setting to none --- osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index d6b9c62369..e7b2ce1672 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -279,6 +279,8 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters switch (style) { case LabelStyles.None: + labelEarly.Clear(); + labelLate.Clear(); break; case LabelStyles.Icons: From 33bb1212d1e84c3d887380d27f6159ca95361ad5 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 28 Oct 2022 16:19:15 +0900 Subject: [PATCH 0288/2991] Add notifications websocket + chat implementation --- osu.Game/Online/Chat/Message.cs | 7 ++ .../Online/Notifications/EndChatRequest.cs | 16 +++ .../Notifications/NewChatMessageData.cs | 29 +++++ .../Notifications/NotificationsClient.cs | 113 ++++++++++++++++++ .../NotificationsClientConnector.cs | 65 ++++++++++ .../NotificationsClient_Processing.cs | 102 ++++++++++++++++ .../Online/Notifications/SocketMessage.cs | 21 ++++ .../Online/Notifications/StartChatRequest.cs | 16 +++ 8 files changed, 369 insertions(+) create mode 100644 osu.Game/Online/Notifications/EndChatRequest.cs create mode 100644 osu.Game/Online/Notifications/NewChatMessageData.cs create mode 100644 osu.Game/Online/Notifications/NotificationsClient.cs create mode 100644 osu.Game/Online/Notifications/NotificationsClientConnector.cs create mode 100644 osu.Game/Online/Notifications/NotificationsClient_Processing.cs create mode 100644 osu.Game/Online/Notifications/SocketMessage.cs create mode 100644 osu.Game/Online/Notifications/StartChatRequest.cs diff --git a/osu.Game/Online/Chat/Message.cs b/osu.Game/Online/Chat/Message.cs index 86562341eb..25c5b0853f 100644 --- a/osu.Game/Online/Chat/Message.cs +++ b/osu.Game/Online/Chat/Message.cs @@ -30,6 +30,13 @@ namespace osu.Game.Online.Chat [JsonProperty(@"sender")] public APIUser Sender; + [JsonProperty(@"sender_id")] + public int SenderId + { + get => Sender?.Id ?? 0; + set => Sender = new APIUser { Id = value }; + } + [JsonConstructor] public Message() { diff --git a/osu.Game/Online/Notifications/EndChatRequest.cs b/osu.Game/Online/Notifications/EndChatRequest.cs new file mode 100644 index 0000000000..1173b1e8d0 --- /dev/null +++ b/osu.Game/Online/Notifications/EndChatRequest.cs @@ -0,0 +1,16 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Newtonsoft.Json; + +namespace osu.Game.Online.Notifications +{ + [JsonObject(MemberSerialization.OptIn)] + public class EndChatRequest : SocketMessage + { + public EndChatRequest() + { + Event = "chat.end"; + } + } +} diff --git a/osu.Game/Online/Notifications/NewChatMessageData.cs b/osu.Game/Online/Notifications/NewChatMessageData.cs new file mode 100644 index 0000000000..b388afa743 --- /dev/null +++ b/osu.Game/Online/Notifications/NewChatMessageData.cs @@ -0,0 +1,29 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Chat; + +namespace osu.Game.Online.Notifications +{ + [JsonObject(MemberSerialization.OptIn)] + public class NewChatMessageData + { + [JsonProperty("messages")] + public List Messages { get; set; } = null!; + + [JsonProperty("users")] + private List users { get; set; } = null!; + + [OnDeserialized] + private void onDeserialised(StreamingContext context) + { + foreach (var m in Messages) + m.Sender = users.Single(u => u.OnlineID == m.SenderId); + } + } +} diff --git a/osu.Game/Online/Notifications/NotificationsClient.cs b/osu.Game/Online/Notifications/NotificationsClient.cs new file mode 100644 index 0000000000..63260e5df9 --- /dev/null +++ b/osu.Game/Online/Notifications/NotificationsClient.cs @@ -0,0 +1,113 @@ +// 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.Diagnostics; +using System.Net.WebSockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Newtonsoft.Json; +using osu.Framework.Extensions.TypeExtensions; +using osu.Framework.Logging; +using osu.Game.Online.API; + +namespace osu.Game.Online.Notifications +{ + public partial class NotificationsClient : SocketClient + { + private readonly ClientWebSocket socket; + private readonly string endpoint; + private readonly IAPIProvider api; + + public NotificationsClient(ClientWebSocket socket, string endpoint, IAPIProvider api) + { + this.socket = socket; + this.endpoint = endpoint; + this.api = api; + } + + public override async Task StartAsync(CancellationToken cancellationToken) + { + await socket.ConnectAsync(new Uri(endpoint), cancellationToken).ConfigureAwait(false); + await onConnectedAsync(); + runReadLoop(cancellationToken); + } + + private void runReadLoop(CancellationToken cancellationToken) => Task.Run((Func)(async () => + { + byte[] buffer = new byte[1024]; + StringBuilder messageResult = new StringBuilder(); + + while (!cancellationToken.IsCancellationRequested) + { + try + { + WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, cancellationToken); + + switch (result.MessageType) + { + case WebSocketMessageType.Text: + messageResult.Append(Encoding.UTF8.GetString(buffer[..result.Count])); + + if (result.EndOfMessage) + { + SocketMessage? message = JsonConvert.DeserializeObject(messageResult.ToString()); + messageResult.Clear(); + + Debug.Assert(message != null); + + if (message.Error != null) + { + Logger.Log($"{GetType().ReadableName()} error: {message.Error}", LoggingTarget.Network); + break; + } + + await onMessageReceivedAsync(message); + } + + break; + + case WebSocketMessageType.Binary: + throw new NotImplementedException(); + + case WebSocketMessageType.Close: + throw new Exception("Connection closed by remote host."); + } + } + catch (Exception ex) + { + await InvokeClosed(ex); + return; + } + } + }), cancellationToken); + + private async Task closeAsync() + { + try + { + await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Disconnecting", CancellationToken.None).ConfigureAwait(false); + } + catch + { + // Closure can fail if the connection is aborted. Don't really care since it's disposed anyway. + } + } + + private async Task sendMessage(SocketMessage message, CancellationToken cancellationToken) + { + if (socket.State != WebSocketState.Open) + return; + + await socket.SendAsync(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message)), WebSocketMessageType.Text, true, cancellationToken); + } + + public override async ValueTask DisposeAsync() + { + await base.DisposeAsync(); + await closeAsync(); + socket.Dispose(); + } + } +} diff --git a/osu.Game/Online/Notifications/NotificationsClientConnector.cs b/osu.Game/Online/Notifications/NotificationsClientConnector.cs new file mode 100644 index 0000000000..18b2a1b19d --- /dev/null +++ b/osu.Game/Online/Notifications/NotificationsClientConnector.cs @@ -0,0 +1,65 @@ +// 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.Net; +using System.Net.WebSockets; +using System.Threading; +using System.Threading.Tasks; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.Chat; + +namespace osu.Game.Online.Notifications +{ + public class NotificationsClientConnector : SocketClientConnector + { + public event Action? ChannelJoined; + public event Action>? NewMessages; + public event Action? PresenceReceived; + + private readonly IAPIProvider api; + private bool chatStarted; + + public NotificationsClientConnector(IAPIProvider api) + : base(api) + { + this.api = api; + } + + public void StartChat() + { + chatStarted = true; + + if (CurrentConnection is NotificationsClient client) + client.EnableChat = true; + } + + protected override async Task BuildConnectionAsync(CancellationToken cancellationToken) + { + var tcs = new TaskCompletionSource(); + + var req = new GetNotificationsRequest(); + req.Success += bundle => tcs.SetResult(bundle.Endpoint); + req.Failure += ex => tcs.SetException(ex); + api.Queue(req); + + string endpoint = await tcs.Task; + + ClientWebSocket socket = new ClientWebSocket(); + socket.Options.SetRequestHeader("Authorization", $"Bearer {api.AccessToken}"); + socket.Options.Proxy = WebRequest.DefaultWebProxy; + if (socket.Options.Proxy != null) + socket.Options.Proxy.Credentials = CredentialCache.DefaultCredentials; + + return new NotificationsClient(socket, endpoint, api) + { + ChannelJoined = c => ChannelJoined?.Invoke(c), + NewMessages = m => NewMessages?.Invoke(m), + PresenceReceived = () => PresenceReceived?.Invoke(), + EnableChat = chatStarted + }; + } + } +} diff --git a/osu.Game/Online/Notifications/NotificationsClient_Processing.cs b/osu.Game/Online/Notifications/NotificationsClient_Processing.cs new file mode 100644 index 0000000000..4950a53f6f --- /dev/null +++ b/osu.Game/Online/Notifications/NotificationsClient_Processing.cs @@ -0,0 +1,102 @@ +// 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.Diagnostics; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Newtonsoft.Json; +using osu.Game.Online.API.Requests; +using osu.Game.Online.Chat; + +namespace osu.Game.Online.Notifications +{ + public partial class NotificationsClient + { + public Action? ChannelJoined; + public Action>? NewMessages; + public Action? PresenceReceived; + + private bool enableChat; + private long lastMessageId; + + public bool EnableChat + { + get => enableChat; + set + { + enableChat = value; + Task.Run(startChatIfEnabledAsync); + } + } + + private async Task onConnectedAsync() + { + await startChatIfEnabledAsync(); + } + + private async Task startChatIfEnabledAsync() + { + if (!EnableChat) + return; + + await sendMessage(new StartChatRequest(), CancellationToken.None); + + var fetchReq = new GetUpdatesRequest(lastMessageId); + + fetchReq.Success += updates => + { + if (updates?.Presence != null) + { + foreach (var channel in updates.Presence) + handleJoinedChannel(channel); + + //todo: handle left channels + + handleMessages(updates.Messages); + } + + PresenceReceived?.Invoke(); + }; + + api.Queue(fetchReq); + } + + private Task onMessageReceivedAsync(SocketMessage message) + { + switch (message.Event) + { + case "chat.message.new": + Debug.Assert(message.Data != null); + + NewChatMessageData? messageData = JsonConvert.DeserializeObject(message.Data.ToString()); + Debug.Assert(messageData != null); + + List messages = messageData.Messages.Where(m => m.Sender.OnlineID != api.LocalUser.Value.OnlineID).ToList(); + + foreach (var msg in messages) + handleJoinedChannel(new Channel(msg.Sender) { Id = msg.ChannelId }); + + handleMessages(messages); + break; + } + + return Task.CompletedTask; + } + + private void handleJoinedChannel(Channel channel) + { + // we received this from the server so should mark the channel already joined. + channel.Joined.Value = true; + ChannelJoined?.Invoke(channel); + } + + private void handleMessages(List messages) + { + NewMessages?.Invoke(messages); + lastMessageId = messages.LastOrDefault()?.Id ?? lastMessageId; + } + } +} diff --git a/osu.Game/Online/Notifications/SocketMessage.cs b/osu.Game/Online/Notifications/SocketMessage.cs new file mode 100644 index 0000000000..6b5f3435fc --- /dev/null +++ b/osu.Game/Online/Notifications/SocketMessage.cs @@ -0,0 +1,21 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace osu.Game.Online.Notifications +{ + [JsonObject(MemberSerialization.OptIn)] + public class SocketMessage + { + [JsonProperty("event")] + public string Event { get; set; } = null!; + + [JsonProperty("data")] + public JObject? Data { get; set; } + + [JsonProperty("error")] + public string? Error { get; set; } + } +} diff --git a/osu.Game/Online/Notifications/StartChatRequest.cs b/osu.Game/Online/Notifications/StartChatRequest.cs new file mode 100644 index 0000000000..274738886d --- /dev/null +++ b/osu.Game/Online/Notifications/StartChatRequest.cs @@ -0,0 +1,16 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Newtonsoft.Json; + +namespace osu.Game.Online.Notifications +{ + [JsonObject(MemberSerialization.OptIn)] + public class StartChatRequest : SocketMessage + { + public StartChatRequest() + { + Event = "chat.start"; + } + } +} From 2f731f86bad8d71790fe0d63e400a6601b5e6408 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 28 Oct 2022 16:22:35 +0900 Subject: [PATCH 0289/2991] Adjust ChannelManager to use notifications client --- .../Components/TournamentMatchChatDisplay.cs | 2 +- osu.Game/Online/Chat/ChannelManager.cs | 119 ++++++------------ osu.Game/OsuGame.cs | 17 +-- 3 files changed, 43 insertions(+), 95 deletions(-) diff --git a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs index 6a8e4aa951..ca2b400e8b 100644 --- a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs +++ b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs @@ -48,7 +48,7 @@ namespace osu.Game.Tournament.Components if (manager == null) { - AddInternal(manager = new ChannelManager(api) { HighPollRate = { Value = true } }); + AddInternal(manager = new ChannelManager(api)); Channel.BindTo(manager.CurrentChannel); } diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index ec84b0643d..b63f841f59 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -6,16 +6,17 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions; +using osu.Framework.Graphics.Containers; using osu.Framework.Logging; +using osu.Framework.Threading; using osu.Game.Database; -using osu.Game.Input; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Notifications; using osu.Game.Overlays.Chat.Listing; namespace osu.Game.Online.Chat @@ -23,7 +24,7 @@ namespace osu.Game.Online.Chat /// /// Manages everything channel related /// - public class ChannelManager : PollingComponent, IChannelPostTarget + public class ChannelManager : CompositeComponent, IChannelPostTarget { /// /// The channels the player joins on startup @@ -68,9 +69,12 @@ namespace osu.Game.Online.Chat [Resolved] private UserLookupCache users { get; set; } - public readonly BindableBool HighPollRate = new BindableBool(); + [Resolved] + private NotificationsClientConnector connector { get; set; } - private readonly IBindable isIdle = new BindableBool(); + private readonly IBindable apiState = new Bindable(); + private bool channelsInitialised; + private ScheduledDelegate ackDelegate; public ChannelManager(IAPIProvider api) { @@ -78,30 +82,34 @@ namespace osu.Game.Online.Chat CurrentChannel.ValueChanged += currentChannelChanged; } - [BackgroundDependencyLoader(permitNulls: true)] - private void load(IdleTracker idleTracker) + [BackgroundDependencyLoader] + private void load() { - HighPollRate.BindValueChanged(updatePollRate); - isIdle.BindValueChanged(updatePollRate, true); - - if (idleTracker != null) - isIdle.BindTo(idleTracker.IsIdle); - } - - private void updatePollRate(ValueChangedEvent valueChangedEvent) - { - // Polling will eventually be replaced with websocket, but let's avoid doing these background operations as much as possible for now. - // The only loss will be delayed PM/message highlight notifications. - int millisecondsBetweenPolls = HighPollRate.Value ? 1000 : 60000; - - if (isIdle.Value) - millisecondsBetweenPolls *= 10; - - if (TimeBetweenPolls.Value != millisecondsBetweenPolls) + connector.ChannelJoined += ch => joinChannel(ch); + connector.NewMessages += addMessages; + connector.PresenceReceived += () => { - TimeBetweenPolls.Value = millisecondsBetweenPolls; - Logger.Log($"Chat is now polling every {TimeBetweenPolls.Value} ms"); - } + if (!channelsInitialised) + { + channelsInitialised = true; + // we want this to run after the first presence so we can see if the user is in any channels already. + initializeChannels(); + } + }; + + connector.StartChat(); + + apiState.BindTo(api.State); + apiState.BindValueChanged(status => + { + ackDelegate?.Cancel(); + + if (status.NewValue == APIState.Online) + { + Scheduler.Add(ackDelegate = new ScheduledDelegate(() => api.Queue(new ChatAckRequest()), 0, 60000)); + // Todo: Handle silences. + } + }, true); } /// @@ -328,7 +336,7 @@ namespace osu.Game.Online.Chat } } - private void handleChannelMessages(IEnumerable messages) + private void addMessages(List messages) { var channels = JoinedChannels.ToList(); @@ -376,7 +384,7 @@ namespace osu.Game.Online.Chat var fetchInitialMsgReq = new GetMessagesRequest(channel); fetchInitialMsgReq.Success += messages => { - handleChannelMessages(messages); + addMessages(messages); channel.MessagesLoaded = true; // this will mark the channel as having received messages even if there were none. }; @@ -464,7 +472,7 @@ namespace osu.Game.Online.Chat { channel.Id = resChannel.ChannelID.Value; - handleChannelMessages(resChannel.RecentMessages); + addMessages(resChannel.RecentMessages); channel.MessagesLoaded = true; // this will mark the channel as having received messages even if there were none. } }; @@ -574,57 +582,6 @@ namespace osu.Game.Online.Chat } } - private long lastMessageId; - - private bool channelsInitialised; - - protected override Task Poll() - { - if (!api.IsLoggedIn) - return base.Poll(); - - var fetchReq = new GetUpdatesRequest(lastMessageId); - - var tcs = new TaskCompletionSource(); - - fetchReq.Success += updates => - { - if (updates?.Presence != null) - { - foreach (var channel in updates.Presence) - { - // we received this from the server so should mark the channel already joined. - channel.Joined.Value = true; - joinChannel(channel); - } - - //todo: handle left channels - - handleChannelMessages(updates.Messages); - - foreach (var group in updates.Messages.GroupBy(m => m.ChannelId)) - JoinedChannels.FirstOrDefault(c => c.Id == group.Key)?.AddNewMessages(group.ToArray()); - - lastMessageId = updates.Messages.LastOrDefault()?.Id ?? lastMessageId; - } - - if (!channelsInitialised) - { - channelsInitialised = true; - // we want this to run after the first presence so we can see if the user is in any channels already. - initializeChannels(); - } - - tcs.SetResult(true); - }; - - fetchReq.Failure += _ => tcs.SetResult(false); - - api.Queue(fetchReq); - - return tcs.Task; - } - /// /// Marks the as read /// diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 2bdcb57f2a..7a42007fb8 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -44,6 +44,7 @@ using osu.Game.Localisation; using osu.Game.Online; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; +using osu.Game.Online.Notifications; using osu.Game.Overlays; using osu.Game.Overlays.Music; using osu.Game.Overlays.Notifications; @@ -83,6 +84,7 @@ namespace osu.Game private ChatOverlay chatOverlay; private ChannelManager channelManager; + private NotificationsClientConnector notificationsClient; [NotNull] protected readonly NotificationOverlay Notifications = new NotificationOverlay(); @@ -676,6 +678,7 @@ namespace osu.Game { base.Dispose(isDisposing); SentryLogger.Dispose(); + notificationsClient.Dispose(); } protected override IDictionary GetFrameworkConfigDefaults() @@ -879,6 +882,7 @@ namespace osu.Game loadComponentSingleFile(dashboard = new DashboardOverlay(), overlayContent.Add, true); loadComponentSingleFile(news = new NewsOverlay(), overlayContent.Add, true); var rankingsOverlay = loadComponentSingleFile(new RankingsOverlay(), overlayContent.Add, true); + loadComponentSingleFile(notificationsClient = new NotificationsClientConnector(API), AddInternal, true); loadComponentSingleFile(channelManager = new ChannelManager(API), AddInternal, true); loadComponentSingleFile(chatOverlay = new ChatOverlay(), overlayContent.Add, true); loadComponentSingleFile(new MessageNotifier(), AddInternal, true); @@ -908,19 +912,6 @@ namespace osu.Game loadComponentSingleFile(new BackgroundBeatmapProcessor(), Add); - chatOverlay.State.BindValueChanged(_ => updateChatPollRate()); - // Multiplayer modes need to increase poll rate temporarily. - API.Activity.BindValueChanged(_ => updateChatPollRate(), true); - - void updateChatPollRate() - { - channelManager.HighPollRate.Value = - chatOverlay.State.Value == Visibility.Visible - || API.Activity.Value is UserActivity.InLobby - || API.Activity.Value is UserActivity.InMultiplayerGame - || API.Activity.Value is UserActivity.SpectatingMultiplayerGame; - } - Add(difficultyRecommender); Add(externalLinkOpener = new ExternalLinkOpener()); Add(new MusicKeyBindingHandler()); From efa82569117573894533e22beaadcc20a69579f3 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 28 Oct 2022 16:32:17 +0900 Subject: [PATCH 0290/2991] Use more verbatim strings --- .../API/Requests/GetNotificationsRequest.cs | 2 +- .../API/Requests/Responses/APINotification.cs | 16 ++++++++-------- .../Requests/Responses/APINotificationsBundle.cs | 6 +++--- osu.Game/Online/Notifications/EndChatRequest.cs | 2 +- .../Online/Notifications/NewChatMessageData.cs | 4 ++-- .../Online/Notifications/NotificationsClient.cs | 2 +- .../NotificationsClientConnector.cs | 2 +- .../NotificationsClient_Processing.cs | 5 ++++- osu.Game/Online/Notifications/SocketMessage.cs | 6 +++--- .../Online/Notifications/StartChatRequest.cs | 2 +- 10 files changed, 25 insertions(+), 22 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetNotificationsRequest.cs b/osu.Game/Online/API/Requests/GetNotificationsRequest.cs index e419807a85..afd4da296e 100644 --- a/osu.Game/Online/API/Requests/GetNotificationsRequest.cs +++ b/osu.Game/Online/API/Requests/GetNotificationsRequest.cs @@ -7,6 +7,6 @@ namespace osu.Game.Online.API.Requests { public class GetNotificationsRequest : APIRequest { - protected override string Target => "notifications"; + protected override string Target => @"notifications"; } } diff --git a/osu.Game/Online/API/Requests/Responses/APINotification.cs b/osu.Game/Online/API/Requests/Responses/APINotification.cs index e1f0fa7221..2d9122c04b 100644 --- a/osu.Game/Online/API/Requests/Responses/APINotification.cs +++ b/osu.Game/Online/API/Requests/Responses/APINotification.cs @@ -10,28 +10,28 @@ namespace osu.Game.Online.API.Requests.Responses [JsonObject(MemberSerialization.OptIn)] public class APINotification { - [JsonProperty("id")] + [JsonProperty(@"id")] public long Id { get; set; } - [JsonProperty("name")] + [JsonProperty(@"name")] public string Name { get; set; } = null!; - [JsonProperty("created_at")] + [JsonProperty(@"created_at")] public DateTimeOffset? CreatedAt { get; set; } - [JsonProperty("object_type")] + [JsonProperty(@"object_type")] public string ObjectType { get; set; } = null!; - [JsonProperty("object_id")] + [JsonProperty(@"object_id")] public string ObjectId { get; set; } = null!; - [JsonProperty("source_user_id")] + [JsonProperty(@"source_user_id")] public long? SourceUserId { get; set; } - [JsonProperty("is_read")] + [JsonProperty(@"is_read")] public bool IsRead { get; set; } - [JsonProperty("details")] + [JsonProperty(@"details")] public Dictionary? Details { get; set; } } } diff --git a/osu.Game/Online/API/Requests/Responses/APINotificationsBundle.cs b/osu.Game/Online/API/Requests/Responses/APINotificationsBundle.cs index 067f1066b3..ae299e2614 100644 --- a/osu.Game/Online/API/Requests/Responses/APINotificationsBundle.cs +++ b/osu.Game/Online/API/Requests/Responses/APINotificationsBundle.cs @@ -8,13 +8,13 @@ namespace osu.Game.Online.API.Requests.Responses [JsonObject(MemberSerialization.OptIn)] public class APINotificationsBundle { - [JsonProperty("has_more")] + [JsonProperty(@"has_more")] public bool HasMore { get; set; } - [JsonProperty("notifications")] + [JsonProperty(@"notifications")] public APINotification[] Notifications { get; set; } = null!; - [JsonProperty("notification_endpoint")] + [JsonProperty(@"notification_endpoint")] public string Endpoint { get; set; } = null!; } } diff --git a/osu.Game/Online/Notifications/EndChatRequest.cs b/osu.Game/Online/Notifications/EndChatRequest.cs index 1173b1e8d0..f863511804 100644 --- a/osu.Game/Online/Notifications/EndChatRequest.cs +++ b/osu.Game/Online/Notifications/EndChatRequest.cs @@ -10,7 +10,7 @@ namespace osu.Game.Online.Notifications { public EndChatRequest() { - Event = "chat.end"; + Event = @"chat.end"; } } } diff --git a/osu.Game/Online/Notifications/NewChatMessageData.cs b/osu.Game/Online/Notifications/NewChatMessageData.cs index b388afa743..eda9a3a11b 100644 --- a/osu.Game/Online/Notifications/NewChatMessageData.cs +++ b/osu.Game/Online/Notifications/NewChatMessageData.cs @@ -13,10 +13,10 @@ namespace osu.Game.Online.Notifications [JsonObject(MemberSerialization.OptIn)] public class NewChatMessageData { - [JsonProperty("messages")] + [JsonProperty(@"messages")] public List Messages { get; set; } = null!; - [JsonProperty("users")] + [JsonProperty(@"users")] private List users { get; set; } = null!; [OnDeserialized] diff --git a/osu.Game/Online/Notifications/NotificationsClient.cs b/osu.Game/Online/Notifications/NotificationsClient.cs index 63260e5df9..af9e3ba1e7 100644 --- a/osu.Game/Online/Notifications/NotificationsClient.cs +++ b/osu.Game/Online/Notifications/NotificationsClient.cs @@ -87,7 +87,7 @@ namespace osu.Game.Online.Notifications { try { - await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Disconnecting", CancellationToken.None).ConfigureAwait(false); + await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, @"Disconnecting", CancellationToken.None).ConfigureAwait(false); } catch { diff --git a/osu.Game/Online/Notifications/NotificationsClientConnector.cs b/osu.Game/Online/Notifications/NotificationsClientConnector.cs index 18b2a1b19d..e938ed59f0 100644 --- a/osu.Game/Online/Notifications/NotificationsClientConnector.cs +++ b/osu.Game/Online/Notifications/NotificationsClientConnector.cs @@ -48,7 +48,7 @@ namespace osu.Game.Online.Notifications string endpoint = await tcs.Task; ClientWebSocket socket = new ClientWebSocket(); - socket.Options.SetRequestHeader("Authorization", $"Bearer {api.AccessToken}"); + socket.Options.SetRequestHeader(@"Authorization", @$"Bearer {api.AccessToken}"); socket.Options.Proxy = WebRequest.DefaultWebProxy; if (socket.Options.Proxy != null) socket.Options.Proxy.Credentials = CredentialCache.DefaultCredentials; diff --git a/osu.Game/Online/Notifications/NotificationsClient_Processing.cs b/osu.Game/Online/Notifications/NotificationsClient_Processing.cs index 4950a53f6f..35cf737135 100644 --- a/osu.Game/Online/Notifications/NotificationsClient_Processing.cs +++ b/osu.Game/Online/Notifications/NotificationsClient_Processing.cs @@ -27,6 +27,9 @@ namespace osu.Game.Online.Notifications get => enableChat; set { + if (enableChat == value) + return; + enableChat = value; Task.Run(startChatIfEnabledAsync); } @@ -68,7 +71,7 @@ namespace osu.Game.Online.Notifications { switch (message.Event) { - case "chat.message.new": + case @"chat.message.new": Debug.Assert(message.Data != null); NewChatMessageData? messageData = JsonConvert.DeserializeObject(message.Data.ToString()); diff --git a/osu.Game/Online/Notifications/SocketMessage.cs b/osu.Game/Online/Notifications/SocketMessage.cs index 6b5f3435fc..c52072ccd5 100644 --- a/osu.Game/Online/Notifications/SocketMessage.cs +++ b/osu.Game/Online/Notifications/SocketMessage.cs @@ -9,13 +9,13 @@ namespace osu.Game.Online.Notifications [JsonObject(MemberSerialization.OptIn)] public class SocketMessage { - [JsonProperty("event")] + [JsonProperty(@"event")] public string Event { get; set; } = null!; - [JsonProperty("data")] + [JsonProperty(@"data")] public JObject? Data { get; set; } - [JsonProperty("error")] + [JsonProperty(@"error")] public string? Error { get; set; } } } diff --git a/osu.Game/Online/Notifications/StartChatRequest.cs b/osu.Game/Online/Notifications/StartChatRequest.cs index 274738886d..d17644ee3b 100644 --- a/osu.Game/Online/Notifications/StartChatRequest.cs +++ b/osu.Game/Online/Notifications/StartChatRequest.cs @@ -10,7 +10,7 @@ namespace osu.Game.Online.Notifications { public StartChatRequest() { - Event = "chat.start"; + Event = @"chat.start"; } } } From 8c057b3af7a3d97727007b792017feb1a65660d4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 17:26:53 +0900 Subject: [PATCH 0291/2991] Add comment explaining why handlers are added in `OsuGameBase` --- osu.Game/OsuGameBase.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 1177f01609..c94ad34f11 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -526,6 +526,11 @@ namespace osu.Game /// Should be overriden per-platform to provide settings for platform-specific handlers. public virtual SettingsSubsection CreateSettingsSubsectionFor(InputHandler handler) { + // One would think that this could be moved to the `OsuGameDesktop` class, but doing so means that + // OsuGameTestScenes will not show any input options (as they are based on OsuGame not OsuGameDesktop). + // + // This in turn makes it hard for ruleset creators to adjust input settings while testing their ruleset + // within the test browser interface. if (RuntimeInfo.IsDesktop) { switch (handler) From 527b1d9db10e0bdcf4d5c75ac64f4794662bc979 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 28 Oct 2022 17:53:28 +0900 Subject: [PATCH 0292/2991] Generalise + add polling-style for usage in tests --- osu.Game/Online/HubClient.cs | 2 +- .../Notifications/NotificationsClient.cs | 147 ++++++++--------- .../NotificationsClientConnector.cs | 42 ++--- .../NotificationsClient_Processing.cs | 105 ------------- .../Polling/PollingNotificationsClient.cs | 37 +++++ .../PollingNotificationsClientConnector.cs | 26 +++ .../{ => WebSocket}/EndChatRequest.cs | 5 +- .../{ => WebSocket}/NewChatMessageData.cs | 5 +- .../{ => WebSocket}/SocketMessage.cs | 5 +- .../{ => WebSocket}/StartChatRequest.cs | 5 +- .../WebSocket/WebSocketNotificationsClient.cs | 148 ++++++++++++++++++ .../WebSocketNotificationsClientConnector.cs | 46 ++++++ osu.Game/Online/SocketClient.cs | 2 +- osu.Game/Online/SocketClientConnector.cs | 2 +- osu.Game/OsuGame.cs | 3 +- 15 files changed, 357 insertions(+), 223 deletions(-) delete mode 100644 osu.Game/Online/Notifications/NotificationsClient_Processing.cs create mode 100644 osu.Game/Online/Notifications/Polling/PollingNotificationsClient.cs create mode 100644 osu.Game/Online/Notifications/Polling/PollingNotificationsClientConnector.cs rename osu.Game/Online/Notifications/{ => WebSocket}/EndChatRequest.cs (65%) rename osu.Game/Online/Notifications/{ => WebSocket}/NewChatMessageData.cs (83%) rename osu.Game/Online/Notifications/{ => WebSocket}/SocketMessage.cs (77%) rename osu.Game/Online/Notifications/{ => WebSocket}/StartChatRequest.cs (66%) create mode 100644 osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs create mode 100644 osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClientConnector.cs diff --git a/osu.Game/Online/HubClient.cs b/osu.Game/Online/HubClient.cs index 262e298f34..e80931eeae 100644 --- a/osu.Game/Online/HubClient.cs +++ b/osu.Game/Online/HubClient.cs @@ -17,7 +17,7 @@ namespace osu.Game.Online Connection.Closed += InvokeClosed; } - public override Task StartAsync(CancellationToken cancellationToken) => Connection.StartAsync(cancellationToken); + public override Task ConnectAsync(CancellationToken cancellationToken) => Connection.StartAsync(cancellationToken); public override async ValueTask DisposeAsync() { diff --git a/osu.Game/Online/Notifications/NotificationsClient.cs b/osu.Game/Online/Notifications/NotificationsClient.cs index af9e3ba1e7..6d9226ca17 100644 --- a/osu.Game/Online/Notifications/NotificationsClient.cs +++ b/osu.Game/Online/Notifications/NotificationsClient.cs @@ -2,112 +2,95 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; -using System.Net.WebSockets; -using System.Text; +using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; -using Newtonsoft.Json; -using osu.Framework.Extensions.TypeExtensions; -using osu.Framework.Logging; using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.Chat; namespace osu.Game.Online.Notifications { - public partial class NotificationsClient : SocketClient + /// + /// An abstract client which receives notification-related events (chat/notifications). + /// + public abstract class NotificationsClient : SocketClient { - private readonly ClientWebSocket socket; - private readonly string endpoint; + public Action? ChannelJoined; + public Action>? NewMessages; + public Action? PresenceReceived; + private readonly IAPIProvider api; - public NotificationsClient(ClientWebSocket socket, string endpoint, IAPIProvider api) + private bool enableChat; + private long lastMessageId; + + protected NotificationsClient(IAPIProvider api) { - this.socket = socket; - this.endpoint = endpoint; this.api = api; } - public override async Task StartAsync(CancellationToken cancellationToken) + public bool EnableChat { - await socket.ConnectAsync(new Uri(endpoint), cancellationToken).ConfigureAwait(false); - await onConnectedAsync(); - runReadLoop(cancellationToken); - } - - private void runReadLoop(CancellationToken cancellationToken) => Task.Run((Func)(async () => - { - byte[] buffer = new byte[1024]; - StringBuilder messageResult = new StringBuilder(); - - while (!cancellationToken.IsCancellationRequested) + get => enableChat; + set { - try - { - WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, cancellationToken); - - switch (result.MessageType) - { - case WebSocketMessageType.Text: - messageResult.Append(Encoding.UTF8.GetString(buffer[..result.Count])); - - if (result.EndOfMessage) - { - SocketMessage? message = JsonConvert.DeserializeObject(messageResult.ToString()); - messageResult.Clear(); - - Debug.Assert(message != null); - - if (message.Error != null) - { - Logger.Log($"{GetType().ReadableName()} error: {message.Error}", LoggingTarget.Network); - break; - } - - await onMessageReceivedAsync(message); - } - - break; - - case WebSocketMessageType.Binary: - throw new NotImplementedException(); - - case WebSocketMessageType.Close: - throw new Exception("Connection closed by remote host."); - } - } - catch (Exception ex) - { - await InvokeClosed(ex); + if (enableChat == value) return; + + enableChat = value; + + if (EnableChat) + Task.Run(StartChatAsync); + } + } + + public override async Task ConnectAsync(CancellationToken cancellationToken) + { + if (EnableChat) + await StartChatAsync(); + } + + protected virtual Task StartChatAsync() + { + api.Queue(CreateFetchMessagesRequest(0)); + return Task.CompletedTask; + } + + protected APIRequest CreateFetchMessagesRequest(long? lastMessageId = null) + { + var fetchReq = new GetUpdatesRequest(lastMessageId ?? this.lastMessageId); + + fetchReq.Success += updates => + { + if (updates?.Presence != null) + { + foreach (var channel in updates.Presence) + HandleJoinedChannel(channel); + + //todo: handle left channels + + HandleMessages(updates.Messages); } - } - }), cancellationToken); - private async Task closeAsync() - { - try - { - await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, @"Disconnecting", CancellationToken.None).ConfigureAwait(false); - } - catch - { - // Closure can fail if the connection is aborted. Don't really care since it's disposed anyway. - } + PresenceReceived?.Invoke(); + }; + + return fetchReq; } - private async Task sendMessage(SocketMessage message, CancellationToken cancellationToken) + protected void HandleJoinedChannel(Channel channel) { - if (socket.State != WebSocketState.Open) - return; - - await socket.SendAsync(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message)), WebSocketMessageType.Text, true, cancellationToken); + // we received this from the server so should mark the channel already joined. + channel.Joined.Value = true; + ChannelJoined?.Invoke(channel); } - public override async ValueTask DisposeAsync() + protected void HandleMessages(List messages) { - await base.DisposeAsync(); - await closeAsync(); - socket.Dispose(); + NewMessages?.Invoke(messages); + lastMessageId = Math.Max(lastMessageId, messages.LastOrDefault()?.Id ?? 0); } } } diff --git a/osu.Game/Online/Notifications/NotificationsClientConnector.cs b/osu.Game/Online/Notifications/NotificationsClientConnector.cs index e938ed59f0..5b2d6a4e13 100644 --- a/osu.Game/Online/Notifications/NotificationsClientConnector.cs +++ b/osu.Game/Online/Notifications/NotificationsClientConnector.cs @@ -3,29 +3,27 @@ using System; using System.Collections.Generic; -using System.Net; -using System.Net.WebSockets; using System.Threading; using System.Threading.Tasks; using osu.Game.Online.API; -using osu.Game.Online.API.Requests; using osu.Game.Online.Chat; namespace osu.Game.Online.Notifications { - public class NotificationsClientConnector : SocketClientConnector + /// + /// An abstract connector or s. + /// + public abstract class NotificationsClientConnector : SocketClientConnector { public event Action? ChannelJoined; public event Action>? NewMessages; public event Action? PresenceReceived; - private readonly IAPIProvider api; private bool chatStarted; - public NotificationsClientConnector(IAPIProvider api) + protected NotificationsClientConnector(IAPIProvider api) : base(api) { - this.api = api; } public void StartChat() @@ -36,30 +34,18 @@ namespace osu.Game.Online.Notifications client.EnableChat = true; } - protected override async Task BuildConnectionAsync(CancellationToken cancellationToken) + protected sealed override async Task BuildConnectionAsync(CancellationToken cancellationToken) { - var tcs = new TaskCompletionSource(); + var client = await BuildNotificationClientAsync(cancellationToken); - var req = new GetNotificationsRequest(); - req.Success += bundle => tcs.SetResult(bundle.Endpoint); - req.Failure += ex => tcs.SetException(ex); - api.Queue(req); + client.ChannelJoined = c => ChannelJoined?.Invoke(c); + client.NewMessages = m => NewMessages?.Invoke(m); + client.PresenceReceived = () => PresenceReceived?.Invoke(); + client.EnableChat = chatStarted; - string endpoint = await tcs.Task; - - ClientWebSocket socket = new ClientWebSocket(); - socket.Options.SetRequestHeader(@"Authorization", @$"Bearer {api.AccessToken}"); - socket.Options.Proxy = WebRequest.DefaultWebProxy; - if (socket.Options.Proxy != null) - socket.Options.Proxy.Credentials = CredentialCache.DefaultCredentials; - - return new NotificationsClient(socket, endpoint, api) - { - ChannelJoined = c => ChannelJoined?.Invoke(c), - NewMessages = m => NewMessages?.Invoke(m), - PresenceReceived = () => PresenceReceived?.Invoke(), - EnableChat = chatStarted - }; + return client; } + + protected abstract Task BuildNotificationClientAsync(CancellationToken cancellationToken); } } diff --git a/osu.Game/Online/Notifications/NotificationsClient_Processing.cs b/osu.Game/Online/Notifications/NotificationsClient_Processing.cs deleted file mode 100644 index 35cf737135..0000000000 --- a/osu.Game/Online/Notifications/NotificationsClient_Processing.cs +++ /dev/null @@ -1,105 +0,0 @@ -// 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.Diagnostics; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Newtonsoft.Json; -using osu.Game.Online.API.Requests; -using osu.Game.Online.Chat; - -namespace osu.Game.Online.Notifications -{ - public partial class NotificationsClient - { - public Action? ChannelJoined; - public Action>? NewMessages; - public Action? PresenceReceived; - - private bool enableChat; - private long lastMessageId; - - public bool EnableChat - { - get => enableChat; - set - { - if (enableChat == value) - return; - - enableChat = value; - Task.Run(startChatIfEnabledAsync); - } - } - - private async Task onConnectedAsync() - { - await startChatIfEnabledAsync(); - } - - private async Task startChatIfEnabledAsync() - { - if (!EnableChat) - return; - - await sendMessage(new StartChatRequest(), CancellationToken.None); - - var fetchReq = new GetUpdatesRequest(lastMessageId); - - fetchReq.Success += updates => - { - if (updates?.Presence != null) - { - foreach (var channel in updates.Presence) - handleJoinedChannel(channel); - - //todo: handle left channels - - handleMessages(updates.Messages); - } - - PresenceReceived?.Invoke(); - }; - - api.Queue(fetchReq); - } - - private Task onMessageReceivedAsync(SocketMessage message) - { - switch (message.Event) - { - case @"chat.message.new": - Debug.Assert(message.Data != null); - - NewChatMessageData? messageData = JsonConvert.DeserializeObject(message.Data.ToString()); - Debug.Assert(messageData != null); - - List messages = messageData.Messages.Where(m => m.Sender.OnlineID != api.LocalUser.Value.OnlineID).ToList(); - - foreach (var msg in messages) - handleJoinedChannel(new Channel(msg.Sender) { Id = msg.ChannelId }); - - handleMessages(messages); - break; - } - - return Task.CompletedTask; - } - - private void handleJoinedChannel(Channel channel) - { - // we received this from the server so should mark the channel already joined. - channel.Joined.Value = true; - ChannelJoined?.Invoke(channel); - } - - private void handleMessages(List messages) - { - NewMessages?.Invoke(messages); - lastMessageId = messages.LastOrDefault()?.Id ?? lastMessageId; - } - } -} diff --git a/osu.Game/Online/Notifications/Polling/PollingNotificationsClient.cs b/osu.Game/Online/Notifications/Polling/PollingNotificationsClient.cs new file mode 100644 index 0000000000..1c5559fcb4 --- /dev/null +++ b/osu.Game/Online/Notifications/Polling/PollingNotificationsClient.cs @@ -0,0 +1,37 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Threading; +using System.Threading.Tasks; +using osu.Game.Online.API; + +namespace osu.Game.Online.Notifications.Polling +{ + /// + /// A notifications client which polls for new messages every second. + /// + public class PollingNotificationsClient : NotificationsClient + { + private readonly IAPIProvider api; + + public PollingNotificationsClient(IAPIProvider api) + : base(api) + { + this.api = api; + } + + public override Task ConnectAsync(CancellationToken cancellationToken) + { + Task.Run(async () => + { + while (!cancellationToken.IsCancellationRequested) + { + await api.PerformAsync(CreateFetchMessagesRequest()); + await Task.Delay(1000, cancellationToken); + } + }, cancellationToken); + + return Task.CompletedTask; + } + } +} diff --git a/osu.Game/Online/Notifications/Polling/PollingNotificationsClientConnector.cs b/osu.Game/Online/Notifications/Polling/PollingNotificationsClientConnector.cs new file mode 100644 index 0000000000..18a31ff061 --- /dev/null +++ b/osu.Game/Online/Notifications/Polling/PollingNotificationsClientConnector.cs @@ -0,0 +1,26 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Threading; +using System.Threading.Tasks; +using osu.Game.Online.API; + +namespace osu.Game.Online.Notifications.Polling +{ + /// + /// A connector for s that poll for new messages. + /// + public class PollingNotificationsClientConnector : NotificationsClientConnector + { + private readonly IAPIProvider api; + + public PollingNotificationsClientConnector(IAPIProvider api) + : base(api) + { + this.api = api; + } + + protected override Task BuildNotificationClientAsync(CancellationToken cancellationToken) + => Task.FromResult((NotificationsClient)new PollingNotificationsClient(api)); + } +} diff --git a/osu.Game/Online/Notifications/EndChatRequest.cs b/osu.Game/Online/Notifications/WebSocket/EndChatRequest.cs similarity index 65% rename from osu.Game/Online/Notifications/EndChatRequest.cs rename to osu.Game/Online/Notifications/WebSocket/EndChatRequest.cs index f863511804..7f67587f5d 100644 --- a/osu.Game/Online/Notifications/EndChatRequest.cs +++ b/osu.Game/Online/Notifications/WebSocket/EndChatRequest.cs @@ -3,8 +3,11 @@ using Newtonsoft.Json; -namespace osu.Game.Online.Notifications +namespace osu.Game.Online.Notifications.WebSocket { + /// + /// A websocket message notifying the server that the client no longer wants to receive chat messages. + /// [JsonObject(MemberSerialization.OptIn)] public class EndChatRequest : SocketMessage { diff --git a/osu.Game/Online/Notifications/NewChatMessageData.cs b/osu.Game/Online/Notifications/WebSocket/NewChatMessageData.cs similarity index 83% rename from osu.Game/Online/Notifications/NewChatMessageData.cs rename to osu.Game/Online/Notifications/WebSocket/NewChatMessageData.cs index eda9a3a11b..850fbd226b 100644 --- a/osu.Game/Online/Notifications/NewChatMessageData.cs +++ b/osu.Game/Online/Notifications/WebSocket/NewChatMessageData.cs @@ -8,8 +8,11 @@ using Newtonsoft.Json; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; -namespace osu.Game.Online.Notifications +namespace osu.Game.Online.Notifications.WebSocket { + /// + /// A websocket message sent from the server when new messages arrive. + /// [JsonObject(MemberSerialization.OptIn)] public class NewChatMessageData { diff --git a/osu.Game/Online/Notifications/SocketMessage.cs b/osu.Game/Online/Notifications/WebSocket/SocketMessage.cs similarity index 77% rename from osu.Game/Online/Notifications/SocketMessage.cs rename to osu.Game/Online/Notifications/WebSocket/SocketMessage.cs index c52072ccd5..666a9dd8a3 100644 --- a/osu.Game/Online/Notifications/SocketMessage.cs +++ b/osu.Game/Online/Notifications/WebSocket/SocketMessage.cs @@ -4,8 +4,11 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; -namespace osu.Game.Online.Notifications +namespace osu.Game.Online.Notifications.WebSocket { + /// + /// A websocket message, sent either from the client or server. + /// [JsonObject(MemberSerialization.OptIn)] public class SocketMessage { diff --git a/osu.Game/Online/Notifications/StartChatRequest.cs b/osu.Game/Online/Notifications/WebSocket/StartChatRequest.cs similarity index 66% rename from osu.Game/Online/Notifications/StartChatRequest.cs rename to osu.Game/Online/Notifications/WebSocket/StartChatRequest.cs index d17644ee3b..9dd69a7377 100644 --- a/osu.Game/Online/Notifications/StartChatRequest.cs +++ b/osu.Game/Online/Notifications/WebSocket/StartChatRequest.cs @@ -3,8 +3,11 @@ using Newtonsoft.Json; -namespace osu.Game.Online.Notifications +namespace osu.Game.Online.Notifications.WebSocket { + /// + /// A websocket message notifying the server that the client wants to receive chat messages. + /// [JsonObject(MemberSerialization.OptIn)] public class StartChatRequest : SocketMessage { diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs new file mode 100644 index 0000000000..cadeb8b9fa --- /dev/null +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -0,0 +1,148 @@ +// 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.Diagnostics; +using System.Linq; +using System.Net.WebSockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Newtonsoft.Json; +using osu.Framework.Extensions.TypeExtensions; +using osu.Framework.Logging; +using osu.Game.Online.API; +using osu.Game.Online.Chat; + +namespace osu.Game.Online.Notifications.WebSocket +{ + /// + /// A notifications client which receives events via a websocket. + /// + public class WebSocketNotificationsClient : NotificationsClient + { + private readonly ClientWebSocket socket; + private readonly string endpoint; + private readonly IAPIProvider api; + + public WebSocketNotificationsClient(ClientWebSocket socket, string endpoint, IAPIProvider api) + : base(api) + { + this.socket = socket; + this.endpoint = endpoint; + this.api = api; + } + + public override async Task ConnectAsync(CancellationToken cancellationToken) + { + await socket.ConnectAsync(new Uri(endpoint), cancellationToken).ConfigureAwait(false); + runReadLoop(cancellationToken); + await base.ConnectAsync(cancellationToken); + } + + protected override async Task StartChatAsync() + { + await sendMessage(new StartChatRequest(), CancellationToken.None); + await base.StartChatAsync(); + } + + private void runReadLoop(CancellationToken cancellationToken) => Task.Run((Func)(async () => + { + byte[] buffer = new byte[1024]; + StringBuilder messageResult = new StringBuilder(); + + while (!cancellationToken.IsCancellationRequested) + { + try + { + WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, cancellationToken); + + switch (result.MessageType) + { + case WebSocketMessageType.Text: + messageResult.Append(Encoding.UTF8.GetString(buffer[..result.Count])); + + if (result.EndOfMessage) + { + SocketMessage? message = JsonConvert.DeserializeObject(messageResult.ToString()); + messageResult.Clear(); + + Debug.Assert(message != null); + + if (message.Error != null) + { + Logger.Log($"{GetType().ReadableName()} error: {message.Error}", LoggingTarget.Network); + break; + } + + await onMessageReceivedAsync(message); + } + + break; + + case WebSocketMessageType.Binary: + throw new NotImplementedException(); + + case WebSocketMessageType.Close: + throw new Exception("Connection closed by remote host."); + } + } + catch (Exception ex) + { + await InvokeClosed(ex); + return; + } + } + }), cancellationToken); + + private async Task closeAsync() + { + try + { + await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, @"Disconnecting", CancellationToken.None).ConfigureAwait(false); + } + catch + { + // Closure can fail if the connection is aborted. Don't really care since it's disposed anyway. + } + } + + private async Task sendMessage(SocketMessage message, CancellationToken cancellationToken) + { + if (socket.State != WebSocketState.Open) + return; + + await socket.SendAsync(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message)), WebSocketMessageType.Text, true, cancellationToken); + } + + private Task onMessageReceivedAsync(SocketMessage message) + { + switch (message.Event) + { + case @"chat.message.new": + Debug.Assert(message.Data != null); + + NewChatMessageData? messageData = JsonConvert.DeserializeObject(message.Data.ToString()); + Debug.Assert(messageData != null); + + List messages = messageData.Messages.Where(m => m.Sender.OnlineID != api.LocalUser.Value.OnlineID).ToList(); + + foreach (var msg in messages) + HandleJoinedChannel(new Channel(msg.Sender) { Id = msg.ChannelId }); + + HandleMessages(messages); + break; + } + + return Task.CompletedTask; + } + + public override async ValueTask DisposeAsync() + { + await base.DisposeAsync(); + await closeAsync(); + socket.Dispose(); + } + } +} diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClientConnector.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClientConnector.cs new file mode 100644 index 0000000000..21335a3b59 --- /dev/null +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClientConnector.cs @@ -0,0 +1,46 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Net; +using System.Net.WebSockets; +using System.Threading; +using System.Threading.Tasks; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; + +namespace osu.Game.Online.Notifications.WebSocket +{ + /// + /// A connector for s that receive events via a websocket. + /// + public class WebSocketNotificationsClientConnector : NotificationsClientConnector + { + private readonly IAPIProvider api; + + public WebSocketNotificationsClientConnector(IAPIProvider api) + : base(api) + { + this.api = api; + } + + protected override async Task BuildNotificationClientAsync(CancellationToken cancellationToken) + { + var tcs = new TaskCompletionSource(); + + var req = new GetNotificationsRequest(); + req.Success += bundle => tcs.SetResult(bundle.Endpoint); + req.Failure += ex => tcs.SetException(ex); + api.Queue(req); + + string endpoint = await tcs.Task; + + ClientWebSocket socket = new ClientWebSocket(); + socket.Options.SetRequestHeader(@"Authorization", @$"Bearer {api.AccessToken}"); + socket.Options.Proxy = WebRequest.DefaultWebProxy; + if (socket.Options.Proxy != null) + socket.Options.Proxy.Credentials = CredentialCache.DefaultCredentials; + + return new WebSocketNotificationsClient(socket, endpoint, api); + } + } +} diff --git a/osu.Game/Online/SocketClient.cs b/osu.Game/Online/SocketClient.cs index 3b4aa1b49b..748e77fc0b 100644 --- a/osu.Game/Online/SocketClient.cs +++ b/osu.Game/Online/SocketClient.cs @@ -13,7 +13,7 @@ namespace osu.Game.Online protected Task InvokeClosed(Exception? exception) => Closed?.Invoke(exception) ?? Task.CompletedTask; - public abstract Task StartAsync(CancellationToken cancellationToken); + public abstract Task ConnectAsync(CancellationToken cancellationToken); public virtual ValueTask DisposeAsync() { diff --git a/osu.Game/Online/SocketClientConnector.cs b/osu.Game/Online/SocketClientConnector.cs index 823e724ef9..4ce5c75ba8 100644 --- a/osu.Game/Online/SocketClientConnector.cs +++ b/osu.Game/Online/SocketClientConnector.cs @@ -92,7 +92,7 @@ namespace osu.Game.Online cancellationToken.ThrowIfCancellationRequested(); - await CurrentConnection.StartAsync(cancellationToken).ConfigureAwait(false); + await CurrentConnection.ConnectAsync(cancellationToken).ConfigureAwait(false); Logger.Log($"{ClientName} connected!", LoggingTarget.Network); isConnected.Value = true; diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 7a42007fb8..df3000a547 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -45,6 +45,7 @@ using osu.Game.Online; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; using osu.Game.Online.Notifications; +using osu.Game.Online.Notifications.Polling; using osu.Game.Overlays; using osu.Game.Overlays.Music; using osu.Game.Overlays.Notifications; @@ -882,7 +883,7 @@ namespace osu.Game loadComponentSingleFile(dashboard = new DashboardOverlay(), overlayContent.Add, true); loadComponentSingleFile(news = new NewsOverlay(), overlayContent.Add, true); var rankingsOverlay = loadComponentSingleFile(new RankingsOverlay(), overlayContent.Add, true); - loadComponentSingleFile(notificationsClient = new NotificationsClientConnector(API), AddInternal, true); + loadComponentSingleFile(notificationsClient = new PollingNotificationsClientConnector(API), AddInternal, true); loadComponentSingleFile(channelManager = new ChannelManager(API), AddInternal, true); loadComponentSingleFile(chatOverlay = new ChatOverlay(), overlayContent.Add, true); loadComponentSingleFile(new MessageNotifier(), AddInternal, true); From 66ed77ac91f7a9ab4cd6297833fba3f52a044bf5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 18:04:28 +0900 Subject: [PATCH 0293/2991] Rename and add documentation to function --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- osu.Game/Database/LegacyExporter.cs | 2 +- osu.Game/Extensions/ModelExtensions.cs | 16 +++++++++------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index befc56d244..965cc43815 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -340,7 +340,7 @@ namespace osu.Game.Beatmaps static string createBeatmapFilenameFromMetadata(BeatmapInfo beatmapInfo) { var metadata = beatmapInfo.Metadata; - return $"{metadata.Artist} - {metadata.Title} ({metadata.Author.Username}) [{beatmapInfo.DifficultyName}].osu".GetValidArchiveContentFilename(); + return $"{metadata.Artist} - {metadata.Title} ({metadata.Author.Username}) [{beatmapInfo.DifficultyName}].osu".GetValidFilename(); } } diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index d9fdc40abc..16d7441dde 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -37,7 +37,7 @@ namespace osu.Game.Database /// The item to export. public void Export(TModel item) { - string filename = $"{item.GetDisplayString().GetValidArchiveContentFilename()}{FileExtension}"; + string filename = $"{item.GetDisplayString().GetValidFilename()}{FileExtension}"; using (var stream = exportStorage.CreateFileSafely(filename)) ExportModelTo(item, stream); diff --git a/osu.Game/Extensions/ModelExtensions.cs b/osu.Game/Extensions/ModelExtensions.cs index f8db5f4e88..efb3c4d633 100644 --- a/osu.Game/Extensions/ModelExtensions.cs +++ b/osu.Game/Extensions/ModelExtensions.cs @@ -15,6 +15,8 @@ namespace osu.Game.Extensions { public static class ModelExtensions { + private static readonly Regex invalid_filename_chars = new Regex(@"(?!$)[^A-Za-z0-9_()[\]. \-]", RegexOptions.Compiled); + /// /// Get the relative path in osu! storage for this file. /// @@ -137,14 +139,14 @@ namespace osu.Game.Extensions return instance.OnlineID.Equals(other.OnlineID); } - private static readonly Regex invalid_filename_chars = new Regex(@"(?!$)[^A-Za-z0-9_()[\]. \-]", RegexOptions.Compiled); - /// - /// Get a valid filename for use inside a zip file. Avoids backslashes being incorrectly converted to directories. + /// Create a valid filename which should work across all platforms. /// - public static string GetValidArchiveContentFilename(this string filename) - { - return invalid_filename_chars.Replace(filename, "_"); - } + /// + /// This function replaces all characters not included in a very pessimistic list which should be compatible + /// across all operating systems. We are using this in place of as + /// that function does not have per-platform considerations (and is only made to work on windows). + /// + public static string GetValidFilename(this string filename) => invalid_filename_chars.Replace(filename, "_"); } } From f46a9d683aebe2f3bef438792bee1921466e727f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 18:07:25 +0900 Subject: [PATCH 0294/2991] Fix null reference in headless tests --- osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index f77e1bfc6a..7f0bded806 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -244,7 +244,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics else displayDropdown.Hide(); - if (host.Window.SafeAreaPadding.Value.Total != Vector2.Zero) + if (host.Window?.SafeAreaPadding.Value.Total != Vector2.Zero) safeAreaConsiderationsCheckbox.Show(); else safeAreaConsiderationsCheckbox.Hide(); From 169bcc265416b52324ab12d177f32b771fa09a0d Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 28 Oct 2022 18:08:08 +0900 Subject: [PATCH 0295/2991] Use polling connector in tests --- .../Chat/TestSceneChannelManager.cs | 3 ++- .../Visual/Online/TestSceneChatLink.cs | 5 ++++- .../Visual/Online/TestSceneChatOverlay.cs | 3 ++- .../Visual/Online/TestSceneMessageNotifier.cs | 3 ++- .../Online/TestSceneStandAloneChatDisplay.cs | 5 ++++- .../Components/TournamentMatchChatDisplay.cs | 3 ++- osu.Game/Online/Chat/ChannelManager.cs | 14 ++++++++++---- osu.Game/Online/SocketClientConnector.cs | 19 +++++++++++++++---- osu.Game/OsuGame.cs | 6 +++--- 9 files changed, 44 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Chat/TestSceneChannelManager.cs b/osu.Game.Tests/Chat/TestSceneChannelManager.cs index e7eb06c795..84609a2733 100644 --- a/osu.Game.Tests/Chat/TestSceneChannelManager.cs +++ b/osu.Game.Tests/Chat/TestSceneChannelManager.cs @@ -13,6 +13,7 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; +using osu.Game.Online.Notifications.Polling; using osu.Game.Tests.Visual; namespace osu.Game.Tests.Chat @@ -151,7 +152,7 @@ namespace osu.Game.Tests.Chat public ChannelManagerContainer(IAPIProvider apiProvider) { - InternalChild = ChannelManager = new ChannelManager(apiProvider); + InternalChild = ChannelManager = new ChannelManager(apiProvider, new PollingNotificationsClientConnector(apiProvider)); } } } diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs index a537f0660c..63526d4278 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs @@ -14,6 +14,7 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; +using osu.Game.Online.Notifications.Polling; using osu.Game.Overlays.Chat; using osuTK.Graphics; @@ -41,11 +42,13 @@ namespace osu.Game.Tests.Visual.Online { linkColour = colours.Blue; - var chatManager = new ChannelManager(API); + var chatManager = new ChannelManager(API, new PollingNotificationsClientConnector(API)); BindableList availableChannels = (BindableList)chatManager.AvailableChannels; availableChannels.Add(new Channel { Name = "#english" }); availableChannels.Add(new Channel { Name = "#japanese" }); Dependencies.Cache(chatManager); + + Add(chatManager); } [SetUp] diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 0b982a5745..dee258f747 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -24,6 +24,7 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; +using osu.Game.Online.Notifications.Polling; using osu.Game.Overlays; using osu.Game.Overlays.Chat; using osu.Game.Overlays.Chat.Listing; @@ -59,7 +60,7 @@ namespace osu.Game.Tests.Visual.Online RelativeSizeAxes = Axes.Both, CachedDependencies = new (Type, object)[] { - (typeof(ChannelManager), channelManager = new ChannelManager(API)), + (typeof(ChannelManager), channelManager = new ChannelManager(API, new PollingNotificationsClientConnector(API))), }, Children = new Drawable[] { diff --git a/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs b/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs index 57514cdf37..6d83fb3123 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs @@ -16,6 +16,7 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; +using osu.Game.Online.Notifications.Polling; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; using osuTK.Input; @@ -250,7 +251,7 @@ namespace osu.Game.Tests.Visual.Online public TestContainer(IAPIProvider api, Channel[] channels) { this.channels = channels; - ChannelManager = new ChannelManager(api); + ChannelManager = new ChannelManager(api, new PollingNotificationsClientConnector(api)); } [BackgroundDependencyLoader] diff --git a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs index 292facab11..f1daa05e08 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs @@ -15,6 +15,7 @@ using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Notifications.Polling; using osu.Game.Overlays.Chat; using osuTK.Input; @@ -56,7 +57,9 @@ namespace osu.Game.Tests.Visual.Online protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - Add(channelManager = new ChannelManager(parent.Get())); + var api = parent.Get(); + + Add(channelManager = new ChannelManager(api, new PollingNotificationsClientConnector(api))); var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); diff --git a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs index ca2b400e8b..99cd9beecf 100644 --- a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs +++ b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs @@ -9,6 +9,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Online.API; using osu.Game.Online.Chat; +using osu.Game.Online.Notifications.WebSocket; using osu.Game.Overlays.Chat; using osu.Game.Tournament.IPC; using osu.Game.Tournament.Models; @@ -48,7 +49,7 @@ namespace osu.Game.Tournament.Components if (manager == null) { - AddInternal(manager = new ChannelManager(api)); + AddInternal(manager = new ChannelManager(api, new WebSocketNotificationsClientConnector(api))); Channel.BindTo(manager.CurrentChannel); } diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index b63f841f59..ab3ac6f692 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -65,20 +65,20 @@ namespace osu.Game.Online.Chat public IBindableList AvailableChannels => availableChannels; private readonly IAPIProvider api; + private readonly NotificationsClientConnector connector; [Resolved] private UserLookupCache users { get; set; } - [Resolved] - private NotificationsClientConnector connector { get; set; } - private readonly IBindable apiState = new Bindable(); private bool channelsInitialised; private ScheduledDelegate ackDelegate; - public ChannelManager(IAPIProvider api) + public ChannelManager(IAPIProvider api, NotificationsClientConnector connector) { this.api = api; + this.connector = connector; + CurrentChannel.ValueChanged += currentChannelChanged; } @@ -603,6 +603,12 @@ namespace osu.Game.Online.Chat api.Queue(req); } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + connector?.Dispose(); + } } /// diff --git a/osu.Game/Online/SocketClientConnector.cs b/osu.Game/Online/SocketClientConnector.cs index 4ce5c75ba8..c6d5601c1f 100644 --- a/osu.Game/Online/SocketClientConnector.cs +++ b/osu.Game/Online/SocketClientConnector.cs @@ -6,13 +6,12 @@ using System.Threading; using System.Threading.Tasks; using osu.Framework.Bindables; using osu.Framework.Extensions.TypeExtensions; -using osu.Framework.Graphics; using osu.Framework.Logging; using osu.Game.Online.API; namespace osu.Game.Online { - public abstract class SocketClientConnector : Component + public abstract class SocketClientConnector : IDisposable { /// /// Whether this is connected to the hub, use to access the connection, if this is true. @@ -173,11 +172,23 @@ namespace osu.Game.Online public override string ToString() => $"{ClientName} ({(IsConnected.Value ? "connected" : "not connected")})"; - protected override void Dispose(bool isDisposing) + private bool isDisposed; + + protected virtual void Dispose(bool isDisposing) { - base.Dispose(isDisposing); + if (isDisposed) + return; + apiState.UnbindAll(); cancelExistingConnect(); + + isDisposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); } } } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index df3000a547..4ceefbf1fd 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -45,7 +45,7 @@ using osu.Game.Online; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; using osu.Game.Online.Notifications; -using osu.Game.Online.Notifications.Polling; +using osu.Game.Online.Notifications.WebSocket; using osu.Game.Overlays; using osu.Game.Overlays.Music; using osu.Game.Overlays.Notifications; @@ -757,6 +757,7 @@ namespace osu.Game BackButton.Receptor receptor; dependencies.CacheAs(idleTracker = new GameIdleTracker(6000)); + dependencies.CacheAs(notificationsClient = new WebSocketNotificationsClientConnector(API)); var sessionIdleTracker = new GameIdleTracker(300000); sessionIdleTracker.IsIdle.BindValueChanged(idle => @@ -883,8 +884,7 @@ namespace osu.Game loadComponentSingleFile(dashboard = new DashboardOverlay(), overlayContent.Add, true); loadComponentSingleFile(news = new NewsOverlay(), overlayContent.Add, true); var rankingsOverlay = loadComponentSingleFile(new RankingsOverlay(), overlayContent.Add, true); - loadComponentSingleFile(notificationsClient = new PollingNotificationsClientConnector(API), AddInternal, true); - loadComponentSingleFile(channelManager = new ChannelManager(API), AddInternal, true); + loadComponentSingleFile(channelManager = new ChannelManager(API, notificationsClient), AddInternal, true); loadComponentSingleFile(chatOverlay = new ChatOverlay(), overlayContent.Add, true); loadComponentSingleFile(new MessageNotifier(), AddInternal, true); loadComponentSingleFile(Settings = new SettingsOverlay(), leftFloatingOverlayContent.Add, true); From e87b541c5893d2c642abac4f288e83cd53e2d8f7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 18:29:55 +0900 Subject: [PATCH 0296/2991] Add fade to banana's lighting as it approaches the catcher This also avoids using the `UprightScalingContainer` (and allows for scale adjust in the process). --- .../Skinning/Argon/ArgonBananaPiece.cs | 21 ++++++++++++++++--- .../Skinning/Default/BananaPiece.cs | 6 ++---- .../Skinning/Default/CatchHitObjectPiece.cs | 2 +- .../Skinning/Default/FruitPiece.cs | 2 +- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs index 49edc80770..1a37136f53 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs @@ -5,9 +5,10 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics.Containers; +using osu.Game.Rulesets.Catch.Objects; using osuTK; using osuTK.Graphics; @@ -15,10 +16,14 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon { internal class ArgonBananaPiece : ArgonFruitPiece { + private Container stabilisedPieceContainer = null!; + + protected override Drawable BorderPiece => stabilisedPieceContainer; + [BackgroundDependencyLoader] private void load() { - AddInternal(new UprightAspectMaintainingContainer + AddInternal(stabilisedPieceContainer = new Container { RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, @@ -44,7 +49,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon Width = 1.6f, Height = 2, }, - new Box + new Circle { Colour = ColourInfo.GradientHorizontal(Color4.White, Color4.White.Opacity(0)), RelativeSizeAxes = Axes.X, @@ -78,5 +83,15 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon } }); } + + protected override void Update() + { + base.Update(); + + float scale = 0.5f + 0.5f * (1 / (ObjectState.DisplaySize.X / (CatchHitObject.OBJECT_RADIUS * 2))); + + stabilisedPieceContainer.Rotation = -ObjectState.DisplayRotation; + stabilisedPieceContainer.Scale = new Vector2(scale); + } } } diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/BananaPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/BananaPiece.cs index 27252594af..359756f159 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/BananaPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/BananaPiece.cs @@ -1,21 +1,19 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; namespace osu.Game.Rulesets.Catch.Skinning.Default { public class BananaPiece : CatchHitObjectPiece { - protected override BorderPiece BorderPiece { get; } + protected override Drawable BorderPiece { get; } public BananaPiece() { RelativeSizeAxes = Axes.Both; - InternalChildren = new Drawable[] + InternalChildren = new[] { new BananaPulpFormation { diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs index fd1047f27e..3b8df6ee6f 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default /// A part of this piece that will be faded out while falling in the playfield. /// [CanBeNull] - protected virtual BorderPiece BorderPiece => null; + protected virtual Drawable BorderPiece => null; /// /// A part of this piece that will be only visible when is true. diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs index 9dce0e9129..adee960c3c 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default public readonly Bindable VisualRepresentation = new Bindable(); - protected override BorderPiece BorderPiece { get; } + protected override Drawable BorderPiece { get; } protected override Drawable HyperBorderPiece { get; } public FruitPiece() From ab78cde2d471fe3478f0a5ac4efc074b102c4f2c Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 28 Oct 2022 18:37:43 +0900 Subject: [PATCH 0297/2991] Fix crossthread mutations --- osu.Game/Online/Chat/ChannelManager.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index ab3ac6f692..a901c15bf4 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -85,9 +85,9 @@ namespace osu.Game.Online.Chat [BackgroundDependencyLoader] private void load() { - connector.ChannelJoined += ch => joinChannel(ch); - connector.NewMessages += addMessages; - connector.PresenceReceived += () => + connector.ChannelJoined += ch => Schedule(() => joinChannel(ch)); + connector.NewMessages += msgs => Schedule(() => addMessages(msgs)); + connector.PresenceReceived += () => Schedule(() => { if (!channelsInitialised) { @@ -95,7 +95,7 @@ namespace osu.Game.Online.Chat // we want this to run after the first presence so we can see if the user is in any channels already. initializeChannels(); } - }; + }); connector.StartChat(); From d3173ab1bd836d4061325beb67b8a40eb98cd658 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 28 Oct 2022 18:54:34 +0900 Subject: [PATCH 0298/2991] Remove weird cast --- .../Notifications/WebSocket/WebSocketNotificationsClient.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index cadeb8b9fa..ff0941ecba 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -47,7 +47,7 @@ namespace osu.Game.Online.Notifications.WebSocket await base.StartChatAsync(); } - private void runReadLoop(CancellationToken cancellationToken) => Task.Run((Func)(async () => + private void runReadLoop(CancellationToken cancellationToken) => Task.Run(async () => { byte[] buffer = new byte[1024]; StringBuilder messageResult = new StringBuilder(); @@ -94,7 +94,7 @@ namespace osu.Game.Online.Notifications.WebSocket return; } } - }), cancellationToken); + }, cancellationToken); private async Task closeAsync() { From 40efa1603bf1d8c0ea8688753a9f1cfab110df15 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 19:35:50 +0900 Subject: [PATCH 0299/2991] Adjust metrics to make banana lens flares look better --- .../Objects/Drawables/CaughtObject.cs | 2 + .../DrawablePalpableCatchHitObject.cs | 2 + .../Objects/Drawables/IHasCatchObjectState.cs | 2 + .../Skinning/Argon/ArgonBananaPiece.cs | 87 ++++++++++++------- 4 files changed, 62 insertions(+), 31 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs index fd0ffbd032..ddfbb34435 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs @@ -28,6 +28,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables public float DisplayRotation => Rotation; + public double DisplayStartTime => HitObject.StartTime; + /// /// Whether this hit object should stay on the catcher plate when the object is caught by the catcher. /// diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs index 5de372852b..dd09b6c06d 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs @@ -18,6 +18,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { public new PalpableCatchHitObject HitObject => (PalpableCatchHitObject)base.HitObject; + public double DisplayStartTime => LifetimeStart; + Bindable IHasCatchObjectState.AccentColour => AccentColour; public Bindable HyperDash { get; } = new Bindable(); diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/IHasCatchObjectState.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/IHasCatchObjectState.cs index 93c80b09db..f30ef0831a 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/IHasCatchObjectState.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/IHasCatchObjectState.cs @@ -16,6 +16,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { PalpableCatchHitObject HitObject { get; } + double DisplayStartTime { get; } + Bindable AccentColour { get; } Bindable HyperDash { get; } diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs index 1a37136f53..f8a71cbec9 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; +using osu.Framework.Utils; using osu.Game.Rulesets.Catch.Objects; using osuTK; using osuTK.Graphics; @@ -18,46 +19,53 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon { private Container stabilisedPieceContainer = null!; - protected override Drawable BorderPiece => stabilisedPieceContainer; + private Drawable fadeContent = null!; [BackgroundDependencyLoader] private void load() { - AddInternal(stabilisedPieceContainer = new Container + AddInternal(fadeContent = new Container { RelativeSizeAxes = Axes.Both, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, Children = new Drawable[] { - new Circle + stabilisedPieceContainer = new Container { - Colour = Color4.White.Opacity(0.4f), + RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, - Blending = BlendingParameters.Additive, - Size = new Vector2(8), - Scale = new Vector2(30, 1), - }, - new Box - { - Colour = ColourInfo.GradientHorizontal(Color4.White.Opacity(0), Color4.White), - RelativeSizeAxes = Axes.X, - Blending = BlendingParameters.Additive, - Anchor = Anchor.Centre, - Origin = Anchor.CentreRight, - Width = 1.6f, - Height = 2, - }, - new Circle - { - Colour = ColourInfo.GradientHorizontal(Color4.White, Color4.White.Opacity(0)), - RelativeSizeAxes = Axes.X, - Blending = BlendingParameters.Additive, - Anchor = Anchor.Centre, - Origin = Anchor.CentreLeft, - Width = 1.6f, - Height = 2, + Children = new Drawable[] + { + new Circle + { + Colour = Color4.White.Opacity(0.4f), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Blending = BlendingParameters.Additive, + Size = new Vector2(8), + Scale = new Vector2(25, 1), + }, + new Box + { + Colour = ColourInfo.GradientHorizontal(Color4.White.Opacity(0), Color4.White.Opacity(0.8f)), + RelativeSizeAxes = Axes.X, + Blending = BlendingParameters.Additive, + Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + Width = 1.6f, + Height = 2, + }, + new Circle + { + Colour = ColourInfo.GradientHorizontal(Color4.White.Opacity(0.8f), Color4.White.Opacity(0)), + RelativeSizeAxes = Axes.X, + Blending = BlendingParameters.Additive, + Anchor = Anchor.Centre, + Origin = Anchor.CentreLeft, + Width = 1.6f, + Height = 2, + }, + } }, new Circle { @@ -88,10 +96,27 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon { base.Update(); - float scale = 0.5f + 0.5f * (1 / (ObjectState.DisplaySize.X / (CatchHitObject.OBJECT_RADIUS * 2))); + const float parent_scale_application = 0.4f; + + // relative to time on screen + const float lens_flare_start = 0.3f; + const float lens_flare_end = 0.3f; + + // Undo some of the parent scale being applied to make the lens flare feel a bit better.. + float scale = parent_scale_application + (1 - parent_scale_application) * (1 / (ObjectState.DisplaySize.X / (CatchHitObject.OBJECT_RADIUS * 2))); stabilisedPieceContainer.Rotation = -ObjectState.DisplayRotation; - stabilisedPieceContainer.Scale = new Vector2(scale); + stabilisedPieceContainer.Scale = new Vector2(scale, 1); + + double duration = ObjectState.HitObject.StartTime - ObjectState.DisplayStartTime; + + fadeContent.Alpha = MathHelper.Clamp( + Interpolation.ValueAt( + Time.Current, 1f, 0f, + ObjectState.DisplayStartTime + duration * lens_flare_start, + ObjectState.DisplayStartTime + duration * lens_flare_end, + Easing.OutQuint + ), 0, 1); } } } From 0c25658805458f016f2a2ca64729134a2b00b400 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2022 21:58:38 +0900 Subject: [PATCH 0300/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 5d6c32cea8..b691751f13 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 5d1a834b0e..9dd0d18817 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index bf218f856a..6dce938ebf 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From 21d68bfb84dfeaf6605623b2700cec2faa5ed147 Mon Sep 17 00:00:00 2001 From: "D.Headley" Date: Fri, 28 Oct 2022 16:40:21 +0200 Subject: [PATCH 0301/2991] Delete unused button --- .../Screens/Edit/Components/CircularButton.cs | 28 ------------------- 1 file changed, 28 deletions(-) delete mode 100644 osu.Game/Screens/Edit/Components/CircularButton.cs diff --git a/osu.Game/Screens/Edit/Components/CircularButton.cs b/osu.Game/Screens/Edit/Components/CircularButton.cs deleted file mode 100644 index 74e4162102..0000000000 --- a/osu.Game/Screens/Edit/Components/CircularButton.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -#nullable disable - -using osu.Game.Graphics.UserInterface; -using osuTK; - -namespace osu.Game.Screens.Edit.Components -{ - public class CircularButton : OsuButton - { - private const float width = 125; - private const float height = 30; - - public CircularButton() - { - Size = new Vector2(width, height); - } - - protected override void Update() - { - base.Update(); - Content.CornerRadius = DrawHeight / 2f; - Content.CornerExponent = 2; - } - } -} From 19e0b9085c473a2470e86b167d1e2ae05c28ac91 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 29 Oct 2022 00:24:33 +0900 Subject: [PATCH 0302/2991] Remove redundant parameters --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs | 2 +- osu.Game.Tests/Collections/IO/ImportCollectionsTest.cs | 2 +- .../NonVisual/CustomTourneyDirectoryTest.cs | 2 +- osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs index de6ca7dd38..a41ed17d78 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs @@ -80,7 +80,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { // For the same reasons as above w.r.t rewinding, we shouldn't propagate to children here either. // ReSharper disable once RedundantArgumentDefaultValue - removing the "redundant" default value triggers BaseMethodCallWithDefaultParameter - base.ApplyTransformsAt(time, false); + base.ApplyTransformsAt(time); } private bool tracking; diff --git a/osu.Game.Tests/Collections/IO/ImportCollectionsTest.cs b/osu.Game.Tests/Collections/IO/ImportCollectionsTest.cs index 604b87dc4c..9079ecdc48 100644 --- a/osu.Game.Tests/Collections/IO/ImportCollectionsTest.cs +++ b/osu.Game.Tests/Collections/IO/ImportCollectionsTest.cs @@ -188,7 +188,7 @@ namespace osu.Game.Tests.Collections.IO } // Name matches the automatically chosen name from `CleanRunHeadlessGameHost` above, so we end up using the same storage location. - using (HeadlessGameHost host = new TestRunHeadlessGameHost(firstRunName, null)) + using (HeadlessGameHost host = new TestRunHeadlessGameHost(firstRunName)) { try { diff --git a/osu.Game.Tournament.Tests/NonVisual/CustomTourneyDirectoryTest.cs b/osu.Game.Tournament.Tests/NonVisual/CustomTourneyDirectoryTest.cs index f778e67f58..45dffdc94a 100644 --- a/osu.Game.Tournament.Tests/NonVisual/CustomTourneyDirectoryTest.cs +++ b/osu.Game.Tournament.Tests/NonVisual/CustomTourneyDirectoryTest.cs @@ -39,7 +39,7 @@ namespace osu.Game.Tournament.Tests.NonVisual [Test] public void TestCustomDirectory() { - using (HeadlessGameHost host = new TestRunHeadlessGameHost(nameof(TestCustomDirectory), null)) // don't use clean run as we are writing a config file. + using (HeadlessGameHost host = new TestRunHeadlessGameHost(nameof(TestCustomDirectory))) // don't use clean run as we are writing a config file. { string osuDesktopStorage = Path.Combine(host.UserStoragePaths.First(), nameof(TestCustomDirectory)); const string custom_tournament = "custom"; diff --git a/osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs b/osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs index 1bbbcc3661..ca6354cb48 100644 --- a/osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs +++ b/osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tournament.Tests.NonVisual public void CheckIPCLocation() { // don't use clean run because files are being written before osu! launches. - using (var host = new TestRunHeadlessGameHost(nameof(CheckIPCLocation), null)) + using (var host = new TestRunHeadlessGameHost(nameof(CheckIPCLocation))) { string basePath = Path.Combine(host.UserStoragePaths.First(), nameof(CheckIPCLocation)); From 295c40581b766b14d2fe9d453a396608aeb142d7 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 28 Oct 2022 20:18:11 +0300 Subject: [PATCH 0303/2991] Add a global popover container --- osu.Game/OsuGameBase.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 7d9ed7bf3e..2e2f6f0832 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -18,6 +18,7 @@ using osu.Framework.Development; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Textures; using osu.Framework.Input; using osu.Framework.Input.Handlers; @@ -350,9 +351,13 @@ namespace osu.Game (GlobalCursorDisplay = new GlobalCursorDisplay { RelativeSizeAxes = Axes.Both - }).WithChild(content = new OsuTooltipContainer(GlobalCursorDisplay.MenuCursor) + }).WithChild(new OsuTooltipContainer(GlobalCursorDisplay.MenuCursor) { - RelativeSizeAxes = Axes.Both + RelativeSizeAxes = Axes.Both, + Child = content = new PopoverContainer + { + RelativeSizeAxes = Axes.Both, + } }), // to avoid positional input being blocked by children, ensure the GlobalActionContainer is above everything. globalBindings = new GlobalActionContainer(this) From 9df96aab38fa7e83ef2055af3c96189e24d7fb50 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 28 Oct 2022 22:17:45 +0300 Subject: [PATCH 0304/2991] Remove local popover containers --- osu.Game/Overlays/BeatmapSetOverlay.cs | 24 +++++++------------ .../Overlays/Changelog/ChangelogContent.cs | 17 +++---------- 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 904fd6ead6..207dc91ca5 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -10,7 +10,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.BeatmapSet; @@ -45,25 +44,20 @@ namespace osu.Game.Overlays Info info; CommentsSection comments; - Child = new PopoverContainer + Child = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Child = new FillFlowContainer + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), - Children = new Drawable[] + info = new Info(), + new ScoresContainer { - info = new Info(), - new ScoresContainer - { - Beatmap = { BindTarget = Header.HeaderContent.Picker.Beatmap } - }, - comments = new CommentsSection() - } + Beatmap = { BindTarget = Header.HeaderContent.Picker.Beatmap } + }, + comments = new CommentsSection() } }; diff --git a/osu.Game/Overlays/Changelog/ChangelogContent.cs b/osu.Game/Overlays/Changelog/ChangelogContent.cs index 2b54df7226..e04133f2e4 100644 --- a/osu.Game/Overlays/Changelog/ChangelogContent.cs +++ b/osu.Game/Overlays/Changelog/ChangelogContent.cs @@ -1,35 +1,24 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Online.API.Requests.Responses; using System; -using osu.Framework.Graphics.Cursor; namespace osu.Game.Overlays.Changelog { - public class ChangelogContent : PopoverContainer + public class ChangelogContent : FillFlowContainer { - public Action BuildSelected; + public Action? BuildSelected; public void SelectBuild(APIChangelogBuild build) => BuildSelected?.Invoke(build); - protected override Container Content { get; } - public ChangelogContent() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - - base.Content.Add(Content = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical - }); + Direction = FillDirection.Vertical; } } } From a985151e3173f5605d49288bccf4b5346fb32d3b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 29 Oct 2022 18:06:25 +0900 Subject: [PATCH 0305/2991] Fix incorrect constant --- osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs index f8a71cbec9..9a657c9216 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs @@ -100,7 +100,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon // relative to time on screen const float lens_flare_start = 0.3f; - const float lens_flare_end = 0.3f; + const float lens_flare_end = 0.8f; // Undo some of the parent scale being applied to make the lens flare feel a bit better.. float scale = parent_scale_application + (1 - parent_scale_application) * (1 / (ObjectState.DisplaySize.X / (CatchHitObject.OBJECT_RADIUS * 2))); From 8c9250285f0fe2188a56451b67c7643b81b49dbf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 29 Oct 2022 18:09:27 +0900 Subject: [PATCH 0306/2991] Revert incorrect removal default value (causing a new warning) --- .../Objects/Drawables/DrawableSliderBall.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs index a41ed17d78..9966ad3a90 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs @@ -79,8 +79,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public override void ApplyTransformsAt(double time, bool propagateChildren = false) { // For the same reasons as above w.r.t rewinding, we shouldn't propagate to children here either. - // ReSharper disable once RedundantArgumentDefaultValue - removing the "redundant" default value triggers BaseMethodCallWithDefaultParameter - base.ApplyTransformsAt(time); + + // ReSharper disable once RedundantArgumentDefaultValue + base.ApplyTransformsAt(time, false); } private bool tracking; From d56786b5ff051ab358b5e0b4c180fdc7743b247d Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 29 Oct 2022 15:25:16 -0700 Subject: [PATCH 0307/2991] Fix toolbar visual bug when toggling clock displays --- osu.Game/Overlays/Toolbar/Toolbar.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 82fa20aa9c..9d0f43c45a 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -141,6 +141,8 @@ namespace osu.Game.Overlays.Toolbar Name = "Right buttons", RelativeSizeAxes = Axes.Y, AutoSizeAxes = Axes.X, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, Children = new Drawable[] { new Box From 24c27e62f6e9a45774b78cf44cbe0b9df21b10d0 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 30 Oct 2022 16:25:15 +0800 Subject: [PATCH 0308/2991] Remove nullable disable annotation in the issue and issue template-related class. --- osu.Game/Rulesets/Edit/Checks/Components/CheckCategory.cs | 2 -- osu.Game/Rulesets/Edit/Checks/Components/CheckMetadata.cs | 2 -- osu.Game/Rulesets/Edit/Checks/Components/ICheck.cs | 2 -- osu.Game/Rulesets/Edit/Checks/Components/Issue.cs | 2 -- osu.Game/Rulesets/Edit/Checks/Components/IssueTemplate.cs | 2 -- osu.Game/Rulesets/Edit/Checks/Components/IssueType.cs | 2 -- 6 files changed, 12 deletions(-) diff --git a/osu.Game/Rulesets/Edit/Checks/Components/CheckCategory.cs b/osu.Game/Rulesets/Edit/Checks/Components/CheckCategory.cs index 3e2150fe0b..ae943cfda9 100644 --- a/osu.Game/Rulesets/Edit/Checks/Components/CheckCategory.cs +++ b/osu.Game/Rulesets/Edit/Checks/Components/CheckCategory.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Edit.Checks.Components { /// diff --git a/osu.Game/Rulesets/Edit/Checks/Components/CheckMetadata.cs b/osu.Game/Rulesets/Edit/Checks/Components/CheckMetadata.cs index 5c9021ba61..cebb2f5455 100644 --- a/osu.Game/Rulesets/Edit/Checks/Components/CheckMetadata.cs +++ b/osu.Game/Rulesets/Edit/Checks/Components/CheckMetadata.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Edit.Checks.Components { public class CheckMetadata diff --git a/osu.Game/Rulesets/Edit/Checks/Components/ICheck.cs b/osu.Game/Rulesets/Edit/Checks/Components/ICheck.cs index 333ec0a810..141de55f1d 100644 --- a/osu.Game/Rulesets/Edit/Checks/Components/ICheck.cs +++ b/osu.Game/Rulesets/Edit/Checks/Components/ICheck.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; namespace osu.Game.Rulesets.Edit.Checks.Components diff --git a/osu.Game/Rulesets/Edit/Checks/Components/Issue.cs b/osu.Game/Rulesets/Edit/Checks/Components/Issue.cs index b3f227f364..2bc9930e8f 100644 --- a/osu.Game/Rulesets/Edit/Checks/Components/Issue.cs +++ b/osu.Game/Rulesets/Edit/Checks/Components/Issue.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; diff --git a/osu.Game/Rulesets/Edit/Checks/Components/IssueTemplate.cs b/osu.Game/Rulesets/Edit/Checks/Components/IssueTemplate.cs index 9101d83fa7..97df79ecd8 100644 --- a/osu.Game/Rulesets/Edit/Checks/Components/IssueTemplate.cs +++ b/osu.Game/Rulesets/Edit/Checks/Components/IssueTemplate.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using Humanizer; using osu.Framework.Graphics; using osuTK.Graphics; diff --git a/osu.Game/Rulesets/Edit/Checks/Components/IssueType.cs b/osu.Game/Rulesets/Edit/Checks/Components/IssueType.cs index a957cbc296..1f708209fe 100644 --- a/osu.Game/Rulesets/Edit/Checks/Components/IssueType.cs +++ b/osu.Game/Rulesets/Edit/Checks/Components/IssueType.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Edit.Checks.Components { /// From db48a57fa7f52be8acee66942e92c118b6a23eb8 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 30 Oct 2022 16:28:49 +0800 Subject: [PATCH 0309/2991] Remove nullable disable annotation in some checks class. --- osu.Game/Rulesets/Edit/Checks/CheckAudioInVideo.cs | 4 +--- osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs | 2 -- osu.Game/Rulesets/Edit/Checks/CheckAudioQuality.cs | 4 +--- osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs | 2 -- osu.Game/Rulesets/Edit/Checks/CheckBackgroundQuality.cs | 6 ++---- osu.Game/Rulesets/Edit/Checks/CheckConcurrentObjects.cs | 2 -- osu.Game/Rulesets/Edit/Checks/CheckFewHitsounds.cs | 2 -- osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs | 4 +--- osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs | 4 +--- osu.Game/Rulesets/Edit/Checks/CheckTooShortAudioFiles.cs | 2 -- osu.Game/Rulesets/Edit/Checks/CheckUnsnappedObjects.cs | 2 -- osu.Game/Rulesets/Edit/Checks/CheckZeroByteFiles.cs | 2 -- osu.Game/Rulesets/Edit/Checks/CheckZeroLengthObjects.cs | 2 -- 13 files changed, 6 insertions(+), 32 deletions(-) diff --git a/osu.Game/Rulesets/Edit/Checks/CheckAudioInVideo.cs b/osu.Game/Rulesets/Edit/Checks/CheckAudioInVideo.cs index a66c00d78b..f712a7867d 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckAudioInVideo.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckAudioInVideo.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.IO; using osu.Game.Beatmaps; @@ -45,7 +43,7 @@ namespace osu.Game.Rulesets.Edit.Checks foreach (string filename in videoPaths) { - string storagePath = beatmapSet?.GetPathForFile(filename); + string? storagePath = beatmapSet?.GetPathForFile(filename); if (storagePath == null) { diff --git a/osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs b/osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs index fa3e114c55..94c48c300a 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit.Checks.Components; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckAudioQuality.cs b/osu.Game/Rulesets/Edit/Checks/CheckAudioQuality.cs index 96254ba6fd..daa33fb0da 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckAudioQuality.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckAudioQuality.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Rulesets.Edit.Checks.Components; @@ -29,7 +27,7 @@ namespace osu.Game.Rulesets.Edit.Checks public IEnumerable Run(BeatmapVerifierContext context) { - string audioFile = context.Beatmap.Metadata?.AudioFile; + string? audioFile = context.Beatmap.Metadata?.AudioFile; if (string.IsNullOrEmpty(audioFile)) yield break; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs b/osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs index 96840fd344..067800b409 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit.Checks.Components; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckBackgroundQuality.cs b/osu.Game/Rulesets/Edit/Checks/CheckBackgroundQuality.cs index be0c4501e7..23fa28e7bc 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckBackgroundQuality.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckBackgroundQuality.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.IO; using osu.Game.Beatmaps; @@ -35,7 +33,7 @@ namespace osu.Game.Rulesets.Edit.Checks public IEnumerable Run(BeatmapVerifierContext context) { - string backgroundFile = context.Beatmap.Metadata?.BackgroundFile; + string? backgroundFile = context.Beatmap.Metadata?.BackgroundFile; if (backgroundFile == null) yield break; @@ -51,7 +49,7 @@ namespace osu.Game.Rulesets.Edit.Checks else if (texture.Width < low_width || texture.Height < low_height) yield return new IssueTemplateLowResolution(this).Create(texture.Width, texture.Height); - string storagePath = context.Beatmap.BeatmapInfo.BeatmapSet?.GetPathForFile(backgroundFile); + string? storagePath = context.Beatmap.BeatmapInfo.BeatmapSet?.GetPathForFile(backgroundFile); using (Stream stream = context.WorkingBeatmap.GetStream(storagePath)) { diff --git a/osu.Game/Rulesets/Edit/Checks/CheckConcurrentObjects.cs b/osu.Game/Rulesets/Edit/Checks/CheckConcurrentObjects.cs index 02579b675d..ba5fbcf58d 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckConcurrentObjects.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckConcurrentObjects.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Rulesets.Edit.Checks.Components; using osu.Game.Rulesets.Objects; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckFewHitsounds.cs b/osu.Game/Rulesets/Edit/Checks/CheckFewHitsounds.cs index b25abb0cfc..3358e81d5f 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckFewHitsounds.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckFewHitsounds.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Game.Audio; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs b/osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs index 67d480c28c..6b256d025a 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit.Checks.Components; @@ -35,7 +33,7 @@ namespace osu.Game.Rulesets.Edit.Checks } // If the file is set, also make sure it still exists. - string storagePath = context.Beatmap.BeatmapInfo.BeatmapSet?.GetPathForFile(filename); + string? storagePath = context.Beatmap.BeatmapInfo.BeatmapSet?.GetPathForFile(filename); if (storagePath != null) yield break; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs b/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs index 00b1ca9dc9..d755b5bba5 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -59,7 +57,7 @@ namespace osu.Game.Rulesets.Edit.Checks } } - private IEnumerable getVolumeIssues(HitObject hitObject, HitObject sampledHitObject = null) + private IEnumerable getVolumeIssues(HitObject hitObject, HitObject? sampledHitObject = null) { sampledHitObject ??= hitObject; if (!sampledHitObject.Samples.Any()) diff --git a/osu.Game/Rulesets/Edit/Checks/CheckTooShortAudioFiles.cs b/osu.Game/Rulesets/Edit/Checks/CheckTooShortAudioFiles.cs index 2a222aece0..1c2ea36948 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckTooShortAudioFiles.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckTooShortAudioFiles.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.IO; using System.Linq; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckUnsnappedObjects.cs b/osu.Game/Rulesets/Edit/Checks/CheckUnsnappedObjects.cs index a3c52cf547..ded1bb54ca 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckUnsnappedObjects.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckUnsnappedObjects.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using osu.Game.Rulesets.Edit.Checks.Components; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckZeroByteFiles.cs b/osu.Game/Rulesets/Edit/Checks/CheckZeroByteFiles.cs index 987711188e..75cb08002f 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckZeroByteFiles.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckZeroByteFiles.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.IO; using osu.Game.Extensions; diff --git a/osu.Game/Rulesets/Edit/Checks/CheckZeroLengthObjects.cs b/osu.Game/Rulesets/Edit/Checks/CheckZeroLengthObjects.cs index 3b30fab934..b9be94736b 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckZeroLengthObjects.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckZeroLengthObjects.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Rulesets.Edit.Checks.Components; using osu.Game.Rulesets.Objects; From 505ec800da7b55876099ceb63548d1428da51c7e Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 30 Oct 2022 16:29:54 +0800 Subject: [PATCH 0310/2991] File name should be nullable. --- osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs | 2 +- osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs | 2 +- osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs b/osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs index 94c48c300a..e922ddf023 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckAudioPresence.cs @@ -10,6 +10,6 @@ namespace osu.Game.Rulesets.Edit.Checks { protected override CheckCategory Category => CheckCategory.Audio; protected override string TypeOfFile => "audio"; - protected override string GetFilename(IBeatmap beatmap) => beatmap.Metadata?.AudioFile; + protected override string? GetFilename(IBeatmap beatmap) => beatmap.Metadata?.AudioFile; } } diff --git a/osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs b/osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs index 067800b409..4ca93a9807 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckBackgroundPresence.cs @@ -10,6 +10,6 @@ namespace osu.Game.Rulesets.Edit.Checks { protected override CheckCategory Category => CheckCategory.Resources; protected override string TypeOfFile => "background"; - protected override string GetFilename(IBeatmap beatmap) => beatmap.Metadata?.BackgroundFile; + protected override string? GetFilename(IBeatmap beatmap) => beatmap.Metadata?.BackgroundFile; } } diff --git a/osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs b/osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs index 6b256d025a..9a921ba808 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckFilePresence.cs @@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Edit.Checks { protected abstract CheckCategory Category { get; } protected abstract string TypeOfFile { get; } - protected abstract string GetFilename(IBeatmap beatmap); + protected abstract string? GetFilename(IBeatmap beatmap); public CheckMetadata Metadata => new CheckMetadata(Category, $"Missing {TypeOfFile}"); @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Edit.Checks public IEnumerable Run(BeatmapVerifierContext context) { - string filename = GetFilename(context.Beatmap); + string? filename = GetFilename(context.Beatmap); if (string.IsNullOrEmpty(filename)) { From a1a9238bd161d553ece76851b62204c653f3c0d8 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 30 Oct 2022 16:31:07 +0800 Subject: [PATCH 0311/2991] Use empty string instead of null because issue template not accept null. --- osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs b/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs index d755b5bba5..5b59a81f91 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs @@ -72,7 +72,7 @@ namespace osu.Game.Rulesets.Edit.Checks if (edgeType == EdgeType.None) yield break; - string postfix = hitObject is IHasDuration ? edgeType.ToString().ToLowerInvariant() : null; + string postfix = hitObject is IHasDuration ? edgeType.ToString().ToLowerInvariant() : string.Empty; if (maxVolume <= muted_threshold) { From 4c9c65856ca117dd34122e4987c3c0570902d077 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 30 Oct 2022 16:51:56 +0800 Subject: [PATCH 0312/2991] Remove the nullable disable annotation in the testing beatmap and mark some of the properties as nullable. This class will be used in some check test cases. --- osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs index 3d7ebad831..7d2aa99dbe 100644 --- a/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestWorkingBeatmap.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.IO; using osu.Framework.Audio; using osu.Framework.Audio.Track; @@ -16,7 +14,7 @@ namespace osu.Game.Tests.Beatmaps public class TestWorkingBeatmap : WorkingBeatmap { private readonly IBeatmap beatmap; - private readonly Storyboard storyboard; + private readonly Storyboard? storyboard; /// /// Create an instance which provides the when requested. @@ -24,7 +22,7 @@ namespace osu.Game.Tests.Beatmaps /// The beatmap. /// An optional storyboard. /// The . - public TestWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null, AudioManager audioManager = null) + public TestWorkingBeatmap(IBeatmap beatmap, Storyboard? storyboard = null, AudioManager? audioManager = null) : base(beatmap.BeatmapInfo, audioManager) { this.beatmap = beatmap; @@ -37,12 +35,12 @@ namespace osu.Game.Tests.Beatmaps protected override Storyboard GetStoryboard() => storyboard ?? base.GetStoryboard(); - protected internal override ISkin GetSkin() => null; + protected internal override ISkin? GetSkin() => null; - public override Stream GetStream(string storagePath) => null; + public override Stream? GetStream(string storagePath) => null; - protected override Texture GetBackground() => null; + protected override Texture? GetBackground() => null; - protected override Track GetBeatmapTrack() => null; + protected override Track? GetBeatmapTrack() => null; } } From 6ce3841686bbbd6d2630e13d37ae1f1419c1e88b Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 30 Oct 2022 16:36:22 +0800 Subject: [PATCH 0313/2991] Remove nullable disable annotation in the test case. --- .../Editing/Checks/CheckAudioInVideoTest.cs | 6 ++---- .../Editing/Checks/CheckAudioQualityTest.cs | 6 ++---- .../Editing/Checks/CheckBackgroundQualityTest.cs | 11 ++++------- .../Editing/Checks/CheckConcurrentObjectsTest.cs | 4 +--- .../Editing/Checks/CheckFewHitsoundsTest.cs | 8 +++----- .../Editing/Checks/CheckFilePresenceTest.cs | 6 ++---- .../Editing/Checks/CheckMutedObjectsTest.cs | 6 ++---- osu.Game.Tests/Editing/Checks/CheckTestHelpers.cs | 2 -- .../Editing/Checks/CheckTooShortAudioFilesTest.cs | 6 ++---- .../Editing/Checks/CheckUnsnappedObjectsTest.cs | 6 ++---- .../Editing/Checks/CheckZeroByteFilesTest.cs | 6 ++---- .../Editing/Checks/CheckZeroLengthObjectsTest.cs | 4 +--- .../Editing/Checks/MockNestableHitObject.cs | 2 -- 13 files changed, 23 insertions(+), 50 deletions(-) diff --git a/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs b/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs index 947e884494..9f253527fc 100644 --- a/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.IO; using System.Linq; using Moq; @@ -20,8 +18,8 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckAudioInVideoTest { - private CheckAudioInVideo check; - private IBeatmap beatmap; + private CheckAudioInVideo check = null!; + private IBeatmap beatmap = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs index 50e6087526..3a2cdaf233 100644 --- a/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using Moq; using NUnit.Framework; @@ -19,8 +17,8 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckAudioQualityTest { - private CheckAudioQuality check; - private IBeatmap beatmap; + private CheckAudioQuality check = null!; + private IBeatmap beatmap = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs index f91e83a556..d0dffb8fad 100644 --- a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.IO; using System.Linq; -using JetBrains.Annotations; using Moq; using NUnit.Framework; using osu.Framework.Graphics.Rendering.Dummy; @@ -21,8 +18,8 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckBackgroundQualityTest { - private CheckBackgroundQuality check; - private IBeatmap beatmap; + private CheckBackgroundQuality check = null!; + private IBeatmap beatmap = null!; [SetUp] public void Setup() @@ -118,7 +115,7 @@ namespace osu.Game.Tests.Editing.Checks stream.Verify(x => x.Close(), Times.Once()); } - private BeatmapVerifierContext getContext(Texture background, [CanBeNull] Stream stream = null) + private BeatmapVerifierContext getContext(Texture background, Stream? stream = null) { return new BeatmapVerifierContext(beatmap, getMockWorkingBeatmap(background, stream).Object); } @@ -128,7 +125,7 @@ namespace osu.Game.Tests.Editing.Checks /// /// The texture of the background. /// The stream representing the background file. - private Mock getMockWorkingBeatmap(Texture background, [CanBeNull] Stream stream = null) + private Mock getMockWorkingBeatmap(Texture background, Stream? stream = null) { stream ??= new MemoryStream(new byte[1024 * 1024]); diff --git a/osu.Game.Tests/Editing/Checks/CheckConcurrentObjectsTest.cs b/osu.Game.Tests/Editing/Checks/CheckConcurrentObjectsTest.cs index 9c1dd2c1e8..b5c6568583 100644 --- a/osu.Game.Tests/Editing/Checks/CheckConcurrentObjectsTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckConcurrentObjectsTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using Moq; @@ -21,7 +19,7 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckConcurrentObjectsTest { - private CheckConcurrentObjects check; + private CheckConcurrentObjects check = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/CheckFewHitsoundsTest.cs b/osu.Game.Tests/Editing/Checks/CheckFewHitsoundsTest.cs index 82bb2e59c9..01781b98ad 100644 --- a/osu.Game.Tests/Editing/Checks/CheckFewHitsoundsTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckFewHitsoundsTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -20,10 +18,10 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckFewHitsoundsTest { - private CheckFewHitsounds check; + private CheckFewHitsounds check = null!; - private List notHitsounded; - private List hitsounded; + private List notHitsounded = null!; + private List hitsounded = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/CheckFilePresenceTest.cs b/osu.Game.Tests/Editing/Checks/CheckFilePresenceTest.cs index 2f18720a5b..89bb2f9396 100644 --- a/osu.Game.Tests/Editing/Checks/CheckFilePresenceTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckFilePresenceTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using NUnit.Framework; using osu.Game.Beatmaps; @@ -16,8 +14,8 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckFilePresenceTest { - private CheckBackgroundPresence check; - private IBeatmap beatmap; + private CheckBackgroundPresence check = null!; + private IBeatmap beatmap = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/CheckMutedObjectsTest.cs b/osu.Game.Tests/Editing/Checks/CheckMutedObjectsTest.cs index 622386405a..1e1c214c30 100644 --- a/osu.Game.Tests/Editing/Checks/CheckMutedObjectsTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckMutedObjectsTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -21,8 +19,8 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckMutedObjectsTest { - private CheckMutedObjects check; - private ControlPointInfo cpi; + private CheckMutedObjects check = null!; + private ControlPointInfo cpi = null!; private const int volume_regular = 50; private const int volume_low = 15; diff --git a/osu.Game.Tests/Editing/Checks/CheckTestHelpers.cs b/osu.Game.Tests/Editing/Checks/CheckTestHelpers.cs index 405738cd55..9067714ff9 100644 --- a/osu.Game.Tests/Editing/Checks/CheckTestHelpers.cs +++ b/osu.Game.Tests/Editing/Checks/CheckTestHelpers.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Models; namespace osu.Game.Tests.Editing.Checks diff --git a/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs b/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs index 7d33b92dbe..05856de556 100644 --- a/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Diagnostics; using System.IO; using System.Linq; @@ -22,8 +20,8 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckTooShortAudioFilesTest { - private CheckTooShortAudioFiles check; - private IBeatmap beatmap; + private CheckTooShortAudioFiles check = null!; + private IBeatmap beatmap = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/CheckUnsnappedObjectsTest.cs b/osu.Game.Tests/Editing/Checks/CheckUnsnappedObjectsTest.cs index f647bf8d8e..c9335dcda5 100644 --- a/osu.Game.Tests/Editing/Checks/CheckUnsnappedObjectsTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckUnsnappedObjectsTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using Moq; @@ -21,8 +19,8 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckUnsnappedObjectsTest { - private CheckUnsnappedObjects check; - private ControlPointInfo cpi; + private CheckUnsnappedObjects check = null!; + private ControlPointInfo cpi = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs b/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs index 793cc70a3f..5c66e1beaa 100644 --- a/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.IO; using System.Linq; using Moq; @@ -17,8 +15,8 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckZeroByteFilesTest { - private CheckZeroByteFiles check; - private IBeatmap beatmap; + private CheckZeroByteFiles check = null!; + private IBeatmap beatmap = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/CheckZeroLengthObjectsTest.cs b/osu.Game.Tests/Editing/Checks/CheckZeroLengthObjectsTest.cs index 1c1965ab56..648f02839f 100644 --- a/osu.Game.Tests/Editing/Checks/CheckZeroLengthObjectsTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckZeroLengthObjectsTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using Moq; @@ -21,7 +19,7 @@ namespace osu.Game.Tests.Editing.Checks [TestFixture] public class CheckZeroLengthObjectsTest { - private CheckZeroLengthObjects check; + private CheckZeroLengthObjects check = null!; [SetUp] public void Setup() diff --git a/osu.Game.Tests/Editing/Checks/MockNestableHitObject.cs b/osu.Game.Tests/Editing/Checks/MockNestableHitObject.cs index 6c0306d63d..29938839d3 100644 --- a/osu.Game.Tests/Editing/Checks/MockNestableHitObject.cs +++ b/osu.Game.Tests/Editing/Checks/MockNestableHitObject.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Threading; using osu.Game.Rulesets.Objects; From 500bf90a34b1c02fa17255351b0f9582dbf3484e Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 30 Oct 2022 16:58:16 +0800 Subject: [PATCH 0314/2991] Mark as accept the nullable stream. --- osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs | 2 +- osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs | 4 ++-- osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs b/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs index 9f253527fc..9774a8ebb6 100644 --- a/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs @@ -82,7 +82,7 @@ namespace osu.Game.Tests.Editing.Checks Assert.That(issues.Single().Template is CheckAudioInVideo.IssueTemplateMissingFile); } - private BeatmapVerifierContext getContext(Stream resourceStream) + private BeatmapVerifierContext getContext(Stream? resourceStream) { var storyboard = new Storyboard(); var layer = storyboard.GetLayer("Video"); diff --git a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs index d0dffb8fad..5d3fd9cd65 100644 --- a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs @@ -115,7 +115,7 @@ namespace osu.Game.Tests.Editing.Checks stream.Verify(x => x.Close(), Times.Once()); } - private BeatmapVerifierContext getContext(Texture background, Stream? stream = null) + private BeatmapVerifierContext getContext(Texture? background, Stream? stream = null) { return new BeatmapVerifierContext(beatmap, getMockWorkingBeatmap(background, stream).Object); } @@ -125,7 +125,7 @@ namespace osu.Game.Tests.Editing.Checks /// /// The texture of the background. /// The stream representing the background file. - private Mock getMockWorkingBeatmap(Texture background, Stream? stream = null) + private Mock getMockWorkingBeatmap(Texture? background, Stream? stream = null) { stream ??= new MemoryStream(new byte[1024 * 1024]); diff --git a/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs b/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs index 05856de556..4918369460 100644 --- a/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs @@ -107,7 +107,7 @@ namespace osu.Game.Tests.Editing.Checks } } - private BeatmapVerifierContext getContext(Stream resourceStream) + private BeatmapVerifierContext getContext(Stream? resourceStream) { var mockWorkingBeatmap = new Mock(beatmap, null, null); mockWorkingBeatmap.Setup(w => w.GetStream(It.IsAny())).Returns(resourceStream); From c8c76f23513f91f7d8d2ace60487eca351f77444 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 30 Oct 2022 16:55:53 +0800 Subject: [PATCH 0315/2991] Use AsNonNull() because the type does not accept the null case. --- osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs | 3 ++- osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs | 3 ++- osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs index 3a2cdaf233..8e269cbab2 100644 --- a/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs @@ -5,6 +5,7 @@ using System.Linq; using Moq; using NUnit.Framework; using osu.Framework.Audio.Track; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit; @@ -41,7 +42,7 @@ namespace osu.Game.Tests.Editing.Checks var mock = new Mock(); mock.SetupGet(w => w.Beatmap).Returns(beatmap); - mock.SetupGet(w => w.Track).Returns((Track)null); + mock.SetupGet(w => w.Track).Returns(default(Track?).AsNonNull()); Assert.That(check.Run(new BeatmapVerifierContext(beatmap, mock.Object)), Is.Empty); } diff --git a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs index 5d3fd9cd65..1aead6d78c 100644 --- a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using Moq; using NUnit.Framework; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.Rendering.Dummy; using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; @@ -131,7 +132,7 @@ namespace osu.Game.Tests.Editing.Checks var mock = new Mock(); mock.SetupGet(w => w.Beatmap).Returns(beatmap); - mock.SetupGet(w => w.Background).Returns(background); + mock.SetupGet(w => w.Background).Returns(background.AsNonNull()); mock.Setup(w => w.GetStream(It.IsAny())).Returns(stream); return mock; diff --git a/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs b/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs index 5c66e1beaa..7c2b1690af 100644 --- a/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using Moq; using NUnit.Framework; +using osu.Framework.Extensions.ObjectExtensions; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Checks; @@ -72,7 +73,7 @@ namespace osu.Game.Tests.Editing.Checks private BeatmapVerifierContext getContextMissing() { var mockWorkingBeatmap = new Mock(); - mockWorkingBeatmap.Setup(w => w.GetStream(It.IsAny())).Returns((Stream)null); + mockWorkingBeatmap.Setup(w => w.GetStream(It.IsAny())).Returns(default(Stream?).AsNonNull()); return new BeatmapVerifierContext(beatmap, mockWorkingBeatmap.Object); } From a753369d3e3096ef75087abdf34ff965abcb7a59 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sun, 30 Oct 2022 17:21:50 +0800 Subject: [PATCH 0316/2991] Reuse function `TimeAtPosition()` and `PositionAtTime()`. --- .../Screens/Edit/Compose/Components/Timeline/Timeline.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index a73ada76f5..3a93499527 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -250,7 +250,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private void seekTrackToCurrent() { - double target = Current / Content.DrawWidth * editorClock.TrackLength; + double target = TimeAtPosition(Current); editorClock.Seek(Math.Min(editorClock.TrackLength, target)); } @@ -264,7 +264,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline if (handlingDragInput) editorClock.Stop(); - ScrollTo((float)(editorClock.CurrentTime / editorClock.TrackLength) * Content.DrawWidth, false); + float position = PositionAtTime(editorClock.CurrentTime); + ScrollTo(position, false); } protected override bool OnMouseDown(MouseDownEvent e) From f5e11343c28eebb15a0d6d0916b214a0df7dabbb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 30 Oct 2022 21:24:58 +0900 Subject: [PATCH 0317/2991] Apply nullability to HUD test scene --- .../Visual/Gameplay/TestSceneHUDOverlay.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index a984f508ea..325839a6c9 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -1,12 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; @@ -26,9 +25,9 @@ namespace osu.Game.Tests.Visual.Gameplay { public class TestSceneHUDOverlay : OsuManualInputManagerTestScene { - private OsuConfigManager localConfig; + private OsuConfigManager localConfig = null!; - private HUDOverlay hudOverlay; + private HUDOverlay hudOverlay = null!; [Cached] private ScoreProcessor scoreProcessor = new ScoreProcessor(new OsuRuleset()); @@ -220,7 +219,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("skinnable components loaded", () => hudOverlay.ChildrenOfType().Single().ComponentsLoaded); } - private void createNew(Action action = null) + private void createNew(Action? action = null) { AddStep("create overlay", () => { @@ -239,7 +238,9 @@ namespace osu.Game.Tests.Visual.Gameplay protected override void Dispose(bool isDisposing) { - localConfig?.Dispose(); + if (localConfig.IsNotNull()) + localConfig.Dispose(); + base.Dispose(isDisposing); } } From 8399261c77a53ffb66672d61af7de85440a1a344 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 30 Oct 2022 21:38:31 +0900 Subject: [PATCH 0318/2991] Add failing test showing hold for menu not working when HUD is hidden --- .../Visual/Gameplay/TestSceneHUDOverlay.cs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 325839a6c9..75510fa822 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Framework.Timing; using osu.Game.Configuration; +using osu.Game.Graphics.Containers; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Scoring; @@ -148,6 +149,41 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("key counters still hidden", () => !keyCounterFlow.IsPresent); } + [Test] + public void TestHoldForMenuDoesWorkWhenHidden() + { + bool activated = false; + + HoldForMenuButton getHoldForMenu() => hudOverlay.ChildrenOfType().Single(); + + createNew(); + + AddStep("bind action", () => + { + activated = false; + + var holdForMenu = getHoldForMenu(); + + holdForMenu.Action += () => activated = true; + }); + + AddStep("set showhud false", () => hudOverlay.ShowHud.Value = false); + AddUntilStep("hidetarget is hidden", () => !hideTarget.IsPresent); + + AddStep("attempt activate", () => + { + InputManager.MoveMouseTo(getHoldForMenu().OfType().Single()); + InputManager.PressButton(MouseButton.Left); + }); + + AddUntilStep("activated", () => activated); + + AddStep("release mouse button", () => + { + InputManager.ReleaseButton(MouseButton.Left); + }); + } + [Test] public void TestInputDoesntWorkWhenHUDHidden() { From 1035b5fb1905b0a07f910f888e8c253582b13e5b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 30 Oct 2022 21:38:45 +0900 Subject: [PATCH 0319/2991] Fix hold to pause button not working when HUD is hidden --- osu.Game/Screens/Play/HUDOverlay.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 7833c2d7fa..2791f5ff8f 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -39,9 +39,16 @@ namespace osu.Game.Screens.Play /// public float BottomScoringElementsHeight { get; private set; } - // HUD uses AlwaysVisible on child components so they can be in an updated state for next display. - // Without blocking input, this would also allow them to be interacted with in such a state. - public override bool PropagatePositionalInputSubTree => ShowHud.Value; + protected override bool ShouldBeConsideredForInput(Drawable child) + { + // HUD uses AlwaysVisible on child components so they can be in an updated state for next display. + // Without blocking input, this would also allow them to be interacted with in such a state. + if (ShowHud.Value) + return base.ShouldBeConsideredForInput(child); + + // hold to quit button should always be interactive. + return child == bottomRightElements; + } public readonly KeyCounterDisplay KeyCounter; public readonly ModDisplay ModDisplay; From 3f17c206d2cea58bbc1f143d74fee22bdddd1f2b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Oct 2022 12:49:50 +0900 Subject: [PATCH 0320/2991] Update `fastlane` and dependencies --- Gemfile.lock | 66 ++++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index cae682ec2b..07ca3542f9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,25 +3,25 @@ GEM specs: CFPropertyList (3.0.5) rexml - addressable (2.8.0) - public_suffix (>= 2.0.2, < 5.0) + addressable (2.8.1) + public_suffix (>= 2.0.2, < 6.0) artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.2.0) - aws-partitions (1.601.0) - aws-sdk-core (3.131.2) + aws-partitions (1.653.0) + aws-sdk-core (3.166.0) aws-eventstream (~> 1, >= 1.0.2) - aws-partitions (~> 1, >= 1.525.0) - aws-sigv4 (~> 1.1) + aws-partitions (~> 1, >= 1.651.0) + aws-sigv4 (~> 1.5) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.57.0) - aws-sdk-core (~> 3, >= 3.127.0) + aws-sdk-kms (1.59.0) + aws-sdk-core (~> 3, >= 3.165.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.114.0) - aws-sdk-core (~> 3, >= 3.127.0) + aws-sdk-s3 (1.117.1) + aws-sdk-core (~> 3, >= 3.165.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.4) - aws-sigv4 (1.5.0) + aws-sigv4 (1.5.2) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) claide (1.1.0) @@ -34,10 +34,10 @@ GEM rake (>= 12.0.0, < 14.0.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - dotenv (2.7.6) + dotenv (2.8.1) emoji_regex (3.2.3) - excon (0.92.3) - faraday (1.10.0) + excon (0.93.1) + faraday (1.10.2) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -66,7 +66,7 @@ GEM faraday_middleware (1.2.0) faraday (~> 1.0) fastimage (2.2.6) - fastlane (2.206.2) + fastlane (2.210.1) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -110,9 +110,9 @@ GEM souyuz (= 0.11.1) fastlane-plugin-xamarin (0.6.3) gh_inspector (1.1.3) - google-apis-androidpublisher_v3 (0.23.0) - google-apis-core (>= 0.6, < 2.a) - google-apis-core (0.6.0) + google-apis-androidpublisher_v3 (0.29.0) + google-apis-core (>= 0.9.0, < 2.a) + google-apis-core (0.9.1) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.16.2, < 2.a) httpclient (>= 2.8.1, < 3.a) @@ -121,27 +121,27 @@ GEM retriable (>= 2.0, < 4.a) rexml webrick - google-apis-iamcredentials_v1 (0.12.0) - google-apis-core (>= 0.6, < 2.a) - google-apis-playcustomapp_v1 (0.9.0) - google-apis-core (>= 0.6, < 2.a) - google-apis-storage_v1 (0.16.0) - google-apis-core (>= 0.6, < 2.a) + google-apis-iamcredentials_v1 (0.15.0) + google-apis-core (>= 0.9.0, < 2.a) + google-apis-playcustomapp_v1 (0.12.0) + google-apis-core (>= 0.9.1, < 2.a) + google-apis-storage_v1 (0.19.0) + google-apis-core (>= 0.9.0, < 2.a) google-cloud-core (1.6.0) google-cloud-env (~> 1.0) google-cloud-errors (~> 1.0) google-cloud-env (1.6.0) faraday (>= 0.17.3, < 3.0) - google-cloud-errors (1.2.0) - google-cloud-storage (1.36.2) + google-cloud-errors (1.3.0) + google-cloud-storage (1.43.0) addressable (~> 2.8) digest-crc (~> 0.4) google-apis-iamcredentials_v1 (~> 0.1) - google-apis-storage_v1 (~> 0.1) + google-apis-storage_v1 (~> 0.19.0) google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) - googleauth (1.2.0) + googleauth (1.3.0) faraday (>= 0.17.3, < 3.a) jwt (>= 1.4, < 3.0) memoist (~> 0.16) @@ -154,22 +154,22 @@ GEM httpclient (2.8.3) jmespath (1.6.1) json (2.6.2) - jwt (2.4.1) + jwt (2.5.0) memoist (0.16.2) mini_magick (4.11.0) mini_mime (1.1.2) - mini_portile2 (2.7.1) + mini_portile2 (2.8.0) multi_json (1.15.0) multipart-post (2.0.0) nanaimo (0.3.0) naturally (2.2.1) - nokogiri (1.13.1) - mini_portile2 (~> 2.7.0) + nokogiri (1.13.9) + mini_portile2 (~> 2.8.0) racc (~> 1.4) optparse (0.1.1) os (1.1.4) plist (3.6.0) - public_suffix (4.0.7) + public_suffix (5.0.0) racc (1.6.0) rake (13.0.6) representable (3.2.0) From 4213abfc46b499db14dd65dedf514f906f73f5c9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Oct 2022 12:55:23 +0900 Subject: [PATCH 0321/2991] Adjust testflight cleanup interval to 30 days Been using this for a while but haven't committed it. --- fastlane/Fastfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index cc5abf5b03..716115e5c6 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -138,10 +138,10 @@ platform :ios do end lane :testflight_prune_dry do - clean_testflight_testers(days_of_inactivity:45, dry_run: true) + clean_testflight_testers(days_of_inactivity:30, dry_run: true) end lane :testflight_prune do - clean_testflight_testers(days_of_inactivity: 45) + clean_testflight_testers(days_of_inactivity: 30) end end From 94dd4045f1ff6d9ac1324720725047df6538a9f7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Oct 2022 15:42:17 +0900 Subject: [PATCH 0322/2991] Remove borrowed framework code --- osu.Game/Rulesets/Objects/BezierConverter.cs | 81 +------------------- 1 file changed, 1 insertion(+), 80 deletions(-) diff --git a/osu.Game/Rulesets/Objects/BezierConverter.cs b/osu.Game/Rulesets/Objects/BezierConverter.cs index 9220993559..9c3ea5cf6e 100644 --- a/osu.Game/Rulesets/Objects/BezierConverter.cs +++ b/osu.Game/Rulesets/Objects/BezierConverter.cs @@ -39,85 +39,6 @@ namespace osu.Game.Rulesets.Objects new[] { new Vector2d(1, 0), new Vector2d(1, 1.2447058f), new Vector2d(-0.8526471f, 2.118367f), new Vector2d(-2.6211002f, 7.854936e-06f), new Vector2d(-0.8526448f, -2.118357f), new Vector2d(1, -1.2447058f), new Vector2d(1, 0) }) }; - #region CircularArcProperties - - //TODO: Get this from osu!framework instead - public readonly struct CircularArcProperties - { - public readonly bool IsValid; - public readonly double ThetaStart; - public readonly double ThetaRange; - public readonly double Direction; - public readonly float Radius; - public readonly Vector2 Centre; - - public double ThetaEnd => ThetaStart + ThetaRange * Direction; - - public CircularArcProperties(double thetaStart, double thetaRange, double direction, float radius, Vector2 centre) - { - IsValid = true; - ThetaStart = thetaStart; - ThetaRange = thetaRange; - Direction = direction; - Radius = radius; - Centre = centre; - } - } - - /// - /// Computes various properties that can be used to approximate the circular arc. - /// - /// Three distinct points on the arc. - private static CircularArcProperties circularArcProperties(ReadOnlySpan controlPoints) - { - Vector2 a = controlPoints[0]; - Vector2 b = controlPoints[1]; - Vector2 c = controlPoints[2]; - - // If we have a degenerate triangle where a side-length is almost zero, then give up and fallback to a more numerically stable method. - if (Precision.AlmostEquals(0, (b.Y - a.Y) * (c.X - a.X) - (b.X - a.X) * (c.Y - a.Y))) - return default; // Implicitly sets `IsValid` to false - - // See: https://en.wikipedia.org/wiki/Circumscribed_circle#Cartesian_coordinates_2 - float d = 2 * (a.X * (b - c).Y + b.X * (c - a).Y + c.X * (a - b).Y); - float aSq = a.LengthSquared; - float bSq = b.LengthSquared; - float cSq = c.LengthSquared; - - Vector2 centre = new Vector2( - aSq * (b - c).Y + bSq * (c - a).Y + cSq * (a - b).Y, - aSq * (c - b).X + bSq * (a - c).X + cSq * (b - a).X) / d; - - Vector2 dA = a - centre; - Vector2 dC = c - centre; - - float r = dA.Length; - - double thetaStart = Math.Atan2(dA.Y, dA.X); - double thetaEnd = Math.Atan2(dC.Y, dC.X); - - while (thetaEnd < thetaStart) - thetaEnd += 2 * Math.PI; - - double dir = 1; - double thetaRange = thetaEnd - thetaStart; - - // Decide in which direction to draw the circle, depending on which side of - // AC B lies. - Vector2 orthoAtoC = c - a; - orthoAtoC = new Vector2(orthoAtoC.Y, -orthoAtoC.X); - - if (Vector2.Dot(orthoAtoC, b - a) < 0) - { - dir = -dir; - thetaRange = 2 * Math.PI - thetaRange; - } - - return new CircularArcProperties(thetaStart, thetaRange, dir, r, centre); - } - - #endregion - public static IEnumerable ConvertToLegacyBezier(IList controlPoints, Vector2 position) { Vector2[] vertices = new Vector2[controlPoints.Count]; @@ -248,7 +169,7 @@ namespace osu.Game.Rulesets.Objects if (controlPoints.Length != 3) return controlPoints.ToArray(); - var pr = circularArcProperties(controlPoints); + var pr = new CircularArcProperties(controlPoints); if (!pr.IsValid) return controlPoints.ToArray(); From e38ba5e4c620d986dbae99c83137f183efd6cc9f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 31 Oct 2022 15:46:57 +0900 Subject: [PATCH 0323/2991] Apply nullability to new test scene --- .../Gameplay/TestSceneBezierConverter.cs | 51 +++++++++++-------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs index c915ae0054..701f30bfd4 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -22,8 +20,9 @@ namespace osu.Game.Tests.Visual.Gameplay private readonly SmoothPath controlPointDrawablePath; private readonly SmoothPath convertedDrawablePath; private readonly SmoothPath convertedControlPointDrawablePath; - private SliderPath path; - private SliderPath convertedPath; + + private SliderPath path = null!; + private SliderPath convertedPath = null!; public TestSceneBezierConverter() { @@ -58,16 +57,20 @@ namespace osu.Game.Tests.Visual.Gameplay Position = new Vector2(100, 300) } }; + + resetPath(); } [SetUp] - public void Setup() => Schedule(() => + public void Setup() => Schedule(resetPath); + + private void resetPath() { path = new SliderPath(); convertedPath = new SliderPath(); path.Version.ValueChanged += getConvertedControlPoints; - }); + } private void getConvertedControlPoints(ValueChangedEvent obj) { @@ -79,26 +82,30 @@ namespace osu.Game.Tests.Visual.Gameplay { base.Update(); - if (path != null) - { - List vertices = new List(); - path.GetPathToProgress(vertices, 0, 1); + List vertices = new List(); - drawablePath.Vertices = vertices; - controlPointDrawablePath.Vertices = path.ControlPoints.Select(o => o.Position).ToList(); - if (controlPointDrawablePath.Vertices.Count > 0) - controlPointDrawablePath.Position = drawablePath.PositionInBoundingBox(drawablePath.Vertices[0]) - controlPointDrawablePath.PositionInBoundingBox(controlPointDrawablePath.Vertices[0]); + path.GetPathToProgress(vertices, 0, 1); + + drawablePath.Vertices = vertices; + controlPointDrawablePath.Vertices = path.ControlPoints.Select(o => o.Position).ToList(); + + if (controlPointDrawablePath.Vertices.Count > 0) + { + controlPointDrawablePath.Position = + drawablePath.PositionInBoundingBox(drawablePath.Vertices[0]) - controlPointDrawablePath.PositionInBoundingBox(controlPointDrawablePath.Vertices[0]); } - if (convertedPath != null) - { - List vertices = new List(); - convertedPath.GetPathToProgress(vertices, 0, 1); + vertices.Clear(); - convertedDrawablePath.Vertices = vertices; - convertedControlPointDrawablePath.Vertices = convertedPath.ControlPoints.Select(o => o.Position).ToList(); - if (convertedControlPointDrawablePath.Vertices.Count > 0) - convertedControlPointDrawablePath.Position = convertedDrawablePath.PositionInBoundingBox(convertedDrawablePath.Vertices[0]) - convertedControlPointDrawablePath.PositionInBoundingBox(convertedControlPointDrawablePath.Vertices[0]); + convertedPath.GetPathToProgress(vertices, 0, 1); + + convertedDrawablePath.Vertices = vertices; + convertedControlPointDrawablePath.Vertices = convertedPath.ControlPoints.Select(o => o.Position).ToList(); + + if (convertedControlPointDrawablePath.Vertices.Count > 0) + { + convertedControlPointDrawablePath.Position = convertedDrawablePath.PositionInBoundingBox(convertedDrawablePath.Vertices[0]) + - convertedControlPointDrawablePath.PositionInBoundingBox(convertedControlPointDrawablePath.Vertices[0]); } } From 414e21c65758beaf70beb0a75aec0edfb2f49407 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Mon, 31 Oct 2022 11:39:14 +0100 Subject: [PATCH 0324/2991] Added xmldoc to public methods --- osu.Game/Rulesets/Objects/BezierConverter.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game/Rulesets/Objects/BezierConverter.cs b/osu.Game/Rulesets/Objects/BezierConverter.cs index 9c3ea5cf6e..1ea79f8fd4 100644 --- a/osu.Game/Rulesets/Objects/BezierConverter.cs +++ b/osu.Game/Rulesets/Objects/BezierConverter.cs @@ -40,6 +40,12 @@ namespace osu.Game.Rulesets.Objects }; public static IEnumerable ConvertToLegacyBezier(IList controlPoints, Vector2 position) + /// + /// Converts a slider path to bezier control point positions compatible with the legacy osu! client. + /// + /// The control points of the path. + /// The offset for the whole path. + /// The list of legacy bezier control point positions. { Vector2[] vertices = new Vector2[controlPoints.Count]; for (int i = 0; i < controlPoints.Count; i++) @@ -90,6 +96,11 @@ namespace osu.Game.Rulesets.Objects return result; } + /// + /// Converts a path of control points to an identical path using only Bezier type control points. + /// + /// The control points of the path. + /// The list of bezier control points. public static List ConvertToModernBezier(IList controlPoints) { Vector2[] vertices = new Vector2[controlPoints.Count]; From 04613038954cf4a977f4e7d91b7e0f3fad2edbce Mon Sep 17 00:00:00 2001 From: OliBomby Date: Mon, 31 Oct 2022 11:39:41 +0100 Subject: [PATCH 0325/2991] Change return type to List --- osu.Game/Rulesets/Objects/BezierConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/BezierConverter.cs b/osu.Game/Rulesets/Objects/BezierConverter.cs index 1ea79f8fd4..ebee36a7db 100644 --- a/osu.Game/Rulesets/Objects/BezierConverter.cs +++ b/osu.Game/Rulesets/Objects/BezierConverter.cs @@ -39,13 +39,13 @@ namespace osu.Game.Rulesets.Objects new[] { new Vector2d(1, 0), new Vector2d(1, 1.2447058f), new Vector2d(-0.8526471f, 2.118367f), new Vector2d(-2.6211002f, 7.854936e-06f), new Vector2d(-0.8526448f, -2.118357f), new Vector2d(1, -1.2447058f), new Vector2d(1, 0) }) }; - public static IEnumerable ConvertToLegacyBezier(IList controlPoints, Vector2 position) /// /// Converts a slider path to bezier control point positions compatible with the legacy osu! client. /// /// The control points of the path. /// The offset for the whole path. /// The list of legacy bezier control point positions. + public static List ConvertToLegacyBezier(IList controlPoints, Vector2 position) { Vector2[] vertices = new Vector2[controlPoints.Count]; for (int i = 0; i < controlPoints.Count; i++) From 706adfb28c290eda95bda8e982e062ad79760c18 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 13:57:34 +0900 Subject: [PATCH 0326/2991] Improve messaging when ruleset load fails --- osu.Game/Rulesets/RulesetStore.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs index fdbcd0ed1e..e2b8cd2c4e 100644 --- a/osu.Game/Rulesets/RulesetStore.cs +++ b/osu.Game/Rulesets/RulesetStore.cs @@ -158,7 +158,7 @@ namespace osu.Game.Rulesets } catch (Exception e) { - LogFailedLoad(assembly.FullName, e); + LogFailedLoad(assembly.GetName().Name.Split('.').Last(), e); } } @@ -168,14 +168,14 @@ namespace osu.Game.Rulesets GC.SuppressFinalize(this); } - protected virtual void Dispose(bool disposing) + protected void Dispose(bool disposing) { AppDomain.CurrentDomain.AssemblyResolve -= resolveRulesetDependencyAssembly; } protected void LogFailedLoad(string name, Exception exception) { - Logger.Log($"Could not load ruleset {name}. Please check for an update from the developer.", level: LogLevel.Error); + Logger.Log($"Could not load ruleset \"{name}\". Please check for an update from the developer.", level: LogLevel.Error); Logger.Log($"Ruleset load failed: {exception}"); } From 2a88409dfe65fd5e48c52bbfdb0397e8d8b4f575 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 15:00:23 +0900 Subject: [PATCH 0327/2991] Fix time snap of sliders not matching when SV is not 1.0x This regressed with https://github.com/ppy/osu/pull/20850 because the function was used in other places which expect it to factor slider velocity into the equation. Rather than reverting, I've added a new argument, as based on the method naming alone it was hard to discern whether SV should actually be considered. The reason for the change in #20850 was to avoid the SV coming in from a reference object which may not have a correct SV in the first place. In such cases, passing `false` to the function will give the expected behaviour. --- osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs | 2 +- osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs | 6 +++--- osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs | 3 ++- .../Screens/Edit/Compose/Components/DistanceSnapGrid.cs | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs index 53b6db2277..01a49c7dea 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs @@ -193,7 +193,7 @@ namespace osu.Game.Tests.Visual.Editing IBindable IDistanceSnapProvider.DistanceSpacingMultiplier => DistanceSpacingMultiplier; - public float GetBeatSnapDistanceAt(HitObject referenceObject) => beat_snap_distance; + public float GetBeatSnapDistanceAt(HitObject referenceObject, bool useReferenceSliderVelocity = true) => beat_snap_distance; public float DurationToDistance(HitObject referenceObject, double duration) => (float)duration; diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index ca7ca79813..840ed7682a 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -259,9 +259,9 @@ namespace osu.Game.Rulesets.Edit return true; } - public virtual float GetBeatSnapDistanceAt(HitObject referenceObject) + public virtual float GetBeatSnapDistanceAt(HitObject referenceObject, bool useReferenceSliderVelocity = true) { - return (float)(100 * EditorBeatmap.Difficulty.SliderMultiplier * 1 / BeatSnapProvider.BeatDivisor); + return (float)(100 * (useReferenceSliderVelocity ? referenceObject.DifficultyControlPoint.SliderVelocity : 1) * EditorBeatmap.Difficulty.SliderMultiplier * 1 / BeatSnapProvider.BeatDivisor); } public virtual float DurationToDistance(HitObject referenceObject, double duration) @@ -273,7 +273,7 @@ namespace osu.Game.Rulesets.Edit public virtual double DistanceToDuration(HitObject referenceObject, float distance) { double beatLength = BeatSnapProvider.GetBeatLengthAtTime(referenceObject.StartTime); - return distance / GetBeatSnapDistanceAt(referenceObject) * beatLength; + return distance / GetBeatSnapDistanceAt(referenceObject) * beatLength * referenceObject.DifficultyControlPoint.SliderVelocity; } public virtual double FindSnappedDuration(HitObject referenceObject, float distance) diff --git a/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs b/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs index 5ad1cc78ff..6fbd994e23 100644 --- a/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs +++ b/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs @@ -27,8 +27,9 @@ namespace osu.Game.Rulesets.Edit /// Retrieves the distance between two points within a timing point that are one beat length apart. /// /// An object to be used as a reference point for this operation. + /// Whether the 's slider velocity should be factored into the returned distance. /// The distance between two points residing in the timing point that are one beat length apart. - float GetBeatSnapDistanceAt(HitObject referenceObject); + float GetBeatSnapDistanceAt(HitObject referenceObject, bool useReferenceSliderVelocity = true); /// /// Converts a duration to a distance without applying any snapping. diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs index 69c7fc2775..c179e7f0c2 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs @@ -97,7 +97,7 @@ namespace osu.Game.Screens.Edit.Compose.Components private void updateSpacing() { float distanceSpacingMultiplier = (float)DistanceSpacingMultiplier.Value; - float beatSnapDistance = SnapProvider.GetBeatSnapDistanceAt(ReferenceObject); + float beatSnapDistance = SnapProvider.GetBeatSnapDistanceAt(ReferenceObject, false); DistanceBetweenTicks = beatSnapDistance * distanceSpacingMultiplier; From e8b791429569d3f9513265ae7ae4f23c2754aba7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 15:13:05 +0900 Subject: [PATCH 0328/2991] Add test coverage of new parameter --- ...tSceneHitObjectComposerDistanceSnapping.cs | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index a98f931e7a..6fb21e38b0 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -66,7 +66,7 @@ namespace osu.Game.Tests.Editing { AddStep($"set slider multiplier = {multiplier}", () => composer.EditorBeatmap.Difficulty.SliderMultiplier = multiplier); - assertSnapDistance(100 * multiplier); + assertSnapDistance(100 * multiplier, null, true); } [TestCase(1)] @@ -79,7 +79,20 @@ namespace osu.Game.Tests.Editing { SliderVelocity = multiplier } - }); + }, false); + } + + [TestCase(1)] + [TestCase(2)] + public void TestSpeedMultiplierDoesChangeDistanceSnap(float multiplier) + { + assertSnapDistance(100 * multiplier, new HitObject + { + DifficultyControlPoint = new DifficultyControlPoint + { + SliderVelocity = multiplier + } + }, true); } [TestCase(1)] @@ -88,7 +101,7 @@ namespace osu.Game.Tests.Editing { AddStep($"set divisor = {divisor}", () => BeatDivisor.Value = divisor); - assertSnapDistance(100f / divisor); + assertSnapDistance(100f / divisor, null, true); } [Test] @@ -197,8 +210,8 @@ namespace osu.Game.Tests.Editing assertSnappedDistance(400, 400); } - private void assertSnapDistance(float expectedDistance, HitObject? hitObject = null) - => AddAssert($"distance is {expectedDistance}", () => composer.GetBeatSnapDistanceAt(hitObject ?? new HitObject()), () => Is.EqualTo(expectedDistance)); + private void assertSnapDistance(float expectedDistance, HitObject? refereneObject, bool includeSliderVelocity) + => AddAssert($"distance is {expectedDistance}", () => composer.GetBeatSnapDistanceAt(refereneObject ?? new HitObject(), includeSliderVelocity), () => Is.EqualTo(expectedDistance)); private void assertDurationToDistance(double duration, float expectedDistance) => AddAssert($"duration = {duration} -> distance = {expectedDistance}", () => composer.DurationToDistance(new HitObject(), duration) == expectedDistance); From d807d9d82299c85e13405472394061668e1f1698 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 15:21:17 +0900 Subject: [PATCH 0329/2991] Add failing test covering snap calculations with SV applied --- ...tSceneHitObjectComposerDistanceSnapping.cs | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index 6fb21e38b0..f759ed5dcf 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -7,6 +7,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; +using osu.Framework.Utils; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; @@ -104,6 +105,28 @@ namespace osu.Game.Tests.Editing assertSnapDistance(100f / divisor, null, true); } + /// + /// The basic distance-duration functions should always include slider velocity of the reference object. + /// + [Test] + public void TestConversionsWithSliderVelocity() + { + const float base_distance = 100; + const float slider_velocity = 1.2f; + + var referenceObject = new HitObject + { + DifficultyControlPoint = new DifficultyControlPoint + { + SliderVelocity = slider_velocity + } + }; + + assertSnapDistance(base_distance * slider_velocity, referenceObject, true); + assertSnappedDistance(base_distance * slider_velocity + 10, base_distance * slider_velocity, referenceObject); + assertSnappedDuration(base_distance * slider_velocity + 10, 1000, referenceObject); + } + [Test] public void TestConvertDurationToDistance() { @@ -210,20 +233,20 @@ namespace osu.Game.Tests.Editing assertSnappedDistance(400, 400); } - private void assertSnapDistance(float expectedDistance, HitObject? refereneObject, bool includeSliderVelocity) - => AddAssert($"distance is {expectedDistance}", () => composer.GetBeatSnapDistanceAt(refereneObject ?? new HitObject(), includeSliderVelocity), () => Is.EqualTo(expectedDistance)); + private void assertSnapDistance(float expectedDistance, HitObject? referenceObject, bool includeSliderVelocity) + => AddAssert($"distance is {expectedDistance}", () => composer.GetBeatSnapDistanceAt(referenceObject ?? new HitObject(), includeSliderVelocity), () => Is.EqualTo(expectedDistance).Within(Precision.FLOAT_EPSILON)); - private void assertDurationToDistance(double duration, float expectedDistance) - => AddAssert($"duration = {duration} -> distance = {expectedDistance}", () => composer.DurationToDistance(new HitObject(), duration) == expectedDistance); + private void assertDurationToDistance(double duration, float expectedDistance, HitObject? referenceObject = null) + => AddAssert($"duration = {duration} -> distance = {expectedDistance}", () => composer.DurationToDistance(referenceObject ?? new HitObject(), duration), () => Is.EqualTo(expectedDistance).Within(Precision.FLOAT_EPSILON)); - private void assertDistanceToDuration(float distance, double expectedDuration) - => AddAssert($"distance = {distance} -> duration = {expectedDuration}", () => composer.DistanceToDuration(new HitObject(), distance) == expectedDuration); + private void assertDistanceToDuration(float distance, double expectedDuration, HitObject? referenceObject = null) + => AddAssert($"distance = {distance} -> duration = {expectedDuration}", () => composer.DistanceToDuration(referenceObject ?? new HitObject(), distance), () => Is.EqualTo(expectedDuration).Within(Precision.FLOAT_EPSILON)); - private void assertSnappedDuration(float distance, double expectedDuration) - => AddAssert($"distance = {distance} -> duration = {expectedDuration} (snapped)", () => composer.FindSnappedDuration(new HitObject(), distance) == expectedDuration); + private void assertSnappedDuration(float distance, double expectedDuration, HitObject? referenceObject = null) + => AddAssert($"distance = {distance} -> duration = {expectedDuration} (snapped)", () => composer.FindSnappedDuration(referenceObject ?? new HitObject(), distance), () => Is.EqualTo(expectedDuration).Within(Precision.FLOAT_EPSILON)); - private void assertSnappedDistance(float distance, float expectedDistance) - => AddAssert($"distance = {distance} -> distance = {expectedDistance} (snapped)", () => composer.FindSnappedDistance(new HitObject(), distance) == expectedDistance); + private void assertSnappedDistance(float distance, float expectedDistance, HitObject? referenceObject = null) + => AddAssert($"distance = {distance} -> distance = {expectedDistance} (snapped)", () => composer.FindSnappedDistance(referenceObject ?? new HitObject(), distance), () => Is.EqualTo(expectedDistance).Within(Precision.FLOAT_EPSILON)); private class TestHitObjectComposer : OsuHitObjectComposer { From 8280605e92f6ab0d8220531a22b50895bf52ef27 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 16:31:09 +0900 Subject: [PATCH 0330/2991] Fix notch toggle not applying correctly after restart --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 2ac2edd3fc..4f8098136f 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -313,7 +313,7 @@ namespace osu.Game Beatmap.BindValueChanged(beatmapChanged, true); applySafeAreaConsiderations = LocalConfig.GetBindable(OsuSetting.SafeAreaConsiderations); - applySafeAreaConsiderations.BindValueChanged(apply => SafeAreaContainer.SafeAreaOverrideEdges = apply.NewValue ? SafeAreaOverrideEdges : Edges.All); + applySafeAreaConsiderations.BindValueChanged(apply => SafeAreaContainer.SafeAreaOverrideEdges = apply.NewValue ? SafeAreaOverrideEdges : Edges.All, true); } private ExternalLinkOpener externalLinkOpener; From d15585153daf759289013bce8f06e32ada67a501 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 17:07:58 +0900 Subject: [PATCH 0331/2991] Fix breadcrumb display in directory selector overlapping new "show hidden" button Closes #21034. --- .../UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs index 0833c7eb8b..08a569269e 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs @@ -25,10 +25,9 @@ namespace osu.Game.Graphics.UserInterfaceV2 protected override DirectorySelectorDirectory CreateDirectoryItem(DirectoryInfo directory, string displayName = null) => new OsuBreadcrumbDisplayDirectory(directory, displayName); - [BackgroundDependencyLoader] - private void load() + public OsuDirectorySelectorBreadcrumbDisplay() { - Height = 50; + Padding = new MarginPadding(15); } private class OsuBreadcrumbDisplayComputer : OsuBreadcrumbDisplayDirectory From 29bc653d24caaf65038ee39c75b7dab1bfc5307b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 17:14:30 +0900 Subject: [PATCH 0332/2991] Remove incorrect double multiplication and add missing test coverage --- .../Editing/TestSceneHitObjectComposerDistanceSnapping.cs | 3 +++ osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index f759ed5dcf..495a221159 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -125,6 +125,9 @@ namespace osu.Game.Tests.Editing assertSnapDistance(base_distance * slider_velocity, referenceObject, true); assertSnappedDistance(base_distance * slider_velocity + 10, base_distance * slider_velocity, referenceObject); assertSnappedDuration(base_distance * slider_velocity + 10, 1000, referenceObject); + + assertDistanceToDuration(base_distance * slider_velocity, 1000, referenceObject); + assertDurationToDistance(1000, base_distance * slider_velocity, referenceObject); } [Test] diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index 840ed7682a..b0a2694a0a 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -273,7 +273,7 @@ namespace osu.Game.Rulesets.Edit public virtual double DistanceToDuration(HitObject referenceObject, float distance) { double beatLength = BeatSnapProvider.GetBeatLengthAtTime(referenceObject.StartTime); - return distance / GetBeatSnapDistanceAt(referenceObject) * beatLength * referenceObject.DifficultyControlPoint.SliderVelocity; + return distance / GetBeatSnapDistanceAt(referenceObject) * beatLength; } public virtual double FindSnappedDuration(HitObject referenceObject, float distance) From 978d15955c911bf4eeef844a3eefabb71a6cb974 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 17:37:32 +0900 Subject: [PATCH 0333/2991] Fix control points not being cloned when running beatmap conversion Closes #20994. I haven't considered how this affects performance of difficulty calculation or otherwise. Seems like a sane initial fix which we can iterate on going forward. I've tested using the scenario in the linked issue. I'm not going to add test coverage because [BeatmapConversionTest](https://github.com/ppy/osu/blob/master/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs) should correctly cover this scenario once we are serialising control points as well. --- osu.Game/Beatmaps/BeatmapConverter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index 4419791e43..c7c244bf0e 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -47,6 +47,7 @@ namespace osu.Game.Beatmaps // Shallow clone isn't enough to ensure we don't mutate beatmap info unexpectedly. // Can potentially be removed after `Beatmap.Difficulty` doesn't save back to `Beatmap.BeatmapInfo`. original.BeatmapInfo = original.BeatmapInfo.Clone(); + original.ControlPointInfo = original.ControlPointInfo.DeepClone(); return ConvertBeatmap(original, cancellationToken); } From 37407293aa516363a2f4290311db371bebdbd96f Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Tue, 1 Nov 2022 17:57:20 +0900 Subject: [PATCH 0334/2991] Adjust target and hold off mod multipliers --- osu.Game.Rulesets.Mania/Mods/ManiaModHoldOff.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHoldOff.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHoldOff.cs index ca9bc89473..2b0098744f 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModHoldOff.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHoldOff.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mania.Mods public override string Acronym => "HO"; - public override double ScoreMultiplier => 1; + public override double ScoreMultiplier => 0.9; public override LocalisableString Description => @"Replaces all hold notes with normal notes."; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs b/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs index 406968ba08..dc64918e03 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Conversion; public override IconUsage? Icon => OsuIcon.ModTarget; public override LocalisableString Description => @"Practice keeping up with the beat of the song."; - public override double ScoreMultiplier => 1; + public override double ScoreMultiplier => 0.1; public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { From c179f0bb521bdc6c757a39fe8cff8955b5d09864 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 18:31:30 +0900 Subject: [PATCH 0335/2991] Fix argon hit circle outer gradient getting smaller each state application --- osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs index 36dc8c801d..4b4860e789 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs @@ -171,7 +171,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon // This is to give it a bomb-like effect, with the border "triggering" its animation when getting close. using (BeginDelayedSequence(flash_in_duration / 12)) { - outerGradient.ResizeTo(outerGradient.Size * shrink_size, resize_duration, Easing.OutElasticHalf); + outerGradient.ResizeTo(OUTER_GRADIENT_SIZE * shrink_size, resize_duration, Easing.OutElasticHalf); outerGradient .FadeColour(Color4.White, 80) .Then() From ff60eebe216618e9f2e7ac1ca4fd114f0632c847 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 19:12:59 +0900 Subject: [PATCH 0336/2991] Fix large transform retention when adjusting accent colour of hitobject during pause --- .../Skinning/Argon/ArgonMainCirclePiece.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs index 36dc8c801d..7269c7b151 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs @@ -121,12 +121,16 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon innerGradient.Colour = ColourInfo.GradientVertical(colour.NewValue.Darken(0.5f), colour.NewValue.Darken(0.6f)); flash.Colour = colour.NewValue; - updateStateTransforms(drawableObject, drawableObject.State.Value); + // Accent colour may be changed many times during a paused gameplay state. + // Schedule the change to avoid transforms piling up. + Scheduler.AddOnce(updateStateTransforms); }, true); drawableObject.ApplyCustomUpdateState += updateStateTransforms; } + private void updateStateTransforms() => updateStateTransforms(drawableObject, drawableObject.State.Value); + private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state) { using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime)) From f014acfc8d54c453a50b0f9b22862f6c29204761 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 19:34:53 +0900 Subject: [PATCH 0337/2991] Fix `DrawableHitObject.AccentColour` not being updated if object entry is not attached --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index d624164013..e5150576f2 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -266,6 +266,10 @@ namespace osu.Game.Rulesets.Objects.Drawables updateState(ArmedState.Miss, true); else updateState(ArmedState.Idle, true); + + // Combo colour may have been applied via a bindable flow while no object entry was attached. + // Update here to ensure we're in a good state. + UpdateComboColour(); } } From cd8dc9b17bbfb43e30a28ce4e765885380b494b6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 19:47:20 +0900 Subject: [PATCH 0338/2991] Rename "Target" to "Target Practice" --- osu.Game.Rulesets.Osu.Tests/OsuLegacyModConversionTest.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs | 2 +- .../Mods/{OsuModTarget.cs => OsuModTargetPractice.cs} | 7 +++---- osu.Game.Rulesets.Osu/OsuRuleset.cs | 6 +++--- 7 files changed, 11 insertions(+), 12 deletions(-) rename osu.Game.Rulesets.Osu/Mods/{OsuModTarget.cs => OsuModTargetPractice.cs} (98%) diff --git a/osu.Game.Rulesets.Osu.Tests/OsuLegacyModConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuLegacyModConversionTest.cs index 01d83b55e6..b4727b3c02 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuLegacyModConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuLegacyModConversionTest.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Tests new object[] { LegacyMods.Autoplay, new[] { typeof(OsuModAutoplay) } }, new object[] { LegacyMods.SpunOut, new[] { typeof(OsuModSpunOut) } }, new object[] { LegacyMods.Autopilot, new[] { typeof(OsuModAutopilot) } }, - new object[] { LegacyMods.Target, new[] { typeof(OsuModTarget) } }, + new object[] { LegacyMods.Target, new[] { typeof(OsuModTargetPractice) } }, new object[] { LegacyMods.HardRock | LegacyMods.DoubleTime, new[] { typeof(OsuModHardRock), typeof(OsuModDoubleTime) } } }; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs index 618fcfe05d..1621bb50b1 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Mods { public override LocalisableString Description => "It never gets boring!"; - public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModTarget)).ToArray(); + public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModTargetPractice)).ToArray(); [SettingSource("Angle sharpness", "How sharp angles should be", SettingControlType = typeof(SettingsSlider))] public BindableFloat AngleSharpness { get; } = new BindableFloat(7) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs index 9708800daa..f691731afe 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Automation; public override LocalisableString Description => @"Spinners will be automatically completed."; public override double ScoreMultiplier => 0.9; - public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot), typeof(OsuModTarget) }; + public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot), typeof(OsuModTargetPractice) }; public void ApplyToDrawableHitObject(DrawableHitObject hitObject) { diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs b/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs index 67b19124e1..af37f1e2e5 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.DifficultyIncrease; public override LocalisableString Description => @"Once you start a slider, follow precisely or get a miss."; public override double ScoreMultiplier => 1.0; - public override Type[] IncompatibleMods => new[] { typeof(ModClassic), typeof(OsuModTarget) }; + public override Type[] IncompatibleMods => new[] { typeof(ModClassic), typeof(OsuModTargetPractice) }; public void ApplyToDrawableHitObject(DrawableHitObject drawable) { diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs index 429fe30fc5..b4edb1581e 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot), - typeof(OsuModTarget), + typeof(OsuModTargetPractice), }).ToArray(); } } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs b/osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs similarity index 98% rename from osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs rename to osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs index dc64918e03..55c20eebe9 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs @@ -32,11 +32,10 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModTarget : ModWithVisibilityAdjustment, IApplicableToDrawableRuleset, - IApplicableToHealthProcessor, IApplicableToDifficulty, IApplicableFailOverride, - IHasSeed, IHidesApproachCircles + public class OsuModTargetPractice : ModWithVisibilityAdjustment, IApplicableToDrawableRuleset, + IApplicableToHealthProcessor, IApplicableToDifficulty, IApplicableFailOverride, IHasSeed, IHidesApproachCircles { - public override string Name => "Target"; + public override string Name => "Target Practice"; public override string Acronym => "TP"; public override ModType Type => ModType.Conversion; public override IconUsage? Icon => OsuIcon.ModTarget; diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 69df12ff6d..79a566e33c 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -109,7 +109,7 @@ namespace osu.Game.Rulesets.Osu yield return new OsuModSpunOut(); if (mods.HasFlagFast(LegacyMods.Target)) - yield return new OsuModTarget(); + yield return new OsuModTargetPractice(); if (mods.HasFlagFast(LegacyMods.TouchDevice)) yield return new OsuModTouchDevice(); @@ -131,7 +131,7 @@ namespace osu.Game.Rulesets.Osu value |= LegacyMods.SpunOut; break; - case OsuModTarget: + case OsuModTargetPractice: value |= LegacyMods.Target; break; @@ -170,7 +170,7 @@ namespace osu.Game.Rulesets.Osu case ModType.Conversion: return new Mod[] { - new OsuModTarget(), + new OsuModTargetPractice(), new OsuModDifficultyAdjust(), new OsuModClassic(), new OsuModRandom(), From 5b25ef5f2fcc7d4c1db03cd529733fb8375237c4 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Tue, 1 Nov 2022 21:34:34 +0900 Subject: [PATCH 0339/2991] Construct notifications client via IAPIProvider --- osu.Game.Tests/Chat/TestSceneChannelManager.cs | 3 +-- osu.Game.Tests/Visual/Online/TestSceneChatLink.cs | 3 +-- osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs | 3 +-- osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs | 3 +-- .../Visual/Online/TestSceneStandAloneChatDisplay.cs | 3 +-- osu.Game/Online/API/APIAccess.cs | 5 +++++ osu.Game/Online/API/DummyAPIAccess.cs | 4 ++++ osu.Game/Online/API/IAPIProvider.cs | 6 ++++++ osu.Game/OsuGame.cs | 3 +-- 9 files changed, 21 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Chat/TestSceneChannelManager.cs b/osu.Game.Tests/Chat/TestSceneChannelManager.cs index 84609a2733..86be638781 100644 --- a/osu.Game.Tests/Chat/TestSceneChannelManager.cs +++ b/osu.Game.Tests/Chat/TestSceneChannelManager.cs @@ -13,7 +13,6 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; -using osu.Game.Online.Notifications.Polling; using osu.Game.Tests.Visual; namespace osu.Game.Tests.Chat @@ -152,7 +151,7 @@ namespace osu.Game.Tests.Chat public ChannelManagerContainer(IAPIProvider apiProvider) { - InternalChild = ChannelManager = new ChannelManager(apiProvider, new PollingNotificationsClientConnector(apiProvider)); + InternalChild = ChannelManager = new ChannelManager(apiProvider, apiProvider.GetNotificationsConnector()); } } } diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs index 63526d4278..5c46cd96be 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs @@ -14,7 +14,6 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; -using osu.Game.Online.Notifications.Polling; using osu.Game.Overlays.Chat; using osuTK.Graphics; @@ -42,7 +41,7 @@ namespace osu.Game.Tests.Visual.Online { linkColour = colours.Blue; - var chatManager = new ChannelManager(API, new PollingNotificationsClientConnector(API)); + var chatManager = new ChannelManager(API, API.GetNotificationsConnector()); BindableList availableChannels = (BindableList)chatManager.AvailableChannels; availableChannels.Add(new Channel { Name = "#english" }); availableChannels.Add(new Channel { Name = "#japanese" }); diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index dee258f747..6b2124f1f8 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -24,7 +24,6 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; -using osu.Game.Online.Notifications.Polling; using osu.Game.Overlays; using osu.Game.Overlays.Chat; using osu.Game.Overlays.Chat.Listing; @@ -60,7 +59,7 @@ namespace osu.Game.Tests.Visual.Online RelativeSizeAxes = Axes.Both, CachedDependencies = new (Type, object)[] { - (typeof(ChannelManager), channelManager = new ChannelManager(API, new PollingNotificationsClientConnector(API))), + (typeof(ChannelManager), channelManager = new ChannelManager(API, API.GetNotificationsConnector())), }, Children = new Drawable[] { diff --git a/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs b/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs index 6d83fb3123..cb93812bc2 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs @@ -16,7 +16,6 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; -using osu.Game.Online.Notifications.Polling; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; using osuTK.Input; @@ -251,7 +250,7 @@ namespace osu.Game.Tests.Visual.Online public TestContainer(IAPIProvider api, Channel[] channels) { this.channels = channels; - ChannelManager = new ChannelManager(api, new PollingNotificationsClientConnector(api)); + ChannelManager = new ChannelManager(api, api.GetNotificationsConnector()); } [BackgroundDependencyLoader] diff --git a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs index f1daa05e08..07196cc92a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs @@ -15,7 +15,6 @@ using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; -using osu.Game.Online.Notifications.Polling; using osu.Game.Overlays.Chat; using osuTK.Input; @@ -59,7 +58,7 @@ namespace osu.Game.Tests.Visual.Online { var api = parent.Get(); - Add(channelManager = new ChannelManager(api, new PollingNotificationsClientConnector(api))); + Add(channelManager = new ChannelManager(api, api.GetNotificationsConnector())); var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index a0c8e0d555..8ac2e2d453 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -20,6 +20,8 @@ using osu.Framework.Logging; using osu.Game.Configuration; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Notifications; +using osu.Game.Online.Notifications.WebSocket; using osu.Game.Users; namespace osu.Game.Online.API @@ -299,6 +301,9 @@ namespace osu.Game.Online.API public IHubClientConnector GetHubConnector(string clientName, string endpoint, bool preferMessagePack) => new HubClientConnector(clientName, endpoint, this, versionHash, preferMessagePack); + public NotificationsClientConnector GetNotificationsConnector() => + new WebSocketNotificationsClientConnector(this); + public RegistrationRequest.RegistrationRequestErrors CreateAccount(string email, string username, string password) { Debug.Assert(State.Value == APIState.Offline); diff --git a/osu.Game/Online/API/DummyAPIAccess.cs b/osu.Game/Online/API/DummyAPIAccess.cs index 7dc34d1293..865e1e0a70 100644 --- a/osu.Game/Online/API/DummyAPIAccess.cs +++ b/osu.Game/Online/API/DummyAPIAccess.cs @@ -9,6 +9,8 @@ using System.Threading.Tasks; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Notifications; +using osu.Game.Online.Notifications.Polling; using osu.Game.Users; namespace osu.Game.Online.API @@ -115,6 +117,8 @@ namespace osu.Game.Online.API public IHubClientConnector GetHubConnector(string clientName, string endpoint, bool preferMessagePack) => null; + public NotificationsClientConnector GetNotificationsConnector() => new PollingNotificationsClientConnector(this); + public RegistrationRequest.RegistrationRequestErrors CreateAccount(string email, string username, string password) { Thread.Sleep(200); diff --git a/osu.Game/Online/API/IAPIProvider.cs b/osu.Game/Online/API/IAPIProvider.cs index a90b11e354..6054effaa1 100644 --- a/osu.Game/Online/API/IAPIProvider.cs +++ b/osu.Game/Online/API/IAPIProvider.cs @@ -5,6 +5,7 @@ using System; using System.Threading.Tasks; using osu.Framework.Bindables; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Notifications; using osu.Game.Users; namespace osu.Game.Online.API @@ -112,6 +113,11 @@ namespace osu.Game.Online.API /// Whether to use MessagePack for serialisation if available on this platform. IHubClientConnector? GetHubConnector(string clientName, string endpoint, bool preferMessagePack = true); + /// + /// Constructs a new . + /// + NotificationsClientConnector GetNotificationsConnector(); + /// /// Create a new user account. This is a blocking operation. /// diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index c1db9630a0..7384c2a297 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -45,7 +45,6 @@ using osu.Game.Online; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; using osu.Game.Online.Notifications; -using osu.Game.Online.Notifications.WebSocket; using osu.Game.Overlays; using osu.Game.Overlays.Music; using osu.Game.Overlays.Notifications; @@ -759,7 +758,7 @@ namespace osu.Game BackButton.Receptor receptor; dependencies.CacheAs(idleTracker = new GameIdleTracker(6000)); - dependencies.CacheAs(notificationsClient = new WebSocketNotificationsClientConnector(API)); + dependencies.CacheAs(notificationsClient = API.GetNotificationsConnector()); var sessionIdleTracker = new GameIdleTracker(300000); sessionIdleTracker.IsIdle.BindValueChanged(idle => From e10424286448cc962a346234d0eea9ac2bad4c1e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 1 Nov 2022 22:28:06 +0900 Subject: [PATCH 0340/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index b691751f13..8711ceec64 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9dd0d18817..8d45ebec57 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 6dce938ebf..76d2e727c8 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From 905ebc3c1f7cfdfa798c6cffa2bdff3479b4d1d3 Mon Sep 17 00:00:00 2001 From: C0D3 M4513R <28912031+C0D3-M4513R@users.noreply.github.com> Date: Tue, 1 Nov 2022 20:46:32 +0100 Subject: [PATCH 0341/2991] Initial implementation of a Beatmap Information Skinning Element Signed-off-by: C0D3 M4513R <28912031+C0D3-M4513R@users.noreply.github.com> --- osu.Game/OsuGameBase.cs | 2 +- .../Components/BeatmapInfoDrawable.cs | 189 ++++++++++++++++++ 2 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Skinning/Components/BeatmapInfoDrawable.cs diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 39ddffd2d0..622e802b72 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -155,7 +155,7 @@ namespace osu.Game protected Storage Storage { get; set; } - protected Bindable Beatmap { get; private set; } // cached via load() method + public Bindable Beatmap { get; private set; } // cached via load() method [Cached] [Cached(typeof(IBindable))] diff --git a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs new file mode 100644 index 0000000000..770082daf9 --- /dev/null +++ b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs @@ -0,0 +1,189 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable disable + +using System; +using System.Text; +using JetBrains.Annotations; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Configuration; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Skinning.Components +{ + /// + /// Intended to be a test bed for skinning. May be removed at some point in the future. + /// + [UsedImplicitly] + public class BeatmapInfoDrawable : Container, ISkinnableDrawable + { + public bool UsesFixedAnchor { get; set; } + + [SettingSource("Tracked Beatmap Info", "Which part of the BeatmapInformation should be tracked")] + public Bindable Type { get; } = new Bindable(BeatmapInfo.StarRating); + + [Resolved] + private OsuGameBase mGameBase { get; set; } + + private readonly OsuSpriteText text; + + public BeatmapInfoDrawable() + { + AutoSizeAxes = Axes.Both; + + InternalChildren = new Drawable[] + { + text = new OsuSpriteText + { + Text = "BeatInfoDrawable", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.Default.With(size: 40) + } + }; + } + + // [BackgroundDependencyLoader] + // private void load(WorkingBeatmap beatmap) + // { + // this.beatmap = beatmap; + // } + + protected override void LoadComplete() + { + base.LoadComplete(); + Type.BindValueChanged(update, true); + } + + private void update(ValueChangedEvent type) + { + switch (type.NewValue) + { + case BeatmapInfo.CircleSize: + mGameBase.Beatmap.BindValueChanged(bm => + { + text.Current.Value = bm.NewValue.BeatmapInfo.Difficulty.CircleSize.ToString("F2"); + }, true); + break; + + case BeatmapInfo.HPDrain: + mGameBase.Beatmap.BindValueChanged(bm => + { + text.Current.Value = bm.NewValue.BeatmapInfo.Difficulty.DrainRate.ToString("F2"); + }, true); + break; + + case BeatmapInfo.Accuracy: + mGameBase.Beatmap.BindValueChanged(bm => + { + text.Current.Value = bm.NewValue.BeatmapInfo.Difficulty.OverallDifficulty.ToString("F2"); + }, true); + break; + + case BeatmapInfo.ApproachRate: + mGameBase.Beatmap.BindValueChanged(bm => + { + text.Current.Value = bm.NewValue.BeatmapInfo.Difficulty.ApproachRate.ToString("F2"); + }, true); + break; + + case BeatmapInfo.StarRating: + mGameBase.Beatmap.BindValueChanged(bm => + { + text.Current.Value = bm.NewValue.BeatmapInfo.StarRating.ToString("F2"); + }, true); + break; + + case BeatmapInfo.Song: + mGameBase.Beatmap.BindValueChanged(bm => + { + text.Current.Value = bm.NewValue.BeatmapInfo.Metadata.Title; + }, true); + break; + + case BeatmapInfo.Artist: + mGameBase.Beatmap.BindValueChanged(bm => + { + text.Current.Value = bm.NewValue.BeatmapInfo.Metadata.Artist; + }, true); + break; + + case BeatmapInfo.Difficulty: + mGameBase.Beatmap.BindValueChanged(bm => + { + text.Current.Value = bm.NewValue.BeatmapInfo.DifficultyName; + }, true); + break; + + case BeatmapInfo.Mapper: + mGameBase.Beatmap.BindValueChanged(bm => + { + text.Current.Value = bm.NewValue.BeatmapInfo.Metadata.Author.Username; + }, true); + break; + + case BeatmapInfo.Length: + mGameBase.Beatmap.BindValueChanged(bm => + { + const long ms_to_s = 1000; + double length = bm.NewValue.BeatmapInfo.Length; + double rawS = length / ms_to_s; + double rawM = rawS / 60; + double rawH = rawM / 60; + double rawD = rawH / 24; + + long s = (long)rawS % 60; + long m = (long)rawM % 60; + long h = (long)rawH % 24; + long d = (long)rawD; + StringBuilder builder = new StringBuilder(); + + if (d != 0) + { + builder.Append(d.ToString("D2")); + builder.Append(":"); + } + + if (h != 0 || d != 0) + { + builder.Append(h.ToString("D2")); + builder.Append(":"); + } + + builder.Append(m.ToString("D2")); + builder.Append(":"); + builder.Append(s.ToString("D2")); + text.Current.Value = builder.ToString(); + }, true); + break; + + case BeatmapInfo.BPM: + mGameBase.Beatmap.BindValueChanged(bm => + { + text.Current.Value = bm.NewValue.BeatmapInfo.BPM.ToString("F2"); + }, true); + break; + } + } + } + + public enum BeatmapInfo + { + CircleSize, + HPDrain, + Accuracy, //OD? + ApproachRate, + StarRating, + Song, + Artist, + Difficulty, + Mapper, + Length, + BPM, + } +} From c231a20cbb9b0607e3e56ec20ef118ff889bbedf Mon Sep 17 00:00:00 2001 From: C0D3 M4513R <28912031+C0D3-M4513R@users.noreply.github.com> Date: Tue, 1 Nov 2022 20:54:52 +0100 Subject: [PATCH 0342/2991] Add a generic text Element Signed-off-by: C0D3 M4513R <28912031+C0D3-M4513R@users.noreply.github.com> --- .../Components/BeatmapInfoDrawable.cs | 12 +----- osu.Game/Skinning/Components/TextElement.cs | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 osu.Game/Skinning/Components/TextElement.cs diff --git a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs index 770082daf9..cb207d7329 100644 --- a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs +++ b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs @@ -3,7 +3,6 @@ #nullable disable -using System; using System.Text; using JetBrains.Annotations; using osu.Framework.Allocation; @@ -16,9 +15,6 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Skinning.Components { - /// - /// Intended to be a test bed for skinning. May be removed at some point in the future. - /// [UsedImplicitly] public class BeatmapInfoDrawable : Container, ISkinnableDrawable { @@ -48,12 +44,6 @@ namespace osu.Game.Skinning.Components }; } - // [BackgroundDependencyLoader] - // private void load(WorkingBeatmap beatmap) - // { - // this.beatmap = beatmap; - // } - protected override void LoadComplete() { base.LoadComplete(); @@ -176,7 +166,7 @@ namespace osu.Game.Skinning.Components { CircleSize, HPDrain, - Accuracy, //OD? + Accuracy, ApproachRate, StarRating, Song, diff --git a/osu.Game/Skinning/Components/TextElement.cs b/osu.Game/Skinning/Components/TextElement.cs new file mode 100644 index 0000000000..e29ab6de58 --- /dev/null +++ b/osu.Game/Skinning/Components/TextElement.cs @@ -0,0 +1,40 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable disable + +using JetBrains.Annotations; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Configuration; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Skinning.Components +{ + [UsedImplicitly] + public class TextElement : Container, ISkinnableDrawable + { + public bool UsesFixedAnchor { get; set; } + + [SettingSource("Displayed Text", "What text should be displayed")] + public Bindable Text { get; } = new Bindable("Circles!"); + + public TextElement() + { + AutoSizeAxes = Axes.Both; + OsuSpriteText text; + InternalChildren = new Drawable[] + { + text = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.Default.With(size: 40) + } + }; + text.Current.BindTo(Text); + } + } +} From 975eed964e5c773de4b882cb7c620e9633130755 Mon Sep 17 00:00:00 2001 From: C0D3 M4513R <28912031+C0D3-M4513R@users.noreply.github.com> Date: Tue, 1 Nov 2022 21:19:01 +0100 Subject: [PATCH 0343/2991] Don't make Beatmap in OsuGameBase public Signed-off-by: C0D3 M4513R <28912031+C0D3-M4513R@users.noreply.github.com> --- osu.Game/OsuGameBase.cs | 2 +- .../Components/BeatmapInfoDrawable.cs | 25 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 622e802b72..39ddffd2d0 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -155,7 +155,7 @@ namespace osu.Game protected Storage Storage { get; set; } - public Bindable Beatmap { get; private set; } // cached via load() method + protected Bindable Beatmap { get; private set; } // cached via load() method [Cached] [Cached(typeof(IBindable))] diff --git a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs index cb207d7329..ae91d14830 100644 --- a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs +++ b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs @@ -9,6 +9,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -24,7 +25,7 @@ namespace osu.Game.Skinning.Components public Bindable Type { get; } = new Bindable(BeatmapInfo.StarRating); [Resolved] - private OsuGameBase mGameBase { get; set; } + private IBindable beatmap { get; set; } private readonly OsuSpriteText text; @@ -55,70 +56,70 @@ namespace osu.Game.Skinning.Components switch (type.NewValue) { case BeatmapInfo.CircleSize: - mGameBase.Beatmap.BindValueChanged(bm => + beatmap.BindValueChanged(bm => { text.Current.Value = bm.NewValue.BeatmapInfo.Difficulty.CircleSize.ToString("F2"); }, true); break; case BeatmapInfo.HPDrain: - mGameBase.Beatmap.BindValueChanged(bm => + beatmap.BindValueChanged(bm => { text.Current.Value = bm.NewValue.BeatmapInfo.Difficulty.DrainRate.ToString("F2"); }, true); break; case BeatmapInfo.Accuracy: - mGameBase.Beatmap.BindValueChanged(bm => + beatmap.BindValueChanged(bm => { text.Current.Value = bm.NewValue.BeatmapInfo.Difficulty.OverallDifficulty.ToString("F2"); }, true); break; case BeatmapInfo.ApproachRate: - mGameBase.Beatmap.BindValueChanged(bm => + beatmap.BindValueChanged(bm => { text.Current.Value = bm.NewValue.BeatmapInfo.Difficulty.ApproachRate.ToString("F2"); }, true); break; case BeatmapInfo.StarRating: - mGameBase.Beatmap.BindValueChanged(bm => + beatmap.BindValueChanged(bm => { text.Current.Value = bm.NewValue.BeatmapInfo.StarRating.ToString("F2"); }, true); break; case BeatmapInfo.Song: - mGameBase.Beatmap.BindValueChanged(bm => + beatmap.BindValueChanged(bm => { text.Current.Value = bm.NewValue.BeatmapInfo.Metadata.Title; }, true); break; case BeatmapInfo.Artist: - mGameBase.Beatmap.BindValueChanged(bm => + beatmap.BindValueChanged(bm => { text.Current.Value = bm.NewValue.BeatmapInfo.Metadata.Artist; }, true); break; case BeatmapInfo.Difficulty: - mGameBase.Beatmap.BindValueChanged(bm => + beatmap.BindValueChanged(bm => { text.Current.Value = bm.NewValue.BeatmapInfo.DifficultyName; }, true); break; case BeatmapInfo.Mapper: - mGameBase.Beatmap.BindValueChanged(bm => + beatmap.BindValueChanged(bm => { text.Current.Value = bm.NewValue.BeatmapInfo.Metadata.Author.Username; }, true); break; case BeatmapInfo.Length: - mGameBase.Beatmap.BindValueChanged(bm => + beatmap.BindValueChanged(bm => { const long ms_to_s = 1000; double length = bm.NewValue.BeatmapInfo.Length; @@ -153,7 +154,7 @@ namespace osu.Game.Skinning.Components break; case BeatmapInfo.BPM: - mGameBase.Beatmap.BindValueChanged(bm => + beatmap.BindValueChanged(bm => { text.Current.Value = bm.NewValue.BeatmapInfo.BPM.ToString("F2"); }, true); From 8ac2075c61727961b1fe43554bc077abdc7ee7b5 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 10:04:24 +0900 Subject: [PATCH 0344/2991] Fix possible threading issues Not really sure of the best way to handle this in general. It could be argued that this should be a `Component` type and the bindable bound in `LoadComplete()`... --- osu.Game/Online/Notifications/NotificationsClient.cs | 6 +++--- .../Notifications/Polling/PollingNotificationsClient.cs | 5 +---- .../Polling/PollingNotificationsClientConnector.cs | 5 +---- osu.Game/Online/SocketClientConnector.cs | 7 +++++-- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/osu.Game/Online/Notifications/NotificationsClient.cs b/osu.Game/Online/Notifications/NotificationsClient.cs index 6d9226ca17..8c41ae10d7 100644 --- a/osu.Game/Online/Notifications/NotificationsClient.cs +++ b/osu.Game/Online/Notifications/NotificationsClient.cs @@ -21,14 +21,14 @@ namespace osu.Game.Online.Notifications public Action>? NewMessages; public Action? PresenceReceived; - private readonly IAPIProvider api; + protected readonly IAPIProvider API; private bool enableChat; private long lastMessageId; protected NotificationsClient(IAPIProvider api) { - this.api = api; + API = api; } public bool EnableChat @@ -54,7 +54,7 @@ namespace osu.Game.Online.Notifications protected virtual Task StartChatAsync() { - api.Queue(CreateFetchMessagesRequest(0)); + API.Queue(CreateFetchMessagesRequest(0)); return Task.CompletedTask; } diff --git a/osu.Game/Online/Notifications/Polling/PollingNotificationsClient.cs b/osu.Game/Online/Notifications/Polling/PollingNotificationsClient.cs index 1c5559fcb4..2f343abf86 100644 --- a/osu.Game/Online/Notifications/Polling/PollingNotificationsClient.cs +++ b/osu.Game/Online/Notifications/Polling/PollingNotificationsClient.cs @@ -12,12 +12,9 @@ namespace osu.Game.Online.Notifications.Polling /// public class PollingNotificationsClient : NotificationsClient { - private readonly IAPIProvider api; - public PollingNotificationsClient(IAPIProvider api) : base(api) { - this.api = api; } public override Task ConnectAsync(CancellationToken cancellationToken) @@ -26,7 +23,7 @@ namespace osu.Game.Online.Notifications.Polling { while (!cancellationToken.IsCancellationRequested) { - await api.PerformAsync(CreateFetchMessagesRequest()); + await API.PerformAsync(CreateFetchMessagesRequest()); await Task.Delay(1000, cancellationToken); } }, cancellationToken); diff --git a/osu.Game/Online/Notifications/Polling/PollingNotificationsClientConnector.cs b/osu.Game/Online/Notifications/Polling/PollingNotificationsClientConnector.cs index 18a31ff061..ff3f30edcd 100644 --- a/osu.Game/Online/Notifications/Polling/PollingNotificationsClientConnector.cs +++ b/osu.Game/Online/Notifications/Polling/PollingNotificationsClientConnector.cs @@ -12,15 +12,12 @@ namespace osu.Game.Online.Notifications.Polling /// public class PollingNotificationsClientConnector : NotificationsClientConnector { - private readonly IAPIProvider api; - public PollingNotificationsClientConnector(IAPIProvider api) : base(api) { - this.api = api; } protected override Task BuildNotificationClientAsync(CancellationToken cancellationToken) - => Task.FromResult((NotificationsClient)new PollingNotificationsClient(api)); + => Task.FromResult((NotificationsClient)new PollingNotificationsClient(API)); } } diff --git a/osu.Game/Online/SocketClientConnector.cs b/osu.Game/Online/SocketClientConnector.cs index c6d5601c1f..abf19fbba3 100644 --- a/osu.Game/Online/SocketClientConnector.cs +++ b/osu.Game/Online/SocketClientConnector.cs @@ -23,18 +23,21 @@ namespace osu.Game.Online /// public SocketClient? CurrentConnection { get; private set; } + protected readonly IAPIProvider API; + + private readonly IBindable apiState = new Bindable(); private readonly Bindable isConnected = new Bindable(); private readonly SemaphoreSlim connectionLock = new SemaphoreSlim(1); private CancellationTokenSource connectCancelSource = new CancellationTokenSource(); - private readonly IBindable apiState = new Bindable(); - /// /// Constructs a new . /// /// An API provider used to react to connection state changes. protected SocketClientConnector(IAPIProvider api) { + API = api; + apiState.BindTo(api.State); apiState.BindValueChanged(_ => Task.Run(connectIfPossible), true); } From 5448c0209e0a824a0d6a75d1ae5577c79f03c549 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 10:14:40 +0900 Subject: [PATCH 0345/2991] Rename var --- .../Difficulty/TaikoPerformanceCalculator.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index 4839a89646..317e4a2f72 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty effectiveMissCount = Math.Max(1.0, 1000.0 / totalSuccessfulHits) * countMiss; // TODO: The detection of rulesets is temporary until the leftover old skills have been reworked. - bool rulesetTaiko = score.BeatmapInfo.Ruleset.OnlineID == 1; + bool taikoSpecificBeatmap = score.BeatmapInfo.Ruleset.OnlineID == 1; double multiplier = 1.13; @@ -54,8 +54,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModEasy)) multiplier *= 0.975; - double difficultyValue = computeDifficultyValue(score, taikoAttributes, rulesetTaiko); - double accuracyValue = computeAccuracyValue(score, taikoAttributes, rulesetTaiko); + double difficultyValue = computeDifficultyValue(score, taikoAttributes, taikoSpecificBeatmap); + double accuracyValue = computeAccuracyValue(score, taikoAttributes, taikoSpecificBeatmap); double totalValue = Math.Pow( Math.Pow(difficultyValue, 1.1) + @@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty }; } - private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool rulesetTaiko) + private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool taikoSpecificBeatmap) { double difficultyValue = Math.Pow(5 * Math.Max(1.0, attributes.StarRating / 0.115) - 4.0, 2.25) / 1150.0; @@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModEasy)) difficultyValue *= 0.985; - if (score.Mods.Any(m => m is ModHidden) && rulesetTaiko) + if (score.Mods.Any(m => m is ModHidden) && taikoSpecificBeatmap) difficultyValue *= 1.025; if (score.Mods.Any(m => m is ModHardRock)) @@ -95,7 +95,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty return difficultyValue * Math.Pow(accuracy, 2.0); } - private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool rulesetTaiko) + private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool taikoSpecificBeatmap) { if (attributes.GreatHitWindow <= 0) return 0; @@ -106,7 +106,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty accuracyValue *= lengthBonus; // Slight HDFL Bonus for accuracy. A clamp is used to prevent against negative values. - if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && rulesetTaiko) + if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && taikoSpecificBeatmap) accuracyValue *= Math.Max(1.0, 1.1 * lengthBonus); return accuracyValue; From 46d1713e28c1726c28d998bd89a9c481cb7a53ce Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 11:43:22 +0900 Subject: [PATCH 0346/2991] Rename Socket* -> PersistentEndpoint* --- osu.Game/Online/HubClient.cs | 2 +- osu.Game/Online/HubClientConnector.cs | 6 +++--- .../{SocketClient.cs => PersistentEndpointClient.cs} | 2 +- ...tConnector.cs => PersistentEndpointClientConnector.cs} | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) rename osu.Game/Online/{SocketClient.cs => PersistentEndpointClient.cs} (90%) rename osu.Game/Online/{SocketClientConnector.cs => PersistentEndpointClientConnector.cs} (95%) diff --git a/osu.Game/Online/HubClient.cs b/osu.Game/Online/HubClient.cs index 262e298f34..07428f58b4 100644 --- a/osu.Game/Online/HubClient.cs +++ b/osu.Game/Online/HubClient.cs @@ -7,7 +7,7 @@ using Microsoft.AspNetCore.SignalR.Client; namespace osu.Game.Online { - public class HubClient : SocketClient + public class HubClient : PersistentEndpointClient { public readonly HubConnection Connection; diff --git a/osu.Game/Online/HubClientConnector.cs b/osu.Game/Online/HubClientConnector.cs index 33e9f92817..6f246f6dd3 100644 --- a/osu.Game/Online/HubClientConnector.cs +++ b/osu.Game/Online/HubClientConnector.cs @@ -14,7 +14,7 @@ using osu.Game.Online.API; namespace osu.Game.Online { - public class HubClientConnector : SocketClientConnector, IHubClientConnector + public class HubClientConnector : PersistentEndpointClientConnector, IHubClientConnector { public const string SERVER_SHUTDOWN_MESSAGE = "Server is shutting down."; @@ -51,7 +51,7 @@ namespace osu.Game.Online this.preferMessagePack = preferMessagePack; } - protected override Task BuildConnectionAsync(CancellationToken cancellationToken) + protected override Task BuildConnectionAsync(CancellationToken cancellationToken) { var builder = new HubConnectionBuilder() .WithUrl(endpoint, options => @@ -91,7 +91,7 @@ namespace osu.Game.Online ConfigureConnection?.Invoke(newConnection); - return Task.FromResult((SocketClient)new HubClient(newConnection)); + return Task.FromResult((PersistentEndpointClient)new HubClient(newConnection)); } protected override string ClientName { get; } diff --git a/osu.Game/Online/SocketClient.cs b/osu.Game/Online/PersistentEndpointClient.cs similarity index 90% rename from osu.Game/Online/SocketClient.cs rename to osu.Game/Online/PersistentEndpointClient.cs index 3b4aa1b49b..d6ed2d8aec 100644 --- a/osu.Game/Online/SocketClient.cs +++ b/osu.Game/Online/PersistentEndpointClient.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; namespace osu.Game.Online { - public abstract class SocketClient : IAsyncDisposable + public abstract class PersistentEndpointClient : IAsyncDisposable { public event Func? Closed; diff --git a/osu.Game/Online/SocketClientConnector.cs b/osu.Game/Online/PersistentEndpointClientConnector.cs similarity index 95% rename from osu.Game/Online/SocketClientConnector.cs rename to osu.Game/Online/PersistentEndpointClientConnector.cs index 823e724ef9..fca7f2ed48 100644 --- a/osu.Game/Online/SocketClientConnector.cs +++ b/osu.Game/Online/PersistentEndpointClientConnector.cs @@ -12,7 +12,7 @@ using osu.Game.Online.API; namespace osu.Game.Online { - public abstract class SocketClientConnector : Component + public abstract class PersistentEndpointClientConnector : Component { /// /// Whether this is connected to the hub, use to access the connection, if this is true. @@ -22,7 +22,7 @@ namespace osu.Game.Online /// /// The current connection opened by this connector. /// - public SocketClient? CurrentConnection { get; private set; } + public PersistentEndpointClient? CurrentConnection { get; private set; } private readonly Bindable isConnected = new Bindable(); private readonly SemaphoreSlim connectionLock = new SemaphoreSlim(1); @@ -34,7 +34,7 @@ namespace osu.Game.Online /// Constructs a new . /// /// An API provider used to react to connection state changes. - protected SocketClientConnector(IAPIProvider api) + protected PersistentEndpointClientConnector(IAPIProvider api) { apiState.BindTo(api.State); apiState.BindValueChanged(_ => Task.Run(connectIfPossible), true); @@ -124,7 +124,7 @@ namespace osu.Game.Online await Task.Delay(5000, cancellationToken).ConfigureAwait(false); } - protected abstract Task BuildConnectionAsync(CancellationToken cancellationToken); + protected abstract Task BuildConnectionAsync(CancellationToken cancellationToken); private async Task onConnectionClosed(Exception? ex, CancellationToken cancellationToken) { From c9108ce41bd3afc65a931bbd7f79a770030b75df Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 11:44:16 +0900 Subject: [PATCH 0347/2991] Rename StartAsync -> ConnectAsync --- osu.Game/Online/HubClient.cs | 2 +- osu.Game/Online/PersistentEndpointClient.cs | 2 +- osu.Game/Online/PersistentEndpointClientConnector.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/HubClient.cs b/osu.Game/Online/HubClient.cs index 07428f58b4..583f15a4a4 100644 --- a/osu.Game/Online/HubClient.cs +++ b/osu.Game/Online/HubClient.cs @@ -17,7 +17,7 @@ namespace osu.Game.Online Connection.Closed += InvokeClosed; } - public override Task StartAsync(CancellationToken cancellationToken) => Connection.StartAsync(cancellationToken); + public override Task ConnectAsync(CancellationToken cancellationToken) => Connection.StartAsync(cancellationToken); public override async ValueTask DisposeAsync() { diff --git a/osu.Game/Online/PersistentEndpointClient.cs b/osu.Game/Online/PersistentEndpointClient.cs index d6ed2d8aec..e0307f7c6a 100644 --- a/osu.Game/Online/PersistentEndpointClient.cs +++ b/osu.Game/Online/PersistentEndpointClient.cs @@ -13,7 +13,7 @@ namespace osu.Game.Online protected Task InvokeClosed(Exception? exception) => Closed?.Invoke(exception) ?? Task.CompletedTask; - public abstract Task StartAsync(CancellationToken cancellationToken); + public abstract Task ConnectAsync(CancellationToken cancellationToken); public virtual ValueTask DisposeAsync() { diff --git a/osu.Game/Online/PersistentEndpointClientConnector.cs b/osu.Game/Online/PersistentEndpointClientConnector.cs index fca7f2ed48..7082757b15 100644 --- a/osu.Game/Online/PersistentEndpointClientConnector.cs +++ b/osu.Game/Online/PersistentEndpointClientConnector.cs @@ -92,7 +92,7 @@ namespace osu.Game.Online cancellationToken.ThrowIfCancellationRequested(); - await CurrentConnection.StartAsync(cancellationToken).ConfigureAwait(false); + await CurrentConnection.ConnectAsync(cancellationToken).ConfigureAwait(false); Logger.Log($"{ClientName} connected!", LoggingTarget.Network); isConnected.Value = true; From e59c8b7d24fff0072a1392442808ad55634cb6ba Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 11:49:04 +0900 Subject: [PATCH 0348/2991] Use IDisposable instead --- .../PersistentEndpointClientConnector.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/PersistentEndpointClientConnector.cs b/osu.Game/Online/PersistentEndpointClientConnector.cs index 7082757b15..2ea0c95ec1 100644 --- a/osu.Game/Online/PersistentEndpointClientConnector.cs +++ b/osu.Game/Online/PersistentEndpointClientConnector.cs @@ -6,13 +6,12 @@ using System.Threading; using System.Threading.Tasks; using osu.Framework.Bindables; using osu.Framework.Extensions.TypeExtensions; -using osu.Framework.Graphics; using osu.Framework.Logging; using osu.Game.Online.API; namespace osu.Game.Online { - public abstract class PersistentEndpointClientConnector : Component + public abstract class PersistentEndpointClientConnector : IDisposable { /// /// Whether this is connected to the hub, use to access the connection, if this is true. @@ -173,11 +172,23 @@ namespace osu.Game.Online public override string ToString() => $"{ClientName} ({(IsConnected.Value ? "connected" : "not connected")})"; - protected override void Dispose(bool isDisposing) + private bool isDisposed; + + protected virtual void Dispose(bool isDisposing) { - base.Dispose(isDisposing); + if (isDisposed) + return; + apiState.UnbindAll(); cancelExistingConnect(); + + isDisposed = true; + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); } } } From 2f3c80f884abd31f0b801a8b2c3193d619adfa60 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 13:08:29 +0900 Subject: [PATCH 0349/2991] Remove toggle and change method of application to blend with original colour --- osu.Game/Configuration/OsuConfigManager.cs | 4 +--- .../Settings/Sections/Gameplay/BeatmapSettings.cs | 14 -------------- .../Objects/Drawables/DrawableHitObject.cs | 10 +++++++--- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 08724aab4b..0d56ab8962 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -175,8 +175,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.LastProcessedMetadataId, -1); - SetDefault(OsuSetting.NormaliseComboColourBrightness, false); - SetDefault(OsuSetting.ComboColourBrightness, 0.7f, 0f, 1f); + SetDefault(OsuSetting.ComboColourBrightness, 0f, -1f, 1f, 1f); } protected override bool CheckLookupContainsPrivateInformation(OsuSetting lookup) @@ -367,7 +366,6 @@ namespace osu.Game.Configuration AutomaticallyDownloadWhenSpectating, ShowOnlineExplicitContent, LastProcessedMetadataId, - NormaliseComboColourBrightness, SafeAreaConsiderations, ComboColourBrightness, } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs index 0de8f6509f..8bfa3e502c 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs @@ -17,13 +17,11 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay protected override LocalisableString Header => GameplaySettingsStrings.BeatmapHeader; private readonly BindableFloat comboColourBrightness = new BindableFloat(); - private readonly BindableBool normaliseComboColourBrightness = new BindableBool(); [BackgroundDependencyLoader] private void load(OsuConfigManager config) { config.BindWith(OsuSetting.ComboColourBrightness, comboColourBrightness); - config.BindWith(OsuSetting.NormaliseComboColourBrightness, normaliseComboColourBrightness); Children = new Drawable[] { @@ -47,11 +45,6 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay LabelText = GraphicsSettingsStrings.StoryboardVideo, Current = config.GetBindable(OsuSetting.ShowStoryboard) }, - new SettingsCheckbox - { - LabelText = "Normalise combo colour brightness", - Current = normaliseComboColourBrightness - }, new SettingsSlider { LabelText = "Combo colour brightness", @@ -60,12 +53,5 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay } }; } - - protected override void LoadComplete() - { - base.LoadComplete(); - - normaliseComboColourBrightness.BindValueChanged(normalise => comboColourBrightness.Disabled = !normalise.NewValue, true); - } } } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 8a32c015a3..077606cb3a 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -15,6 +15,7 @@ using osu.Framework.Extensions.TypeExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Primitives; using osu.Framework.Threading; +using osu.Framework.Utils; using osu.Game.Audio; using osu.Game.Configuration; using osu.Game.Graphics; @@ -174,7 +175,6 @@ namespace osu.Game.Rulesets.Objects.Drawables private void load(OsuConfigManager config, ISkinSource skinSource) { config.BindWith(OsuSetting.PositionalHitsoundsLevel, positionalHitsoundsLevel); - config.BindWith(OsuSetting.NormaliseComboColourBrightness, normaliseComboColourBrightness); config.BindWith(OsuSetting.ComboColourBrightness, comboColourBrightness); // Explicit non-virtual function call in case a DrawableHitObject overrides AddInternal. @@ -522,8 +522,12 @@ namespace osu.Game.Rulesets.Objects.Drawables Color4 colour = combo.GetComboColour(CurrentSkin); // Normalise the combo colour to the given brightness level. - if (normaliseComboColourBrightness.Value) - colour = new HSPAColour(colour) { P = comboColourBrightness.Value }.ToColor4(); + if (comboColourBrightness.Value != 0) + { + float pAdjust = 0.6f + 0.4f * comboColourBrightness.Value; + + colour = Interpolation.ValueAt(Math.Abs(comboColourBrightness.Value), colour, new HSPAColour(colour) { P = pAdjust }.ToColor4(), 0, 1, Easing.Out); + } AccentColour.Value = colour; } From 30800c925299a7701e3f83853f47ee22afeb8386 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 13:15:34 +0900 Subject: [PATCH 0350/2991] Add/adjust xmldocs --- osu.Game/Online/PersistentEndpointClient.cs | 11 +++++++++++ osu.Game/Online/PersistentEndpointClientConnector.cs | 8 ++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/PersistentEndpointClient.cs b/osu.Game/Online/PersistentEndpointClient.cs index e0307f7c6a..32c243fbbb 100644 --- a/osu.Game/Online/PersistentEndpointClient.cs +++ b/osu.Game/Online/PersistentEndpointClient.cs @@ -9,10 +9,21 @@ namespace osu.Game.Online { public abstract class PersistentEndpointClient : IAsyncDisposable { + /// + /// An event notifying the that the connection has been closed + /// public event Func? Closed; + /// + /// Notifies the that the connection has been closed. + /// + /// The exception that the connection closed with. protected Task InvokeClosed(Exception? exception) => Closed?.Invoke(exception) ?? Task.CompletedTask; + /// + /// Connects the client to the remote service to begin processing messages. + /// + /// A cancellation token to stop processing messages. public abstract Task ConnectAsync(CancellationToken cancellationToken); public virtual ValueTask DisposeAsync() diff --git a/osu.Game/Online/PersistentEndpointClientConnector.cs b/osu.Game/Online/PersistentEndpointClientConnector.cs index 2ea0c95ec1..70e10c6c7d 100644 --- a/osu.Game/Online/PersistentEndpointClientConnector.cs +++ b/osu.Game/Online/PersistentEndpointClientConnector.cs @@ -14,7 +14,7 @@ namespace osu.Game.Online public abstract class PersistentEndpointClientConnector : IDisposable { /// - /// Whether this is connected to the hub, use to access the connection, if this is true. + /// Whether the managed connection is currently connected. When true use to access the connection. /// public IBindable IsConnected => isConnected; @@ -30,7 +30,7 @@ namespace osu.Game.Online private readonly IBindable apiState = new Bindable(); /// - /// Constructs a new . + /// Constructs a new . /// /// An API provider used to react to connection state changes. protected PersistentEndpointClientConnector(IAPIProvider api) @@ -123,6 +123,10 @@ namespace osu.Game.Online await Task.Delay(5000, cancellationToken).ConfigureAwait(false); } + /// + /// Creates a new . + /// + /// A cancellation token to stop the process. protected abstract Task BuildConnectionAsync(CancellationToken cancellationToken); private async Task onConnectionClosed(Exception? ex, CancellationToken cancellationToken) From 99ba7c29dd99c92bd29396e276558206bc62076b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 13:46:50 +0900 Subject: [PATCH 0351/2991] Change range to 0-100% and rename to "normalisation" --- osu.Game/Configuration/OsuConfigManager.cs | 4 ++-- .../Settings/Sections/Gameplay/BeatmapSettings.cs | 8 ++++---- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 6 ++---- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 0d56ab8962..98776c7487 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -175,7 +175,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.LastProcessedMetadataId, -1); - SetDefault(OsuSetting.ComboColourBrightness, 0f, -1f, 1f, 1f); + SetDefault(OsuSetting.ComboColourNormalisation, 0.2f, 0f, 1f, 0.01f); } protected override bool CheckLookupContainsPrivateInformation(OsuSetting lookup) @@ -367,6 +367,6 @@ namespace osu.Game.Configuration ShowOnlineExplicitContent, LastProcessedMetadataId, SafeAreaConsiderations, - ComboColourBrightness, + ComboColourNormalisation, } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs index 8bfa3e502c..ab9be70a5b 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs @@ -16,12 +16,12 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { protected override LocalisableString Header => GameplaySettingsStrings.BeatmapHeader; - private readonly BindableFloat comboColourBrightness = new BindableFloat(); + private readonly BindableFloat comboColourNormalisation = new BindableFloat(); [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - config.BindWith(OsuSetting.ComboColourBrightness, comboColourBrightness); + config.BindWith(OsuSetting.ComboColourNormalisation, comboColourNormalisation); Children = new Drawable[] { @@ -47,8 +47,8 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay }, new SettingsSlider { - LabelText = "Combo colour brightness", - Current = comboColourBrightness, + LabelText = "Combo colour normalisation", + Current = comboColourNormalisation, DisplayAsPercentage = true, } }; diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 077606cb3a..98fd73c8e9 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -175,7 +175,7 @@ namespace osu.Game.Rulesets.Objects.Drawables private void load(OsuConfigManager config, ISkinSource skinSource) { config.BindWith(OsuSetting.PositionalHitsoundsLevel, positionalHitsoundsLevel); - config.BindWith(OsuSetting.ComboColourBrightness, comboColourBrightness); + config.BindWith(OsuSetting.ComboColourNormalisation, comboColourBrightness); // Explicit non-virtual function call in case a DrawableHitObject overrides AddInternal. base.AddInternal(Samples = new PausableSkinnableSound()); @@ -524,9 +524,7 @@ namespace osu.Game.Rulesets.Objects.Drawables // Normalise the combo colour to the given brightness level. if (comboColourBrightness.Value != 0) { - float pAdjust = 0.6f + 0.4f * comboColourBrightness.Value; - - colour = Interpolation.ValueAt(Math.Abs(comboColourBrightness.Value), colour, new HSPAColour(colour) { P = pAdjust }.ToColor4(), 0, 1, Easing.Out); + colour = Interpolation.ValueAt(Math.Abs(comboColourBrightness.Value), colour, new HSPAColour(colour) { P = 0.6f }.ToColor4(), 0, 1); } AccentColour.Value = colour; From d8aa06ea92fa5a73c23b9305838efbd486aaaa55 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 13:55:01 +0900 Subject: [PATCH 0352/2991] Standardise "Visual Settings" components to fix mismatched paddings and labels --- .../Play/PlayerSettings/PlayerCheckbox.cs | 21 ++++++++++++------- .../Play/PlayerSettings/VisualSettings.cs | 16 ++------------ 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs index dc09676254..cea03d2155 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs @@ -1,22 +1,27 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Settings; namespace osu.Game.Screens.Play.PlayerSettings { - public class PlayerCheckbox : OsuCheckbox + public class PlayerCheckbox : SettingsCheckbox { - [BackgroundDependencyLoader] - private void load(OsuColour colours) + protected override Drawable CreateControl() => new PlayerCheckboxControl(); + + public class PlayerCheckboxControl : OsuCheckbox { - Nub.AccentColour = colours.Yellow; - Nub.GlowingAccentColour = colours.YellowLighter; - Nub.GlowColour = colours.YellowDark; + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Nub.AccentColour = colours.Yellow; + Nub.GlowingAccentColour = colours.YellowLighter; + Nub.GlowColour = colours.YellowDark; + } } } } diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs index e55af0bba7..72a57f658c 100644 --- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Configuration; @@ -24,26 +22,16 @@ namespace osu.Game.Screens.Play.PlayerSettings { Children = new Drawable[] { - new OsuSpriteText - { - Text = GameplaySettingsStrings.BackgroundDim - }, dimSliderBar = new PlayerSliderBar { + LabelText = GameplaySettingsStrings.BackgroundDim, DisplayAsPercentage = true }, - new OsuSpriteText - { - Text = GameplaySettingsStrings.BackgroundBlur - }, blurSliderBar = new PlayerSliderBar { + LabelText = GameplaySettingsStrings.BackgroundBlur, DisplayAsPercentage = true }, - new OsuSpriteText - { - Text = "Toggles:" - }, showStoryboardToggle = new PlayerCheckbox { LabelText = GraphicsSettingsStrings.StoryboardVideo }, beatmapSkinsToggle = new PlayerCheckbox { LabelText = SkinSettingsStrings.BeatmapSkins }, beatmapColorsToggle = new PlayerCheckbox { LabelText = SkinSettingsStrings.BeatmapColours }, From 61fc3c8cc0878dab7cea7a4dbc7d0bb26e6e6fab Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 13:48:03 +0900 Subject: [PATCH 0353/2991] Add setting to visual settings toolbox --- osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs index 72a57f658c..10d132fc4d 100644 --- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs @@ -4,7 +4,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Configuration; -using osu.Game.Graphics.Sprites; using osu.Game.Localisation; namespace osu.Game.Screens.Play.PlayerSettings @@ -13,6 +12,7 @@ namespace osu.Game.Screens.Play.PlayerSettings { private readonly PlayerSliderBar dimSliderBar; private readonly PlayerSliderBar blurSliderBar; + private readonly PlayerSliderBar comboColourNormalisationSliderBar; private readonly PlayerCheckbox showStoryboardToggle; private readonly PlayerCheckbox beatmapSkinsToggle; private readonly PlayerCheckbox beatmapColorsToggle; @@ -35,6 +35,11 @@ namespace osu.Game.Screens.Play.PlayerSettings showStoryboardToggle = new PlayerCheckbox { LabelText = GraphicsSettingsStrings.StoryboardVideo }, beatmapSkinsToggle = new PlayerCheckbox { LabelText = SkinSettingsStrings.BeatmapSkins }, beatmapColorsToggle = new PlayerCheckbox { LabelText = SkinSettingsStrings.BeatmapColours }, + comboColourNormalisationSliderBar = new PlayerSliderBar + { + LabelText = "Combo colour normalisation", + DisplayAsPercentage = true, + }, }; } @@ -46,6 +51,7 @@ namespace osu.Game.Screens.Play.PlayerSettings showStoryboardToggle.Current = config.GetBindable(OsuSetting.ShowStoryboard); beatmapSkinsToggle.Current = config.GetBindable(OsuSetting.BeatmapSkins); beatmapColorsToggle.Current = config.GetBindable(OsuSetting.BeatmapColours); + comboColourNormalisationSliderBar.Current = config.GetBindable(OsuSetting.ComboColourNormalisation); } } } From 50b6fe4acb24e5fa9794d9653489c84d78989d12 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 14:01:03 +0900 Subject: [PATCH 0354/2991] Localise new label --- osu.Game/Localisation/GraphicsSettingsStrings.cs | 5 +++++ .../Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs | 2 +- osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Localisation/GraphicsSettingsStrings.cs b/osu.Game/Localisation/GraphicsSettingsStrings.cs index 2ab9d9de87..6e05929d81 100644 --- a/osu.Game/Localisation/GraphicsSettingsStrings.cs +++ b/osu.Game/Localisation/GraphicsSettingsStrings.cs @@ -99,6 +99,11 @@ namespace osu.Game.Localisation /// public static LocalisableString StoryboardVideo => new TranslatableString(getKey(@"storyboard_video"), @"Storyboard / video"); + /// + /// "Combo colour normalisation" + /// + public static LocalisableString ComboColourNormalisation => new TranslatableString(getKey(@"combo_colour_normalisation"), @"Combo colour normalisation"); + /// /// "Hit lighting" /// diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs index ab9be70a5b..8d64337eab 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs @@ -47,7 +47,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay }, new SettingsSlider { - LabelText = "Combo colour normalisation", + LabelText = GraphicsSettingsStrings.ComboColourNormalisation, Current = comboColourNormalisation, DisplayAsPercentage = true, } diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs index 10d132fc4d..c837f61a09 100644 --- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs @@ -37,7 +37,7 @@ namespace osu.Game.Screens.Play.PlayerSettings beatmapColorsToggle = new PlayerCheckbox { LabelText = SkinSettingsStrings.BeatmapColours }, comboColourNormalisationSliderBar = new PlayerSliderBar { - LabelText = "Combo colour normalisation", + LabelText = GraphicsSettingsStrings.ComboColourNormalisation, DisplayAsPercentage = true, }, }; From 37300ba9e25ae1d2e3f6e9dd747d27b5fa4d18c9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 13:55:01 +0900 Subject: [PATCH 0355/2991] Standardise "Visual Settings" components to fix mismatched paddings and labels --- .../Play/PlayerSettings/PlayerCheckbox.cs | 21 ++++++++++++------- .../Play/PlayerSettings/VisualSettings.cs | 17 ++------------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs index dc09676254..cea03d2155 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs @@ -1,22 +1,27 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Settings; namespace osu.Game.Screens.Play.PlayerSettings { - public class PlayerCheckbox : OsuCheckbox + public class PlayerCheckbox : SettingsCheckbox { - [BackgroundDependencyLoader] - private void load(OsuColour colours) + protected override Drawable CreateControl() => new PlayerCheckboxControl(); + + public class PlayerCheckboxControl : OsuCheckbox { - Nub.AccentColour = colours.Yellow; - Nub.GlowingAccentColour = colours.YellowLighter; - Nub.GlowColour = colours.YellowDark; + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Nub.AccentColour = colours.Yellow; + Nub.GlowingAccentColour = colours.YellowLighter; + Nub.GlowColour = colours.YellowDark; + } } } } diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs index e55af0bba7..bb3360acec 100644 --- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Configuration; -using osu.Game.Graphics.Sprites; using osu.Game.Localisation; namespace osu.Game.Screens.Play.PlayerSettings @@ -24,26 +21,16 @@ namespace osu.Game.Screens.Play.PlayerSettings { Children = new Drawable[] { - new OsuSpriteText - { - Text = GameplaySettingsStrings.BackgroundDim - }, dimSliderBar = new PlayerSliderBar { + LabelText = GameplaySettingsStrings.BackgroundDim, DisplayAsPercentage = true }, - new OsuSpriteText - { - Text = GameplaySettingsStrings.BackgroundBlur - }, blurSliderBar = new PlayerSliderBar { + LabelText = GameplaySettingsStrings.BackgroundBlur, DisplayAsPercentage = true }, - new OsuSpriteText - { - Text = "Toggles:" - }, showStoryboardToggle = new PlayerCheckbox { LabelText = GraphicsSettingsStrings.StoryboardVideo }, beatmapSkinsToggle = new PlayerCheckbox { LabelText = SkinSettingsStrings.BeatmapSkins }, beatmapColorsToggle = new PlayerCheckbox { LabelText = SkinSettingsStrings.BeatmapColours }, From e761c0395d411aadc40e565f8deeff43c641c4a6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 14:47:56 +0900 Subject: [PATCH 0356/2991] Fix multiple notifications arriving for imports in edge cases --- osu.Game/Overlays/Notifications/ProgressNotification.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Notifications/ProgressNotification.cs b/osu.Game/Overlays/Notifications/ProgressNotification.cs index 4cf47013bd..7b62c95179 100644 --- a/osu.Game/Overlays/Notifications/ProgressNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressNotification.cs @@ -148,7 +148,7 @@ namespace osu.Game.Overlays.Notifications } } - private bool completionSent; + private int completionSent; /// /// Attempt to post a completion notification. @@ -162,11 +162,11 @@ namespace osu.Game.Overlays.Notifications if (CompletionTarget == null) return; - if (completionSent) + // Thread-safe barrier, as this may be called by a web request and also scheduled to the update thread at the same time. + if (Interlocked.Increment(ref completionSent) == 0) return; CompletionTarget.Invoke(CreateCompletionNotification()); - completionSent = true; Close(false); } From df1f7e2b13192efc811594d8bbfbf6b2eaab607f Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 2 Nov 2022 15:09:40 +0900 Subject: [PATCH 0357/2991] remove `#nullable disable` --- osu.Game/Graphics/Containers/UserDimContainer.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index 296855522b..a6a8f341b6 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -46,13 +44,13 @@ namespace osu.Game.Graphics.Containers /// public bool ContentDisplayed { get; private set; } - protected Bindable UserDimLevel { get; private set; } + protected Bindable UserDimLevel { get; private set; } = null!; public Bindable DimAmount { get; set; } = new Bindable(); - protected Bindable LightenDuringBreaks { get; private set; } + protected Bindable LightenDuringBreaks { get; private set; } = null!; - protected Bindable ShowStoryboard { get; private set; } + protected Bindable ShowStoryboard { get; private set; } = null!; private float breakLightening => LightenDuringBreaks.Value && IsBreakTime.Value ? BREAK_LIGHTEN_AMOUNT : 0; From d6b8439121ce20ec11c8ad2bfae9892394ba9523 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 2 Nov 2022 15:11:49 +0900 Subject: [PATCH 0358/2991] add xmldoc for DimAmount --- osu.Game/Graphics/Containers/UserDimContainer.cs | 3 +++ osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index a6a8f341b6..62dd4e19b0 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -46,6 +46,9 @@ namespace osu.Game.Graphics.Containers protected Bindable UserDimLevel { get; private set; } = null!; + /// + /// The amount of dim to be override if is true. + /// public Bindable DimAmount { get; set; } = new Bindable(); protected Bindable LightenDuringBreaks { get; private set; } = null!; diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs index 053bcf2387..9f3e99d793 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs @@ -43,6 +43,9 @@ namespace osu.Game.Screens.Backgrounds /// public readonly Bindable BlurAmount = new BindableFloat(); + /// + /// The amount of dim to be override if is true. + /// public readonly Bindable DimAmount = new Bindable(); internal readonly IBindable IsBreakTime = new Bindable(); From 98846182909f5be197ce44c413ccdc05cfa79e48 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 2 Nov 2022 15:12:15 +0900 Subject: [PATCH 0359/2991] rename `editorDim` to `editorBackgroundDim` --- osu.Game/Screens/Edit/Editor.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 3c91d302ae..04fa96171d 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -175,7 +175,7 @@ namespace osu.Game.Screens.Edit [Resolved(canBeNull: true)] private OnScreenDisplay onScreenDisplay { get; set; } - private Bindable editorDim; + private Bindable editorBackgroundDim; public Editor(EditorLoader loader = null) { @@ -261,7 +261,7 @@ namespace osu.Game.Screens.Edit OsuMenuItem undoMenuItem; OsuMenuItem redoMenuItem; - editorDim = config.GetBindable(OsuSetting.EditorDim); + editorBackgroundDim = config.GetBindable(OsuSetting.EditorDim); AddInternal(new OsuContextMenuContainer { @@ -314,7 +314,7 @@ namespace osu.Game.Screens.Edit Items = new MenuItem[] { new WaveformOpacityMenuItem(config.GetBindable(OsuSetting.EditorWaveformOpacity)), - new BackgroundDimMenuItem(editorDim), + new BackgroundDimMenuItem(editorBackgroundDim), } } } @@ -335,7 +335,7 @@ namespace osu.Game.Screens.Edit changeHandler?.CanUndo.BindValueChanged(v => undoMenuItem.Action.Disabled = !v.NewValue, true); changeHandler?.CanRedo.BindValueChanged(v => redoMenuItem.Action.Disabled = !v.NewValue, true); - editorDim.BindValueChanged(_ => dimBackground()); + editorBackgroundDim.BindValueChanged(_ => dimBackground()); } [Resolved] @@ -632,7 +632,7 @@ namespace osu.Game.Screens.Edit ApplyToBackground(b => { b.IgnoreUserSettings.Value = true; - b.DimAmount.Value = editorDim.Value; + b.DimAmount.Value = editorBackgroundDim.Value; b.BlurAmount.Value = 0; }); } From e5f53b1ad8346c3d0e9241bfd79138df2aae3121 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 15:18:47 +0900 Subject: [PATCH 0360/2991] Use Interlocked.Exhange() instead Increment isn't correct since it returns the post-incremented value. It also always increments. --- osu.Game/Overlays/Notifications/ProgressNotification.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Notifications/ProgressNotification.cs b/osu.Game/Overlays/Notifications/ProgressNotification.cs index 7b62c95179..54a1d69a9e 100644 --- a/osu.Game/Overlays/Notifications/ProgressNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressNotification.cs @@ -163,7 +163,7 @@ namespace osu.Game.Overlays.Notifications return; // Thread-safe barrier, as this may be called by a web request and also scheduled to the update thread at the same time. - if (Interlocked.Increment(ref completionSent) == 0) + if (Interlocked.Exchange(ref completionSent, 1) == 0) return; CompletionTarget.Invoke(CreateCompletionNotification()); From fe66b207020fb816b1395fc50d507717ef8bcf16 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 15:22:46 +0900 Subject: [PATCH 0361/2991] Fix one more case of constructing connector directly --- osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs index 99cd9beecf..04dfe5f7c2 100644 --- a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs +++ b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs @@ -49,7 +49,7 @@ namespace osu.Game.Tournament.Components if (manager == null) { - AddInternal(manager = new ChannelManager(api, new WebSocketNotificationsClientConnector(api))); + AddInternal(manager = new ChannelManager(api, api.GetNotificationsConnector())); Channel.BindTo(manager.CurrentChannel); } From 58c6b026ae503097b86f8c8f139912042fa3360a Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 15:23:11 +0900 Subject: [PATCH 0362/2991] Remove unused using --- osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs index 04dfe5f7c2..48ff45974d 100644 --- a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs +++ b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs @@ -9,7 +9,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Online.API; using osu.Game.Online.Chat; -using osu.Game.Online.Notifications.WebSocket; using osu.Game.Overlays.Chat; using osu.Game.Tournament.IPC; using osu.Game.Tournament.Models; From db34f238c09597748ff5c9e6c22211d8b8346641 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 15:47:30 +0900 Subject: [PATCH 0363/2991] Fix inverted condition --- osu.Game/Overlays/Notifications/ProgressNotification.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Notifications/ProgressNotification.cs b/osu.Game/Overlays/Notifications/ProgressNotification.cs index 54a1d69a9e..9812feb4a1 100644 --- a/osu.Game/Overlays/Notifications/ProgressNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressNotification.cs @@ -163,7 +163,7 @@ namespace osu.Game.Overlays.Notifications return; // Thread-safe barrier, as this may be called by a web request and also scheduled to the update thread at the same time. - if (Interlocked.Exchange(ref completionSent, 1) == 0) + if (Interlocked.Exchange(ref completionSent, 1) == 1) return; CompletionTarget.Invoke(CreateCompletionNotification()); From 695104a66666a46f5a1b9429694aa6071320dc62 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 16:59:03 +0900 Subject: [PATCH 0364/2991] Fix TestSceneChatOverlay messages not being unique --- osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 6b2124f1f8..fd1bd4f0df 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -42,6 +42,7 @@ namespace osu.Game.Tests.Visual.Online private readonly APIUser testUser = new APIUser { Username = "test user", Id = 5071479 }; private Channel[] testChannels; + private Message[] initialMessages; private Channel testChannel1 => testChannels[0]; private Channel testChannel2 => testChannels[1]; @@ -49,10 +50,14 @@ namespace osu.Game.Tests.Visual.Online [Resolved] private OsuConfigManager config { get; set; } = null!; + private int currentMessageId; + [SetUp] public void SetUp() => Schedule(() => { + currentMessageId = 0; testChannels = Enumerable.Range(1, 10).Select(createPublicChannel).ToArray(); + initialMessages = testChannels.SelectMany(createChannelMessages).ToArray(); Child = new DependencyProvidingContainer { @@ -99,7 +104,7 @@ namespace osu.Game.Tests.Visual.Online return true; case GetMessagesRequest getMessages: - getMessages.TriggerSuccess(createChannelMessages(getMessages.Channel)); + getMessages.TriggerSuccess(initialMessages.ToList()); return true; case GetUserRequest getUser: @@ -546,7 +551,7 @@ namespace osu.Game.Tests.Visual.Online private List createChannelMessages(Channel channel) { - var message = new Message + var message = new Message(currentMessageId++) { ChannelId = channel.Id, Content = $"Hello, this is a message in {channel.Name}", From f688ed12d0b611a5955b817e127a3acd32fc6f98 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 17:00:47 +0900 Subject: [PATCH 0365/2991] Add test for removing chat messages --- .../Visual/Online/TestSceneChatOverlay.cs | 30 +++++++++++++++++++ osu.Game/Online/Chat/Channel.cs | 14 +++++++++ 2 files changed, 44 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index fd1bd4f0df..260b47e836 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -40,6 +40,7 @@ namespace osu.Game.Tests.Visual.Online private ChannelManager channelManager; private readonly APIUser testUser = new APIUser { Username = "test user", Id = 5071479 }; + private readonly APIUser testUser1 = new APIUser { Username = "test user", Id = 5071480 }; private Channel[] testChannels; private Message[] initialMessages; @@ -500,6 +501,35 @@ namespace osu.Game.Tests.Visual.Online waitForChannel1Visible(); } + [Test] + public void TestRemoveMessages() + { + AddStep("Show overlay with channel", () => + { + chatOverlay.Show(); + channelManager.CurrentChannel.Value = channelManager.JoinChannel(testChannel1); + }); + + AddAssert("Overlay is visible", () => chatOverlay.State.Value == Visibility.Visible); + waitForChannel1Visible(); + + AddStep("Send message from another user", () => + { + testChannel1.AddNewMessages(new Message + { + ChannelId = testChannel1.Id, + Content = "Message from another user", + Timestamp = DateTimeOffset.Now, + Sender = testUser1, + }); + }); + + AddStep("Remove messages from other user", () => + { + testChannel1.RemoveMessagesFromUser(testUser.Id); + }); + } + private void joinTestChannel(int i) { AddStep($"Join test channel {i}", () => channelManager.JoinChannel(testChannels[i])); diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index f51ea3e8d6..17a6a430b6 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -149,6 +149,20 @@ namespace osu.Game.Online.Chat NewMessagesArrived?.Invoke(messages); } + public void RemoveMessagesFromUser(int userId) + { + for (int i = 0; i < Messages.Count; i++) + { + var message = Messages[i]; + + if (message.SenderId == userId) + { + Messages.RemoveAt(i--); + MessageRemoved?.Invoke(message); + } + } + } + /// /// Replace or remove a message from the channel. /// From 063a8bdf9e3f12461a6201b33ae182be35a4a102 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 17:13:14 +0900 Subject: [PATCH 0366/2991] Remove messages from silenced users --- .../Chat/TestSceneChannelManager.cs | 29 ++++++++++++++++ .../Online/API/Requests/ChatAckRequest.cs | 6 ++++ .../API/Requests/Responses/ChatSilence.cs | 2 +- osu.Game/Online/Chat/ChannelManager.cs | 34 +++++++++++++++++-- 4 files changed, 68 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Chat/TestSceneChannelManager.cs b/osu.Game.Tests/Chat/TestSceneChannelManager.cs index 86be638781..f559b0db73 100644 --- a/osu.Game.Tests/Chat/TestSceneChannelManager.cs +++ b/osu.Game.Tests/Chat/TestSceneChannelManager.cs @@ -23,6 +23,7 @@ namespace osu.Game.Tests.Chat private ChannelManager channelManager; private int currentMessageId; private List sentMessages; + private List silencedUserIds; [SetUp] public void Setup() => Schedule(() => @@ -39,6 +40,7 @@ namespace osu.Game.Tests.Chat { currentMessageId = 0; sentMessages = new List(); + silencedUserIds = new List(); ((DummyAPIAccess)API).HandleRequest = req => { @@ -55,6 +57,11 @@ namespace osu.Game.Tests.Chat case MarkChannelAsReadRequest markRead: handleMarkChannelAsReadRequest(markRead); return true; + + case ChatAckRequest ack: + ack.TriggerSuccess(new ChatAckResponse { Silences = silencedUserIds.Select(u => new ChatSilence { UserId = u }).ToList() }); + silencedUserIds.Clear(); + return true; } return false; @@ -106,6 +113,28 @@ namespace osu.Game.Tests.Chat AddAssert("channel's last read ID is set to the latest message", () => channel.LastReadId == sentMessages.Last().Id); } + [Test] + public void TestSilencedUsersAreRemoved() + { + Channel channel = null; + + AddStep("join channel and select it", () => + { + channelManager.JoinChannel(channel = createChannel(1, ChannelType.Public)); + channelManager.CurrentChannel.Value = channel; + }); + + AddStep("post message", () => channelManager.PostMessage("Definitely something bad")); + + AddStep("mark user as silenced and send ack request", () => + { + silencedUserIds.Add(API.LocalUser.Value.OnlineID); + channelManager.SendAck(); + }); + + AddAssert("channel has no more messages", () => channel.Messages, () => Is.Empty); + } + private void handlePostMessageRequest(PostMessageRequest request) { var message = new Message(++currentMessageId) diff --git a/osu.Game/Online/API/Requests/ChatAckRequest.cs b/osu.Game/Online/API/Requests/ChatAckRequest.cs index f09df4908e..78f51e21c0 100644 --- a/osu.Game/Online/API/Requests/ChatAckRequest.cs +++ b/osu.Game/Online/API/Requests/ChatAckRequest.cs @@ -9,10 +9,16 @@ namespace osu.Game.Online.API.Requests { public class ChatAckRequest : APIRequest { + public long SinceMessageId; + public uint? SinceSilenceId; + protected override WebRequest CreateWebRequest() { var req = base.CreateWebRequest(); req.Method = HttpMethod.Post; + req.AddParameter(@"since", SinceMessageId.ToString()); + if (SinceSilenceId != null) + req.AddParameter(@"history_since", SinceSilenceId.Value.ToString()); return req; } diff --git a/osu.Game/Online/API/Requests/Responses/ChatSilence.cs b/osu.Game/Online/API/Requests/Responses/ChatSilence.cs index 45fd6e1ba3..afb44e385e 100644 --- a/osu.Game/Online/API/Requests/Responses/ChatSilence.cs +++ b/osu.Game/Online/API/Requests/Responses/ChatSilence.cs @@ -12,6 +12,6 @@ namespace osu.Game.Online.API.Requests.Responses public uint Id { get; set; } [JsonProperty("user_id")] - public uint UserId { get; set; } + public int UserId { get; set; } } } diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index a901c15bf4..b9a0aacf5a 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -74,6 +74,9 @@ namespace osu.Game.Online.Chat private bool channelsInitialised; private ScheduledDelegate ackDelegate; + private long lastMessageId; + private uint? lastSilenceId; + public ChannelManager(IAPIProvider api, NotificationsClientConnector connector) { this.api = api; @@ -106,8 +109,7 @@ namespace osu.Game.Online.Chat if (status.NewValue == APIState.Online) { - Scheduler.Add(ackDelegate = new ScheduledDelegate(() => api.Queue(new ChatAckRequest()), 0, 60000)); - // Todo: Handle silences. + Scheduler.Add(ackDelegate = new ScheduledDelegate(SendAck, 0, 60000)); } }, true); } @@ -342,6 +344,8 @@ namespace osu.Game.Online.Chat foreach (var group in messages.GroupBy(m => m.ChannelId)) channels.Find(c => c.Id == group.Key)?.AddNewMessages(group.ToArray()); + + lastMessageId = messages.LastOrDefault()?.Id ?? lastMessageId; } private void initializeChannels() @@ -391,6 +395,32 @@ namespace osu.Game.Online.Chat api.Queue(fetchInitialMsgReq); } + /// + /// Sends an acknowledgement request to the API. + /// This marks the user as online to receive messages from public channels, while also returning a list of silenced users. + /// It needs to be called at least once every 10 minutes. + /// + public void SendAck() + { + var req = new ChatAckRequest + { + SinceMessageId = lastMessageId, + SinceSilenceId = lastSilenceId + }; + + req.Success += ack => + { + foreach (var silence in ack.Silences) + { + foreach (var channel in JoinedChannels) + channel.RemoveMessagesFromUser(silence.UserId); + lastSilenceId = Math.Max(lastSilenceId ?? 0, silence.Id); + } + }; + + api.Queue(req); + } + /// /// Find an existing channel instance for the provided channel. Lookup is performed basd on ID. /// The provided channel may be used if an existing instance is not found. From c66064872a18d1bd75cdcdde80fa4242f5054978 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 15:45:23 +0900 Subject: [PATCH 0367/2991] Fix `DrawableHit` test scene not showing rim hits correctly --- .../Skinning/TestSceneDrawableHit.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs index 8e9c487c2f..eb2b6c1d74 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs @@ -30,23 +30,24 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning Origin = Anchor.Centre, })); - AddStep("Rim hit", () => SetContents(_ => new DrawableHit(createHitAtCurrentTime()) + AddStep("Rim hit", () => SetContents(_ => new DrawableHit(createHitAtCurrentTime(rim: true)) { Anchor = Anchor.Centre, Origin = Anchor.Centre, })); - AddStep("Rim hit (strong)", () => SetContents(_ => new DrawableHit(createHitAtCurrentTime(true)) + AddStep("Rim hit (strong)", () => SetContents(_ => new DrawableHit(createHitAtCurrentTime(true, true)) { Anchor = Anchor.Centre, Origin = Anchor.Centre, })); } - private Hit createHitAtCurrentTime(bool strong = false) + private Hit createHitAtCurrentTime(bool strong = false, bool rim = false) { var hit = new Hit { + Type = rim ? HitType.Rim : HitType.Centre, IsStrong = strong, StartTime = Time.Current + 3000, }; From 0689d3845ff82fcae11f5e35e65f72b0e1e6be7a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 16:55:17 +0900 Subject: [PATCH 0368/2991] Fix `TestSceneHitExplosion` not maintaining aspect ratio --- .../Skinning/TestSceneHitExplosion.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneHitExplosion.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneHitExplosion.cs index f87e0355ad..0ddc607336 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneHitExplosion.cs @@ -13,6 +13,7 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.UI; +using osu.Game.Screens.Ranking; namespace osu.Game.Rulesets.Taiko.Tests.Skinning { @@ -49,11 +50,19 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning // the hit needs to be added to hierarchy in order for nested objects to be created correctly. // setting zero alpha is supposed to prevent the test from looking broken. hit.With(h => h.Alpha = 0), - new HitExplosion(hit.Type) + + new AspectContainer { + RelativeSizeAxes = Axes.X, Anchor = Anchor.Centre, Origin = Anchor.Centre, - }.With(explosion => explosion.Apply(hit)) + Child = + new HitExplosion(hit.Type) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }.With(explosion => explosion.Apply(hit)) + } } }; } From 9c758e542505adc7e64049993d843e359c0c0410 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 17:00:39 +0900 Subject: [PATCH 0369/2991] Move `DefaultInputDrum` to correct location --- .../Skinning/Default/DefaultInputDrum.cs | 181 ++++++++++++++++++ osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 172 +---------------- 2 files changed, 182 insertions(+), 171 deletions(-) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs new file mode 100644 index 0000000000..fa60d209e7 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs @@ -0,0 +1,181 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable disable +using System; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Framework.Input.Bindings; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Screens.Ranking; +using osuTK; + +namespace osu.Game.Rulesets.Taiko.Skinning.Default +{ + public class DefaultInputDrum : AspectContainer + { + public DefaultInputDrum() + { + RelativeSizeAxes = Axes.Y; + } + + [BackgroundDependencyLoader] + private void load() + { + const float middle_split = 0.025f; + + InternalChild = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Scale = new Vector2(0.9f), + Children = new[] + { + new TaikoHalfDrum(false) + { + Name = "Left Half", + Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.X, + X = -middle_split / 2, + RimAction = TaikoAction.LeftRim, + CentreAction = TaikoAction.LeftCentre + }, + new TaikoHalfDrum(true) + { + Name = "Right Half", + Anchor = Anchor.Centre, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.X, + X = middle_split / 2, + RimAction = TaikoAction.RightRim, + CentreAction = TaikoAction.RightCentre + } + } + }; + } + + /// + /// A half-drum. Contains one centre and one rim hit. + /// + private class TaikoHalfDrum : Container, IKeyBindingHandler + { + /// + /// The key to be used for the rim of the half-drum. + /// + public TaikoAction RimAction; + + /// + /// The key to be used for the centre of the half-drum. + /// + public TaikoAction CentreAction; + + private readonly Sprite rim; + private readonly Sprite rimHit; + private readonly Sprite centre; + private readonly Sprite centreHit; + + public TaikoHalfDrum(bool flipped) + { + Masking = true; + + Children = new Drawable[] + { + rim = new Sprite + { + Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both + }, + rimHit = new Sprite + { + Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Alpha = 0, + Blending = BlendingParameters.Additive, + }, + centre = new Sprite + { + Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Size = new Vector2(0.7f) + }, + centreHit = new Sprite + { + Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Size = new Vector2(0.7f), + Alpha = 0, + Blending = BlendingParameters.Additive + } + }; + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures, OsuColour colours) + { + rim.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer"); + rimHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer-hit"); + centre.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner"); + centreHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner-hit"); + + rimHit.Colour = colours.Blue; + centreHit.Colour = colours.Pink; + } + + public bool OnPressed(KeyBindingPressEvent e) + { + Drawable target = null; + Drawable back = null; + + if (e.Action == CentreAction) + { + target = centreHit; + back = centre; + } + else if (e.Action == RimAction) + { + target = rimHit; + back = rim; + } + + if (target != null) + { + const float scale_amount = 0.05f; + const float alpha_amount = 0.5f; + + const float down_time = 40; + const float up_time = 1000; + + back.ScaleTo(target.Scale.X - scale_amount, down_time, Easing.OutQuint) + .Then() + .ScaleTo(1, up_time, Easing.OutQuint); + + target.Animate( + t => t.ScaleTo(target.Scale.X - scale_amount, down_time, Easing.OutQuint), + t => t.FadeTo(Math.Min(target.Alpha + alpha_amount, 1), down_time, Easing.OutQuint) + ).Then( + t => t.ScaleTo(1, up_time, Easing.OutQuint), + t => t.FadeOut(up_time, Easing.OutQuint) + ); + } + + return false; + } + + public void OnReleased(KeyBindingReleaseEvent e) + { + } + } + } +} diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 054f98e18f..94e7138142 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -3,18 +3,11 @@ #nullable disable -using System; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; -using osu.Framework.Input.Bindings; -using osu.Framework.Input.Events; -using osu.Game.Graphics; -using osu.Game.Screens.Ranking; +using osu.Game.Rulesets.Taiko.Skinning.Default; using osu.Game.Skinning; -using osuTK; namespace osu.Game.Rulesets.Taiko.UI { @@ -23,8 +16,6 @@ namespace osu.Game.Rulesets.Taiko.UI /// internal class InputDrum : Container { - private const float middle_split = 0.025f; - public InputDrum() { AutoSizeAxes = Axes.X; @@ -43,166 +34,5 @@ namespace osu.Game.Rulesets.Taiko.UI }, }; } - - private class DefaultInputDrum : AspectContainer - { - public DefaultInputDrum() - { - RelativeSizeAxes = Axes.Y; - } - - [BackgroundDependencyLoader] - private void load() - { - InternalChild = new Container - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Scale = new Vector2(0.9f), - Children = new[] - { - new TaikoHalfDrum(false) - { - Name = "Left Half", - Anchor = Anchor.Centre, - Origin = Anchor.CentreRight, - RelativeSizeAxes = Axes.Both, - RelativePositionAxes = Axes.X, - X = -middle_split / 2, - RimAction = TaikoAction.LeftRim, - CentreAction = TaikoAction.LeftCentre - }, - new TaikoHalfDrum(true) - { - Name = "Right Half", - Anchor = Anchor.Centre, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.Both, - RelativePositionAxes = Axes.X, - X = middle_split / 2, - RimAction = TaikoAction.RightRim, - CentreAction = TaikoAction.RightCentre - } - } - }; - } - - /// - /// A half-drum. Contains one centre and one rim hit. - /// - private class TaikoHalfDrum : Container, IKeyBindingHandler - { - /// - /// The key to be used for the rim of the half-drum. - /// - public TaikoAction RimAction; - - /// - /// The key to be used for the centre of the half-drum. - /// - public TaikoAction CentreAction; - - private readonly Sprite rim; - private readonly Sprite rimHit; - private readonly Sprite centre; - private readonly Sprite centreHit; - - public TaikoHalfDrum(bool flipped) - { - Masking = true; - - Children = new Drawable[] - { - rim = new Sprite - { - Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both - }, - rimHit = new Sprite - { - Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Alpha = 0, - Blending = BlendingParameters.Additive, - }, - centre = new Sprite - { - Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Size = new Vector2(0.7f) - }, - centreHit = new Sprite - { - Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Size = new Vector2(0.7f), - Alpha = 0, - Blending = BlendingParameters.Additive - } - }; - } - - [BackgroundDependencyLoader] - private void load(TextureStore textures, OsuColour colours) - { - rim.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer"); - rimHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer-hit"); - centre.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner"); - centreHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner-hit"); - - rimHit.Colour = colours.Blue; - centreHit.Colour = colours.Pink; - } - - public bool OnPressed(KeyBindingPressEvent e) - { - Drawable target = null; - Drawable back = null; - - if (e.Action == CentreAction) - { - target = centreHit; - back = centre; - } - else if (e.Action == RimAction) - { - target = rimHit; - back = rim; - } - - if (target != null) - { - const float scale_amount = 0.05f; - const float alpha_amount = 0.5f; - - const float down_time = 40; - const float up_time = 1000; - - back.ScaleTo(target.Scale.X - scale_amount, down_time, Easing.OutQuint) - .Then() - .ScaleTo(1, up_time, Easing.OutQuint); - - target.Animate( - t => t.ScaleTo(target.Scale.X - scale_amount, down_time, Easing.OutQuint), - t => t.FadeTo(Math.Min(target.Alpha + alpha_amount, 1), down_time, Easing.OutQuint) - ).Then( - t => t.ScaleTo(1, up_time, Easing.OutQuint), - t => t.FadeOut(up_time, Easing.OutQuint) - ); - } - - return false; - } - - public void OnReleased(KeyBindingReleaseEvent e) - { - } - } - } } } From 2407eb063d4850f23d29b9fa9364722a7a84e744 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 16:51:55 +0900 Subject: [PATCH 0370/2991] Simplify `Circle` usage in default `CentreHitCirclePiece` --- .../Skinning/Default/CentreHitCirclePiece.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs index b91d5cfe8d..958f4b3a17 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs @@ -41,12 +41,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default Children = new[] { - new CircularContainer - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Children = new[] { new Box { RelativeSizeAxes = Axes.Both } } - } + new Circle { RelativeSizeAxes = Axes.Both } }; } } From 910dd3ad01ed44be94c0bc5503134b214e19bc08 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 17:04:45 +0900 Subject: [PATCH 0371/2991] Move more default classes to correct namespace --- .../Default}/DefaultHitExplosion.cs | 14 ++++++-------- .../Default}/DefaultKiaiHitExplosion.cs | 6 ++---- osu.Game.Rulesets.Taiko/UI/HitExplosion.cs | 1 + osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs | 1 + 4 files changed, 10 insertions(+), 12 deletions(-) rename osu.Game.Rulesets.Taiko/{UI => Skinning/Default}/DefaultHitExplosion.cs (87%) rename osu.Game.Rulesets.Taiko/{UI => Skinning/Default}/DefaultKiaiHitExplosion.cs (96%) diff --git a/osu.Game.Rulesets.Taiko/UI/DefaultHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs similarity index 87% rename from osu.Game.Rulesets.Taiko/UI/DefaultHitExplosion.cs rename to osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs index 687c8f788f..58f45fda7c 100644 --- a/osu.Game.Rulesets.Taiko/UI/DefaultHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs @@ -1,9 +1,7 @@ +#nullable enable // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -12,19 +10,19 @@ using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.UI; using osuTK.Graphics; -namespace osu.Game.Rulesets.Taiko.UI +namespace osu.Game.Rulesets.Taiko.Skinning.Default { internal class DefaultHitExplosion : CircularContainer, IAnimatableHitExplosion { private readonly HitResult result; - [CanBeNull] - private Box body; + private Box? body; [Resolved] - private OsuColour colours { get; set; } + private OsuColour colours { get; set; } = null!; public DefaultHitExplosion(HitResult result) { @@ -58,7 +56,7 @@ namespace osu.Game.Rulesets.Taiko.UI updateColour(); } - private void updateColour([CanBeNull] DrawableHitObject judgedObject = null) + private void updateColour(DrawableHitObject? judgedObject = null) { if (body == null) return; diff --git a/osu.Game.Rulesets.Taiko/UI/DefaultKiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultKiaiHitExplosion.cs similarity index 96% rename from osu.Game.Rulesets.Taiko/UI/DefaultKiaiHitExplosion.cs rename to osu.Game.Rulesets.Taiko/Skinning/Default/DefaultKiaiHitExplosion.cs index e91475d87b..ae68d63d97 100644 --- a/osu.Game.Rulesets.Taiko/UI/DefaultKiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultKiaiHitExplosion.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using osuTK; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -11,8 +8,9 @@ using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Rulesets.Taiko.Objects; +using osuTK; -namespace osu.Game.Rulesets.Taiko.UI +namespace osu.Game.Rulesets.Taiko.Skinning.Default { public class DefaultKiaiHitExplosion : CircularContainer { diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs index 046b3a6fd0..d8cdf50d75 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs @@ -13,6 +13,7 @@ using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.Skinning.Default; using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko.UI diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs index 319d8979ae..36d2e32984 100644 --- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.Skinning.Default; using osu.Game.Skinning; using osuTK; From bc3382f373c83091d316b73c45cc9919952c68e9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 17:07:19 +0900 Subject: [PATCH 0372/2991] Apply NRT to many taiko classes --- .../Skinning/Default/ElongatedCirclePiece.cs | 2 -- .../Skinning/Default/RimHitCirclePiece.cs | 2 -- .../Skinning/Default/SwellSymbolPiece.cs | 2 -- .../Skinning/Default/TickPiece.cs | 2 -- .../Skinning/Legacy/LegacyBarLine.cs | 2 -- .../Skinning/Legacy/LegacyCirclePiece.cs | 6 ++---- .../Skinning/Legacy/LegacyDrumRoll.cs | 8 +++----- .../Skinning/Legacy/LegacyHit.cs | 2 -- .../Skinning/Legacy/LegacyHitExplosion.cs | 9 +++------ .../Skinning/Legacy/LegacyInputDrum.cs | 10 ++++------ .../Skinning/Legacy/LegacyTaikoScroller.cs | 8 +++----- .../Skinning/Legacy/TaikoLegacyHitTarget.cs | 4 +--- .../Legacy/TaikoLegacyPlayfieldBackgroundRight.cs | 4 +--- osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs | 2 -- osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs | 2 -- osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs | 2 -- .../UI/DrawableTaikoJudgement.cs | 2 -- osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs | 7 +++---- osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs | 2 -- .../UI/DrumSampleTriggerSource.cs | 2 -- osu.Game.Rulesets.Taiko/UI/HitExplosion.cs | 13 +++++-------- osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs | 2 -- .../UI/IAnimatableHitExplosion.cs | 2 -- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 2 -- osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs | 4 +--- .../UI/PlayfieldBackgroundLeft.cs | 2 -- .../UI/PlayfieldBackgroundRight.cs | 2 -- osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs | 2 -- osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs | 6 ++---- .../UI/TaikoMascotAnimationState.cs | 2 -- .../UI/TaikoPlayfieldAdjustmentContainer.cs | 2 -- osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs | 2 -- 32 files changed, 28 insertions(+), 93 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/ElongatedCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/ElongatedCirclePiece.cs index ba2679fe97..210841bca0 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/ElongatedCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/ElongatedCirclePiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Graphics; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs index 63269f1267..c6165495d8 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/SwellSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/SwellSymbolPiece.cs index d19dc4c887..2f59cac3ff 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/SwellSymbolPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/SwellSymbolPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs index 7d3268f777..09c8243aac 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyBarLine.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyBarLine.cs index 97e0a340dd..2b528ae8ce 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyBarLine.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs index 6bbeb0ed4c..6b2576a564 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; @@ -19,7 +17,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { public class LegacyCirclePiece : CompositeDrawable, IHasAccentColour { - private Drawable backgroundLayer; + private Drawable backgroundLayer = null!; // required for editor blueprints (not sure why these circle pieces are zero size). public override Quad ScreenSpaceDrawQuad => backgroundLayer.ScreenSpaceDrawQuad; @@ -32,7 +30,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy [BackgroundDependencyLoader] private void load(ISkinSource skin, DrawableHitObject drawableHitObject) { - Drawable getDrawableFor(string lookup) + Drawable? getDrawableFor(string lookup) { const string normal_hit = "taikohit"; const string big_hit = "taikobig"; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyDrumRoll.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyDrumRoll.cs index 040d8ff965..1249231d92 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyDrumRoll.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -28,11 +26,11 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy } } - private LegacyCirclePiece headCircle; + private LegacyCirclePiece headCircle = null!; - private Sprite body; + private Sprite body = null!; - private Sprite tailCircle; + private Sprite tailCircle = null!; public LegacyDrumRoll() { diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHit.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHit.cs index b4277f86bb..d93317f0e2 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHit.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHit.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Game.Skinning; using osuTK.Graphics; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs index 87ed2e2e60..ea45b69999 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs @@ -1,9 +1,7 @@ +#nullable enable // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; @@ -17,8 +15,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { private readonly Drawable sprite; - [CanBeNull] - private readonly Drawable strongSprite; + private readonly Drawable? strongSprite; /// /// Creates a new legacy hit explosion. @@ -29,7 +26,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy /// /// The normal legacy explosion sprite. /// The strong legacy explosion sprite. - public LegacyHitExplosion(Drawable sprite, [CanBeNull] Drawable strongSprite = null) + public LegacyHitExplosion(Drawable sprite, Drawable? strongSprite = null) { this.sprite = sprite; this.strongSprite = strongSprite; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs index 101f70b97a..0abb365750 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -20,9 +18,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy /// internal class LegacyInputDrum : Container { - private Container content; - private LegacyHalfDrum left; - private LegacyHalfDrum right; + private Container content = null!; + private LegacyHalfDrum left = null!; + private LegacyHalfDrum right = null!; public LegacyInputDrum() { @@ -142,7 +140,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy public bool OnPressed(KeyBindingPressEvent e) { - Drawable target = null; + Drawable? target = null; if (e.Action == CentreAction) { diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyTaikoScroller.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyTaikoScroller.cs index bd4a2f8935..4a2426bff5 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyTaikoScroller.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyTaikoScroller.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -27,7 +25,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy } [BackgroundDependencyLoader(true)] - private void load(GameplayState gameplayState) + private void load(GameplayState? gameplayState) { if (gameplayState != null) ((IBindable)LastResult).BindTo(gameplayState.LastJudgementResult); @@ -91,8 +89,8 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy private class ScrollerSprite : CompositeDrawable { - private Sprite passingSprite; - private Sprite failingSprite; + private Sprite passingSprite = null!; + private Sprite failingSprite = null!; private bool passing = true; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs index a48cdf47f6..21102f6eec 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -15,7 +13,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { public class TaikoLegacyHitTarget : CompositeDrawable { - private Container content; + private Container content = null!; [BackgroundDependencyLoader] private void load(ISkinSource skin) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs index f425a410a4..3186f615a7 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Graphics; @@ -16,7 +14,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { public class TaikoLegacyPlayfieldBackgroundRight : BeatSyncedContainer { - private Sprite kiai; + private Sprite kiai = null!; private bool kiaiDisplayed; diff --git a/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs b/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs index 63314a6822..30bfb605aa 100644 --- a/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs +++ b/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko diff --git a/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs b/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs index d231dc7e4f..bf48898dd2 100644 --- a/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs +++ b/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Taiko { public enum TaikoSkinComponents diff --git a/osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs b/osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs index 071808a044..cb878e8ea0 100644 --- a/osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Objects.Drawables; diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs index 264e4db54e..876fa207bf 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs index 8bedca19d8..dd0b61cdf5 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Audio.Track; @@ -24,7 +22,8 @@ namespace osu.Game.Rulesets.Taiko.UI public readonly Bindable LastResult; private readonly Dictionary animations; - private TaikoMascotAnimation currentAnimation; + + private TaikoMascotAnimation? currentAnimation; private bool lastObjectHit = true; private bool kiaiMode; @@ -40,7 +39,7 @@ namespace osu.Game.Rulesets.Taiko.UI } [BackgroundDependencyLoader(true)] - private void load(GameplayState gameplayState) + private void load(GameplayState? gameplayState) { InternalChildren = new[] { diff --git a/osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs b/osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs index e0d5a3c680..ae37840825 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Taiko.Objects.Drawables; using osu.Game.Rulesets.UI.Scrolling; diff --git a/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs b/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs index ef5bd1d7f0..3279d128d3 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Game.Audio; using osu.Game.Rulesets.Taiko.Objects; diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs index d8cdf50d75..4836984eac 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs @@ -1,10 +1,8 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +#nullable enable +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; -using JetBrains.Annotations; using osuTK; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -30,10 +28,9 @@ namespace osu.Game.Rulesets.Taiko.UI private double? secondHitTime; - [CanBeNull] - public DrawableHitObject JudgedObject; + public DrawableHitObject? JudgedObject; - private SkinnableDrawable skinnable; + private SkinnableDrawable skinnable = null!; /// /// This constructor only exists to meet the new() type constraint of . @@ -63,7 +60,7 @@ namespace osu.Game.Rulesets.Taiko.UI skinnable.OnSkinChanged += runAnimation; } - public void Apply([CanBeNull] DrawableHitObject drawableHitObject) + public void Apply(DrawableHitObject? drawableHitObject) { JudgedObject = drawableHitObject; secondHitTime = null; diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs index 8707f7e840..badf34554c 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics.Pooling; using osu.Game.Rulesets.Scoring; diff --git a/osu.Game.Rulesets.Taiko/UI/IAnimatableHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/IAnimatableHitExplosion.cs index 6a9d43a0ab..cf0f5f9fb6 100644 --- a/osu.Game.Rulesets.Taiko/UI/IAnimatableHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/IAnimatableHitExplosion.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Taiko.UI diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 94e7138142..6d5b6c5f5d 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs index 36d2e32984..c4cff00d2a 100644 --- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -23,7 +21,7 @@ namespace osu.Game.Rulesets.Taiko.UI private readonly HitType hitType; - private SkinnableDrawable skinnable; + private SkinnableDrawable skinnable = null!; public override double LifetimeStart => skinnable.Drawable.LifetimeStart; diff --git a/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundLeft.cs b/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundLeft.cs index db1094e100..2a8890a95d 100644 --- a/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundLeft.cs +++ b/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundLeft.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundRight.cs b/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundRight.cs index 43252e2e77..44bfdacf37 100644 --- a/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundRight.cs +++ b/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundRight.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs b/osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs index f48ed2c941..6401c6d09f 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osuTK; using osuTK.Graphics; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs index 26a37fc464..de539b3cf0 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Audio.Track; @@ -120,7 +118,7 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load(ISkinSource source) { - ISkin skin = source.FindProvider(s => getAnimationFrame(s, TaikoMascotAnimationState.Clear, 0) != null); + ISkin? skin = source.FindProvider(s => getAnimationFrame(s, TaikoMascotAnimationState.Clear, 0) != null); if (skin == null) return; @@ -137,7 +135,7 @@ namespace osu.Game.Rulesets.Taiko.UI } } - private static Texture getAnimationFrame(ISkin skin, TaikoMascotAnimationState state, int frameIndex) + private static Texture? getAnimationFrame(ISkin skin, TaikoMascotAnimationState state, int frameIndex) { var texture = skin.GetTexture($"pippidon{state.ToString().ToLowerInvariant()}{frameIndex}"); diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimationState.cs b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimationState.cs index 717f0d725a..02bf245b7b 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimationState.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimationState.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Taiko.UI { public enum TaikoMascotAnimationState diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs index 8e99a82b1b..9cf530e903 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Bindables; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs b/osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs index a76adc495d..e6391d1386 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Taiko.Replays; From 5dfaf277229566c930d0cbedc9d970d0c2b3c507 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 17:23:45 +0900 Subject: [PATCH 0373/2991] A bit more cleanup --- osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs | 1 - osu.Game.Rulesets.Taiko/UI/HitExplosion.cs | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs index ea45b69999..ff1546381b 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs @@ -1,4 +1,3 @@ -#nullable enable // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs index 4836984eac..10a7495c62 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs @@ -1,5 +1,4 @@ -#nullable enable -// 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; From bfa5d41d89a64ec1a559cc4d5cc5975563d95335 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 17:39:45 +0900 Subject: [PATCH 0374/2991] Fix one more case --- osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs index 58f45fda7c..b7ba76effa 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs @@ -1,4 +1,3 @@ -#nullable enable // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. From 4f8e912f063b08ed8be5afb2a513d8c804092685 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 17:53:19 +0900 Subject: [PATCH 0375/2991] Fix `APINotification` parsing failing --- osu.Game/Online/API/Requests/Responses/APINotification.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APINotification.cs b/osu.Game/Online/API/Requests/Responses/APINotification.cs index 2d9122c04b..de856c0333 100644 --- a/osu.Game/Online/API/Requests/Responses/APINotification.cs +++ b/osu.Game/Online/API/Requests/Responses/APINotification.cs @@ -2,8 +2,8 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace osu.Game.Online.API.Requests.Responses { @@ -32,6 +32,6 @@ namespace osu.Game.Online.API.Requests.Responses public bool IsRead { get; set; } [JsonProperty(@"details")] - public Dictionary? Details { get; set; } + public JObject? Details { get; set; } } } From 0e502de8b473d9dda312bd4ddb590c7ce8dde1a5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 17:49:52 +0900 Subject: [PATCH 0376/2991] Rename field to match usage --- .../Visual/Editing/TestSceneEditorTestGameplay.cs | 4 ++-- osu.Game/Graphics/Containers/UserDimContainer.cs | 8 ++++---- osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs | 6 +++--- osu.Game/Screens/Edit/Editor.cs | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs index 9722c60cba..981967e413 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs @@ -86,7 +86,7 @@ namespace osu.Game.Tests.Visual.Editing // this test cares about checking the background belonging to the editor specifically, so check that using reference equality // (as `.Equals()` cannot discern between the two, as they technically share the same database GUID). var background = this.ChildrenOfType().Single(b => ReferenceEquals(b.Beatmap.BeatmapInfo, EditorBeatmap.BeatmapInfo)); - return background.DimAmount.Value == editorDim.Value && background.BlurAmount.Value == 0; + return background.DimWhenUserSettingsIgnored.Value == editorDim.Value && background.BlurAmount.Value == 0; }); AddAssert("no mods selected", () => SelectedMods.Value.Count == 0); } @@ -119,7 +119,7 @@ namespace osu.Game.Tests.Visual.Editing // this test cares about checking the background belonging to the editor specifically, so check that using reference equality // (as `.Equals()` cannot discern between the two, as they technically share the same database GUID). var background = this.ChildrenOfType().Single(b => ReferenceEquals(b.Beatmap.BeatmapInfo, EditorBeatmap.BeatmapInfo)); - return background.DimAmount.Value == editorDim.Value && background.BlurAmount.Value == 0; + return background.DimWhenUserSettingsIgnored.Value == editorDim.Value && background.BlurAmount.Value == 0; }); AddStep("start track", () => EditorClock.Start()); diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index 62dd4e19b0..0b20159190 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -47,9 +47,9 @@ namespace osu.Game.Graphics.Containers protected Bindable UserDimLevel { get; private set; } = null!; /// - /// The amount of dim to be override if is true. + /// The amount of dim to be used when is true. /// - public Bindable DimAmount { get; set; } = new Bindable(); + public Bindable DimWhenUserSettingsIgnored { get; set; } = new Bindable(); protected Bindable LightenDuringBreaks { get; private set; } = null!; @@ -57,7 +57,7 @@ namespace osu.Game.Graphics.Containers private float breakLightening => LightenDuringBreaks.Value && IsBreakTime.Value ? BREAK_LIGHTEN_AMOUNT : 0; - protected float DimLevel => Math.Max(!IgnoreUserSettings.Value ? (float)UserDimLevel.Value - breakLightening : DimAmount.Value, 0); + protected float DimLevel => Math.Max(!IgnoreUserSettings.Value ? (float)UserDimLevel.Value - breakLightening : DimWhenUserSettingsIgnored.Value, 0); protected override Container Content => dimContent; @@ -79,7 +79,7 @@ namespace osu.Game.Graphics.Containers ShowStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); UserDimLevel.ValueChanged += _ => UpdateVisuals(); - DimAmount.ValueChanged += _ => UpdateVisuals(); + DimWhenUserSettingsIgnored.ValueChanged += _ => UpdateVisuals(); LightenDuringBreaks.ValueChanged += _ => UpdateVisuals(); IsBreakTime.ValueChanged += _ => UpdateVisuals(); ShowStoryboard.ValueChanged += _ => UpdateVisuals(); diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs index 9f3e99d793..4d84a8194d 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs @@ -44,9 +44,9 @@ namespace osu.Game.Screens.Backgrounds public readonly Bindable BlurAmount = new BindableFloat(); /// - /// The amount of dim to be override if is true. + /// The amount of dim to be used when is true. /// - public readonly Bindable DimAmount = new Bindable(); + public readonly Bindable DimWhenUserSettingsIgnored = new Bindable(); internal readonly IBindable IsBreakTime = new Bindable(); @@ -63,7 +63,7 @@ namespace osu.Game.Screens.Backgrounds dimmable.IgnoreUserSettings.BindTo(IgnoreUserSettings); dimmable.IsBreakTime.BindTo(IsBreakTime); dimmable.BlurAmount.BindTo(BlurAmount); - dimmable.DimAmount.BindTo(DimAmount); + dimmable.DimWhenUserSettingsIgnored.BindTo(DimWhenUserSettingsIgnored); StoryboardReplacesBackground.BindTo(dimmable.StoryboardReplacesBackground); } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index bd0c4cfca4..990152471a 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -637,7 +637,7 @@ namespace osu.Game.Screens.Edit ApplyToBackground(b => { b.IgnoreUserSettings.Value = true; - b.DimAmount.Value = editorBackgroundDim.Value; + b.DimWhenUserSettingsIgnored.Value = editorBackgroundDim.Value; b.BlurAmount.Value = 0; }); } @@ -668,7 +668,7 @@ namespace osu.Game.Screens.Edit ApplyToBackground(b => { //b.DimAmount.UnbindAll(); - b.DimAmount.Value = 0; + b.DimWhenUserSettingsIgnored.Value = 0; }); resetTrack(); From 3ec9686e5858ad02070e3358eb971e62c449987b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 18:14:20 +0900 Subject: [PATCH 0377/2991] Fix test failures and rename configuration value to match better --- .../TestSceneLegacyBeatmapSkin.cs | 2 ++ .../Gameplay/TestSceneHitObjectAccentColour.cs | 14 +++++++++++++- osu.Game/Configuration/OsuConfigManager.cs | 4 ++-- .../Settings/Sections/Gameplay/BeatmapSettings.cs | 2 +- .../Objects/Drawables/DrawableHitObject.cs | 2 +- .../Screens/Play/PlayerSettings/VisualSettings.cs | 2 +- 6 files changed, 20 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs index 1767d25e77..bb28b2b217 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs @@ -31,6 +31,8 @@ namespace osu.Game.Rulesets.Osu.Tests { config.BindWith(OsuSetting.BeatmapSkins, BeatmapSkins); config.BindWith(OsuSetting.BeatmapColours, BeatmapColours); + + config.SetValue(OsuSetting.ComboColourNormalisationAmount, 0f); } [TestCase(true, true)] diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs index 9701a32951..bc4c1d4cf2 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -13,6 +14,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Textures; using osu.Framework.Testing; using osu.Game.Audio; +using osu.Game.Configuration; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Legacy; using osu.Game.Rulesets.Objects.Types; @@ -25,10 +27,20 @@ namespace osu.Game.Tests.Gameplay [HeadlessTest] public class TestSceneHitObjectAccentColour : OsuTestScene { + [Resolved] + private OsuConfigManager config { get; set; } + private Container skinContainer; [SetUp] - public void Setup() => Schedule(() => Child = skinContainer = new SkinProvidingContainer(new TestSkin())); + public void Setup() + { + Schedule(() => + { + config.SetValue(OsuSetting.ComboColourNormalisationAmount, 0f); + Child = skinContainer = new SkinProvidingContainer(new TestSkin()); + }); + } [Test] public void TestChangeComboIndexBeforeLoad() diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 98776c7487..fdaad8cf70 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -175,7 +175,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.LastProcessedMetadataId, -1); - SetDefault(OsuSetting.ComboColourNormalisation, 0.2f, 0f, 1f, 0.01f); + SetDefault(OsuSetting.ComboColourNormalisationAmount, 0.2f, 0f, 1f, 0.01f); } protected override bool CheckLookupContainsPrivateInformation(OsuSetting lookup) @@ -367,6 +367,6 @@ namespace osu.Game.Configuration ShowOnlineExplicitContent, LastProcessedMetadataId, SafeAreaConsiderations, - ComboColourNormalisation, + ComboColourNormalisationAmount, } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs index 8d64337eab..14ff6ac2b5 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs @@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - config.BindWith(OsuSetting.ComboColourNormalisation, comboColourNormalisation); + config.BindWith(OsuSetting.ComboColourNormalisationAmount, comboColourNormalisation); Children = new Drawable[] { diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 98fd73c8e9..f82a24ff01 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -175,7 +175,7 @@ namespace osu.Game.Rulesets.Objects.Drawables private void load(OsuConfigManager config, ISkinSource skinSource) { config.BindWith(OsuSetting.PositionalHitsoundsLevel, positionalHitsoundsLevel); - config.BindWith(OsuSetting.ComboColourNormalisation, comboColourBrightness); + config.BindWith(OsuSetting.ComboColourNormalisationAmount, comboColourBrightness); // Explicit non-virtual function call in case a DrawableHitObject overrides AddInternal. base.AddInternal(Samples = new PausableSkinnableSound()); diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs index c837f61a09..6a7eabc6a2 100644 --- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs @@ -51,7 +51,7 @@ namespace osu.Game.Screens.Play.PlayerSettings showStoryboardToggle.Current = config.GetBindable(OsuSetting.ShowStoryboard); beatmapSkinsToggle.Current = config.GetBindable(OsuSetting.BeatmapSkins); beatmapColorsToggle.Current = config.GetBindable(OsuSetting.BeatmapColours); - comboColourNormalisationSliderBar.Current = config.GetBindable(OsuSetting.ComboColourNormalisation); + comboColourNormalisationSliderBar.Current = config.GetBindable(OsuSetting.ComboColourNormalisationAmount); } } } From a44c7c751497d72eb33e4106a0b7baac184254a4 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 2 Nov 2022 19:56:35 +0900 Subject: [PATCH 0378/2991] range and precision for `EditorWaveformOpacity` --- osu.Game/Configuration/OsuConfigManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index e9cfcd56c5..b832d1e310 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -172,7 +172,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.DiscordRichPresence, DiscordRichPresenceMode.Full); - SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f); + SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f, 0f, 1f, 0.25f); SetDefault(OsuSetting.LastProcessedMetadataId, -1); } From 7073d8dd8e9f75f4756adf3fef7a9c6035db911c Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 2 Nov 2022 19:57:01 +0900 Subject: [PATCH 0379/2991] range and precision for `EditorDim` --- osu.Game/Configuration/OsuConfigManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index b832d1e310..3c619d2ddd 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -121,7 +121,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.PositionalHitsoundsLevel, 0.2f, 0, 1); SetDefault(OsuSetting.DimLevel, 0.7, 0, 1, 0.01); SetDefault(OsuSetting.BlurLevel, 0, 0, 1, 0.01); - SetDefault(OsuSetting.EditorDim, 0.25f); + SetDefault(OsuSetting.EditorDim, 0.25f, 0f, 1f, 0.25f); SetDefault(OsuSetting.LightenDuringBreaks, true); SetDefault(OsuSetting.HitLighting, true); From ed7e3a29e2ab96234728f784ea7194d3f74ccdba Mon Sep 17 00:00:00 2001 From: C0D3 M4513R <28912031+C0D3-M4513R@users.noreply.github.com> Date: Wed, 2 Nov 2022 13:00:45 +0100 Subject: [PATCH 0380/2991] Add Localisation Also add Labels for what is displayed, and prefix/suffix for Labels Add a Prefix and Suffix for Values --- .../Components/BeatmapInfoDrawable.cs | 223 ++++++++++++++---- 1 file changed, 180 insertions(+), 43 deletions(-) diff --git a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs index ae91d14830..4110086b2a 100644 --- a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs +++ b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs @@ -1,45 +1,80 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using System.Text; +using System; using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Configuration; +using osu.Game.Extensions; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Game.Localisation; +using osu.Game.Resources.Localisation.Web; namespace osu.Game.Skinning.Components { [UsedImplicitly] - public class BeatmapInfoDrawable : Container, ISkinnableDrawable + public class BeatmapInfoDrawable : Container, ISkinnableDrawable, IHasTooltip { public bool UsesFixedAnchor { get; set; } [SettingSource("Tracked Beatmap Info", "Which part of the BeatmapInformation should be tracked")] public Bindable Type { get; } = new Bindable(BeatmapInfo.StarRating); + [SettingSource("Show Label", "Should a Label be shown, as to which status is currently Displayed?")] + public BindableBool ShowLabel { get; } = new BindableBool(true); + + [SettingSource("Show Value first?", "Should the Value be shown first?")] + public BindableBool ValueBeforeLabel { get; } = new BindableBool(); + + [SettingSource("Label Prefix", "Add something to be shown before the label")] + public Bindable LabelPrefix { get; set; } = new Bindable(""); + + [SettingSource("Show Label Prefix", "Should the Label Prefix be included?")] + public BindableBool ShowLabelPrefix { get; } = new BindableBool(); + + [SettingSource("Label Suffix", "Add something to be shown after the label")] + public Bindable LabelSuffix { get; set; } = new Bindable(": "); + + [SettingSource("Show Label Suffix", "Should the Label Suffix be included?")] + public BindableBool ShowLabelSuffix { get; } = new BindableBool(true); + + [SettingSource("Value Prefix", "Add something to be shown before the Value")] + public Bindable ValuePrefix { get; set; } = new Bindable(""); + + [SettingSource("Show Value Prefix", "Should the Value Prefix be included?")] + public BindableBool ShowValuePrefix { get; } = new BindableBool(); + + [SettingSource("Value Suffix", "Add something to be shown after the Value")] + public Bindable ValueSuffix { get; set; } = new Bindable(""); + + [SettingSource("Show Value Suffix", "Should the Value Suffix be included?")] + public BindableBool ShowValueSuffix { get; } = new BindableBool(); + [Resolved] - private IBindable beatmap { get; set; } + private IBindable beatmap { get; set; } = null!; private readonly OsuSpriteText text; + public LocalisableString TooltipText { get; set; } + private LocalisableString value; + private LocalisableString labelText; + public BeatmapInfoDrawable() { - AutoSizeAxes = Axes.Both; - InternalChildren = new Drawable[] { text = new OsuSpriteText { Text = "BeatInfoDrawable", - Anchor = Anchor.Centre, - Origin = Anchor.Centre, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, Font = OsuFont.Default.With(size: 40) } }; @@ -49,6 +84,45 @@ namespace osu.Game.Skinning.Components { base.LoadComplete(); Type.BindValueChanged(update, true); + ShowLabel.BindValueChanged(ignored => updateLabel()); + ValueBeforeLabel.BindValueChanged(ignored => updateLabel()); + LabelPrefix.BindValueChanged(ignored => updateLabel()); + ShowLabelPrefix.BindValueChanged(ignored => updateLabel()); + LabelSuffix.BindValueChanged(ignored => updateLabel()); + ShowLabelSuffix.BindValueChanged(ignored => updateLabel()); + ValuePrefix.BindValueChanged(ignored => updateLabel()); + ShowValuePrefix.BindValueChanged(ignored => updateLabel()); + ValueSuffix.BindValueChanged(ignored => updateLabel()); + ShowValueSuffix.BindValueChanged(ignored => updateLabel()); + } + + private LocalisableString getLabelText() + { + if (!ShowLabel.Value) return new LocalisableString(""); + + return LocalisableString.Format("{0}{1}{2}", + ShowLabelPrefix.Value ? LabelPrefix.Value : "", + labelText, + ShowLabelSuffix.Value ? LabelSuffix.Value : ""); + } + + private LocalisableString getValueText() + { + return LocalisableString.Format("{0}{1}{2}", + ShowValuePrefix.Value ? ValuePrefix.Value : "", + value, + ShowValueSuffix.Value ? ValueSuffix.Value : ""); + } + + private void updateLabel() + { + text.Text = LocalisableString.Format( + ValueBeforeLabel.Value ? "{1}{0}" : "{0}{1}", + getLabelText(), + getValueText() + ); + Width = text.Width; + Height = text.Height; } private void update(ValueChangedEvent type) @@ -58,105 +132,167 @@ namespace osu.Game.Skinning.Components case BeatmapInfo.CircleSize: beatmap.BindValueChanged(bm => { - text.Current.Value = bm.NewValue.BeatmapInfo.Difficulty.CircleSize.ToString("F2"); + double cs = bm.NewValue.BeatmapInfo.Difficulty.CircleSize; + labelText = TooltipText = BeatmapsetsStrings.ShowStatsCs; + value = cs.ToString("F2"); + updateLabel(); }, true); break; case BeatmapInfo.HPDrain: beatmap.BindValueChanged(bm => { - text.Current.Value = bm.NewValue.BeatmapInfo.Difficulty.DrainRate.ToString("F2"); + double hp = bm.NewValue.BeatmapInfo.Difficulty.DrainRate; + labelText = TooltipText = BeatmapsetsStrings.ShowStatsDrain; + value = hp.ToString("F2"); + updateLabel(); }, true); break; case BeatmapInfo.Accuracy: beatmap.BindValueChanged(bm => { - text.Current.Value = bm.NewValue.BeatmapInfo.Difficulty.OverallDifficulty.ToString("F2"); + double od = bm.NewValue.BeatmapInfo.Difficulty.OverallDifficulty; + labelText = TooltipText = BeatmapsetsStrings.ShowStatsAccuracy; + value = od.ToString("F2"); + updateLabel(); }, true); break; case BeatmapInfo.ApproachRate: beatmap.BindValueChanged(bm => { - text.Current.Value = bm.NewValue.BeatmapInfo.Difficulty.ApproachRate.ToString("F2"); + double ar = bm.NewValue.BeatmapInfo.Difficulty.ApproachRate; + labelText = TooltipText = BeatmapsetsStrings.ShowStatsAr; + value = ar.ToString("F2"); + updateLabel(); }, true); break; case BeatmapInfo.StarRating: beatmap.BindValueChanged(bm => { - text.Current.Value = bm.NewValue.BeatmapInfo.StarRating.ToString("F2"); + double sr = bm.NewValue.BeatmapInfo.StarRating; + labelText = TooltipText = BeatmapsetsStrings.ShowStatsStars; + value = sr.ToString("F2"); + updateLabel(); }, true); break; case BeatmapInfo.Song: beatmap.BindValueChanged(bm => { - text.Current.Value = bm.NewValue.BeatmapInfo.Metadata.Title; + string title = bm.NewValue.BeatmapInfo.Metadata.Title; + //todo: no Song Title localisation? + labelText = TooltipText = "Song Title"; + value = title; + updateLabel(); }, true); break; case BeatmapInfo.Artist: beatmap.BindValueChanged(bm => { - text.Current.Value = bm.NewValue.BeatmapInfo.Metadata.Artist; + string artist = bm.NewValue.BeatmapInfo.Metadata.Artist; + //todo: Localize Artist + labelText = "Artist"; + TooltipText = BeatmapsetsStrings.ShowDetailsByArtist(artist); + value = artist; + updateLabel(); }, true); break; case BeatmapInfo.Difficulty: beatmap.BindValueChanged(bm => { - text.Current.Value = bm.NewValue.BeatmapInfo.DifficultyName; + string diff = bm.NewValue.BeatmapInfo.DifficultyName; + //todo: no Difficulty name localisation? + labelText = TooltipText = "Difficulty"; + text.Current.Value = diff; + updateLabel(); }, true); break; case BeatmapInfo.Mapper: beatmap.BindValueChanged(bm => { - text.Current.Value = bm.NewValue.BeatmapInfo.Metadata.Author.Username; + string mapper = bm.NewValue.BeatmapInfo.Metadata.Author.Username; + //todo: is there a good alternative, to ShowDetailsMappedBy? + labelText = "Mapper"; + TooltipText = BeatmapsetsStrings.ShowDetailsMappedBy(mapper); + value = mapper; + updateLabel(); }, true); break; case BeatmapInfo.Length: beatmap.BindValueChanged(bm => { - const long ms_to_s = 1000; - double length = bm.NewValue.BeatmapInfo.Length; - double rawS = length / ms_to_s; - double rawM = rawS / 60; - double rawH = rawM / 60; - double rawD = rawH / 24; + labelText = TooltipText = BeatmapsetsStrings.ShowStatsTotalLength(TimeSpan.FromMilliseconds(bm.NewValue.BeatmapInfo.Length).ToFormattedDuration()); + value = TimeSpan.FromMilliseconds(bm.NewValue.BeatmapInfo.Length).ToFormattedDuration(); + updateLabel(); + }, true); + break; - long s = (long)rawS % 60; - long m = (long)rawM % 60; - long h = (long)rawH % 24; - long d = (long)rawD; - StringBuilder builder = new StringBuilder(); + case BeatmapInfo.Status: + beatmap.BindValueChanged(bm => + { + BeatmapOnlineStatus status = bm.NewValue.BeatmapInfo.Status; + //todo: no Localizasion for None Beatmap Online Status + //todo: no Localization for Status? + labelText = "Status"; - if (d != 0) + switch (status) { - builder.Append(d.ToString("D2")); - builder.Append(":"); + case BeatmapOnlineStatus.Approved: + value = BeatmapsetsStrings.ShowStatusApproved; + //todo: is this correct? + TooltipText = BeatmapsetsStrings.ShowDetailsDateApproved(bm.NewValue.BeatmapSetInfo.DateRanked.ToString()); + break; + + case BeatmapOnlineStatus.Graveyard: + value = BeatmapsetsStrings.ShowStatusGraveyard; + break; + + case BeatmapOnlineStatus.Loved: + value = BeatmapsetsStrings.ShowStatusLoved; + break; + + case BeatmapOnlineStatus.None: + value = "None"; + break; + + case BeatmapOnlineStatus.Pending: + value = BeatmapsetsStrings.ShowStatusPending; + break; + + case BeatmapOnlineStatus.Qualified: + value = BeatmapsetsStrings.ShowStatusQualified; + break; + + case BeatmapOnlineStatus.Ranked: + value = BeatmapsetsStrings.ShowStatusRanked; + break; + + case BeatmapOnlineStatus.LocallyModified: + value = SongSelectStrings.LocallyModified; + break; + + case BeatmapOnlineStatus.WIP: + value = BeatmapsetsStrings.ShowStatusWip; + break; } - if (h != 0 || d != 0) - { - builder.Append(h.ToString("D2")); - builder.Append(":"); - } - - builder.Append(m.ToString("D2")); - builder.Append(":"); - builder.Append(s.ToString("D2")); - text.Current.Value = builder.ToString(); + updateLabel(); }, true); break; case BeatmapInfo.BPM: beatmap.BindValueChanged(bm => { - text.Current.Value = bm.NewValue.BeatmapInfo.BPM.ToString("F2"); + labelText = TooltipText = BeatmapsetsStrings.ShowStatsBpm; + value = bm.NewValue.BeatmapInfo.BPM.ToString("F2"); + updateLabel(); }, true); break; } @@ -175,6 +311,7 @@ namespace osu.Game.Skinning.Components Difficulty, Mapper, Length, + Status, BPM, } } From 2e5db5e25983d9d074c695c4f27020e6f31dfb83 Mon Sep 17 00:00:00 2001 From: C0D3 M4513R <28912031+C0D3-M4513R@users.noreply.github.com> Date: Wed, 2 Nov 2022 13:24:05 +0100 Subject: [PATCH 0381/2991] Remove nullable disable from TextElement --- osu.Game/Skinning/Components/TextElement.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Skinning/Components/TextElement.cs b/osu.Game/Skinning/Components/TextElement.cs index e29ab6de58..da09aa76b2 100644 --- a/osu.Game/Skinning/Components/TextElement.cs +++ b/osu.Game/Skinning/Components/TextElement.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using JetBrains.Annotations; using osu.Framework.Bindables; using osu.Framework.Graphics; From 95e2521ca46cea560e88d26c1e82f47483e8798b Mon Sep 17 00:00:00 2001 From: C0D3 M4513R <28912031+C0D3-M4513R@users.noreply.github.com> Date: Wed, 2 Nov 2022 13:56:55 +0100 Subject: [PATCH 0382/2991] Use more Localisations --- .../Skinning/Components/BeatmapInfoDrawable.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs index 4110086b2a..44c3914d2c 100644 --- a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs +++ b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs @@ -184,7 +184,7 @@ namespace osu.Game.Skinning.Components { string title = bm.NewValue.BeatmapInfo.Metadata.Title; //todo: no Song Title localisation? - labelText = TooltipText = "Song Title"; + labelText = TooltipText = EditorSetupStrings.Title; value = title; updateLabel(); }, true); @@ -194,8 +194,7 @@ namespace osu.Game.Skinning.Components beatmap.BindValueChanged(bm => { string artist = bm.NewValue.BeatmapInfo.Metadata.Artist; - //todo: Localize Artist - labelText = "Artist"; + labelText = EditorSetupStrings.Artist; TooltipText = BeatmapsetsStrings.ShowDetailsByArtist(artist); value = artist; updateLabel(); @@ -206,8 +205,7 @@ namespace osu.Game.Skinning.Components beatmap.BindValueChanged(bm => { string diff = bm.NewValue.BeatmapInfo.DifficultyName; - //todo: no Difficulty name localisation? - labelText = TooltipText = "Difficulty"; + labelText = TooltipText = EditorSetupStrings.DifficultyHeader; text.Current.Value = diff; updateLabel(); }, true); @@ -218,7 +216,7 @@ namespace osu.Game.Skinning.Components { string mapper = bm.NewValue.BeatmapInfo.Metadata.Author.Username; //todo: is there a good alternative, to ShowDetailsMappedBy? - labelText = "Mapper"; + labelText = AccountsStrings.NotificationsOptionsMapping; TooltipText = BeatmapsetsStrings.ShowDetailsMappedBy(mapper); value = mapper; updateLabel(); @@ -228,7 +226,7 @@ namespace osu.Game.Skinning.Components case BeatmapInfo.Length: beatmap.BindValueChanged(bm => { - labelText = TooltipText = BeatmapsetsStrings.ShowStatsTotalLength(TimeSpan.FromMilliseconds(bm.NewValue.BeatmapInfo.Length).ToFormattedDuration()); + labelText = TooltipText = ArtistStrings.TracklistLength; value = TimeSpan.FromMilliseconds(bm.NewValue.BeatmapInfo.Length).ToFormattedDuration(); updateLabel(); }, true); @@ -239,8 +237,7 @@ namespace osu.Game.Skinning.Components { BeatmapOnlineStatus status = bm.NewValue.BeatmapInfo.Status; //todo: no Localizasion for None Beatmap Online Status - //todo: no Localization for Status? - labelText = "Status"; + labelText = BeatmapDiscussionsStrings.IndexFormBeatmapsetStatusDefault; switch (status) { From 75b5025e123f5716b6b0aff6aebe7ef8667553ee Mon Sep 17 00:00:00 2001 From: C0D3 M4513R <28912031+C0D3-M4513R@users.noreply.github.com> Date: Wed, 2 Nov 2022 16:37:48 +0100 Subject: [PATCH 0383/2991] Fix Skin Deserialisation Test --- .../Archives/modified-default-20221102.osk | Bin 0 -> 1534 bytes osu.Game.Tests/Skins/SkinDeserialisationTest.cs | 4 +++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/Resources/Archives/modified-default-20221102.osk diff --git a/osu.Game.Tests/Resources/Archives/modified-default-20221102.osk b/osu.Game.Tests/Resources/Archives/modified-default-20221102.osk new file mode 100644 index 0000000000000000000000000000000000000000..3ec328db4e8212e2cb709865362b24f83951b93e GIT binary patch literal 1534 zcmWIWW@Zs#U|`^2NN-6B{k=AO?o1$WGgyRyp*TA;PcJhsQ}v7?Uz3A?!^L?i?+t<+ zla2&jio6+_nX1E<*3i4#IPE6y!yGZWliC~`|LOn#{Vzl`#=R|W?&X`O80LDVbQ(Nn znX#yx+1rz4%;f*Sr?uTAxyVI%L+HDUVhxY@BW5nr?WLKLEw~Gv4vZmjIpK z1H`;Q403*EURu6hR&jpb>Ss@b0s=mHpYaXd6clhuUoSMIBhX97>-_odz@Q5TMg~Tg zLN1&*>wnVcw2$w_kV}l(<$7MeIw$p+UUHm0eeSgW`DU+*XQI}d?VI+U#a$tj}*2ki&Obn>bd;h|Bkv}5?LpU=713%Dt z!TEXV!Kpc^$t7S1?wuH$eaJwf^*!r<=WE_87slTzdvNqxt--MwXLd<{RJs<_k*Cm#O61*4n}CKI$QjBky+}4dvo?E9ALgL{iCd#pKZ5a%i#m^JlemmzSzU* zn>F{6i?6z5Vu9M*ZOpwIWqwccDz*t;iaE+#Ikm*syV5-8LP%rPg6fEEm$eUxY&q?i zExc6g`}RX8+cqt23Cb|jk1YMX+$reB>uR>0mVcZD|1z*|e9!){Fs)Yq$l-;;t{+)_ zD=a=GtCuWJe#_;4FMsKl&*IxI>0MR3X!LFROBL6>XIi$rUD$G}r*YRNznnSYH{PDv z&xjiK)eZ7#FMwfR1`K#HVA%U6X6AW>x;W?O7Ubup=9LtKqu}lI*zDT|B5m)v|MII{ zUpK-2QNN?!ttHXNB#gax&A!Ba)Yj7_Ra54qPU4&W;d!#tkD6<1mc2-8c3j_gU-?VH zo5i<38z27}YAcg&a6dQU!$C=n*h&6t7>rH}I%G}a+@^eaHs{O(lcpZ(3Edcw9O}jV z!s>Uy^`DF@c1}|EnwNK7^7aFvM3sdmCt6;oJazi;hx^U5SBy_QraAH4v8r8WV*agk zcT1IP*qvJw#jB1ipVF46{C3S%C>i4mS7sdL-U)uL=KT!B_ z)h7=BUU#+~ArS^MotNz}*>(JyrqrY>aUbn3+u0UquI1j?-rhSYp?rP}qcQ94nrYsq zj^8HhvXm6gSzzb+cj5D`yOyU&{H&{B5%fxWrMmC=@%GT~OMWMQ`ELLD-^VkF+3Q$E z$}TWYvrzM#p?18aC Ghz9_U=60t5 literal 0 HcmV?d00001 diff --git a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs index 989459632e..4ecf307d68 100644 --- a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs +++ b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs @@ -40,7 +40,9 @@ namespace osu.Game.Tests.Skins // Covers clicks/s counter "Archives/modified-default-20220818.osk", // Covers longest combo counter - "Archives/modified-default-20221012.osk" + "Archives/modified-default-20221012.osk", + // Covers TextElement and BeatmapInfoDrawable + "Archives/modified-default-20221102.osk" }; /// From 993439d30b173a5bdac0e22fea97c0e97bcb09a7 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Thu, 3 Nov 2022 11:28:39 +0900 Subject: [PATCH 0384/2991] Fix missed nullability --- osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs index de539b3cf0..0f214b8436 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load(ISkinSource source) { - ISkin skin = source.FindProvider(s => getAnimationFrame(s, state, 0) != null); + ISkin? skin = source.FindProvider(s => getAnimationFrame(s, state, 0) != null); if (skin == null) return; From ec4ac77f14cbf6f85281c7e634a329efafa1b92a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 13:27:54 +0900 Subject: [PATCH 0385/2991] Increase the maximum seed range for tournament client --- osu.Game.Tournament/Models/SeedingBeatmap.cs | 2 +- osu.Game.Tournament/Models/SeedingResult.cs | 2 +- osu.Game.Tournament/Models/TournamentTeam.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tournament/Models/SeedingBeatmap.cs b/osu.Game.Tournament/Models/SeedingBeatmap.cs index fb0e20556c..0ac312342c 100644 --- a/osu.Game.Tournament/Models/SeedingBeatmap.cs +++ b/osu.Game.Tournament/Models/SeedingBeatmap.cs @@ -18,7 +18,7 @@ namespace osu.Game.Tournament.Models public Bindable Seed = new BindableInt { MinValue = 1, - MaxValue = 64 + MaxValue = 256 }; } } diff --git a/osu.Game.Tournament/Models/SeedingResult.cs b/osu.Game.Tournament/Models/SeedingResult.cs index 71e52b3324..2a404153e6 100644 --- a/osu.Game.Tournament/Models/SeedingResult.cs +++ b/osu.Game.Tournament/Models/SeedingResult.cs @@ -17,7 +17,7 @@ namespace osu.Game.Tournament.Models public Bindable Seed = new BindableInt { MinValue = 1, - MaxValue = 64 + MaxValue = 256 }; } } diff --git a/osu.Game.Tournament/Models/TournamentTeam.cs b/osu.Game.Tournament/Models/TournamentTeam.cs index ac57f748da..1beea517d5 100644 --- a/osu.Game.Tournament/Models/TournamentTeam.cs +++ b/osu.Game.Tournament/Models/TournamentTeam.cs @@ -54,7 +54,7 @@ namespace osu.Game.Tournament.Models public Bindable LastYearPlacing = new BindableInt { MinValue = 1, - MaxValue = 64 + MaxValue = 256 }; [JsonProperty] From aef3c7918c98d3acd7cdb4bdba9e5bc0e9551054 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 12:14:37 +0900 Subject: [PATCH 0386/2991] Add total skip count to `SkipOverlay` --- .../Visual/Gameplay/TestSceneSkipOverlay.cs | 7 +++++-- osu.Game/Screens/Play/SkipOverlay.cs | 11 ++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs index 6b02449aa3..4b564f704a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs @@ -137,8 +137,11 @@ namespace osu.Game.Tests.Visual.Gameplay checkRequestCount(0); } - private void checkRequestCount(int expected) => - AddAssert($"request count is {expected}", () => requestCount == expected); + private void checkRequestCount(int expected) + { + AddAssert($"skip count is {expected}", () => skip.SkipCount, () => Is.EqualTo(expected)); + AddAssert($"request count is {expected}", () => requestCount, () => Is.EqualTo(expected)); + } private class TestSkipOverlay : SkipOverlay { diff --git a/osu.Game/Screens/Play/SkipOverlay.cs b/osu.Game/Screens/Play/SkipOverlay.cs index 974d40b538..ee05fce730 100644 --- a/osu.Game/Screens/Play/SkipOverlay.cs +++ b/osu.Game/Screens/Play/SkipOverlay.cs @@ -27,6 +27,11 @@ namespace osu.Game.Screens.Play { public class SkipOverlay : CompositeDrawable, IKeyBindingHandler { + /// + /// The total number of successful skips performed by this overlay. + /// + public int SkipCount { get; private set; } + private readonly double startTime; public Action RequestSkip; @@ -124,7 +129,11 @@ namespace osu.Game.Screens.Play return; } - button.Action = () => RequestSkip?.Invoke(); + button.Action = () => + { + SkipCount++; + RequestSkip?.Invoke(); + }; fadeContainer.TriggerShow(); From 5f2f6b84b2febc80fdc166c89011c7175bba3818 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 12:27:37 +0900 Subject: [PATCH 0387/2991] Add failing test coverage of automated skip scenarios --- .../Visual/Gameplay/TestSceneSkipOverlay.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs index 4b564f704a..1bba62a5cf 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs @@ -93,6 +93,15 @@ namespace osu.Game.Tests.Visual.Gameplay checkRequestCount(1); } + [Test] + public void TestAutomaticSkipActuatesOnce() + { + createTest(); + AddStep("start automated skip", () => skip.SkipWhenReady()); + AddUntilStep("wait for button disabled", () => !skip.IsButtonVisible); + checkRequestCount(1); + } + [Test] public void TestClickOnlyActuatesOnce() { @@ -110,6 +119,16 @@ namespace osu.Game.Tests.Visual.Gameplay checkRequestCount(1); } + [Test] + public void TestAutomaticSkipActuatesMultipleTimes() + { + createTest(); + AddStep("set increment lower", () => increment = 3000); + AddStep("start automated skip", () => skip.SkipWhenReady()); + AddUntilStep("wait for button disabled", () => !skip.IsButtonVisible); + checkRequestCount(2); + } + [Test] public void TestClickOnlyActuatesMultipleTimes() { From 4154be6cdaccb5cf40f1a95b79d1ab226ddc5dd5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 12:05:00 +0900 Subject: [PATCH 0388/2991] Adjust auto-skip to skip multiple times if necessary --- osu.Game/Screens/Play/SkipOverlay.cs | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Play/SkipOverlay.cs b/osu.Game/Screens/Play/SkipOverlay.cs index ee05fce730..99fe659bf3 100644 --- a/osu.Game/Screens/Play/SkipOverlay.cs +++ b/osu.Game/Screens/Play/SkipOverlay.cs @@ -136,20 +136,29 @@ namespace osu.Game.Screens.Play }; fadeContainer.TriggerShow(); - - if (skipQueued) - { - Scheduler.AddDelayed(() => button.TriggerClick(), 200); - skipQueued = false; - } } + /// + /// Triggers an "automated" skip to happen as soon as available. + /// public void SkipWhenReady() { - if (IsLoaded) + if (skipQueued) return; + + skipQueued = true; + attemptNextSkip(); + + void attemptNextSkip() => Scheduler.AddDelayed(() => + { + if (!button.Enabled.Value) + { + skipQueued = false; + return; + } + button.TriggerClick(); - else - skipQueued = true; + attemptNextSkip(); + }, 200); } protected override void Update() From df9f49eef21a46431f2752b29f20a1434392bfdf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 13:56:06 +0900 Subject: [PATCH 0389/2991] Move hover layer behind icon Looked bad on the "already downloaded" state where the icon becomes black. --- .../Drawables/Cards/Buttons/BeatmapCardIconButton.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs index a4beab02ed..6b9b67123e 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs @@ -78,17 +78,17 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons Anchor = Anchor.Centre, Children = new Drawable[] { - Icon = new SpriteIcon - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - }, hover = new Box { RelativeSizeAxes = Axes.Both, Colour = Color4.White.Opacity(0.1f), Blending = BlendingParameters.Additive, }, + Icon = new SpriteIcon + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + }, } }); From fc191807c6ea44659158d32476e5100058940837 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Thu, 3 Nov 2022 13:59:22 +0900 Subject: [PATCH 0390/2991] Fix velocity test failing with no audio device --- .../Timelines/Summary/Parts/TimelinePart.cs | 14 ++++++-------- osu.Game/Screens/Edit/EditorClock.cs | 2 +- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index 54914f4b23..bb5b4a6cea 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -57,15 +57,13 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts private void updateRelativeChildSize() { - // the track may not be loaded completely (only has a length once it is). - if (!beatmap.Value.Track.IsLoaded) - { - content.RelativeChildSize = Vector2.One; - Schedule(updateRelativeChildSize); - return; - } + // If the track is not loaded, assign a default sane length otherwise relative positioning becomes meaningless. + double trackLength = beatmap.Value.Track.IsLoaded ? beatmap.Value.Track.Length : 60000; + content.RelativeChildSize = new Vector2((float)Math.Max(1, trackLength), 1); - content.RelativeChildSize = new Vector2((float)Math.Max(1, beatmap.Value.Track.Length), 1); + // The track may not be loaded completely (only has a length once it is). + if (!beatmap.Value.Track.IsLoaded) + Schedule(updateRelativeChildSize); } protected virtual void LoadBeatmap(EditorBeatmap beatmap) diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index 6485f683ad..81d82130da 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -27,7 +27,7 @@ namespace osu.Game.Screens.Edit private readonly Bindable track = new Bindable(); - public double TrackLength => track.Value?.Length ?? 60000; + public double TrackLength => track.Value?.IsLoaded == true ? track.Value.Length : 60000; public ControlPointInfo ControlPointInfo => Beatmap.ControlPointInfo; From 66a6084d3f6a93e4e10a61ea0625a9f457b51a48 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 14:03:19 +0900 Subject: [PATCH 0391/2991] Scale in the background fill alongside the icon --- .../Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs index 6b9b67123e..af1a8eb06a 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs @@ -74,6 +74,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons RelativeSizeAxes = Axes.Both, Masking = true, CornerRadius = BeatmapCard.CORNER_RADIUS, + Scale = new Vector2(0.8f), Origin = Anchor.Centre, Anchor = Anchor.Centre, Children = new Drawable[] @@ -88,6 +89,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons { Origin = Anchor.Centre, Anchor = Anchor.Centre, + Scale = new Vector2(1.2f), }, } }); @@ -127,7 +129,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons bool isHovered = IsHovered && Enabled.Value; hover.FadeTo(isHovered ? 1f : 0f, 500, Easing.OutQuint); - Icon.ScaleTo(isHovered ? 1.2f : 1, 500, Easing.OutQuint); + content.ScaleTo(isHovered ? 1 : 0.8f, 500, Easing.OutQuint); Icon.FadeColour(isHovered ? HoverColour : IdleColour, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); } } From 07bfac40faaccdd47bbd4b96eaaa4d6789d1733c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 14:03:28 +0900 Subject: [PATCH 0392/2991] Adjust padding to avoid overlap with card border when expanded --- .../Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs b/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs index f70694bdda..9b200d62aa 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs @@ -95,7 +95,9 @@ namespace osu.Game.Beatmaps.Drawables.Cards Child = buttons = new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding(3), + // Padding of 4 avoids touching the card borders when in the expanded (ie. showing difficulties) state. + // Left override allows the buttons to visually be wider and look better. + Padding = new MarginPadding(4) { Left = 2 }, Children = new BeatmapCardIconButton[] { new FavouriteButton(beatmapSet) From 62660ec92fe12dd64c42de6e7d3831e3169064eb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 14:21:22 +0900 Subject: [PATCH 0393/2991] Reorganise drawables and transforms to make more sequential sense --- .../Skinning/Argon/ArgonSpinnerDisc.cs | 83 +++++++++---------- 1 file changed, 40 insertions(+), 43 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs index 3b418fcb2d..b2c804a2da 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs @@ -98,28 +98,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon AlwaysPresent = true, } }, - new Container - { - Name = @"Ring", - Masking = true, - RelativeSizeAxes = Axes.Both, - Children = new[] - { - new ArgonSpinnerRingArc - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Name = "Top Arc", - }, - new ArgonSpinnerRingArc - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Name = "Bottom Arc", - Scale = new Vector2(1, -1), - }, - } - }, ticksContainer = new Container { Anchor = Anchor.Centre, @@ -130,6 +108,29 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon }, }, new Container + { + Name = @"Ring", + Masking = true, + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding(8f), + Children = new[] + { + new ArgonSpinnerRingArc + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Name = "Top Arc", + }, + new ArgonSpinnerRingArc + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Name = "Bottom Arc", + Scale = new Vector2(1, -1), + }, + } + }, + new Container { Name = @"Sides", RelativeSizeAxes = Axes.Both, @@ -226,6 +227,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon { this.ScaleTo(initial_scale); ticksContainer.RotateTo(0); + centre.ScaleTo(0); + disc.ScaleTo(0); using (BeginDelayedSequence(spinner.TimePreempt / 2)) { @@ -233,27 +236,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon ticksContainer.RotateTo((float)(25 * spinner.Duration / 2000), spinner.TimePreempt + spinner.Duration); } - using (BeginDelayedSequence(spinner.TimePreempt + spinner.Duration + drawableHitObject.Result.TimeOffset)) - { - switch (state) - { - case ArmedState.Hit: - this.ScaleTo(initial_scale * 1.2f, 320, Easing.Out); - ticksContainer.RotateTo(ticksContainer.Rotation + 180, 320); - break; - - case ArmedState.Miss: - this.ScaleTo(initial_scale * 0.8f, 320, Easing.In); - break; - } - } - } - - using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt)) - { - centre.ScaleTo(0); - disc.ScaleTo(0); - using (BeginDelayedSequence(spinner.TimePreempt / 2)) { centre.ScaleTo(0.3f, spinner.TimePreempt / 4, Easing.OutQuint); @@ -265,6 +247,21 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon disc.ScaleTo(1, spinner.TimePreempt / 2, Easing.OutQuint); } } + + using (BeginDelayedSequence(spinner.TimePreempt + spinner.Duration + drawableHitObject.Result.TimeOffset)) + { + switch (state) + { + case ArmedState.Hit: + disc.ScaleTo(initial_scale * 1.2f, 320, Easing.Out); + ticksContainer.RotateTo(ticksContainer.Rotation + 180, 320); + break; + + case ArmedState.Miss: + disc.ScaleTo(initial_scale * 0.8f, 320, Easing.In); + break; + } + } } if (drawableSpinner.Result?.TimeStarted != null) From 0868c00ee83f00af4d4eb7a43317ac9569260ca0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 14:36:11 +0900 Subject: [PATCH 0394/2991] Fix spinner centre size being updated every frame using transforms --- .../Skinning/Argon/ArgonSpinnerDisc.cs | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs index b2c804a2da..f99d4275bd 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.ObjectExtensions; @@ -184,6 +183,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon updateStateTransforms(drawableSpinner, drawableSpinner.State.Value); } + private float trackingElementInterpolation; + protected override void Update() { base.Update(); @@ -203,11 +204,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon } else { - fill.Alpha = (float)Interpolation.Damp(fill.Alpha, drawableSpinner.RotationTracker.Tracking ? tracking_alpha : idle_alpha, 0.98f, (float)Math.Abs(Clock.ElapsedFrameTime)); - } + trackingElementInterpolation = + (float)Interpolation.Damp(trackingElementInterpolation, drawableSpinner.RotationTracker.Tracking ? 1 : 0, 0.985f, (float)Math.Abs(Clock.ElapsedFrameTime)); - if (centre.Width == idle_centre_size && drawableSpinner.Result?.TimeStarted != null) - updateCentrePieceSize(); + fill.Alpha = trackingElementInterpolation * (tracking_alpha - idle_alpha) + idle_alpha; + centre.Size = new Vector2(trackingElementInterpolation * (tracking_centre_size - idle_centre_size) + idle_centre_size); + } const float initial_fill_scale = 0.1f; float targetScale = initial_fill_scale + (0.98f - initial_fill_scale) * drawableSpinner.Progress; @@ -263,19 +265,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon } } } - - if (drawableSpinner.Result?.TimeStarted != null) - updateCentrePieceSize(); - } - - private void updateCentrePieceSize() - { - Debug.Assert(drawableSpinner.Result?.TimeStarted != null); - - Spinner spinner = drawableSpinner.HitObject; - - using (BeginAbsoluteSequence(drawableSpinner.Result.TimeStarted.Value)) - centre.ResizeTo(new Vector2(tracking_centre_size), spinner.TimePreempt / 2, Easing.OutQuint); } protected override void Dispose(bool isDisposing) From 94b1c2602eba7a75c76a7a4f4335377f5d4865aa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 14:36:11 +0900 Subject: [PATCH 0395/2991] Fix spinner centre size being updated every frame using transforms --- .../Skinning/Argon/ArgonSpinnerDisc.cs | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs index 4669b5b913..d88752f025 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.ObjectExtensions; @@ -138,6 +137,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon updateStateTransforms(drawableSpinner, drawableSpinner.State.Value); } + private float trackingElementInterpolation; + protected override void Update() { base.Update(); @@ -157,11 +158,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon } else { - fill.Alpha = (float)Interpolation.Damp(fill.Alpha, drawableSpinner.RotationTracker.Tracking ? tracking_alpha : idle_alpha, 0.98f, (float)Math.Abs(Clock.ElapsedFrameTime)); - } + trackingElementInterpolation = + (float)Interpolation.Damp(trackingElementInterpolation, drawableSpinner.RotationTracker.Tracking ? 1 : 0, 0.985f, (float)Math.Abs(Clock.ElapsedFrameTime)); - if (centre.Width == idle_centre_size && drawableSpinner.Result?.TimeStarted != null) - updateCentrePieceSize(); + fill.Alpha = trackingElementInterpolation * (tracking_alpha - idle_alpha) + idle_alpha; + centre.Size = new Vector2(trackingElementInterpolation * (tracking_centre_size - idle_centre_size) + idle_centre_size); + } const float initial_fill_scale = 0.1f; float targetScale = initial_fill_scale + (0.98f - initial_fill_scale) * drawableSpinner.Progress; @@ -221,19 +223,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon } } } - - if (drawableSpinner.Result?.TimeStarted != null) - updateCentrePieceSize(); - } - - private void updateCentrePieceSize() - { - Debug.Assert(drawableSpinner.Result?.TimeStarted != null); - - Spinner spinner = drawableSpinner.HitObject; - - using (BeginAbsoluteSequence(drawableSpinner.Result.TimeStarted.Value)) - centre.ResizeTo(new Vector2(tracking_centre_size), spinner.TimePreempt / 2, Easing.OutQuint); } protected override void Dispose(bool isDisposing) From e89d3840fc99c8f3724d674d14aad779e994bb2f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 15:11:26 +0900 Subject: [PATCH 0396/2991] Adjust completion animation --- .../Skinning/Argon/ArgonSpinnerProgressArc.cs | 14 +++++++---- .../Skinning/Argon/ArgonSpinnerRingArc.cs | 24 +++++++++++++++++-- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs index be7921a1f1..e998f55755 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; using osu.Framework.Utils; -using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables; using osuTK.Graphics; @@ -24,8 +23,10 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon private DrawableSpinner spinner = null!; + private CircularProgress background = null!; + [BackgroundDependencyLoader] - private void load(DrawableHitObject drawableHitObject, OsuColour colours) + private void load(DrawableHitObject drawableHitObject) { RelativeSizeAxes = Axes.Both; @@ -33,7 +34,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon InternalChildren = new Drawable[] { - new CircularProgress + background = new CircularProgress { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -59,8 +60,11 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon { base.Update(); - fill.Alpha = (float)Interpolation.DampContinuously(fill.Alpha, spinner.Progress > 0 ? 1 : 0, 120f, (float)Math.Abs(Time.Elapsed)); - fill.Current.Value = (float)Interpolation.DampContinuously(fill.Current.Value, arc_fill * spinner.Progress, 120f, (float)Math.Abs(Time.Elapsed)); + background.Alpha = spinner.Progress >= 1 ? 0 : 1; + + fill.Alpha = (float)Interpolation.DampContinuously(fill.Alpha, spinner.Progress > 0 && spinner.Progress < 1 ? 1 : 0, 40f, (float)Math.Abs(Time.Elapsed)); + fill.Current.Value = (float)Interpolation.DampContinuously(fill.Current.Value, spinner.Progress >= 1 ? 0 : arc_fill * spinner.Progress, 40f, (float)Math.Abs(Time.Elapsed)); + fill.Rotation = (float)(90 - fill.Current.Value * 180); } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs index ec9d7bbae5..57fb57a09e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs @@ -1,24 +1,34 @@ // 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.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; +using osu.Framework.Utils; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Skinning.Argon { public class ArgonSpinnerRingArc : CompositeDrawable { private const float arc_fill = 0.31f; + private const float arc_fill_complete = 0.50f; + private const float arc_radius = 0.02f; + private DrawableSpinner spinner = null!; + private CircularProgress fill = null!; + [BackgroundDependencyLoader] - private void load() + private void load(DrawableHitObject drawableHitObject) { RelativeSizeAxes = Axes.Both; - InternalChild = new CircularProgress + spinner = (DrawableSpinner)drawableHitObject; + InternalChild = fill = new CircularProgress { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -29,5 +39,15 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon RoundedCaps = true, }; } + + protected override void Update() + { + base.Update(); + + fill.Current.Value = (float)Interpolation.DampContinuously(fill.Current.Value, spinner.Progress >= 1 ? arc_fill_complete : arc_fill, 40f, (float)Math.Abs(Time.Elapsed)); + fill.InnerRadius = (float)Interpolation.DampContinuously(fill.InnerRadius, spinner.Progress >= 1 ? arc_radius * 2.2f : arc_radius, 40f, (float)Math.Abs(Time.Elapsed)); + + fill.Rotation = (float)(-fill.Current.Value * 180); + } } } From 56ef519cc28fc1ee5c7ca321723aa3d9370cbdd3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 15:43:06 +0900 Subject: [PATCH 0397/2991] Move `PopoverContainer` into `OnlineOverlay` to ensure correct colours --- osu.Game/OsuGameBase.cs | 9 ++------- osu.Game/Overlays/OnlineOverlay.cs | 3 ++- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index c4c2c8325d..39ddffd2d0 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -18,7 +18,6 @@ using osu.Framework.Development; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Textures; using osu.Framework.Input; using osu.Framework.Input.Handlers; @@ -358,13 +357,9 @@ namespace osu.Game (GlobalCursorDisplay = new GlobalCursorDisplay { RelativeSizeAxes = Axes.Both - }).WithChild(new OsuTooltipContainer(GlobalCursorDisplay.MenuCursor) + }).WithChild(content = new OsuTooltipContainer(GlobalCursorDisplay.MenuCursor) { - RelativeSizeAxes = Axes.Both, - Child = content = new PopoverContainer - { - RelativeSizeAxes = Axes.Both, - } + RelativeSizeAxes = Axes.Both }), // to avoid positional input being blocked by children, ensure the GlobalActionContainer is above everything. globalBindings = new GlobalActionContainer(this) diff --git a/osu.Game/Overlays/OnlineOverlay.cs b/osu.Game/Overlays/OnlineOverlay.cs index 424584fbcf..24bc7a73e0 100644 --- a/osu.Game/Overlays/OnlineOverlay.cs +++ b/osu.Game/Overlays/OnlineOverlay.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Game.Graphics.UserInterface; using osu.Game.Online; @@ -45,7 +46,7 @@ namespace osu.Game.Overlays Children = new Drawable[] { Header.With(h => h.Depth = float.MinValue), - content = new Container + content = new PopoverContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y From 502bfa950ec94ab296fbae266e82a1e1b3a5b3ee Mon Sep 17 00:00:00 2001 From: C0D3 M4513R <28912031+C0D3-M4513R@users.noreply.github.com> Date: Thu, 3 Nov 2022 08:05:26 +0100 Subject: [PATCH 0398/2991] Fix potential resource leak --- .../Components/BeatmapInfoDrawable.cs | 213 +++++++----------- 1 file changed, 82 insertions(+), 131 deletions(-) diff --git a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs index 44c3914d2c..ac771af8f9 100644 --- a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs +++ b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs @@ -83,17 +83,18 @@ namespace osu.Game.Skinning.Components protected override void LoadComplete() { base.LoadComplete(); - Type.BindValueChanged(update, true); - ShowLabel.BindValueChanged(ignored => updateLabel()); - ValueBeforeLabel.BindValueChanged(ignored => updateLabel()); - LabelPrefix.BindValueChanged(ignored => updateLabel()); - ShowLabelPrefix.BindValueChanged(ignored => updateLabel()); - LabelSuffix.BindValueChanged(ignored => updateLabel()); - ShowLabelSuffix.BindValueChanged(ignored => updateLabel()); - ValuePrefix.BindValueChanged(ignored => updateLabel()); - ShowValuePrefix.BindValueChanged(ignored => updateLabel()); - ValueSuffix.BindValueChanged(ignored => updateLabel()); - ShowValueSuffix.BindValueChanged(ignored => updateLabel()); + Type.BindValueChanged(_ => updateBeatmapContent()); + beatmap.BindValueChanged(_ => updateBeatmapContent(), true); + ShowLabel.BindValueChanged(_ => updateLabel()); + ValueBeforeLabel.BindValueChanged(_ => updateLabel()); + LabelPrefix.BindValueChanged(_ => updateLabel()); + ShowLabelPrefix.BindValueChanged(_ => updateLabel()); + LabelSuffix.BindValueChanged(_ => updateLabel()); + ShowLabelSuffix.BindValueChanged(_ => updateLabel()); + ValuePrefix.BindValueChanged(_ => updateLabel()); + ShowValuePrefix.BindValueChanged(_ => updateLabel()); + ValueSuffix.BindValueChanged(_ => updateLabel()); + ShowValueSuffix.BindValueChanged(_ => updateLabel()); } private LocalisableString getLabelText() @@ -125,174 +126,124 @@ namespace osu.Game.Skinning.Components Height = text.Height; } - private void update(ValueChangedEvent type) + private void updateBeatmapContent() { - switch (type.NewValue) + switch (Type.Value) { case BeatmapInfo.CircleSize: - beatmap.BindValueChanged(bm => - { - double cs = bm.NewValue.BeatmapInfo.Difficulty.CircleSize; - labelText = TooltipText = BeatmapsetsStrings.ShowStatsCs; - value = cs.ToString("F2"); - updateLabel(); - }, true); + double cs = beatmap.Value.BeatmapInfo.Difficulty.CircleSize; + labelText = TooltipText = BeatmapsetsStrings.ShowStatsCs; + value = cs.ToString("F2"); break; case BeatmapInfo.HPDrain: - beatmap.BindValueChanged(bm => - { - double hp = bm.NewValue.BeatmapInfo.Difficulty.DrainRate; - labelText = TooltipText = BeatmapsetsStrings.ShowStatsDrain; - value = hp.ToString("F2"); - updateLabel(); - }, true); + double hp = beatmap.Value.BeatmapInfo.Difficulty.DrainRate; + labelText = TooltipText = BeatmapsetsStrings.ShowStatsDrain; + value = hp.ToString("F2"); break; case BeatmapInfo.Accuracy: - beatmap.BindValueChanged(bm => - { - double od = bm.NewValue.BeatmapInfo.Difficulty.OverallDifficulty; - labelText = TooltipText = BeatmapsetsStrings.ShowStatsAccuracy; - value = od.ToString("F2"); - updateLabel(); - }, true); + double od = beatmap.Value.BeatmapInfo.Difficulty.OverallDifficulty; + labelText = TooltipText = BeatmapsetsStrings.ShowStatsAccuracy; + value = od.ToString("F2"); break; case BeatmapInfo.ApproachRate: - beatmap.BindValueChanged(bm => - { - double ar = bm.NewValue.BeatmapInfo.Difficulty.ApproachRate; - labelText = TooltipText = BeatmapsetsStrings.ShowStatsAr; - value = ar.ToString("F2"); - updateLabel(); - }, true); + double ar = beatmap.Value.BeatmapInfo.Difficulty.ApproachRate; + labelText = TooltipText = BeatmapsetsStrings.ShowStatsAr; + value = ar.ToString("F2"); break; case BeatmapInfo.StarRating: - beatmap.BindValueChanged(bm => - { - double sr = bm.NewValue.BeatmapInfo.StarRating; - labelText = TooltipText = BeatmapsetsStrings.ShowStatsStars; - value = sr.ToString("F2"); - updateLabel(); - }, true); + double sr = beatmap.Value.BeatmapInfo.StarRating; + labelText = TooltipText = BeatmapsetsStrings.ShowStatsStars; + value = sr.ToString("F2"); break; case BeatmapInfo.Song: - beatmap.BindValueChanged(bm => - { - string title = bm.NewValue.BeatmapInfo.Metadata.Title; - //todo: no Song Title localisation? - labelText = TooltipText = EditorSetupStrings.Title; - value = title; - updateLabel(); - }, true); + string title = beatmap.Value.BeatmapInfo.Metadata.Title; + labelText = TooltipText = EditorSetupStrings.Title; + value = title; break; case BeatmapInfo.Artist: - beatmap.BindValueChanged(bm => - { - string artist = bm.NewValue.BeatmapInfo.Metadata.Artist; - labelText = EditorSetupStrings.Artist; - TooltipText = BeatmapsetsStrings.ShowDetailsByArtist(artist); - value = artist; - updateLabel(); - }, true); + string artist = beatmap.Value.BeatmapInfo.Metadata.Artist; + labelText = EditorSetupStrings.Artist; + TooltipText = BeatmapsetsStrings.ShowDetailsByArtist(artist); + value = artist; break; case BeatmapInfo.Difficulty: - beatmap.BindValueChanged(bm => - { - string diff = bm.NewValue.BeatmapInfo.DifficultyName; - labelText = TooltipText = EditorSetupStrings.DifficultyHeader; - text.Current.Value = diff; - updateLabel(); - }, true); + string diff = beatmap.Value.BeatmapInfo.DifficultyName; + labelText = TooltipText = EditorSetupStrings.DifficultyHeader; + text.Current.Value = diff; break; case BeatmapInfo.Mapper: - beatmap.BindValueChanged(bm => - { - string mapper = bm.NewValue.BeatmapInfo.Metadata.Author.Username; - //todo: is there a good alternative, to ShowDetailsMappedBy? - labelText = AccountsStrings.NotificationsOptionsMapping; - TooltipText = BeatmapsetsStrings.ShowDetailsMappedBy(mapper); - value = mapper; - updateLabel(); - }, true); + string mapper = beatmap.Value.BeatmapInfo.Metadata.Author.Username; + //todo: is there a good alternative, to NotificationsOptionsMapping? + labelText = AccountsStrings.NotificationsOptionsMapping; + TooltipText = BeatmapsetsStrings.ShowDetailsMappedBy(mapper); + value = mapper; break; case BeatmapInfo.Length: - beatmap.BindValueChanged(bm => - { - labelText = TooltipText = ArtistStrings.TracklistLength; - value = TimeSpan.FromMilliseconds(bm.NewValue.BeatmapInfo.Length).ToFormattedDuration(); - updateLabel(); - }, true); + labelText = TooltipText = ArtistStrings.TracklistLength; + value = TimeSpan.FromMilliseconds(beatmap.Value.BeatmapInfo.Length).ToFormattedDuration(); break; case BeatmapInfo.Status: - beatmap.BindValueChanged(bm => + BeatmapOnlineStatus status = beatmap.Value.BeatmapInfo.Status; + TooltipText = labelText = BeatmapDiscussionsStrings.IndexFormBeatmapsetStatusDefault; + + switch (status) { - BeatmapOnlineStatus status = bm.NewValue.BeatmapInfo.Status; - //todo: no Localizasion for None Beatmap Online Status - labelText = BeatmapDiscussionsStrings.IndexFormBeatmapsetStatusDefault; + case BeatmapOnlineStatus.Approved: + value = BeatmapsetsStrings.ShowStatusApproved; + break; - switch (status) - { - case BeatmapOnlineStatus.Approved: - value = BeatmapsetsStrings.ShowStatusApproved; - //todo: is this correct? - TooltipText = BeatmapsetsStrings.ShowDetailsDateApproved(bm.NewValue.BeatmapSetInfo.DateRanked.ToString()); - break; + case BeatmapOnlineStatus.Graveyard: + value = BeatmapsetsStrings.ShowStatusGraveyard; + break; - case BeatmapOnlineStatus.Graveyard: - value = BeatmapsetsStrings.ShowStatusGraveyard; - break; + case BeatmapOnlineStatus.Loved: + value = BeatmapsetsStrings.ShowStatusLoved; + break; - case BeatmapOnlineStatus.Loved: - value = BeatmapsetsStrings.ShowStatusLoved; - break; + case BeatmapOnlineStatus.None: + value = "None"; + break; - case BeatmapOnlineStatus.None: - value = "None"; - break; + case BeatmapOnlineStatus.Pending: + value = BeatmapsetsStrings.ShowStatusPending; + break; - case BeatmapOnlineStatus.Pending: - value = BeatmapsetsStrings.ShowStatusPending; - break; + case BeatmapOnlineStatus.Qualified: + value = BeatmapsetsStrings.ShowStatusQualified; + break; - case BeatmapOnlineStatus.Qualified: - value = BeatmapsetsStrings.ShowStatusQualified; - break; + case BeatmapOnlineStatus.Ranked: + value = BeatmapsetsStrings.ShowStatusRanked; + break; - case BeatmapOnlineStatus.Ranked: - value = BeatmapsetsStrings.ShowStatusRanked; - break; + case BeatmapOnlineStatus.LocallyModified: + value = SongSelectStrings.LocallyModified; + break; - case BeatmapOnlineStatus.LocallyModified: - value = SongSelectStrings.LocallyModified; - break; + case BeatmapOnlineStatus.WIP: + value = BeatmapsetsStrings.ShowStatusWip; + break; + } - case BeatmapOnlineStatus.WIP: - value = BeatmapsetsStrings.ShowStatusWip; - break; - } - - updateLabel(); - }, true); break; case BeatmapInfo.BPM: - beatmap.BindValueChanged(bm => - { - labelText = TooltipText = BeatmapsetsStrings.ShowStatsBpm; - value = bm.NewValue.BeatmapInfo.BPM.ToString("F2"); - updateLabel(); - }, true); + labelText = TooltipText = BeatmapsetsStrings.ShowStatsBpm; + value = beatmap.Value.BeatmapInfo.BPM.ToString("F2"); break; } + + updateLabel(); } } From f1c17129eb34d7e49342826e8fbd425b006d4f5f Mon Sep 17 00:00:00 2001 From: Jamie Taylor Date: Thu, 3 Nov 2022 17:44:54 +0900 Subject: [PATCH 0399/2991] Add support for 'disabled' sample variation to HoverClickSounds --- .../UserInterface/TestSceneLabelledSliderBar.cs | 8 ++++++++ .../Graphics/Containers/OsuClickableContainer.cs | 2 +- .../Graphics/UserInterface/DrawableOsuMenuItem.cs | 4 +++- .../Graphics/UserInterface/HoverClickSounds.cs | 15 +++++++++++++-- osu.Game/Graphics/UserInterface/OsuButton.cs | 2 +- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 5 ++++- osu.Game/Graphics/UserInterface/ShearedButton.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarClock.cs | 3 +++ 8 files changed, 34 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs index e5f3aea2f7..5548375af2 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs @@ -38,6 +38,14 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("revert back", () => this.ChildrenOfType>().ForEach(l => l.ResizeWidthTo(1, 200, Easing.OutQuint))); } + [Test] + public void TestDisable() + { + createSliderBar(); + AddStep("set disabled", () => this.ChildrenOfType>().ForEach(l => l.Current.Disabled = true)); + AddStep("unset disabled", () => this.ChildrenOfType>().ForEach(l => l.Current.Disabled = false)); + } + private void createSliderBar() { AddStep("create component", () => diff --git a/osu.Game/Graphics/Containers/OsuClickableContainer.cs b/osu.Game/Graphics/Containers/OsuClickableContainer.cs index 61ec9dfc24..03a1cfcc13 100644 --- a/osu.Game/Graphics/Containers/OsuClickableContainer.cs +++ b/osu.Game/Graphics/Containers/OsuClickableContainer.cs @@ -20,7 +20,7 @@ namespace osu.Game.Graphics.Containers protected override Container Content => content; - protected virtual HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverClickSounds(sampleSet); + protected virtual HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverClickSounds(sampleSet) { Enabled = { BindTarget = Enabled } }; public OsuClickableContainer(HoverSampleSet sampleSet = HoverSampleSet.Default) { diff --git a/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs b/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs index b469c21ab0..6c8eeed391 100644 --- a/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs +++ b/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs @@ -24,6 +24,7 @@ namespace osu.Game.Graphics.UserInterface private const int transition_length = 80; private TextContainer text; + private HoverClickSounds hoverClickSounds; public DrawableOsuMenuItem(MenuItem item) : base(item) @@ -36,7 +37,7 @@ namespace osu.Game.Graphics.UserInterface BackgroundColour = Color4.Transparent; BackgroundColourHover = Color4Extensions.FromHex(@"172023"); - AddInternal(new HoverClickSounds()); + AddInternal(hoverClickSounds = new HoverClickSounds()); updateTextColour(); @@ -76,6 +77,7 @@ namespace osu.Game.Graphics.UserInterface private void updateState() { + hoverClickSounds.Enabled.Value = !Item.Action.Disabled; Alpha = Item.Action.Disabled ? 0.2f : 1; if (IsHovered && !Item.Action.Disabled) diff --git a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs index dab4390ede..9b4bff17e6 100644 --- a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs @@ -7,6 +7,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; +using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Input.Events; using osu.Framework.Utils; @@ -21,6 +22,8 @@ namespace osu.Game.Graphics.UserInterface public class HoverClickSounds : HoverSounds { private Sample sampleClick; + private Sample sampleClickDisabled; + public Bindable Enabled = new Bindable(true); private readonly MouseButton[] buttons; /// @@ -41,8 +44,13 @@ namespace osu.Game.Graphics.UserInterface { if (buttons.Contains(e.Button) && Contains(e.ScreenSpaceMousePosition)) { - sampleClick.Frequency.Value = 0.99 + RNG.NextDouble(0.02); - sampleClick.Play(); + var channel = Enabled.Value ? sampleClick?.GetChannel() : sampleClickDisabled?.GetChannel(); + + if (channel != null) + { + channel.Frequency.Value = 0.99 + RNG.NextDouble(0.02); + channel.Play(); + } } return base.OnClick(e); @@ -53,6 +61,9 @@ namespace osu.Game.Graphics.UserInterface { sampleClick = audio.Samples.Get($@"UI/{SampleSet.GetDescription()}-select") ?? audio.Samples.Get($@"UI/{HoverSampleSet.Default.GetDescription()}-select"); + + sampleClickDisabled = audio.Samples.Get($@"UI/{SampleSet.GetDescription()}-select-disabled") + ?? audio.Samples.Get($@"UI/{HoverSampleSet.Default.GetDescription()}-select-disabled"); } } } diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index 291ff644fd..88f3ccd191 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -104,7 +104,7 @@ namespace osu.Game.Graphics.UserInterface }); if (hoverSounds.HasValue) - AddInternal(new HoverClickSounds(hoverSounds.Value)); + AddInternal(new HoverClickSounds(hoverSounds.Value) { Enabled = { BindTarget = Enabled } }); } [BackgroundDependencyLoader] diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index 9acb0c7f94..392740690a 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -46,6 +46,8 @@ namespace osu.Game.Graphics.UserInterface public bool PlaySamplesOnAdjust { get; set; } = true; + private readonly HoverClickSounds hoverClickSounds; + /// /// Whether to format the tooltip as a percentage or the actual value. /// @@ -127,7 +129,7 @@ namespace osu.Game.Graphics.UserInterface Current = { Value = true } }, }, - new HoverClickSounds() + hoverClickSounds = new HoverClickSounds() }; Current.DisabledChanged += disabled => { Alpha = disabled ? 0.3f : 1; }; @@ -152,6 +154,7 @@ namespace osu.Game.Graphics.UserInterface { base.LoadComplete(); CurrentNumber.BindValueChanged(current => TooltipText = getTooltipText(current.NewValue), true); + Current.DisabledChanged += disabled => hoverClickSounds.Enabled.Value = !disabled; } protected override bool OnHover(HoverEvent e) diff --git a/osu.Game/Graphics/UserInterface/ShearedButton.cs b/osu.Game/Graphics/UserInterface/ShearedButton.cs index 0c25d06cd4..e406e273e6 100644 --- a/osu.Game/Graphics/UserInterface/ShearedButton.cs +++ b/osu.Game/Graphics/UserInterface/ShearedButton.cs @@ -138,7 +138,7 @@ namespace osu.Game.Graphics.UserInterface } } - protected override HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverClickSounds(sampleSet); + protected override HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverClickSounds(sampleSet) { Enabled = { BindTarget = Enabled } }; protected override void LoadComplete() { diff --git a/osu.Game/Overlays/Toolbar/ToolbarClock.cs b/osu.Game/Overlays/Toolbar/ToolbarClock.cs index c5add6eee2..9c264acbd1 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarClock.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarClock.cs @@ -13,6 +13,7 @@ using osu.Framework.Input.Events; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; using osuTK; using osuTK.Graphics; @@ -123,6 +124,8 @@ namespace osu.Game.Overlays.Toolbar base.OnHoverLost(e); } + protected override HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverClickSounds(sampleSet) { Enabled = { Value = true } }; + private void cycleDisplayMode() { switch (clockDisplayMode.Value) From 59bbd9c460afc87ee2cc8613692fc6d0e156dfff Mon Sep 17 00:00:00 2001 From: Jamie Taylor Date: Thu, 3 Nov 2022 17:47:29 +0900 Subject: [PATCH 0400/2991] Fix some components using wrong sample set --- osu.Game/Graphics/UserInterface/LoadingButton.cs | 1 + osu.Game/Overlays/Comments/CancellableCommentEditor.cs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/LoadingButton.cs b/osu.Game/Graphics/UserInterface/LoadingButton.cs index 8be50a4b43..44067bac8b 100644 --- a/osu.Game/Graphics/UserInterface/LoadingButton.cs +++ b/osu.Game/Graphics/UserInterface/LoadingButton.cs @@ -41,6 +41,7 @@ namespace osu.Game.Graphics.UserInterface private readonly LoadingSpinner loading; protected LoadingButton() + : base(HoverSampleSet.Button) { Add(loading = new LoadingSpinner { diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs index 853171ea4a..7ba6de86b7 100644 --- a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -12,6 +12,7 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments @@ -38,6 +39,7 @@ namespace osu.Game.Overlays.Comments private readonly Box background; public CancelButton() + : base(HoverSampleSet.Button) { AutoSizeAxes = Axes.Both; Child = new CircularContainer From f75c4ba95fff8056cb4b48582d281d53183f1758 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 20:27:44 +0900 Subject: [PATCH 0401/2991] Update resources --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 8711ceec64..b3c48da2bf 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -51,7 +51,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8d45ebec57..fe44ed3688 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 76d2e727c8..b5b488d82e 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -61,7 +61,7 @@ - + From f6c376c09077dd79713940c785c6985a802bbbbe Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 3 Nov 2022 20:29:27 +0900 Subject: [PATCH 0402/2991] Minor refactoring --- osu.Game/Graphics/UserInterface/HoverClickSounds.cs | 4 +++- osu.Game/Overlays/Toolbar/ToolbarClock.cs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs index 9b4bff17e6..89d1570cd4 100644 --- a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs @@ -21,9 +21,11 @@ namespace osu.Game.Graphics.UserInterface /// public class HoverClickSounds : HoverSounds { + public Bindable Enabled = new Bindable(true); + private Sample sampleClick; private Sample sampleClickDisabled; - public Bindable Enabled = new Bindable(true); + private readonly MouseButton[] buttons; /// diff --git a/osu.Game/Overlays/Toolbar/ToolbarClock.cs b/osu.Game/Overlays/Toolbar/ToolbarClock.cs index 9c264acbd1..3fd37d9a62 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarClock.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarClock.cs @@ -124,7 +124,7 @@ namespace osu.Game.Overlays.Toolbar base.OnHoverLost(e); } - protected override HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverClickSounds(sampleSet) { Enabled = { Value = true } }; + protected override HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverClickSounds(sampleSet); private void cycleDisplayMode() { From a435e365ea966cae81caff8b9923b8f7ed25c77e Mon Sep 17 00:00:00 2001 From: C0D3 M4513R <28912031+C0D3-M4513R@users.noreply.github.com> Date: Thu, 3 Nov 2022 18:54:55 +0100 Subject: [PATCH 0403/2991] Allow for the Value of BeatmapInfoDrawable to be formatted --- .../Components/BeatmapInfoDrawable.cs | 294 ++++++++++-------- 1 file changed, 159 insertions(+), 135 deletions(-) diff --git a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs index ac771af8f9..479124a43d 100644 --- a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs +++ b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs @@ -2,12 +2,14 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Configuration; @@ -20,12 +22,13 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Skinning.Components { [UsedImplicitly] - public class BeatmapInfoDrawable : Container, ISkinnableDrawable, IHasTooltip + public class BeatmapInfoDrawable : Container, ISkinnableDrawable { + private const BeatmapInfo default_beatmap_info = BeatmapInfo.StarRating; public bool UsesFixedAnchor { get; set; } - [SettingSource("Tracked Beatmap Info", "Which part of the BeatmapInformation should be tracked")] - public Bindable Type { get; } = new Bindable(BeatmapInfo.StarRating); + [SettingSource("Tracked Beatmap Info/Label", "Which part of the BeatmapInformation should be displayed. Gets overridden by complex changes to ValueFormat")] + public Bindable Type { get; } = new Bindable(default_beatmap_info); [SettingSource("Show Label", "Should a Label be shown, as to which status is currently Displayed?")] public BindableBool ShowLabel { get; } = new BindableBool(true); @@ -45,26 +48,37 @@ namespace osu.Game.Skinning.Components [SettingSource("Show Label Suffix", "Should the Label Suffix be included?")] public BindableBool ShowLabelSuffix { get; } = new BindableBool(true); - [SettingSource("Value Prefix", "Add something to be shown before the Value")] - public Bindable ValuePrefix { get; set; } = new Bindable(""); - - [SettingSource("Show Value Prefix", "Should the Value Prefix be included?")] - public BindableBool ShowValuePrefix { get; } = new BindableBool(); - - [SettingSource("Value Suffix", "Add something to be shown after the Value")] - public Bindable ValueSuffix { get; set; } = new Bindable(""); - - [SettingSource("Show Value Suffix", "Should the Value Suffix be included?")] - public BindableBool ShowValueSuffix { get; } = new BindableBool(); + [SettingSource("Value Formatting", "Bypass the restriction of 1 Info per element. Format is '{'+Type+'}' to substitue values. e.g. '{Song}' ")] + public Bindable ValueFormat { get; set; } = new Bindable("{" + default_beatmap_info + "}"); [Resolved] private IBindable beatmap { get; set; } = null!; + private readonly Dictionary valueDictionary = new Dictionary(); + private static readonly ImmutableDictionary label_dictionary; + private readonly OsuSpriteText text; - public LocalisableString TooltipText { get; set; } - private LocalisableString value; - private LocalisableString labelText; + static BeatmapInfoDrawable() + { + label_dictionary = new Dictionary + { + [BeatmapInfo.CircleSize] = BeatmapsetsStrings.ShowStatsCs, + [BeatmapInfo.Accuracy] = BeatmapsetsStrings.ShowStatsAccuracy, + [BeatmapInfo.HPDrain] = BeatmapsetsStrings.ShowStatsDrain, + [BeatmapInfo.ApproachRate] = BeatmapsetsStrings.ShowStatsAr, + [BeatmapInfo.StarRating] = BeatmapsetsStrings.ShowStatsStars, + [BeatmapInfo.Song] = EditorSetupStrings.Title, + [BeatmapInfo.Artist] = EditorSetupStrings.Artist, + [BeatmapInfo.Difficulty] = EditorSetupStrings.DifficultyHeader, + //todo: is there a good alternative, to NotificationsOptionsMapping? + [BeatmapInfo.Mapper] = AccountsStrings.NotificationsOptionsMapping, + [BeatmapInfo.Length] = ArtistStrings.TracklistLength, + [BeatmapInfo.Status] = BeatmapDiscussionsStrings.IndexFormBeatmapsetStatusDefault, + [BeatmapInfo.BPM] = BeatmapsetsStrings.ShowStatsBpm, + [BeatmapInfo.Custom] = BeatmapInfo.Custom.ToString() + }.ToImmutableDictionary(); + } public BeatmapInfoDrawable() { @@ -78,23 +92,78 @@ namespace osu.Game.Skinning.Components Font = OsuFont.Default.With(size: 40) } }; + + foreach (var type in Enum.GetValues(typeof(BeatmapInfo)).Cast()) + { + valueDictionary[type] = type.ToString(); + } + } + + /// + /// This will return the if the format-String contains of a singular replacement of type info, or not. + /// If there is only one one replacement of type info, it will also return the prefix/suffix (or null if no prefix/suffix exists). + /// + /// The format-String to work on + /// The replacement Type to look for + /// (true, prefix, suffix), if there is only one replacement of type info. Else (false, null, null) + private static (bool, string?, string?) isOnlyPrefixedOrSuffixed(string format, BeatmapInfo info) + { + string[] s = format.Split("{" + info + "}"); + + foreach (string si in s) + { + foreach (var type in Enum.GetValues(typeof(BeatmapInfo)).Cast()) + { + if (si.Contains("{" + type + "}")) return (false, null, null); + } + } + + //Debug.WriteLine($"format:'{format}', type:{info} is only prefixed/suffixed"); + + return (true, + s.Length >= 1 ? s[0] : null, //prefix + s.Length >= 2 ? s[1] : null //suffix + ); } protected override void LoadComplete() { base.LoadComplete(); - Type.BindValueChanged(_ => updateBeatmapContent()); - beatmap.BindValueChanged(_ => updateBeatmapContent(), true); + Type.BindValueChanged(v => + { + string newDefault = "{" + v.NewValue + "}"; + bool custom = v.NewValue == BeatmapInfo.Custom; + + //If the ValueFormat is Default and the user did not change anything we should be able to just swap the strings. + //If it was Default before, it should be default after the Type is changed. + if (ValueFormat.IsDefault && !custom) + ValueFormat.Value = newDefault; + else + { + //In this if statement we decide if the ValueFormat has been trivially changed (so only been prefixed or suffixed) + (bool preOrSuffixed, string? prefix, string? suffix) = isOnlyPrefixedOrSuffixed(ValueFormat.Value, v.OldValue); + if (preOrSuffixed) + //If it has, we can keep the prefix and suffix and just change the thing that would be substituted. + ValueFormat.Value = (prefix ?? "") + newDefault + (suffix ?? ""); + //else we just keep the ValueFormat. I determine here, that the user probably knows what they are doing, and how the ValueFormat works. + } + + //Only if we could preserve the ValueFormat (so nothing was changed except a static prefix/suffix) I want to set the new Default. + ValueFormat.Default = newDefault; + updateLabel(); + }); + ValueFormat.BindValueChanged(f => updateLabel(), true); + beatmap.BindValueChanged(b => + { + UpdateBeatmapContent(b.NewValue); + updateLabel(); + }, true); ShowLabel.BindValueChanged(_ => updateLabel()); ValueBeforeLabel.BindValueChanged(_ => updateLabel()); LabelPrefix.BindValueChanged(_ => updateLabel()); ShowLabelPrefix.BindValueChanged(_ => updateLabel()); LabelSuffix.BindValueChanged(_ => updateLabel()); ShowLabelSuffix.BindValueChanged(_ => updateLabel()); - ValuePrefix.BindValueChanged(_ => updateLabel()); - ShowValuePrefix.BindValueChanged(_ => updateLabel()); - ValueSuffix.BindValueChanged(_ => updateLabel()); - ShowValueSuffix.BindValueChanged(_ => updateLabel()); } private LocalisableString getLabelText() @@ -103,16 +172,20 @@ namespace osu.Game.Skinning.Components return LocalisableString.Format("{0}{1}{2}", ShowLabelPrefix.Value ? LabelPrefix.Value : "", - labelText, + label_dictionary[Type.Value], ShowLabelSuffix.Value ? LabelSuffix.Value : ""); } private LocalisableString getValueText() { - return LocalisableString.Format("{0}{1}{2}", - ShowValuePrefix.Value ? ValuePrefix.Value : "", - value, - ShowValueSuffix.Value ? ValueSuffix.Value : ""); + string value = ValueFormat.Value; + + foreach (var type in Enum.GetValues(typeof(BeatmapInfo)).Cast()) + { + value = value.Replace("{" + type + "}", valueDictionary[type].ToString()); + } + + return value; } private void updateLabel() @@ -126,124 +199,74 @@ namespace osu.Game.Skinning.Components Height = text.Height; } - private void updateBeatmapContent() + public void UpdateBeatmapContent(WorkingBeatmap workingBeatmap) { - switch (Type.Value) + //update cs + double cs = workingBeatmap.BeatmapInfo.Difficulty.CircleSize; + valueDictionary[BeatmapInfo.CircleSize] = cs.ToString("F2"); + //update HP + double hp = workingBeatmap.BeatmapInfo.Difficulty.DrainRate; + valueDictionary[BeatmapInfo.HPDrain] = hp.ToString("F2"); + //update od + double od = workingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty; + valueDictionary[BeatmapInfo.Accuracy] = od.ToString("F2"); + //update ar + double ar = workingBeatmap.BeatmapInfo.Difficulty.ApproachRate; + valueDictionary[BeatmapInfo.ApproachRate] = ar.ToString("F2"); + //update sr + double sr = workingBeatmap.BeatmapInfo.StarRating; + valueDictionary[BeatmapInfo.StarRating] = sr.ToString("F2"); + //update song title + valueDictionary[BeatmapInfo.Song] = workingBeatmap.BeatmapInfo.Metadata.Title; + //update artist + valueDictionary[BeatmapInfo.Artist] = workingBeatmap.BeatmapInfo.Metadata.Artist; + //update difficulty name + valueDictionary[BeatmapInfo.Difficulty] = workingBeatmap.BeatmapInfo.DifficultyName; + //update mapper + valueDictionary[BeatmapInfo.Mapper] = workingBeatmap.BeatmapInfo.Metadata.Author.Username; + //update Length + valueDictionary[BeatmapInfo.Length] = TimeSpan.FromMilliseconds(workingBeatmap.BeatmapInfo.Length).ToFormattedDuration(); + //update Status + valueDictionary[BeatmapInfo.Status] = GetBetmapStatus(workingBeatmap.BeatmapInfo.Status); + //update BPM + valueDictionary[BeatmapInfo.BPM] = workingBeatmap.BeatmapInfo.BPM.ToString("F2"); + valueDictionary[BeatmapInfo.Custom] = BeatmapInfo.Custom.ToString(); + } + + public static LocalisableString GetBetmapStatus(BeatmapOnlineStatus status) + { + switch (status) { - case BeatmapInfo.CircleSize: - double cs = beatmap.Value.BeatmapInfo.Difficulty.CircleSize; - labelText = TooltipText = BeatmapsetsStrings.ShowStatsCs; - value = cs.ToString("F2"); - break; + case BeatmapOnlineStatus.Approved: + return BeatmapsetsStrings.ShowStatusApproved; - case BeatmapInfo.HPDrain: - double hp = beatmap.Value.BeatmapInfo.Difficulty.DrainRate; - labelText = TooltipText = BeatmapsetsStrings.ShowStatsDrain; - value = hp.ToString("F2"); - break; + case BeatmapOnlineStatus.Graveyard: + return BeatmapsetsStrings.ShowStatusGraveyard; - case BeatmapInfo.Accuracy: - double od = beatmap.Value.BeatmapInfo.Difficulty.OverallDifficulty; - labelText = TooltipText = BeatmapsetsStrings.ShowStatsAccuracy; - value = od.ToString("F2"); - break; + case BeatmapOnlineStatus.Loved: + return BeatmapsetsStrings.ShowStatusLoved; - case BeatmapInfo.ApproachRate: - double ar = beatmap.Value.BeatmapInfo.Difficulty.ApproachRate; - labelText = TooltipText = BeatmapsetsStrings.ShowStatsAr; - value = ar.ToString("F2"); - break; + case BeatmapOnlineStatus.None: + return "None"; - case BeatmapInfo.StarRating: - double sr = beatmap.Value.BeatmapInfo.StarRating; - labelText = TooltipText = BeatmapsetsStrings.ShowStatsStars; - value = sr.ToString("F2"); - break; + case BeatmapOnlineStatus.Pending: + return BeatmapsetsStrings.ShowStatusPending; - case BeatmapInfo.Song: - string title = beatmap.Value.BeatmapInfo.Metadata.Title; - labelText = TooltipText = EditorSetupStrings.Title; - value = title; - break; + case BeatmapOnlineStatus.Qualified: + return BeatmapsetsStrings.ShowStatusQualified; - case BeatmapInfo.Artist: - string artist = beatmap.Value.BeatmapInfo.Metadata.Artist; - labelText = EditorSetupStrings.Artist; - TooltipText = BeatmapsetsStrings.ShowDetailsByArtist(artist); - value = artist; - break; + case BeatmapOnlineStatus.Ranked: + return BeatmapsetsStrings.ShowStatusRanked; - case BeatmapInfo.Difficulty: - string diff = beatmap.Value.BeatmapInfo.DifficultyName; - labelText = TooltipText = EditorSetupStrings.DifficultyHeader; - text.Current.Value = diff; - break; + case BeatmapOnlineStatus.LocallyModified: + return SongSelectStrings.LocallyModified; - case BeatmapInfo.Mapper: - string mapper = beatmap.Value.BeatmapInfo.Metadata.Author.Username; - //todo: is there a good alternative, to NotificationsOptionsMapping? - labelText = AccountsStrings.NotificationsOptionsMapping; - TooltipText = BeatmapsetsStrings.ShowDetailsMappedBy(mapper); - value = mapper; - break; + case BeatmapOnlineStatus.WIP: + return BeatmapsetsStrings.ShowStatusWip; - case BeatmapInfo.Length: - labelText = TooltipText = ArtistStrings.TracklistLength; - value = TimeSpan.FromMilliseconds(beatmap.Value.BeatmapInfo.Length).ToFormattedDuration(); - break; - - case BeatmapInfo.Status: - BeatmapOnlineStatus status = beatmap.Value.BeatmapInfo.Status; - TooltipText = labelText = BeatmapDiscussionsStrings.IndexFormBeatmapsetStatusDefault; - - switch (status) - { - case BeatmapOnlineStatus.Approved: - value = BeatmapsetsStrings.ShowStatusApproved; - break; - - case BeatmapOnlineStatus.Graveyard: - value = BeatmapsetsStrings.ShowStatusGraveyard; - break; - - case BeatmapOnlineStatus.Loved: - value = BeatmapsetsStrings.ShowStatusLoved; - break; - - case BeatmapOnlineStatus.None: - value = "None"; - break; - - case BeatmapOnlineStatus.Pending: - value = BeatmapsetsStrings.ShowStatusPending; - break; - - case BeatmapOnlineStatus.Qualified: - value = BeatmapsetsStrings.ShowStatusQualified; - break; - - case BeatmapOnlineStatus.Ranked: - value = BeatmapsetsStrings.ShowStatusRanked; - break; - - case BeatmapOnlineStatus.LocallyModified: - value = SongSelectStrings.LocallyModified; - break; - - case BeatmapOnlineStatus.WIP: - value = BeatmapsetsStrings.ShowStatusWip; - break; - } - - break; - - case BeatmapInfo.BPM: - labelText = TooltipText = BeatmapsetsStrings.ShowStatsBpm; - value = beatmap.Value.BeatmapInfo.BPM.ToString("F2"); - break; + default: + return @"null"; } - - updateLabel(); } } @@ -261,5 +284,6 @@ namespace osu.Game.Skinning.Components Length, Status, BPM, + Custom, } } From 37b5f4891149fa3b6eefadd02e963d4ac3f9f890 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Nov 2022 03:20:24 +0300 Subject: [PATCH 0404/2991] Adjust test scene to cover failure --- .../Visual/Online/TestSceneBeatmapListingOverlay.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs index 2c9b34e4a7..1e0a09d37a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs @@ -198,13 +198,13 @@ namespace osu.Game.Tests.Visual.Online beatmapSet = CreateAPIBeatmapSet(Ruleset.Value); beatmapSet.Title = "last beatmap of first page"; - fetchFor(getManyBeatmaps(49).Append(beatmapSet).ToArray(), true); + fetchFor(getManyBeatmaps(49).Append(new APIBeatmapSet { Title = "last beatmap of first page", OnlineID = beatmapSet.OnlineID }).ToArray(), true); }); AddUntilStep("wait for loaded", () => this.ChildrenOfType().Count() == 50); - AddStep("set next page", () => setSearchResponse(getManyBeatmaps(49).Prepend(beatmapSet).ToArray(), false)); + AddStep("set next page", () => setSearchResponse(getManyBeatmaps(49).Prepend(new APIBeatmapSet { Title = "this shouldn't show up", OnlineID = beatmapSet.OnlineID }).ToArray(), false)); AddStep("scroll to end", () => overlay.ChildrenOfType().Single().ScrollToEnd()); - AddUntilStep("wait for loaded", () => this.ChildrenOfType().Count() == 99); + AddUntilStep("wait for loaded", () => this.ChildrenOfType().Count() >= 99); AddAssert("beatmap not duplicated", () => overlay.ChildrenOfType().Count(c => c.BeatmapSet.Equals(beatmapSet)) == 1); } From ac8fb4f9b2b6ef1411b9aff9ede25607e898d3a8 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Nov 2022 03:20:14 +0300 Subject: [PATCH 0405/2991] Fix beatmap cards still potentially showing twice in listing --- osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index 238f41e53d..717a1de6b5 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -149,5 +149,8 @@ namespace osu.Game.Online.API.Requests.Responses #endregion public bool Equals(IBeatmapSetInfo? other) => other is APIBeatmapSet b && this.MatchesOnlineID(b); + + // ReSharper disable once NonReadonlyMemberInGetHashCode + public override int GetHashCode() => OnlineID.GetHashCode(); } } From e11d44d14f9f575ae591bc89eeee1414107528fd Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Wed, 2 Nov 2022 22:30:30 -0700 Subject: [PATCH 0406/2991] Add url clicking support to profile badges --- .../Online/TestSceneUserProfileOverlay.cs | 11 +++++++++-- .../Header/Components/DrawableBadge.cs | 19 ++++++++++--------- osu.Game/Users/Badge.cs | 3 +++ 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs index caa2d2571d..7064a08151 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs @@ -52,8 +52,15 @@ namespace osu.Game.Tests.Visual.Online { AwardedAt = DateTimeOffset.FromUnixTimeSeconds(1505741569), Description = "Outstanding help by being a voluntary test subject.", - ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg" - } + ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg", + Url = "https://osu.ppy.sh/wiki/en/People/Community_Contributors", + }, + new Badge + { + AwardedAt = DateTimeOffset.FromUnixTimeSeconds(1505741569), + Description = "Badge without a url.", + ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg", + }, }, Title = "osu!volunteer", Colour = "ff0000", diff --git a/osu.Game/Overlays/Profile/Header/Components/DrawableBadge.cs b/osu.Game/Overlays/Profile/Header/Components/DrawableBadge.cs index cf75818a0c..2ee80a7494 100644 --- a/osu.Game/Overlays/Profile/Header/Components/DrawableBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/DrawableBadge.cs @@ -1,22 +1,20 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.Localisation; +using osu.Game.Graphics.Containers; +using osu.Game.Online; using osu.Game.Users; using osuTK; namespace osu.Game.Overlays.Profile.Header.Components { [LongRunningLoad] - public class DrawableBadge : CompositeDrawable, IHasTooltip + public class DrawableBadge : OsuClickableContainer { public static readonly Vector2 DRAWABLE_BADGE_SIZE = new Vector2(86, 40); @@ -29,22 +27,25 @@ namespace osu.Game.Overlays.Profile.Header.Components } [BackgroundDependencyLoader] - private void load(LargeTextureStore textures) + private void load(LargeTextureStore textures, ILinkHandler? linkHandler) { - InternalChild = new Sprite + Child = new Sprite { FillMode = FillMode.Fit, RelativeSizeAxes = Axes.Both, Texture = textures.Get(badge.ImageUrl), }; + + if (!string.IsNullOrEmpty(badge.Url)) + Action = () => linkHandler?.HandleLink(badge.Url); } protected override void LoadComplete() { base.LoadComplete(); - InternalChild.FadeInFromZero(200); + this.FadeInFromZero(200); } - public LocalisableString TooltipText => badge.Description; + public override LocalisableString TooltipText => badge.Description; } } diff --git a/osu.Game/Users/Badge.cs b/osu.Game/Users/Badge.cs index c191c25895..b87e2ddecd 100644 --- a/osu.Game/Users/Badge.cs +++ b/osu.Game/Users/Badge.cs @@ -18,5 +18,8 @@ namespace osu.Game.Users [JsonProperty("image_url")] public string ImageUrl; + + [JsonProperty("url")] + public string Url; } } From c40c70509e1909fab2488120c9e867cb76f66827 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 15:14:09 +0900 Subject: [PATCH 0407/2991] Improve song select transition to gameplay --- osu.Game/Screens/Select/BeatmapCarousel.cs | 20 +++++++++++++++++ osu.Game/Screens/Select/SongSelect.cs | 26 +++++++++++++++++----- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 3b694dbf43..2f99f6acca 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -770,6 +770,26 @@ namespace osu.Game.Screens.Select { updateItem(item); + if (!item.Item.Filtered.Value) + { + bool isSelected = item.Item.State.Value == CarouselItemState.Selected; + + // Cheap way of doing animations when entering / exiting song select. + const double half_time = 50; + const float panel_x_offset_when_inactive = 200; + + if (isSelected || AllowSelection) + { + item.Alpha = (float)Interpolation.DampContinuously(item.Alpha, 1, half_time, Clock.ElapsedFrameTime); + item.X = (float)Interpolation.DampContinuously(item.X, 0, half_time, Clock.ElapsedFrameTime); + } + else + { + item.Alpha = (float)Interpolation.DampContinuously(item.Alpha, 0, half_time, Clock.ElapsedFrameTime); + item.X = (float)Interpolation.DampContinuously(item.X, panel_x_offset_when_inactive, half_time, Clock.ElapsedFrameTime); + } + } + if (item is DrawableCarouselBeatmapSet set) { foreach (var diff in set.DrawableBeatmaps) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index f5a058e945..fe9b67a02e 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -89,6 +89,8 @@ namespace osu.Game.Screens.Select protected BeatmapCarousel Carousel { get; private set; } + private ParallaxContainer wedgeBackground; + protected Container LeftArea { get; private set; } private BeatmapInfoWedge beatmapInfoWedge; @@ -165,10 +167,12 @@ namespace osu.Game.Screens.Select { new Drawable[] { - new ParallaxContainer + wedgeBackground = new ParallaxContainer { ParallaxAmount = 0.005f, RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, Child = new WedgeBackground { RelativeSizeAxes = Axes.Both, @@ -609,9 +613,15 @@ namespace osu.Game.Screens.Select } } - this.FadeIn(250); + LeftArea.MoveToX(0, 400, Easing.OutQuint); + LeftArea.FadeIn(100, Easing.OutQuint); - this.ScaleTo(1, 250, Easing.OutSine); + FilterControl.MoveToY(0, 400, Easing.OutQuint); + FilterControl.FadeIn(100, Easing.OutQuint); + + this.FadeIn(250, Easing.OutQuint); + + wedgeBackground.ScaleTo(1, 500, Easing.OutQuint); FilterControl.Activate(); } @@ -629,9 +639,15 @@ namespace osu.Game.Screens.Select endLooping(); - this.ScaleTo(1.1f, 250, Easing.InSine); + FilterControl.MoveToY(-120, 250, Easing.OutQuint); + FilterControl.FadeOut(100); - this.FadeOut(250); + LeftArea.MoveToX(-150, 1800, Easing.OutQuint); + LeftArea.FadeOut(200, Easing.OutQuint); + + wedgeBackground.ScaleTo(2.4f, 400, Easing.OutQuint); + + this.FadeOut(400, Easing.OutQuint); FilterControl.Deactivate(); base.OnSuspending(e); From 819027d61c812ad29c7dc05b9d2175e964e2bc02 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 4 Nov 2022 16:17:49 +0900 Subject: [PATCH 0408/2991] Rename to `isConvert` --- .../Difficulty/TaikoPerformanceCalculator.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index 317e4a2f72..2d1b2903c9 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty effectiveMissCount = Math.Max(1.0, 1000.0 / totalSuccessfulHits) * countMiss; // TODO: The detection of rulesets is temporary until the leftover old skills have been reworked. - bool taikoSpecificBeatmap = score.BeatmapInfo.Ruleset.OnlineID == 1; + bool isConvert = score.BeatmapInfo.Ruleset.OnlineID != 1; double multiplier = 1.13; @@ -54,8 +54,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModEasy)) multiplier *= 0.975; - double difficultyValue = computeDifficultyValue(score, taikoAttributes, taikoSpecificBeatmap); - double accuracyValue = computeAccuracyValue(score, taikoAttributes, taikoSpecificBeatmap); + double difficultyValue = computeDifficultyValue(score, taikoAttributes, isConvert); + double accuracyValue = computeAccuracyValue(score, taikoAttributes, isConvert); double totalValue = Math.Pow( Math.Pow(difficultyValue, 1.1) + @@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty }; } - private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool taikoSpecificBeatmap) + private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool isConvert) { double difficultyValue = Math.Pow(5 * Math.Max(1.0, attributes.StarRating / 0.115) - 4.0, 2.25) / 1150.0; @@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty if (score.Mods.Any(m => m is ModEasy)) difficultyValue *= 0.985; - if (score.Mods.Any(m => m is ModHidden) && taikoSpecificBeatmap) + if (score.Mods.Any(m => m is ModHidden) && !isConvert) difficultyValue *= 1.025; if (score.Mods.Any(m => m is ModHardRock)) @@ -95,7 +95,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty return difficultyValue * Math.Pow(accuracy, 2.0); } - private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool taikoSpecificBeatmap) + private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool isConvert) { if (attributes.GreatHitWindow <= 0) return 0; @@ -106,7 +106,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty accuracyValue *= lengthBonus; // Slight HDFL Bonus for accuracy. A clamp is used to prevent against negative values. - if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && taikoSpecificBeatmap) + if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && !isConvert) accuracyValue *= Math.Max(1.0, 1.1 * lengthBonus); return accuracyValue; From dd5a3b2bf37ed0859e739849952d72490b9509dc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 16:49:21 +0900 Subject: [PATCH 0409/2991] Add one more complex test --- .../Visual/Gameplay/TestSceneBezierConverter.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs index 701f30bfd4..28a9d17882 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs @@ -134,6 +134,17 @@ namespace osu.Game.Tests.Visual.Gameplay }); } + [Test] + public void TestComplex() + { + AddStep("create path", () => + { + path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero, new Vector2(100, 0))); + path.ControlPoints.AddRange(createSegment(PathType.Bezier, new Vector2(100, 0), new Vector2(150, 30), new Vector2(100, 100))); + path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, new Vector2(100, 100), new Vector2(25, 50), Vector2.Zero)); + }); + } + [TestCase(0, 100)] [TestCase(1, 100)] [TestCase(5, 100)] From 923d44a769c3030e84f36227f33a2739d850dca6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 17:00:58 +0900 Subject: [PATCH 0410/2991] Update dependencies --- .../osu.Game.Rulesets.EmptyFreeform.Tests.csproj | 2 +- .../osu.Game.Rulesets.Pippidon.Tests.csproj | 2 +- .../osu.Game.Rulesets.EmptyScrolling.Tests.csproj | 2 +- .../osu.Game.Rulesets.Pippidon.Tests.csproj | 2 +- osu.Desktop/osu.Desktop.csproj | 2 +- osu.Game.Benchmarks/osu.Game.Benchmarks.csproj | 2 +- .../osu.Game.Rulesets.Catch.Tests.csproj | 2 +- .../osu.Game.Rulesets.Mania.Tests.csproj | 2 +- .../osu.Game.Rulesets.Osu.Tests.csproj | 2 +- .../osu.Game.Rulesets.Taiko.Tests.csproj | 2 +- osu.Game.Tests/osu.Game.Tests.csproj | 4 ++-- .../osu.Game.Tournament.Tests.csproj | 2 +- osu.Game/osu.Game.csproj | 12 ++++++------ 13 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj index 936808f38b..52b728a115 100644 --- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj +++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj index 35e7742172..95b96adab0 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj index c1044965b5..d12403016d 100644 --- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj +++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj index 35e7742172..95b96adab0 100644 --- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj +++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj @@ -11,7 +11,7 @@ - + diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index 3f926ed45a..1f4544098b 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -27,7 +27,7 @@ - + diff --git a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj index d62d422f33..f47b069373 100644 --- a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj +++ b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj @@ -9,7 +9,7 @@ - + diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj index c9db824615..5a2e8e0bf0 100644 --- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj +++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj @@ -3,7 +3,7 @@ - + WinExe diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj index 0d7b03d830..be51dc0e4c 100644 --- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj +++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj @@ -3,7 +3,7 @@ - + WinExe diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj index 1eb1c85d93..c10c3ffb15 100644 --- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj +++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj @@ -4,7 +4,7 @@ - + WinExe diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj index 38e61f5624..6af1beff69 100644 --- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj +++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj @@ -3,7 +3,7 @@ - + WinExe diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index bdf8cc5136..24969414d0 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -1,11 +1,11 @@  - + - + diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj index bdef46a6b2..9f2a088a4b 100644 --- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj +++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj @@ -6,7 +6,7 @@ - + WinExe diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index fe44ed3688..9a6866d264 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -23,10 +23,10 @@ - - - - + + + + @@ -34,10 +34,10 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + From 2b934e0beafbffda932574cf3fb17db4bb66e0b6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 17:19:03 +0900 Subject: [PATCH 0411/2991] Increase delay for changing background on returning to main menu --- osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs index f8546d6ed0..a7a763f2a6 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs @@ -95,7 +95,7 @@ namespace osu.Game.Screens.Backgrounds nextTask = Scheduler.AddDelayed(() => { LoadComponentAsync(nextBackground, displayNext, cancellationTokenSource.Token); - }, 100); + }, 500); return true; } From 4bbff99f315b23b34d88be8f90962e0f3053fafb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 17:35:30 +0900 Subject: [PATCH 0412/2991] Remove unnecessary fade in `SeasonalBackground` --- osu.Game/Graphics/Backgrounds/SeasonalBackgroundLoader.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Graphics/Backgrounds/SeasonalBackgroundLoader.cs b/osu.Game/Graphics/Backgrounds/SeasonalBackgroundLoader.cs index 5c98e22818..9d873762bf 100644 --- a/osu.Game/Graphics/Backgrounds/SeasonalBackgroundLoader.cs +++ b/osu.Game/Graphics/Backgrounds/SeasonalBackgroundLoader.cs @@ -111,8 +111,6 @@ namespace osu.Game.Graphics.Backgrounds private void load(LargeTextureStore textures) { Sprite.Texture = textures.Get(url) ?? textures.Get(fallback_texture_name); - // ensure we're not loading in without a transition. - this.FadeInFromZero(200, Easing.InOutSine); } public override bool Equals(Background other) From 4f14ae4e34ad3f70d0c26dedc7448006025279ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 17:36:11 +0900 Subject: [PATCH 0413/2991] Adjust transition effect for main menu backgrounds --- osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs index a7a763f2a6..44b6fcce4a 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs @@ -102,7 +102,7 @@ namespace osu.Game.Screens.Backgrounds private void displayNext(Background newBackground) { - background?.FadeOut(800, Easing.InOutSine); + background?.FadeOut(800, Easing.OutQuint); background?.Expire(); AddInternal(background = newBackground); From 58396d49dc9e44a7a3dcec75a969851fd7856451 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 4 Nov 2022 16:42:59 +0900 Subject: [PATCH 0414/2991] Fix handling of local echo deduplication --- .../CreateNewPrivateMessageRequest.cs | 1 + .../Online/API/Requests/PostMessageRequest.cs | 1 + osu.Game/Online/Chat/Channel.cs | 8 ++++ osu.Game/Online/Chat/ChannelManager.cs | 48 ++++++++++++------- osu.Game/Online/Chat/Message.cs | 6 +++ .../WebSocket/WebSocketNotificationsClient.cs | 10 ++-- 6 files changed, 51 insertions(+), 23 deletions(-) diff --git a/osu.Game/Online/API/Requests/CreateNewPrivateMessageRequest.cs b/osu.Game/Online/API/Requests/CreateNewPrivateMessageRequest.cs index dea94bfce2..6b7192dbf4 100644 --- a/osu.Game/Online/API/Requests/CreateNewPrivateMessageRequest.cs +++ b/osu.Game/Online/API/Requests/CreateNewPrivateMessageRequest.cs @@ -28,6 +28,7 @@ namespace osu.Game.Online.API.Requests req.AddParameter(@"target_id", user.Id.ToString()); req.AddParameter(@"message", message.Content); req.AddParameter(@"is_action", message.IsAction.ToString().ToLowerInvariant()); + req.AddParameter(@"uuid", message.Uuid); return req; } diff --git a/osu.Game/Online/API/Requests/PostMessageRequest.cs b/osu.Game/Online/API/Requests/PostMessageRequest.cs index 7b20bd9ad5..e3709d8f13 100644 --- a/osu.Game/Online/API/Requests/PostMessageRequest.cs +++ b/osu.Game/Online/API/Requests/PostMessageRequest.cs @@ -25,6 +25,7 @@ namespace osu.Game.Online.API.Requests req.Method = HttpMethod.Post; req.AddParameter(@"is_action", Message.IsAction.ToString().ToLowerInvariant()); req.AddParameter(@"message", Message.Content); + req.AddParameter(@"uuid", Message.Uuid); return req; } diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index f51ea3e8d6..9bfaecc46b 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -134,6 +134,14 @@ namespace osu.Game.Online.Chat /// public void AddNewMessages(params Message[] messages) { + foreach (var m in messages) + { + LocalEchoMessage localEcho = pendingMessages.FirstOrDefault(local => local.Uuid == m.Uuid); + + if (localEcho != null) + ReplaceMessage(localEcho, m); + } + messages = messages.Except(Messages).ToArray(); if (messages.Length == 0) return; diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index a901c15bf4..05e2fb79e8 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -85,8 +85,21 @@ namespace osu.Game.Online.Chat [BackgroundDependencyLoader] private void load() { - connector.ChannelJoined += ch => Schedule(() => joinChannel(ch)); + connector.ChannelJoined += ch => Schedule(() => + { + var localChannel = getChannel(ch); + + if (localChannel != ch) + { + localChannel.Joined.Value = true; + localChannel.Id = ch.Id; + } + + joinChannel(localChannel); + }); + connector.NewMessages += msgs => Schedule(() => addMessages(msgs)); + connector.PresenceReceived += () => Schedule(() => { if (!channelsInitialised) @@ -189,7 +202,8 @@ namespace osu.Game.Online.Chat Timestamp = DateTimeOffset.Now, ChannelId = target.Id, IsAction = isAction, - Content = text + Content = text, + Uuid = Guid.NewGuid().ToString() }; target.AddLocalEcho(message); @@ -199,13 +213,7 @@ namespace osu.Game.Online.Chat { var createNewPrivateMessageRequest = new CreateNewPrivateMessageRequest(target.Users.First(), message); - createNewPrivateMessageRequest.Success += createRes => - { - target.Id = createRes.ChannelID; - target.ReplaceMessage(message, createRes.Message); - dequeueAndRun(); - }; - + createNewPrivateMessageRequest.Success += _ => dequeueAndRun(); createNewPrivateMessageRequest.Failure += exception => { handlePostException(exception); @@ -219,12 +227,7 @@ namespace osu.Game.Online.Chat var req = new PostMessageRequest(message); - req.Success += m => - { - target.ReplaceMessage(message, m); - dequeueAndRun(); - }; - + req.Success += m => dequeueAndRun(); req.Failure += exception => { handlePostException(exception); @@ -403,7 +406,20 @@ namespace osu.Game.Online.Chat { Channel found = null; - bool lookupCondition(Channel ch) => lookup.Id > 0 ? ch.Id == lookup.Id : lookup.Name == ch.Name; + bool lookupCondition(Channel ch) + { + // If both channels have an id, use that. + if (lookup.Id > 0 && ch.Id > 0) + return ch.Id == lookup.Id; + + // In the case that the local echo is received in a new channel (i.e. one that does not yet have an ID), + // then we need to check for any existing channel with the message containing the same message matched by UUID. + if (lookup.Messages.Count > 0 && ch.Messages.Any(m => m.Uuid == lookup.Messages.Last().Uuid)) + return true; + + // As a last resort, fallback to matching by name. + return lookup.Name == ch.Name; + } var available = AvailableChannels.FirstOrDefault(lookupCondition); if (available != null) diff --git a/osu.Game/Online/Chat/Message.cs b/osu.Game/Online/Chat/Message.cs index 25c5b0853f..9f6f9c8d6b 100644 --- a/osu.Game/Online/Chat/Message.cs +++ b/osu.Game/Online/Chat/Message.cs @@ -37,6 +37,12 @@ namespace osu.Game.Online.Chat set => Sender = new APIUser { Id = value }; } + /// + /// A unique identifier for this message. Sent to and from osu!web to use for deduplication. + /// + [JsonProperty(@"uuid")] + public string Uuid { get; set; } = string.Empty; + [JsonConstructor] public Message() { diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index ff0941ecba..0a93081915 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -2,9 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using System.Net.WebSockets; using System.Text; using System.Threading; @@ -126,12 +124,10 @@ namespace osu.Game.Online.Notifications.WebSocket NewChatMessageData? messageData = JsonConvert.DeserializeObject(message.Data.ToString()); Debug.Assert(messageData != null); - List messages = messageData.Messages.Where(m => m.Sender.OnlineID != api.LocalUser.Value.OnlineID).ToList(); + foreach (var msg in messageData.Messages) + HandleJoinedChannel(new Channel(msg.Sender) { Id = msg.ChannelId, Messages = { msg } }); - foreach (var msg in messages) - HandleJoinedChannel(new Channel(msg.Sender) { Id = msg.ChannelId }); - - HandleMessages(messages); + HandleMessages(messageData.Messages); break; } From 72745656e71ef3def43ca65b709a6c2f4000b1ca Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 4 Nov 2022 18:48:34 +0900 Subject: [PATCH 0415/2991] Remove StartChat()/chat enablement --- osu.Game/Online/Chat/ChannelManager.cs | 2 -- .../Notifications/NotificationsClient.cs | 24 +------------------ .../NotificationsClientConnector.cs | 11 --------- .../WebSocket/WebSocketNotificationsClient.cs | 13 ++++------ 4 files changed, 5 insertions(+), 45 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 05e2fb79e8..77d53911d9 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -110,8 +110,6 @@ namespace osu.Game.Online.Chat } }); - connector.StartChat(); - apiState.BindTo(api.State); apiState.BindValueChanged(status => { diff --git a/osu.Game/Online/Notifications/NotificationsClient.cs b/osu.Game/Online/Notifications/NotificationsClient.cs index 5c575e828d..cb5e94fb1d 100644 --- a/osu.Game/Online/Notifications/NotificationsClient.cs +++ b/osu.Game/Online/Notifications/NotificationsClient.cs @@ -23,7 +23,6 @@ namespace osu.Game.Online.Notifications protected readonly IAPIProvider API; - private bool enableChat; private long lastMessageId; protected NotificationsClient(IAPIProvider api) @@ -31,28 +30,7 @@ namespace osu.Game.Online.Notifications API = api; } - public bool EnableChat - { - get => enableChat; - set - { - if (enableChat == value) - return; - - enableChat = value; - - if (EnableChat) - Task.Run(StartChatAsync); - } - } - - public override async Task ConnectAsync(CancellationToken cancellationToken) - { - if (EnableChat) - await StartChatAsync(); - } - - protected virtual Task StartChatAsync() + public override Task ConnectAsync(CancellationToken cancellationToken) { API.Queue(CreateFetchMessagesRequest(0)); return Task.CompletedTask; diff --git a/osu.Game/Online/Notifications/NotificationsClientConnector.cs b/osu.Game/Online/Notifications/NotificationsClientConnector.cs index 5aa49a7783..d4c846a7a2 100644 --- a/osu.Game/Online/Notifications/NotificationsClientConnector.cs +++ b/osu.Game/Online/Notifications/NotificationsClientConnector.cs @@ -19,21 +19,11 @@ namespace osu.Game.Online.Notifications public event Action>? NewMessages; public event Action? PresenceReceived; - private bool chatStarted; - protected NotificationsClientConnector(IAPIProvider api) : base(api) { } - public void StartChat() - { - chatStarted = true; - - if (CurrentConnection is NotificationsClient client) - client.EnableChat = true; - } - protected sealed override async Task BuildConnectionAsync(CancellationToken cancellationToken) { var client = await BuildNotificationClientAsync(cancellationToken); @@ -41,7 +31,6 @@ namespace osu.Game.Online.Notifications client.ChannelJoined = c => ChannelJoined?.Invoke(c); client.NewMessages = m => NewMessages?.Invoke(m); client.PresenceReceived = () => PresenceReceived?.Invoke(); - client.EnableChat = chatStarted; return client; } diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index 0a93081915..bc4ceea993 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -22,27 +22,22 @@ namespace osu.Game.Online.Notifications.WebSocket { private readonly ClientWebSocket socket; private readonly string endpoint; - private readonly IAPIProvider api; public WebSocketNotificationsClient(ClientWebSocket socket, string endpoint, IAPIProvider api) : base(api) { this.socket = socket; this.endpoint = endpoint; - this.api = api; } public override async Task ConnectAsync(CancellationToken cancellationToken) { await socket.ConnectAsync(new Uri(endpoint), cancellationToken).ConfigureAwait(false); - runReadLoop(cancellationToken); - await base.ConnectAsync(cancellationToken); - } - - protected override async Task StartChatAsync() - { await sendMessage(new StartChatRequest(), CancellationToken.None); - await base.StartChatAsync(); + + runReadLoop(cancellationToken); + + await base.ConnectAsync(cancellationToken); } private void runReadLoop(CancellationToken cancellationToken) => Task.Run(async () => From eb836269e765549f5c76e6c0ca733442842c5c25 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 18:50:17 +0900 Subject: [PATCH 0416/2991] Allow testing settings panel with interactivity by default --- .../Visual/Settings/TestSceneSettingsPanel.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs index 9791bb6248..ad60c98e05 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs @@ -35,13 +35,19 @@ namespace osu.Game.Tests.Visual.Settings State = { Value = Visibility.Visible } }); }); + } - AddStep("reset mouse", () => InputManager.MoveMouseTo(settings)); + [Test] + public void TestBasic() + { + AddStep("do nothing", () => { }); } [Test] public void TestFiltering([Values] bool beforeLoad) { + AddStep("reset mouse", () => InputManager.MoveMouseTo(settings)); + if (beforeLoad) AddStep("set filter", () => settings.SectionsContainer.ChildrenOfType().First().Current.Value = "scaling"); @@ -67,6 +73,8 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestFilterAfterLoad() { + AddStep("reset mouse", () => InputManager.MoveMouseTo(settings)); + AddUntilStep("wait for items to load", () => settings.SectionsContainer.ChildrenOfType().Any()); AddStep("set filter", () => settings.SectionsContainer.ChildrenOfType().First().Current.Value = "scaling"); @@ -75,6 +83,8 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void ToggleVisibility() { + AddStep("reset mouse", () => InputManager.MoveMouseTo(settings)); + AddWaitStep("wait some", 5); AddToggleStep("toggle visibility", _ => settings.ToggleVisibility()); } @@ -82,6 +92,8 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestTextboxFocusAfterNestedPanelBackButton() { + AddStep("reset mouse", () => InputManager.MoveMouseTo(settings)); + AddUntilStep("sections loaded", () => settings.SectionsContainer.Children.Count > 0); AddUntilStep("top-level textbox focused", () => settings.SectionsContainer.ChildrenOfType().FirstOrDefault()?.HasFocus == true); @@ -107,6 +119,8 @@ namespace osu.Game.Tests.Visual.Settings [Test] public void TestTextboxFocusAfterNestedPanelEscape() { + AddStep("reset mouse", () => InputManager.MoveMouseTo(settings)); + AddUntilStep("sections loaded", () => settings.SectionsContainer.Children.Count > 0); AddUntilStep("top-level textbox focused", () => settings.SectionsContainer.ChildrenOfType().FirstOrDefault()?.HasFocus == true); From fa18b5f7014671f13c0f4930b3ae740755952f07 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 4 Nov 2022 18:51:00 +0900 Subject: [PATCH 0417/2991] Construct notifications client inside ChannelManager --- osu.Game.Tests/Chat/TestSceneChannelManager.cs | 2 +- osu.Game.Tests/Visual/Online/TestSceneChatLink.cs | 2 +- osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs | 2 +- osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs | 2 +- .../Visual/Online/TestSceneStandAloneChatDisplay.cs | 2 +- .../Components/TournamentMatchChatDisplay.cs | 2 +- osu.Game/Online/Chat/ChannelManager.cs | 5 +++-- osu.Game/OsuGame.cs | 6 +----- 8 files changed, 10 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Chat/TestSceneChannelManager.cs b/osu.Game.Tests/Chat/TestSceneChannelManager.cs index 86be638781..e7eb06c795 100644 --- a/osu.Game.Tests/Chat/TestSceneChannelManager.cs +++ b/osu.Game.Tests/Chat/TestSceneChannelManager.cs @@ -151,7 +151,7 @@ namespace osu.Game.Tests.Chat public ChannelManagerContainer(IAPIProvider apiProvider) { - InternalChild = ChannelManager = new ChannelManager(apiProvider, apiProvider.GetNotificationsConnector()); + InternalChild = ChannelManager = new ChannelManager(apiProvider); } } } diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs index 5c46cd96be..de44986001 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs @@ -41,7 +41,7 @@ namespace osu.Game.Tests.Visual.Online { linkColour = colours.Blue; - var chatManager = new ChannelManager(API, API.GetNotificationsConnector()); + var chatManager = new ChannelManager(API); BindableList availableChannels = (BindableList)chatManager.AvailableChannels; availableChannels.Add(new Channel { Name = "#english" }); availableChannels.Add(new Channel { Name = "#japanese" }); diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 6b2124f1f8..0b982a5745 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -59,7 +59,7 @@ namespace osu.Game.Tests.Visual.Online RelativeSizeAxes = Axes.Both, CachedDependencies = new (Type, object)[] { - (typeof(ChannelManager), channelManager = new ChannelManager(API, API.GetNotificationsConnector())), + (typeof(ChannelManager), channelManager = new ChannelManager(API)), }, Children = new Drawable[] { diff --git a/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs b/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs index cb93812bc2..57514cdf37 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs @@ -250,7 +250,7 @@ namespace osu.Game.Tests.Visual.Online public TestContainer(IAPIProvider api, Channel[] channels) { this.channels = channels; - ChannelManager = new ChannelManager(api, api.GetNotificationsConnector()); + ChannelManager = new ChannelManager(api); } [BackgroundDependencyLoader] diff --git a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs index 07196cc92a..34ecad7dc1 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs @@ -58,7 +58,7 @@ namespace osu.Game.Tests.Visual.Online { var api = parent.Get(); - Add(channelManager = new ChannelManager(api, api.GetNotificationsConnector())); + Add(channelManager = new ChannelManager(api)); var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); diff --git a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs index 48ff45974d..ca2b400e8b 100644 --- a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs +++ b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs @@ -48,7 +48,7 @@ namespace osu.Game.Tournament.Components if (manager == null) { - AddInternal(manager = new ChannelManager(api, api.GetNotificationsConnector())); + AddInternal(manager = new ChannelManager(api)); Channel.BindTo(manager.CurrentChannel); } diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 77d53911d9..a9603506c6 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -74,10 +74,11 @@ namespace osu.Game.Online.Chat private bool channelsInitialised; private ScheduledDelegate ackDelegate; - public ChannelManager(IAPIProvider api, NotificationsClientConnector connector) + public ChannelManager(IAPIProvider api) { this.api = api; - this.connector = connector; + + connector = api.GetNotificationsConnector(); CurrentChannel.ValueChanged += currentChannelChanged; } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index f36d83d5c2..3a8f202d97 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -44,7 +44,6 @@ using osu.Game.Localisation; using osu.Game.Online; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; -using osu.Game.Online.Notifications; using osu.Game.Overlays; using osu.Game.Overlays.Music; using osu.Game.Overlays.Notifications; @@ -84,7 +83,6 @@ namespace osu.Game private ChatOverlay chatOverlay; private ChannelManager channelManager; - private NotificationsClientConnector notificationsClient; [NotNull] protected readonly NotificationOverlay Notifications = new NotificationOverlay(); @@ -680,7 +678,6 @@ namespace osu.Game { base.Dispose(isDisposing); SentryLogger.Dispose(); - notificationsClient.Dispose(); } protected override IDictionary GetFrameworkConfigDefaults() @@ -758,7 +755,6 @@ namespace osu.Game BackButton.Receptor receptor; dependencies.CacheAs(idleTracker = new GameIdleTracker(6000)); - dependencies.CacheAs(notificationsClient = API.GetNotificationsConnector()); var sessionIdleTracker = new GameIdleTracker(300000); sessionIdleTracker.IsIdle.BindValueChanged(idle => @@ -885,7 +881,7 @@ namespace osu.Game loadComponentSingleFile(dashboard = new DashboardOverlay(), overlayContent.Add, true); loadComponentSingleFile(news = new NewsOverlay(), overlayContent.Add, true); var rankingsOverlay = loadComponentSingleFile(new RankingsOverlay(), overlayContent.Add, true); - loadComponentSingleFile(channelManager = new ChannelManager(API, notificationsClient), AddInternal, true); + loadComponentSingleFile(channelManager = new ChannelManager(API), AddInternal, true); loadComponentSingleFile(chatOverlay = new ChatOverlay(), overlayContent.Add, true); loadComponentSingleFile(new MessageNotifier(), AddInternal, true); loadComponentSingleFile(Settings = new SettingsOverlay(), leftFloatingOverlayContent.Add, true); From 8b58475ee04dcbd1ffd59b11736a7c79197df2be Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 18:50:42 +0900 Subject: [PATCH 0418/2991] Update `OsuButton` hover animation to better suit immediacy of sound effects --- osu.Game/Graphics/UserInterface/OsuButton.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index 88f3ccd191..9140815f32 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -4,7 +4,6 @@ #nullable disable using osu.Framework.Allocation; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -95,7 +94,7 @@ namespace osu.Game.Graphics.UserInterface Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - Colour = Color4.White.Opacity(.1f), + Colour = Color4.White, Blending = BlendingParameters.Additive, Depth = float.MinValue }, @@ -126,7 +125,7 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnClick(ClickEvent e) { if (Enabled.Value) - Background.FlashColour(BackgroundColour.Lighten(0.4f), 200); + Background.FlashColour(Color4.White, 800, Easing.OutQuint); return base.OnClick(e); } @@ -134,7 +133,11 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnHover(HoverEvent e) { if (Enabled.Value) - Hover.FadeIn(200, Easing.OutQuint); + { + Hover.FadeTo(0.2f, 40, Easing.OutQuint) + .Then() + .FadeTo(0.1f, 800, Easing.OutQuint); + } return base.OnHover(e); } @@ -143,7 +146,7 @@ namespace osu.Game.Graphics.UserInterface { base.OnHoverLost(e); - Hover.FadeOut(300); + Hover.FadeOut(800, Easing.OutQuint); } protected override bool OnMouseDown(MouseDownEvent e) From 66bbe3411628b0b9664e66ec66f15d241843b1bc Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 4 Nov 2022 18:52:57 +0900 Subject: [PATCH 0419/2991] Move polling clients to osu.Game.Tests namespace --- osu.Game/Online/API/DummyAPIAccess.cs | 2 +- .../Polling => Tests}/PollingNotificationsClient.cs | 3 ++- .../Polling => Tests}/PollingNotificationsClientConnector.cs | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) rename osu.Game/{Online/Notifications/Polling => Tests}/PollingNotificationsClient.cs (94%) rename osu.Game/{Online/Notifications/Polling => Tests}/PollingNotificationsClientConnector.cs (92%) diff --git a/osu.Game/Online/API/DummyAPIAccess.cs b/osu.Game/Online/API/DummyAPIAccess.cs index 865e1e0a70..609efd8ab6 100644 --- a/osu.Game/Online/API/DummyAPIAccess.cs +++ b/osu.Game/Online/API/DummyAPIAccess.cs @@ -10,7 +10,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Notifications; -using osu.Game.Online.Notifications.Polling; +using osu.Game.Tests; using osu.Game.Users; namespace osu.Game.Online.API diff --git a/osu.Game/Online/Notifications/Polling/PollingNotificationsClient.cs b/osu.Game/Tests/PollingNotificationsClient.cs similarity index 94% rename from osu.Game/Online/Notifications/Polling/PollingNotificationsClient.cs rename to osu.Game/Tests/PollingNotificationsClient.cs index 2f343abf86..c1f032a647 100644 --- a/osu.Game/Online/Notifications/Polling/PollingNotificationsClient.cs +++ b/osu.Game/Tests/PollingNotificationsClient.cs @@ -4,8 +4,9 @@ using System.Threading; using System.Threading.Tasks; using osu.Game.Online.API; +using osu.Game.Online.Notifications; -namespace osu.Game.Online.Notifications.Polling +namespace osu.Game.Tests { /// /// A notifications client which polls for new messages every second. diff --git a/osu.Game/Online/Notifications/Polling/PollingNotificationsClientConnector.cs b/osu.Game/Tests/PollingNotificationsClientConnector.cs similarity index 92% rename from osu.Game/Online/Notifications/Polling/PollingNotificationsClientConnector.cs rename to osu.Game/Tests/PollingNotificationsClientConnector.cs index ff3f30edcd..823fc9d157 100644 --- a/osu.Game/Online/Notifications/Polling/PollingNotificationsClientConnector.cs +++ b/osu.Game/Tests/PollingNotificationsClientConnector.cs @@ -4,8 +4,9 @@ using System.Threading; using System.Threading.Tasks; using osu.Game.Online.API; +using osu.Game.Online.Notifications; -namespace osu.Game.Online.Notifications.Polling +namespace osu.Game.Tests { /// /// A connector for s that poll for new messages. From 1d2818dc70dbafecb5a60db70c9229917bdcc487 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 4 Nov 2022 19:02:26 +0900 Subject: [PATCH 0420/2991] Reschedule ack request on completion --- osu.Game/Online/Chat/ChannelManager.cs | 32 ++++++++++++++++++-------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index a9603506c6..035957a7c4 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -72,7 +72,7 @@ namespace osu.Game.Online.Chat private readonly IBindable apiState = new Bindable(); private bool channelsInitialised; - private ScheduledDelegate ackDelegate; + private ScheduledDelegate scheduledAck; public ChannelManager(IAPIProvider api) { @@ -112,16 +112,28 @@ namespace osu.Game.Online.Chat }); apiState.BindTo(api.State); - apiState.BindValueChanged(status => - { - ackDelegate?.Cancel(); + apiState.BindValueChanged(_ => performChatAckRequest(), true); + } - if (status.NewValue == APIState.Online) - { - Scheduler.Add(ackDelegate = new ScheduledDelegate(() => api.Queue(new ChatAckRequest()), 0, 60000)); - // Todo: Handle silences. - } - }, true); + private void performChatAckRequest() + { + if (apiState.Value != APIState.Online) + return; + + scheduledAck?.Cancel(); + + var req = new ChatAckRequest(); + req.Success += _ => scheduleNextRequest(); + req.Failure += _ => scheduleNextRequest(); + api.Queue(req); + + // Todo: Handle silences. + + void scheduleNextRequest() + { + scheduledAck?.Cancel(); + scheduledAck = Scheduler.AddDelayed(performChatAckRequest, 60000); + } } /// From a16540dc6d440f6a368b98ff6b474881eb77e5a6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 18:50:52 +0900 Subject: [PATCH 0421/2991] Update `Nub` hover animation to better suit immediacy of sound effects --- osu.Game/Graphics/UserInterface/Nub.cs | 34 ++++++++++++++++---------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/Nub.cs b/osu.Game/Graphics/UserInterface/Nub.cs index 7a3e54ddf1..80e012f596 100644 --- a/osu.Game/Graphics/UserInterface/Nub.cs +++ b/osu.Game/Graphics/UserInterface/Nub.cs @@ -27,9 +27,6 @@ namespace osu.Game.Graphics.UserInterface private const float border_width = 3; - private const double animate_in_duration = 200; - private const double animate_out_duration = 500; - private readonly Box fill; private readonly Container main; @@ -72,7 +69,7 @@ namespace osu.Game.Graphics.UserInterface Colour = GlowColour.Opacity(0), Type = EdgeEffectType.Glow, Radius = 8, - Roundness = 5, + Roundness = 4, }; } @@ -94,13 +91,18 @@ namespace osu.Game.Graphics.UserInterface if (value) { - main.FadeColour(GlowingAccentColour, animate_in_duration, Easing.OutQuint); - main.FadeEdgeEffectTo(0.2f, animate_in_duration, Easing.OutQuint); + main.FadeColour(GlowingAccentColour.Lighten(0.5f), 40, Easing.OutQuint) + .Then() + .FadeColour(GlowingAccentColour, 800, Easing.OutQuint); + + main.FadeEdgeEffectTo(Color4.White.Opacity(0.1f), 40, Easing.OutQuint) + .Then() + .FadeEdgeEffectTo(GlowColour.Opacity(0.1f), 800, Easing.OutQuint); } else { - main.FadeEdgeEffectTo(0, animate_out_duration, Easing.OutQuint); - main.FadeColour(AccentColour, animate_out_duration, Easing.OutQuint); + main.FadeEdgeEffectTo(GlowColour.Opacity(0), 800, Easing.OutQuint); + main.FadeColour(AccentColour, 800, Easing.OutQuint); } } } @@ -163,14 +165,20 @@ namespace osu.Game.Graphics.UserInterface private void onCurrentValueChanged(ValueChangedEvent filled) { - fill.FadeTo(filled.NewValue ? 1 : 0, 200, Easing.OutQuint); + const double duration = 200; + + fill.FadeTo(filled.NewValue ? 1 : 0, duration, Easing.OutQuint); if (filled.NewValue) - main.ResizeWidthTo(1, animate_in_duration, Easing.OutElasticHalf); + { + main.ResizeWidthTo(1, duration, Easing.OutElasticHalf); + main.TransformTo(nameof(BorderThickness), filled.NewValue ? 8.5f : border_width, duration, Easing.OutElasticHalf); + } else - main.ResizeWidthTo(0.9f, animate_out_duration, Easing.OutElastic); - - main.TransformTo(nameof(BorderThickness), filled.NewValue ? 8.5f : border_width, 200, Easing.OutQuint); + { + main.ResizeWidthTo(0.75f, duration, Easing.OutQuint); + main.TransformTo(nameof(BorderThickness), border_width, duration, Easing.OutQuint); + } } } } From a2fdad4afcf8c8ee2569929ab18fd54f8bac2616 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 18:52:32 +0900 Subject: [PATCH 0422/2991] Fix slider updating glow when disabled --- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index 392740690a..52b907707a 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -159,7 +159,8 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnHover(HoverEvent e) { - updateGlow(); + if (!Current.Disabled) + updateGlow(); return base.OnHover(e); } From 0e350f52f5f644402aa609df9ce20b1a693ca937 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 18:58:20 +0900 Subject: [PATCH 0423/2991] Fix `SliderBar` disabled value potentially not transferring to hover sounds --- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index 52b907707a..d7f308c45d 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -131,8 +131,6 @@ namespace osu.Game.Graphics.UserInterface }, hoverClickSounds = new HoverClickSounds() }; - - Current.DisabledChanged += disabled => { Alpha = disabled ? 0.3f : 1; }; } [BackgroundDependencyLoader(true)] @@ -154,7 +152,12 @@ namespace osu.Game.Graphics.UserInterface { base.LoadComplete(); CurrentNumber.BindValueChanged(current => TooltipText = getTooltipText(current.NewValue), true); - Current.DisabledChanged += disabled => hoverClickSounds.Enabled.Value = !disabled; + + Current.BindDisabledChanged(disabled => + { + Alpha = disabled ? 0.3f : 1; + hoverClickSounds.Enabled.Value = !disabled; + }, true); } protected override bool OnHover(HoverEvent e) From 78bb940e6ce5df325d399146915010439513f37f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 19:01:24 +0900 Subject: [PATCH 0424/2991] Don't play hover sounds on disabled elements --- osu.Game/Graphics/UserInterface/HoverClickSounds.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs index 89d1570cd4..99cec7411c 100644 --- a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs @@ -58,6 +58,14 @@ namespace osu.Game.Graphics.UserInterface return base.OnClick(e); } + public override void PlayHoverSample() + { + if (!Enabled.Value) + return; + + base.PlayHoverSample(); + } + [BackgroundDependencyLoader] private void load(AudioManager audio) { From f12ada9d9247db0fee8cad42d7418bef011db179 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 4 Nov 2022 19:36:24 +0900 Subject: [PATCH 0425/2991] Fix chat connecting too early --- osu.Game/Online/Chat/ChannelManager.cs | 2 ++ osu.Game/Online/HubClientConnector.cs | 3 +++ .../Online/PersistentEndpointClientConnector.cs | 13 ++++++++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 035957a7c4..db2436333b 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -111,6 +111,8 @@ namespace osu.Game.Online.Chat } }); + connector.Start(); + apiState.BindTo(api.State); apiState.BindValueChanged(_ => performChatAckRequest(), true); } diff --git a/osu.Game/Online/HubClientConnector.cs b/osu.Game/Online/HubClientConnector.cs index 6f246f6dd3..ca6d2932f7 100644 --- a/osu.Game/Online/HubClientConnector.cs +++ b/osu.Game/Online/HubClientConnector.cs @@ -49,6 +49,9 @@ namespace osu.Game.Online this.api = api; this.versionHash = versionHash; this.preferMessagePack = preferMessagePack; + + // Automatically start these connections. + Start(); } protected override Task BuildConnectionAsync(CancellationToken cancellationToken) diff --git a/osu.Game/Online/PersistentEndpointClientConnector.cs b/osu.Game/Online/PersistentEndpointClientConnector.cs index 11e8e870d6..2c4e127723 100644 --- a/osu.Game/Online/PersistentEndpointClientConnector.cs +++ b/osu.Game/Online/PersistentEndpointClientConnector.cs @@ -29,6 +29,7 @@ namespace osu.Game.Online private readonly Bindable isConnected = new Bindable(); private readonly SemaphoreSlim connectionLock = new SemaphoreSlim(1); private CancellationTokenSource connectCancelSource = new CancellationTokenSource(); + private bool started; /// /// Constructs a new . @@ -37,9 +38,19 @@ namespace osu.Game.Online protected PersistentEndpointClientConnector(IAPIProvider api) { API = api; - apiState.BindTo(api.State); + } + + /// + /// Attempts to connect and begins processing messages from the remote endpoint. + /// + public void Start() + { + if (started) + return; + apiState.BindValueChanged(_ => Task.Run(connectIfPossible), true); + started = true; } public Task Reconnect() From 20021551bb1ee3c4074075cea11da769e49e9e66 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 19:36:59 +0900 Subject: [PATCH 0426/2991] Fix editor selection behaviour regressions due to new path visualiser optimisation --- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 36ee7c2460..434e8f5012 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -119,10 +119,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders { updateVisualDefinition(); - // In the case more than a single object is selected, block hover from arriving at sliders behind this one. - // Without doing this, the path visualisers of potentially hundreds of sliders will render, which is not only - // visually noisy but also functionally useless. - return !hasSingleObjectSelected; + return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) @@ -148,7 +145,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders private void updateVisualDefinition() { // To reduce overhead of drawing these blueprints, only add extra detail when hovered or when only this slider is selected. - if (IsSelected && (hasSingleObjectSelected || IsHovered)) + if (IsSelected && selectedObjects.Count == 1) { if (ControlPointVisualiser == null) { From d426977f038f0e83e9c15ca952433f51ac654a02 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 4 Nov 2022 20:11:42 +0900 Subject: [PATCH 0427/2991] Handle channel joins --- .../WebSocket/WebSocketNotificationsClient.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index bc4ceea993..eefe684795 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -113,6 +113,15 @@ namespace osu.Game.Online.Notifications.WebSocket { switch (message.Event) { + case @"chat.channel.join": + Debug.Assert(message.Data != null); + + Channel? joinedChannel = JsonConvert.DeserializeObject(message.Data.ToString()); + Debug.Assert(joinedChannel != null); + + HandleJoinedChannel(joinedChannel); + break; + case @"chat.message.new": Debug.Assert(message.Data != null); From 36c08b69fe2ca08cb6a20cfec9a939fa6cde8892 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 4 Nov 2022 20:47:49 +0900 Subject: [PATCH 0428/2991] Fix failing tests --- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 434e8f5012..402858b702 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -105,8 +105,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders return true; } - private bool hasSingleObjectSelected => selectedObjects.Count == 1; - protected override void Update() { base.Update(); @@ -145,7 +143,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders private void updateVisualDefinition() { // To reduce overhead of drawing these blueprints, only add extra detail when hovered or when only this slider is selected. - if (IsSelected && selectedObjects.Count == 1) + if (IsSelected && selectedObjects.Count < 2) { if (ControlPointVisualiser == null) { From bd512c493729fb0e8e5da9e3f911d3cab0169074 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Nov 2022 19:01:52 +0300 Subject: [PATCH 0429/2991] Remove equality comparison implementation from `BeatmapCard` This turned out to be a hurdle instead as it disallows adding two beatmap cards of equal beatmap, which, while being a good behaviour in client, makes tests more complicated to work. --- osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs index 70312a1535..b9e0a4e6cb 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays; namespace osu.Game.Beatmaps.Drawables.Cards { - public abstract class BeatmapCard : OsuClickableContainer, IEquatable + public abstract class BeatmapCard : OsuClickableContainer { public const float TRANSITION_DURATION = 400; public const float CORNER_RADIUS = 10; @@ -96,16 +96,5 @@ namespace osu.Game.Beatmaps.Drawables.Cards throw new ArgumentOutOfRangeException(nameof(size), size, @"Unsupported card size"); } } - - public bool Equals(BeatmapCard? other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - - return BeatmapSet.Equals(other.BeatmapSet); - } - - public override bool Equals(object obj) => obj is BeatmapCard other && Equals(other); - public override int GetHashCode() => BeatmapSet.GetHashCode(); } } From ce5aacb76049b3e815d4ef2248190a5549f02033 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Nov 2022 19:05:03 +0300 Subject: [PATCH 0430/2991] Filter out duplicated cards using custom equality comparer instead --- osu.Game/Overlays/BeatmapListingOverlay.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index c73936da8a..32e1a00675 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -180,7 +180,7 @@ namespace osu.Game.Overlays // new results may contain beatmaps from a previous page, // this is dodgy but matches web behaviour for now. // see: https://github.com/ppy/osu-web/issues/9270 - newCards = newCards.Except(foundContent); + newCards = newCards.Except(foundContent, BeatmapCardEqualityComparer.Default); panelLoadTask = LoadComponentsAsync(newCards, loaded => { @@ -394,5 +394,21 @@ namespace osu.Game.Overlays if (shouldShowMore) filterControl.FetchNextPage(); } + + private class BeatmapCardEqualityComparer : IEqualityComparer + { + public static BeatmapCardEqualityComparer Default { get; } = new BeatmapCardEqualityComparer(); + + public bool Equals(BeatmapCard x, BeatmapCard y) + { + if (ReferenceEquals(x, y)) return true; + if (ReferenceEquals(x, null)) return false; + if (ReferenceEquals(y, null)) return false; + + return x.BeatmapSet.Equals(y.BeatmapSet); + } + + public int GetHashCode(BeatmapCard obj) => obj.BeatmapSet.GetHashCode(); + } } } From ee6f036c44f80f72007e281537093f30a419dbfe Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 4 Nov 2022 19:35:00 +0300 Subject: [PATCH 0431/2991] Add note about using `ExceptBy` once it's available --- osu.Game/Overlays/BeatmapListingOverlay.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index 32e1a00675..c278c9cb93 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -180,6 +180,8 @@ namespace osu.Game.Overlays // new results may contain beatmaps from a previous page, // this is dodgy but matches web behaviour for now. // see: https://github.com/ppy/osu-web/issues/9270 + // todo: replace custom equality compraer with ExceptBy in net6.0 + // newCards = newCards.ExceptBy(foundContent.Select(c => c.BeatmapSet.OnlineID), c => c.BeatmapSet.OnlineID); newCards = newCards.Except(foundContent, BeatmapCardEqualityComparer.Default); panelLoadTask = LoadComponentsAsync(newCards, loaded => From 6c819cba02ac834a2ba3b88f154082be91798525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 4 Nov 2022 19:45:36 +0100 Subject: [PATCH 0432/2991] Add test coverage for regressed scenarios --- .../Editor/TestSceneOsuComposerSelection.cs | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs new file mode 100644 index 0000000000..800e6c0711 --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs @@ -0,0 +1,117 @@ +// 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 NUnit.Framework; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Testing; +using osu.Game.Beatmaps; +using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components; +using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Screens.Edit.Compose.Components; +using osu.Game.Tests.Beatmaps; +using osuTK; +using osuTK.Input; + +namespace osu.Game.Rulesets.Osu.Tests.Editor +{ + [TestFixture] + public class TestSceneOsuComposerSelection : TestSceneOsuEditor + { + protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(ruleset, false); + + [Test] + public void TestContextMenuShownCorrectlyForSelectedSlider() + { + var slider = new Slider + { + StartTime = 0, + Position = new Vector2(100, 100), + Path = new SliderPath + { + ControlPoints = + { + new PathControlPoint(), + new PathControlPoint(new Vector2(100)) + } + } + }; + AddStep("add slider", () => EditorBeatmap.Add(slider)); + + moveMouseToObject(() => slider); + AddStep("left click", () => InputManager.Click(MouseButton.Left)); + AddUntilStep("slider selected", () => EditorBeatmap.SelectedHitObjects.Single() == slider); + + AddStep("move mouse to centre", () => InputManager.MoveMouseTo(blueprintContainer.ChildrenOfType().Single().ScreenSpaceDrawQuad.Centre)); + AddStep("right click", () => InputManager.Click(MouseButton.Right)); + AddUntilStep("context menu is visible", () => contextMenuContainer.ChildrenOfType().Single().State == MenuState.Open); + } + + [Test] + public void TestSelectionIncludingSliderPreservedOnClick() + { + var firstSlider = new Slider + { + StartTime = 0, + Position = new Vector2(0, 0), + Path = new SliderPath + { + ControlPoints = + { + new PathControlPoint(), + new PathControlPoint(new Vector2(100)) + } + } + }; + var secondSlider = new Slider + { + StartTime = 1000, + Position = new Vector2(100, 100), + Path = new SliderPath + { + ControlPoints = + { + new PathControlPoint(), + new PathControlPoint(new Vector2(100, -100)) + } + } + }; + var hitCircle = new HitCircle + { + StartTime = 200, + Position = new Vector2(300, 0) + }; + + AddStep("add objects", () => EditorBeatmap.AddRange(new HitObject[] { firstSlider, secondSlider, hitCircle })); + AddStep("select last 2 objects", () => EditorBeatmap.SelectedHitObjects.AddRange(new HitObject[] { secondSlider, hitCircle })); + + moveMouseToObject(() => secondSlider); + AddStep("click left mouse", () => InputManager.Click(MouseButton.Left)); + AddAssert("selection preserved", () => EditorBeatmap.SelectedHitObjects.Count == 2); + } + + private ComposeBlueprintContainer blueprintContainer + => Editor.ChildrenOfType().First(); + + private ContextMenuContainer contextMenuContainer + => Editor.ChildrenOfType().First(); + + private void moveMouseToObject(Func targetFunc) + { + AddStep("move mouse to object", () => + { + var pos = blueprintContainer.SelectionBlueprints + .First(s => s.Item == targetFunc()) + .ChildrenOfType() + .First().ScreenSpaceDrawQuad.Centre; + + InputManager.MoveMouseTo(pos); + }); + } + } +} From 23134aea612e12b666586bd5024463c7cfabd37e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 4 Nov 2022 19:48:19 +0100 Subject: [PATCH 0433/2991] Update outdated comment --- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 402858b702..3718f0c6bc 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -142,7 +142,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders private void updateVisualDefinition() { - // To reduce overhead of drawing these blueprints, only add extra detail when hovered or when only this slider is selected. + // To reduce overhead of drawing these blueprints, only add extra detail when only this slider is selected. if (IsSelected && selectedObjects.Count < 2) { if (ControlPointVisualiser == null) From b8438dc788b144c30baf3c552d9333b4fe2d309c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 4 Nov 2022 20:01:21 +0100 Subject: [PATCH 0434/2991] Fix realm package downgrade issue in mobile projects --- osu.Android.props | 2 +- osu.iOS.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index b3c48da2bf..b6ddeeb41a 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -56,6 +56,6 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index b5b488d82e..b2854d7ddd 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -87,6 +87,6 @@ - + From 5931e965c5818f018950cdf505fed18ae687c05b Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sat, 5 Nov 2022 16:16:26 +0800 Subject: [PATCH 0435/2991] Mark background prams in the `getMockWorkingBeatmap()` as nun-nullable because technically it should not accept the null background. --- .../Editing/Checks/CheckBackgroundQualityTest.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs index 1aead6d78c..295a10ba5b 100644 --- a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs @@ -6,7 +6,6 @@ using System.IO; using System.Linq; using Moq; using NUnit.Framework; -using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.Rendering.Dummy; using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; @@ -46,7 +45,7 @@ namespace osu.Game.Tests.Editing.Checks { // While this is a problem, it is out of scope for this check and is caught by a different one. beatmap.Metadata.BackgroundFile = string.Empty; - var context = getContext(null, new MemoryStream(Array.Empty())); + var context = getContext(null!, new MemoryStream(Array.Empty())); Assert.That(check.Run(context), Is.Empty); } @@ -116,7 +115,7 @@ namespace osu.Game.Tests.Editing.Checks stream.Verify(x => x.Close(), Times.Once()); } - private BeatmapVerifierContext getContext(Texture? background, Stream? stream = null) + private BeatmapVerifierContext getContext(Texture background, Stream? stream = null) { return new BeatmapVerifierContext(beatmap, getMockWorkingBeatmap(background, stream).Object); } @@ -126,13 +125,13 @@ namespace osu.Game.Tests.Editing.Checks /// /// The texture of the background. /// The stream representing the background file. - private Mock getMockWorkingBeatmap(Texture? background, Stream? stream = null) + private Mock getMockWorkingBeatmap(Texture background, Stream? stream = null) { stream ??= new MemoryStream(new byte[1024 * 1024]); var mock = new Mock(); mock.SetupGet(w => w.Beatmap).Returns(beatmap); - mock.SetupGet(w => w.Background).Returns(background.AsNonNull()); + mock.SetupGet(w => w.Background).Returns(background); mock.Setup(w => w.GetStream(It.IsAny())).Returns(stream); return mock; From 6062641bf4862f43bcc10378e741e2ab4eaf8d77 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sat, 5 Nov 2022 16:17:20 +0800 Subject: [PATCH 0436/2991] Mark mock track as nun-nullable because technically it should not accept the null track. --- osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs index 8e269cbab2..61ee6a3663 100644 --- a/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs @@ -5,7 +5,6 @@ using System.Linq; using Moq; using NUnit.Framework; using osu.Framework.Audio.Track; -using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit; @@ -42,7 +41,7 @@ namespace osu.Game.Tests.Editing.Checks var mock = new Mock(); mock.SetupGet(w => w.Beatmap).Returns(beatmap); - mock.SetupGet(w => w.Track).Returns(default(Track?).AsNonNull()); + mock.SetupGet(w => w.Track).Returns((Track)null!); Assert.That(check.Run(new BeatmapVerifierContext(beatmap, mock.Object)), Is.Empty); } From 4d4d7cf863574619ec41902b9e5bffb181d4635d Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sat, 5 Nov 2022 16:41:35 +0800 Subject: [PATCH 0437/2991] Remove nullable disable annotation in the cache ruleset. --- .../Editor/Checks/TestCheckBananaShowerGap.cs | 4 +--- osu.Game.Rulesets.Catch/Edit/Checks/CheckBananaShowerGap.cs | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/Checks/TestCheckBananaShowerGap.cs b/osu.Game.Rulesets.Catch.Tests/Editor/Checks/TestCheckBananaShowerGap.cs index 16361d12c6..ef34a5d664 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/Checks/TestCheckBananaShowerGap.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/Checks/TestCheckBananaShowerGap.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -18,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor.Checks [TestFixture] public class TestCheckBananaShowerGap { - private CheckBananaShowerGap check; + private CheckBananaShowerGap check = null!; [SetUp] public void Setup() diff --git a/osu.Game.Rulesets.Catch/Edit/Checks/CheckBananaShowerGap.cs b/osu.Game.Rulesets.Catch/Edit/Checks/CheckBananaShowerGap.cs index 00fd74c9a8..4b2933c0e1 100644 --- a/osu.Game.Rulesets.Catch/Edit/Checks/CheckBananaShowerGap.cs +++ b/osu.Game.Rulesets.Catch/Edit/Checks/CheckBananaShowerGap.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using osu.Game.Beatmaps; From b0673636cae8b341d3f99a9ed6fc1318d2754341 Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sat, 5 Nov 2022 16:44:10 +0800 Subject: [PATCH 0438/2991] Remove nullable disable annotation in the osu ruleset. --- .../Editor/Checks/CheckLowDiffOverlapsTest.cs | 4 +--- .../Editor/Checks/CheckOffscreenObjectsTest.cs | 4 +--- .../Editor/Checks/CheckTimeDistanceEqualityTest.cs | 4 +--- .../Editor/Checks/CheckTooShortSlidersTest.cs | 4 +--- .../Editor/Checks/CheckTooShortSpinnersTest.cs | 6 ++---- osu.Game.Rulesets.Osu/Edit/Checks/CheckLowDiffOverlaps.cs | 2 -- osu.Game.Rulesets.Osu/Edit/Checks/CheckOffscreenObjects.cs | 2 -- .../Edit/Checks/CheckTimeDistanceEquality.cs | 2 -- osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSliders.cs | 2 -- osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSpinners.cs | 2 -- 10 files changed, 6 insertions(+), 26 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckLowDiffOverlapsTest.cs b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckLowDiffOverlapsTest.cs index 7a361b0821..d035d2bc17 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckLowDiffOverlapsTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckLowDiffOverlapsTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using Moq; @@ -21,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks [TestFixture] public class CheckLowDiffOverlapsTest { - private CheckLowDiffOverlaps check; + private CheckLowDiffOverlaps check = null!; [SetUp] public void Setup() diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckOffscreenObjectsTest.cs b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckOffscreenObjectsTest.cs index a778b76c67..a72aaa966c 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckOffscreenObjectsTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckOffscreenObjectsTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -23,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks { private static readonly Vector2 playfield_centre = OsuPlayfield.BASE_SIZE * 0.5f; - private CheckOffscreenObjects check; + private CheckOffscreenObjects check = null!; [SetUp] public void Setup() diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTimeDistanceEqualityTest.cs b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTimeDistanceEqualityTest.cs index 4e8be75779..348243326d 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTimeDistanceEqualityTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTimeDistanceEqualityTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using Moq; @@ -21,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks [TestFixture] public class CheckTimeDistanceEqualityTest { - private CheckTimeDistanceEquality check; + private CheckTimeDistanceEquality check = null!; [SetUp] public void Setup() diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSlidersTest.cs b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSlidersTest.cs index 39a9d5e798..2ec3637bb7 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSlidersTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSlidersTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -20,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks [TestFixture] public class CheckTooShortSlidersTest { - private CheckTooShortSliders check; + private CheckTooShortSliders check = null!; [SetUp] public void Setup() diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSpinnersTest.cs b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSpinnersTest.cs index d044ae732a..f215255bab 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSpinnersTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSpinnersTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -19,8 +17,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks [TestFixture] public class CheckTooShortSpinnersTest { - private CheckTooShortSpinners check; - private IBeatmapDifficultyInfo difficulty; + private CheckTooShortSpinners check = null!; + private IBeatmapDifficultyInfo difficulty = null!; [SetUp] public void Setup() diff --git a/osu.Game.Rulesets.Osu/Edit/Checks/CheckLowDiffOverlaps.cs b/osu.Game.Rulesets.Osu/Edit/Checks/CheckLowDiffOverlaps.cs index 57e6a6ad1d..084a3e5ea1 100644 --- a/osu.Game.Rulesets.Osu/Edit/Checks/CheckLowDiffOverlaps.cs +++ b/osu.Game.Rulesets.Osu/Edit/Checks/CheckLowDiffOverlaps.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit; diff --git a/osu.Game.Rulesets.Osu/Edit/Checks/CheckOffscreenObjects.cs b/osu.Game.Rulesets.Osu/Edit/Checks/CheckOffscreenObjects.cs index af3521c35c..a342c2a821 100644 --- a/osu.Game.Rulesets.Osu/Edit/Checks/CheckOffscreenObjects.cs +++ b/osu.Game.Rulesets.Osu/Edit/Checks/CheckOffscreenObjects.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Checks.Components; diff --git a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTimeDistanceEquality.cs b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTimeDistanceEquality.cs index 753ddba710..585bd35bd9 100644 --- a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTimeDistanceEquality.cs +++ b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTimeDistanceEquality.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; diff --git a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSliders.cs b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSliders.cs index 75eeb91918..159498c479 100644 --- a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSliders.cs +++ b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSliders.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit; diff --git a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSpinners.cs b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSpinners.cs index 6b4dc01ab1..f0aade1b7f 100644 --- a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSpinners.cs +++ b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSpinners.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Checks.Components; From e862ba5e04d9e5d8cb3c4b96025124fd0931ff7d Mon Sep 17 00:00:00 2001 From: andy840119 Date: Sat, 5 Nov 2022 20:13:50 +0800 Subject: [PATCH 0439/2991] Fix the wrong `AsNonNull()` usage. --- osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs b/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs index 7c2b1690af..a39ef22b72 100644 --- a/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs @@ -5,7 +5,6 @@ using System.IO; using System.Linq; using Moq; using NUnit.Framework; -using osu.Framework.Extensions.ObjectExtensions; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Checks; @@ -73,7 +72,7 @@ namespace osu.Game.Tests.Editing.Checks private BeatmapVerifierContext getContextMissing() { var mockWorkingBeatmap = new Mock(); - mockWorkingBeatmap.Setup(w => w.GetStream(It.IsAny())).Returns(default(Stream?).AsNonNull()); + mockWorkingBeatmap.Setup(w => w.GetStream(It.IsAny())).Returns((Stream)null!); return new BeatmapVerifierContext(beatmap, mockWorkingBeatmap.Object); } From f8684f3e76df389d16ad5f694d03a8e0e03a2838 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 5 Nov 2022 22:43:26 +0900 Subject: [PATCH 0440/2991] Add script helpers to use local framework --- UseLocalFramework.ps1 | 11 +++++++++++ UseLocalFramework.sh | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 UseLocalFramework.ps1 create mode 100755 UseLocalFramework.sh diff --git a/UseLocalFramework.ps1 b/UseLocalFramework.ps1 new file mode 100644 index 0000000000..b4e240c09b --- /dev/null +++ b/UseLocalFramework.ps1 @@ -0,0 +1,11 @@ +# Run this script to use a local copy of osu-framework rather than fetching it from nuget. +# It expects the osu-framework directory to be at the same level as the osu directory +# +# https://github.com/ppy/osu-framework/wiki/Testing-local-framework-checkout-with-other-projects + +$CSPROJ="osu.Game/osu.Game.csproj" +$SLN="osu.sln" + +dotnet remove $CSPROJ package ppy.osu.Framework; +dotnet sln $SLN add ../osu-framework/osu.Framework/osu.Framework.csproj ../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj; +dotnet add $CSPROJ reference ../osu-framework/osu.Framework/osu.Framework.csproj diff --git a/UseLocalFramework.sh b/UseLocalFramework.sh new file mode 100755 index 0000000000..4fd1fdfd1b --- /dev/null +++ b/UseLocalFramework.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +# Run this script to use a local copy of osu-framework rather than fetching it from nuget. +# It expects the osu-framework directory to be at the same level as the osu directory +# +# https://github.com/ppy/osu-framework/wiki/Testing-local-framework-checkout-with-other-projects + +CSPROJ="osu.Game/osu.Game.csproj" +SLN="osu.sln" + +dotnet remove $CSPROJ package ppy.osu.Framework +dotnet sln $SLN add ../osu-framework/osu.Framework/osu.Framework.csproj ../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj +dotnet add $CSPROJ reference ../osu-framework/osu.Framework/osu.Framework.csproj + +SLNF="osu.Desktop.slnf" +tmp=$(mktemp) +jq '.solution.projects += ["../osu-framework/osu.Framework/osu.Framework.csproj", "../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj"]' osu.Desktop.slnf > $tmp +mv -f $tmp $SLNF From 230009570e4b3409519376fd9cc1f600dddfd16a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 5 Nov 2022 16:23:12 +0100 Subject: [PATCH 0441/2991] Add slnf support to powershell local framework script --- UseLocalFramework.ps1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/UseLocalFramework.ps1 b/UseLocalFramework.ps1 index b4e240c09b..837685f310 100644 --- a/UseLocalFramework.ps1 +++ b/UseLocalFramework.ps1 @@ -9,3 +9,9 @@ $SLN="osu.sln" dotnet remove $CSPROJ package ppy.osu.Framework; dotnet sln $SLN add ../osu-framework/osu.Framework/osu.Framework.csproj ../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj; dotnet add $CSPROJ reference ../osu-framework/osu.Framework/osu.Framework.csproj + +$SLNF=Get-Content "osu.Desktop.slnf" | ConvertFrom-Json +$TMP=New-TemporaryFile +$SLNF.solution.projects += ("../osu-framework/osu.Framework/osu.Framework.csproj", "../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj") +ConvertTo-Json $SLNF | Out-File $TMP -Encoding UTF8 +Move-Item -Path $TMP -Destination "osu.Desktop.slnf" -Force From 887a3f3e2834def69ef7fa399cfd8c89444fe464 Mon Sep 17 00:00:00 2001 From: CenTdemeern1 Date: Sat, 5 Nov 2022 19:44:25 +0100 Subject: [PATCH 0442/2991] Fix preposition for exclusive fullscreen prompt --- osu.Game/Localisation/LayoutSettingsStrings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Localisation/LayoutSettingsStrings.cs b/osu.Game/Localisation/LayoutSettingsStrings.cs index 9b8b207c47..3006361c9a 100644 --- a/osu.Game/Localisation/LayoutSettingsStrings.cs +++ b/osu.Game/Localisation/LayoutSettingsStrings.cs @@ -15,9 +15,9 @@ namespace osu.Game.Localisation public static LocalisableString CheckingForFullscreenCapabilities => new TranslatableString(getKey(@"checking_for_fullscreen_capabilities"), @"Checking for fullscreen capabilities..."); /// - /// "osu! is running exclusive fullscreen, guaranteeing low latency!" + /// "osu! is running in exclusive fullscreen, guaranteeing low latency!" /// - public static LocalisableString OsuIsRunningExclusiveFullscreen => new TranslatableString(getKey(@"osu_is_running_exclusive_fullscreen"), @"osu! is running exclusive fullscreen, guaranteeing low latency!"); + public static LocalisableString OsuIsRunningExclusiveFullscreen => new TranslatableString(getKey(@"osu_is_running_exclusive_fullscreen"), @"osu! is running in exclusive fullscreen, guaranteeing low latency!"); /// /// "Unable to run exclusive fullscreen. You'll still experience some input latency." From 51078bddf95177e266ce101d9ddccbcebdb5a533 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 6 Nov 2022 23:34:04 +0900 Subject: [PATCH 0443/2991] Remove unused bindable --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index f82a24ff01..15d3e63be1 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -130,7 +130,6 @@ namespace osu.Game.Rulesets.Objects.Drawables private readonly Bindable comboIndexBindable = new Bindable(); private readonly Bindable positionalHitsoundsLevel = new Bindable(); - private readonly Bindable normaliseComboColourBrightness = new Bindable(); private readonly Bindable comboColourBrightness = new Bindable(); private readonly Bindable comboIndexWithOffsetsBindable = new Bindable(); @@ -197,7 +196,6 @@ namespace osu.Game.Rulesets.Objects.Drawables comboIndexBindable.BindValueChanged(_ => UpdateComboColour()); comboIndexWithOffsetsBindable.BindValueChanged(_ => UpdateComboColour(), true); - normaliseComboColourBrightness.BindValueChanged(_ => UpdateComboColour()); comboColourBrightness.BindValueChanged(_ => UpdateComboColour()); // Apply transforms From e8603ede15ce9acd38cc02fff84851847291b529 Mon Sep 17 00:00:00 2001 From: CenTdemeern1 Date: Sun, 6 Nov 2022 14:55:16 +0100 Subject: [PATCH 0444/2991] Fix second prompt --- osu.Game/Localisation/LayoutSettingsStrings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Localisation/LayoutSettingsStrings.cs b/osu.Game/Localisation/LayoutSettingsStrings.cs index 3006361c9a..a5172ec774 100644 --- a/osu.Game/Localisation/LayoutSettingsStrings.cs +++ b/osu.Game/Localisation/LayoutSettingsStrings.cs @@ -20,9 +20,9 @@ namespace osu.Game.Localisation public static LocalisableString OsuIsRunningExclusiveFullscreen => new TranslatableString(getKey(@"osu_is_running_exclusive_fullscreen"), @"osu! is running in exclusive fullscreen, guaranteeing low latency!"); /// - /// "Unable to run exclusive fullscreen. You'll still experience some input latency." + /// "Unable to run in exclusive fullscreen. You may experience some input latency." /// - public static LocalisableString UnableToRunExclusiveFullscreen => new TranslatableString(getKey(@"unable_to_run_exclusive_fullscreen"), @"Unable to run exclusive fullscreen. You'll still experience some input latency."); + public static LocalisableString UnableToRunExclusiveFullscreen => new TranslatableString(getKey(@"unable_to_run_exclusive_fullscreen"), @"Unable to run in exclusive fullscreen. You may experience some input latency."); /// /// "Using fullscreen on macOS makes interacting with the menu bar and spaces no longer work, and may lead to freezes if a system dialog is presented. Using borderless is recommended." From 75bf023f1445c4a67efc3ca66b8f783a0352f0ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 6 Nov 2022 23:35:51 +0900 Subject: [PATCH 0445/2991] Fix `HSPAColour.ToColour` not being pure --- osu.Game/Graphics/HSPAColour.cs | 93 +++++++++++++++++---------------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/osu.Game/Graphics/HSPAColour.cs b/osu.Game/Graphics/HSPAColour.cs index 5e3bc29b7e..18f4c6bca4 100644 --- a/osu.Game/Graphics/HSPAColour.cs +++ b/osu.Game/Graphics/HSPAColour.cs @@ -96,100 +96,101 @@ namespace osu.Game.Graphics float minOverMax = 1f - S; Color4 result = new Color4 { A = A }; + float h = H; if (minOverMax > 0f) { - if (H < 1f / 6f) + if (h < 1f / 6f) { - H = 6f * (H - 0f / 6f); - float part = 1f + H * (1f / minOverMax - 1f); + h = 6f * (h - 0f / 6f); + float part = 1f + h * (1f / minOverMax - 1f); result.B = P / MathF.Sqrt(p_r / minOverMax / minOverMax + p_g * part * part + p_b); result.R = result.B / minOverMax; - result.G = result.B + H * (result.R - result.B); + result.G = result.B + h * (result.R - result.B); } - else if (H < 2f / 6f) + else if (h < 2f / 6f) { - H = 6f * (-H + 2f / 6f); - float part = 1f + H * (1f / minOverMax - 1f); + h = 6f * (-h + 2f / 6f); + float part = 1f + h * (1f / minOverMax - 1f); result.B = P / MathF.Sqrt(p_g / minOverMax / minOverMax + p_r * part * part + p_b); result.G = result.B / minOverMax; - result.R = result.B + H * (result.G - result.B); + result.R = result.B + h * (result.G - result.B); } - else if (H < 3f / 6f) + else if (h < 3f / 6f) { - H = 6f * (H - 2f / 6f); - float part = 1f + H * (1f / minOverMax - 1f); + h = 6f * (h - 2f / 6f); + float part = 1f + h * (1f / minOverMax - 1f); result.R = P / MathF.Sqrt(p_g / minOverMax / minOverMax + p_b * part * part + p_r); result.G = result.R / minOverMax; - result.B = result.R + H * (result.G - result.R); + result.B = result.R + h * (result.G - result.R); } - else if (H < 4f / 6f) + else if (h < 4f / 6f) { - H = 6f * (-H + 4f / 6f); - float part = 1f + H * (1f / minOverMax - 1f); + h = 6f * (-h + 4f / 6f); + float part = 1f + h * (1f / minOverMax - 1f); result.R = P / MathF.Sqrt(p_b / minOverMax / minOverMax + p_g * part * part + p_r); result.B = result.R / minOverMax; - result.G = result.R + H * (result.B - result.R); + result.G = result.R + h * (result.B - result.R); } - else if (H < 5f / 6f) + else if (h < 5f / 6f) { - H = 6f * (H - 4f / 6f); - float part = 1f + H * (1f / minOverMax - 1f); + h = 6f * (h - 4f / 6f); + float part = 1f + h * (1f / minOverMax - 1f); result.G = P / MathF.Sqrt(p_b / minOverMax / minOverMax + p_r * part * part + p_g); result.B = result.G / minOverMax; - result.R = result.G + H * (result.B - result.G); + result.R = result.G + h * (result.B - result.G); } else { - H = 6f * (-H + 6f / 6f); - float part = 1f + H * (1f / minOverMax - 1f); + h = 6f * (-h + 6f / 6f); + float part = 1f + h * (1f / minOverMax - 1f); result.G = P / MathF.Sqrt(p_r / minOverMax / minOverMax + p_b * part * part + p_g); result.R = result.G / minOverMax; - result.B = result.G + H * (result.R - result.G); + result.B = result.G + h * (result.R - result.G); } } else { - if (H < 1f / 6f) + if (h < 1f / 6f) { - H = 6f * (H - 0f / 6f); - result.R = MathF.Sqrt(P * P / (p_r + p_g * H * H)); - result.G = result.R * H; + h = 6f * (h - 0f / 6f); + result.R = MathF.Sqrt(P * P / (p_r + p_g * h * h)); + result.G = result.R * h; result.B = 0f; } - else if (H < 2f / 6f) + else if (h < 2f / 6f) { - H = 6f * (-H + 2f / 6f); - result.G = MathF.Sqrt(P * P / (p_g + p_r * H * H)); - result.R = result.G * H; + h = 6f * (-h + 2f / 6f); + result.G = MathF.Sqrt(P * P / (p_g + p_r * h * h)); + result.R = result.G * h; result.B = 0f; } - else if (H < 3f / 6f) + else if (h < 3f / 6f) { - H = 6f * (H - 2f / 6f); - result.G = MathF.Sqrt(P * P / (p_g + p_b * H * H)); - result.B = result.G * H; + h = 6f * (h - 2f / 6f); + result.G = MathF.Sqrt(P * P / (p_g + p_b * h * h)); + result.B = result.G * h; result.R = 0f; } - else if (H < 4f / 6f) + else if (h < 4f / 6f) { - H = 6f * (-H + 4f / 6f); - result.B = MathF.Sqrt(P * P / (p_b + p_g * H * H)); - result.G = result.B * H; + h = 6f * (-h + 4f / 6f); + result.B = MathF.Sqrt(P * P / (p_b + p_g * h * h)); + result.G = result.B * h; result.R = 0f; } - else if (H < 5f / 6f) + else if (h < 5f / 6f) { - H = 6f * (H - 4f / 6f); - result.B = MathF.Sqrt(P * P / (p_b + p_r * H * H)); - result.R = result.B * H; + h = 6f * (h - 4f / 6f); + result.B = MathF.Sqrt(P * P / (p_b + p_r * h * h)); + result.R = result.B * h; result.G = 0f; } else { - H = 6f * (-H + 6f / 6f); - result.R = MathF.Sqrt(P * P / (p_r + p_b * H * H)); - result.B = result.R * H; + h = 6f * (-h + 6f / 6f); + result.R = MathF.Sqrt(P * P / (p_r + p_b * h * h)); + result.B = result.R * h; result.G = 0f; } } From 700f8b04690127464440568185cc8b60954d5325 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 02:13:04 +0900 Subject: [PATCH 0446/2991] Remove pointless nested if conditional MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Graphics/UserInterface/Nub.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/Nub.cs b/osu.Game/Graphics/UserInterface/Nub.cs index 80e012f596..db3a41e303 100644 --- a/osu.Game/Graphics/UserInterface/Nub.cs +++ b/osu.Game/Graphics/UserInterface/Nub.cs @@ -172,7 +172,7 @@ namespace osu.Game.Graphics.UserInterface if (filled.NewValue) { main.ResizeWidthTo(1, duration, Easing.OutElasticHalf); - main.TransformTo(nameof(BorderThickness), filled.NewValue ? 8.5f : border_width, duration, Easing.OutElasticHalf); + main.TransformTo(nameof(BorderThickness), 8.5f, duration, Easing.OutElasticHalf); } else { From e7b543de2f32298cc47045085bd7c10d58ed9db6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 02:19:13 +0900 Subject: [PATCH 0447/2991] Move disabled check to apply to all calls to `updateGlow()` --- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index d7f308c45d..4d3f4be8f6 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -162,8 +162,7 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnHover(HoverEvent e) { - if (!Current.Disabled) - updateGlow(); + updateGlow(); return base.OnHover(e); } @@ -184,7 +183,7 @@ namespace osu.Game.Graphics.UserInterface private void updateGlow() { - Nub.Glowing = IsHovered || IsDragged; + Nub.Glowing = !Current.Disabled && (IsHovered || IsDragged); } protected override void OnUserChange(T value) From b7ef9b176d3c9c0de0e116c34c73e329acc18d3f Mon Sep 17 00:00:00 2001 From: maromalo <54760464+maromalo@users.noreply.github.com> Date: Sun, 6 Nov 2022 19:59:27 -0300 Subject: [PATCH 0448/2991] Make score type consistent --- .../TestSceneSpinnerRotation.cs | 2 +- .../Gameplay/TestSceneScoreProcessor.cs | 2 +- .../Gameplay/TestSceneGameplayLeaderboard.cs | 10 +++++----- .../Graphics/UserInterface/ScoreCounter.cs | 6 +++--- .../API/Requests/Responses/SoloScoreInfo.cs | 4 ++-- .../Online/Rooms/IndexedMultiplayerScores.cs | 2 +- .../Spectator/SpectatorScoreProcessor.cs | 2 +- .../PerformanceBreakdownCalculator.cs | 2 +- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 18 +++++++++--------- osu.Game/Scoring/ScoreManager.cs | 2 +- osu.Game/Scoring/ScoringValues.cs | 4 ++-- .../OnlinePlay/Playlists/PlaylistsPlayer.cs | 2 +- .../Play/HUD/GameplayLeaderboardScore.cs | 2 +- osu.Game/Screens/Play/HUD/ILeaderboardScore.cs | 2 +- .../Play/HUD/MultiplayerGameplayLeaderboard.cs | 2 +- 15 files changed, 31 insertions(+), 31 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs index 5fa4e24f5e..13ea46eadf 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs @@ -134,7 +134,7 @@ namespace osu.Game.Rulesets.Osu.Tests AddAssert("player score matching expected bonus score", () => { // multipled by 2 to nullify the score multiplier. (autoplay mod selected) - double totalScore = ((ScoreExposedPlayer)Player).ScoreProcessor.TotalScore.Value * 2; + long totalScore = ((ScoreExposedPlayer)Player).ScoreProcessor.TotalScore.Value * 2; return totalScore == (int)(drawableSpinner.Result.RateAdjustedRotation / 360) * new SpinnerTick().CreateJudgement().MaxNumericResult; }); diff --git a/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs b/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs index fb9d841d99..d5219f6391 100644 --- a/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs +++ b/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs @@ -35,7 +35,7 @@ namespace osu.Game.Tests.Gameplay // Apply a miss judgement scoreProcessor.ApplyResult(new JudgementResult(new HitObject(), new TestJudgement()) { Type = HitResult.Miss }); - Assert.That(scoreProcessor.TotalScore.Value, Is.EqualTo(0.0)); + Assert.That(scoreProcessor.TotalScore.Value, Is.EqualTo(0)); } [Test] diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs index 171ae829a9..30d2cc6423 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs @@ -22,7 +22,7 @@ namespace osu.Game.Tests.Visual.Gameplay { private TestGameplayLeaderboard leaderboard; - private readonly BindableDouble playerScore = new BindableDouble(); + private readonly BindableLong playerScore = new BindableLong(); public TestSceneGameplayLeaderboard() { @@ -76,8 +76,8 @@ namespace osu.Game.Tests.Visual.Gameplay createLeaderboard(); addLocalPlayer(); - var player2Score = new BindableDouble(1234567); - var player3Score = new BindableDouble(1111111); + var player2Score = new BindableLong(1234567); + var player3Score = new BindableLong(1111111); AddStep("add player 2", () => createLeaderboardScore(player2Score, new APIUser { Username = "Player 2" })); AddStep("add player 3", () => createLeaderboardScore(player3Score, new APIUser { Username = "Player 3" })); @@ -161,9 +161,9 @@ namespace osu.Game.Tests.Visual.Gameplay }); } - private void createRandomScore(APIUser user) => createLeaderboardScore(new BindableDouble(RNG.Next(0, 5_000_000)), user); + private void createRandomScore(APIUser user) => createLeaderboardScore(new BindableLong(RNG.Next(0, 5_000_000)), user); - private void createLeaderboardScore(BindableDouble score, APIUser user, bool isTracked = false) + private void createLeaderboardScore(BindableLong score, APIUser user, bool isTracked = false) { var leaderboardScore = leaderboard.Add(user, isTracked); leaderboardScore.TotalScore.BindTo(score); diff --git a/osu.Game/Graphics/UserInterface/ScoreCounter.cs b/osu.Game/Graphics/UserInterface/ScoreCounter.cs index e46e2b31ac..2efe27c842 100644 --- a/osu.Game/Graphics/UserInterface/ScoreCounter.cs +++ b/osu.Game/Graphics/UserInterface/ScoreCounter.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.UserInterface { - public abstract class ScoreCounter : RollingCounter + public abstract class ScoreCounter : RollingCounter { protected override double RollingDuration => 1000; protected override Easing RollingEasing => Easing.Out; @@ -36,10 +36,10 @@ namespace osu.Game.Graphics.UserInterface UpdateDisplay(); } - protected override double GetProportionalDuration(double currentValue, double newValue) => + protected override double GetProportionalDuration(long currentValue, long newValue) => currentValue > newValue ? currentValue - newValue : newValue - currentValue; - protected override LocalisableString FormatCount(double count) => ((long)count).ToLocalisableString(formatString); + protected override LocalisableString FormatCount(long count) => count.ToLocalisableString(formatString); protected override OsuSpriteText CreateSpriteText() => base.CreateSpriteText().With(s => s.Font = s.Font.With(fixedWidth: true)); diff --git a/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs b/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs index 77dcfd39e3..15f4bace96 100644 --- a/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs +++ b/osu.Game/Online/API/Requests/Responses/SoloScoreInfo.cs @@ -31,7 +31,7 @@ namespace osu.Game.Online.API.Requests.Responses public bool Passed { get; set; } [JsonProperty("total_score")] - public int TotalScore { get; set; } + public long TotalScore { get; set; } [JsonProperty("accuracy")] public double Accuracy { get; set; } @@ -213,7 +213,7 @@ namespace osu.Game.Online.API.Requests.Responses public static SoloScoreInfo ForSubmission(ScoreInfo score) => new SoloScoreInfo { Rank = score.Rank, - TotalScore = (int)score.TotalScore, + TotalScore = score.TotalScore, Accuracy = score.Accuracy, PP = score.PP, MaxCombo = score.MaxCombo, diff --git a/osu.Game/Online/Rooms/IndexedMultiplayerScores.cs b/osu.Game/Online/Rooms/IndexedMultiplayerScores.cs index 459602f1b4..59cba2340d 100644 --- a/osu.Game/Online/Rooms/IndexedMultiplayerScores.cs +++ b/osu.Game/Online/Rooms/IndexedMultiplayerScores.cs @@ -17,7 +17,7 @@ namespace osu.Game.Online.Rooms /// The total scores in the playlist item. /// [JsonProperty("total")] - public int? TotalScores { get; set; } + public long? TotalScores { get; set; } /// /// The user's score, if any. diff --git a/osu.Game/Online/Spectator/SpectatorScoreProcessor.cs b/osu.Game/Online/Spectator/SpectatorScoreProcessor.cs index 87f25874c5..573c504add 100644 --- a/osu.Game/Online/Spectator/SpectatorScoreProcessor.cs +++ b/osu.Game/Online/Spectator/SpectatorScoreProcessor.cs @@ -26,7 +26,7 @@ namespace osu.Game.Online.Spectator /// /// The current total score. /// - public readonly BindableDouble TotalScore = new BindableDouble { MinValue = 0 }; + public readonly BindableLong TotalScore = new BindableLong { MinValue = 0 }; /// /// The current accuracy. diff --git a/osu.Game/Rulesets/Difficulty/PerformanceBreakdownCalculator.cs b/osu.Game/Rulesets/Difficulty/PerformanceBreakdownCalculator.cs index 3fb12041d1..4f802a22a1 100644 --- a/osu.Game/Rulesets/Difficulty/PerformanceBreakdownCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/PerformanceBreakdownCalculator.cs @@ -66,7 +66,7 @@ namespace osu.Game.Rulesets.Difficulty // calculate total score ScoreProcessor scoreProcessor = ruleset.CreateScoreProcessor(); scoreProcessor.Mods.Value = perfectPlay.Mods; - perfectPlay.TotalScore = (long)scoreProcessor.ComputeScore(ScoringMode.Standardised, perfectPlay); + perfectPlay.TotalScore = scoreProcessor.ComputeScore(ScoringMode.Standardised, perfectPlay); // compute rank achieved // default to SS, then adjust the rank with mods diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 7456ce06bd..f619c89368 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Scoring /// /// The current total score. /// - public readonly BindableDouble TotalScore = new BindableDouble { MinValue = 0 }; + public readonly BindableLong TotalScore = new BindableLong { MinValue = 0 }; /// /// The current accuracy. @@ -267,7 +267,7 @@ namespace osu.Game.Rulesets.Scoring private void updateScore() { - Accuracy.Value = currentMaximumScoringValues.BaseScore > 0 ? currentScoringValues.BaseScore / currentMaximumScoringValues.BaseScore : 1; + Accuracy.Value = currentMaximumScoringValues.BaseScore > 0 ? (double)currentScoringValues.BaseScore / currentMaximumScoringValues.BaseScore : 1; TotalScore.Value = ComputeScore(Mode.Value, currentScoringValues, maximumScoringValues); } @@ -298,7 +298,7 @@ namespace osu.Game.Rulesets.Scoring /// The to compute the total score of. /// The total score in the given . [Pure] - public double ComputeScore(ScoringMode mode, ScoreInfo scoreInfo) + public long ComputeScore(ScoringMode mode, ScoreInfo scoreInfo) { if (!ruleset.RulesetInfo.Equals(scoreInfo.Ruleset)) throw new ArgumentException($"Unexpected score ruleset. Expected \"{ruleset.RulesetInfo.ShortName}\" but was \"{scoreInfo.Ruleset.ShortName}\"."); @@ -316,9 +316,9 @@ namespace osu.Game.Rulesets.Scoring /// The maximum scoring values. /// The total score computed from the given scoring values. [Pure] - public double ComputeScore(ScoringMode mode, ScoringValues current, ScoringValues maximum) + public long ComputeScore(ScoringMode mode, ScoringValues current, ScoringValues maximum) { - double accuracyRatio = maximum.BaseScore > 0 ? current.BaseScore / maximum.BaseScore : 1; + double accuracyRatio = maximum.BaseScore > 0 ? (double)current.BaseScore / maximum.BaseScore : 1; double comboRatio = maximum.MaxCombo > 0 ? (double)current.MaxCombo / maximum.MaxCombo : 1; return ComputeScore(mode, accuracyRatio, comboRatio, current.BonusScore, maximum.CountBasicHitObjects); } @@ -333,7 +333,7 @@ namespace osu.Game.Rulesets.Scoring /// The total number of basic (non-tick and non-bonus) hitobjects in the beatmap. /// The total score computed from the given scoring component ratios. [Pure] - public double ComputeScore(ScoringMode mode, double accuracyRatio, double comboRatio, double bonusScore, int totalBasicHitObjects) + public long ComputeScore(ScoringMode mode, double accuracyRatio, double comboRatio, long bonusScore, int totalBasicHitObjects) { switch (mode) { @@ -341,13 +341,13 @@ namespace osu.Game.Rulesets.Scoring case ScoringMode.Standardised: double accuracyScore = accuracyPortion * accuracyRatio; double comboScore = comboPortion * comboRatio; - return (max_score * (accuracyScore + comboScore) + bonusScore) * scoreMultiplier; + return (long)((max_score * (accuracyScore + comboScore) + bonusScore) * scoreMultiplier); case ScoringMode.Classic: // This gives a similar feeling to osu!stable scoring (ScoreV1) while keeping classic scoring as only a constant multiple of standardised scoring. // The invariant is important to ensure that scores don't get re-ordered on leaderboards between the two scoring modes. double scaledStandardised = ComputeScore(ScoringMode.Standardised, accuracyRatio, comboRatio, bonusScore, totalBasicHitObjects) / max_score; - return Math.Pow(scaledStandardised * Math.Max(1, totalBasicHitObjects), 2) * ClassicScoreMultiplier; + return (long)(Math.Pow(scaledStandardised * Math.Max(1, totalBasicHitObjects), 2) * ClassicScoreMultiplier); } } @@ -417,7 +417,7 @@ namespace osu.Game.Rulesets.Scoring score.MaximumStatistics[result] = maximumResultCounts.GetValueOrDefault(result); // Populate total score after everything else. - score.TotalScore = (long)Math.Round(ComputeScore(ScoringMode.Standardised, score)); + score.TotalScore = ComputeScore(ScoringMode.Standardised, score); } /// diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index 8342d3bcc1..b2944ad219 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -99,7 +99,7 @@ namespace osu.Game.Scoring var scoreProcessor = ruleset.CreateScoreProcessor(); scoreProcessor.Mods.Value = score.Mods; - return (long)Math.Round(scoreProcessor.ComputeScore(mode, score)); + return scoreProcessor.ComputeScore(mode, score); } /// diff --git a/osu.Game/Scoring/ScoringValues.cs b/osu.Game/Scoring/ScoringValues.cs index 9bc4e6e12a..471067c9db 100644 --- a/osu.Game/Scoring/ScoringValues.cs +++ b/osu.Game/Scoring/ScoringValues.cs @@ -20,13 +20,13 @@ namespace osu.Game.Scoring /// The sum of all "basic" scoring values. See: and . /// [Key(0)] - public double BaseScore; + public long BaseScore; /// /// The sum of all "bonus" scoring values. See: and . /// [Key(1)] - public double BonusScore; + public long BonusScore; /// /// The highest achieved combo. diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsPlayer.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsPlayer.cs index 1c4d02bb11..2444729118 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsPlayer.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsPlayer.cs @@ -67,7 +67,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists { await base.PrepareScoreForResultsAsync(score).ConfigureAwait(false); - Score.ScoreInfo.TotalScore = (int)Math.Round(ScoreProcessor.ComputeScore(ScoringMode.Standardised, Score.ScoreInfo)); + Score.ScoreInfo.TotalScore = ScoreProcessor.ComputeScore(ScoringMode.Standardised, Score.ScoreInfo); } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs b/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs index 2eec8253b3..15586baab0 100644 --- a/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs +++ b/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Play.HUD private OsuSpriteText positionText, scoreText, accuracyText, comboText, usernameText; - public BindableDouble TotalScore { get; } = new BindableDouble(); + public BindableLong TotalScore { get; } = new BindableLong(); public BindableDouble Accuracy { get; } = new BindableDouble(1); public BindableInt Combo { get; } = new BindableInt(); public BindableBool HasQuit { get; } = new BindableBool(); diff --git a/osu.Game/Screens/Play/HUD/ILeaderboardScore.cs b/osu.Game/Screens/Play/HUD/ILeaderboardScore.cs index aa06bb08a5..428390f90c 100644 --- a/osu.Game/Screens/Play/HUD/ILeaderboardScore.cs +++ b/osu.Game/Screens/Play/HUD/ILeaderboardScore.cs @@ -9,7 +9,7 @@ namespace osu.Game.Screens.Play.HUD { public interface ILeaderboardScore { - BindableDouble TotalScore { get; } + BindableLong TotalScore { get; } BindableDouble Accuracy { get; } BindableInt Combo { get; } diff --git a/osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.cs index 4201b3f4c9..a77d66cdd2 100644 --- a/osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.cs @@ -184,7 +184,7 @@ namespace osu.Game.Screens.Play.HUD continue; if (TeamScores.TryGetValue(u.Team.Value, out var team)) - team.Value += (int)Math.Round(u.ScoreProcessor.TotalScore.Value); + team.Value += u.ScoreProcessor.TotalScore.Value; } } From 8eef2ba8de2bfdce8f4c4278f0390259ab46587b Mon Sep 17 00:00:00 2001 From: maromalo <54760464+maromalo@users.noreply.github.com> Date: Sun, 6 Nov 2022 20:12:26 -0300 Subject: [PATCH 0449/2991] quality shenanigans --- osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.cs index a77d66cdd2..4ac92056ef 100644 --- a/osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.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.Collections.Generic; using System.Collections.Specialized; using System.Linq; From e3adf5a98502d714c6849095f257a2ad343b5038 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 7 Nov 2022 11:36:55 +0900 Subject: [PATCH 0450/2991] Handle channel parts --- osu.Game/Online/Chat/ChannelManager.cs | 2 ++ osu.Game/Online/Notifications/NotificationsClient.cs | 3 +++ .../Online/Notifications/NotificationsClientConnector.cs | 2 ++ .../WebSocket/WebSocketNotificationsClient.cs | 9 +++++++++ 4 files changed, 16 insertions(+) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index db2436333b..93033dffa0 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -99,6 +99,8 @@ namespace osu.Game.Online.Chat joinChannel(localChannel); }); + connector.ChannelParted += ch => Schedule(() => LeaveChannel(getChannel(ch))); + connector.NewMessages += msgs => Schedule(() => addMessages(msgs)); connector.PresenceReceived += () => Schedule(() => diff --git a/osu.Game/Online/Notifications/NotificationsClient.cs b/osu.Game/Online/Notifications/NotificationsClient.cs index cb5e94fb1d..5182bfa0e5 100644 --- a/osu.Game/Online/Notifications/NotificationsClient.cs +++ b/osu.Game/Online/Notifications/NotificationsClient.cs @@ -18,6 +18,7 @@ namespace osu.Game.Online.Notifications public abstract class NotificationsClient : PersistentEndpointClient { public Action? ChannelJoined; + public Action? ChannelParted; public Action>? NewMessages; public Action? PresenceReceived; @@ -65,6 +66,8 @@ namespace osu.Game.Online.Notifications ChannelJoined?.Invoke(channel); } + protected void HandleChannelParted(Channel channel) => ChannelParted?.Invoke(channel); + protected void HandleMessages(List messages) { NewMessages?.Invoke(messages); diff --git a/osu.Game/Online/Notifications/NotificationsClientConnector.cs b/osu.Game/Online/Notifications/NotificationsClientConnector.cs index d4c846a7a2..d2c2e6673c 100644 --- a/osu.Game/Online/Notifications/NotificationsClientConnector.cs +++ b/osu.Game/Online/Notifications/NotificationsClientConnector.cs @@ -16,6 +16,7 @@ namespace osu.Game.Online.Notifications public abstract class NotificationsClientConnector : PersistentEndpointClientConnector { public event Action? ChannelJoined; + public event Action? ChannelParted; public event Action>? NewMessages; public event Action? PresenceReceived; @@ -29,6 +30,7 @@ namespace osu.Game.Online.Notifications var client = await BuildNotificationClientAsync(cancellationToken); client.ChannelJoined = c => ChannelJoined?.Invoke(c); + client.ChannelParted = c => ChannelParted?.Invoke(c); client.NewMessages = m => NewMessages?.Invoke(m); client.PresenceReceived = () => PresenceReceived?.Invoke(); diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index eefe684795..8f4b3c2f97 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -122,6 +122,15 @@ namespace osu.Game.Online.Notifications.WebSocket HandleJoinedChannel(joinedChannel); break; + case @"chat.channel.part": + Debug.Assert(message.Data != null); + + Channel? partedChannel = JsonConvert.DeserializeObject(message.Data.ToString()); + Debug.Assert(partedChannel != null); + + HandleChannelParted(partedChannel); + break; + case @"chat.message.new": Debug.Assert(message.Data != null); From cf03001c83a7f6317513fd283a7761427c050e72 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 7 Nov 2022 11:52:07 +0900 Subject: [PATCH 0451/2991] Better handling for joining channels with only ID --- .../Online/API/Requests/GetChannelRequest.cs | 19 +++++++++++++ .../Requests/Responses/GetChannelResponse.cs | 19 +++++++++++++ osu.Game/Online/Chat/ChannelManager.cs | 28 +++++-------------- .../Notifications/NotificationsClient.cs | 10 +++---- .../WebSocket/WebSocketNotificationsClient.cs | 3 +- 5 files changed, 51 insertions(+), 28 deletions(-) create mode 100644 osu.Game/Online/API/Requests/GetChannelRequest.cs create mode 100644 osu.Game/Online/API/Requests/Responses/GetChannelResponse.cs diff --git a/osu.Game/Online/API/Requests/GetChannelRequest.cs b/osu.Game/Online/API/Requests/GetChannelRequest.cs new file mode 100644 index 0000000000..5bc9cb519a --- /dev/null +++ b/osu.Game/Online/API/Requests/GetChannelRequest.cs @@ -0,0 +1,19 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Online.API.Requests +{ + public class GetChannelRequest : APIRequest + { + private readonly long channelId; + + public GetChannelRequest(long channelId) + { + this.channelId = channelId; + } + + protected override string Target => $"chat/channels/{channelId}"; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/GetChannelResponse.cs b/osu.Game/Online/API/Requests/Responses/GetChannelResponse.cs new file mode 100644 index 0000000000..24b886e74d --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/GetChannelResponse.cs @@ -0,0 +1,19 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using Newtonsoft.Json; +using osu.Game.Online.Chat; + +namespace osu.Game.Online.API.Requests.Responses +{ + [JsonObject(MemberSerialization.OptIn)] + public class GetChannelResponse + { + [JsonProperty(@"channel")] + public Channel Channel { get; set; } = null!; + + [JsonProperty(@"users")] + public List Users { get; set; } = null!; + } +} diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 93033dffa0..ee3194243b 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -88,15 +88,14 @@ namespace osu.Game.Online.Chat { connector.ChannelJoined += ch => Schedule(() => { - var localChannel = getChannel(ch); - - if (localChannel != ch) + if (ch.Joined.Value) + JoinChannel(ch); + else { - localChannel.Joined.Value = true; - localChannel.Id = ch.Id; + var req = new GetChannelRequest(ch.Id); + req.Success += response => JoinChannel(response.Channel); + api.Queue(req); } - - joinChannel(localChannel); }); connector.ChannelParted += ch => Schedule(() => LeaveChannel(getChannel(ch))); @@ -421,20 +420,7 @@ namespace osu.Game.Online.Chat { Channel found = null; - bool lookupCondition(Channel ch) - { - // If both channels have an id, use that. - if (lookup.Id > 0 && ch.Id > 0) - return ch.Id == lookup.Id; - - // In the case that the local echo is received in a new channel (i.e. one that does not yet have an ID), - // then we need to check for any existing channel with the message containing the same message matched by UUID. - if (lookup.Messages.Count > 0 && ch.Messages.Any(m => m.Uuid == lookup.Messages.Last().Uuid)) - return true; - - // As a last resort, fallback to matching by name. - return lookup.Name == ch.Name; - } + bool lookupCondition(Channel ch) => lookup.Id > 0 ? ch.Id == lookup.Id : ch.Name == lookup.Name; var available = AvailableChannels.FirstOrDefault(lookupCondition); if (available != null) diff --git a/osu.Game/Online/Notifications/NotificationsClient.cs b/osu.Game/Online/Notifications/NotificationsClient.cs index 5182bfa0e5..c706124351 100644 --- a/osu.Game/Online/Notifications/NotificationsClient.cs +++ b/osu.Game/Online/Notifications/NotificationsClient.cs @@ -46,7 +46,10 @@ namespace osu.Game.Online.Notifications if (updates?.Presence != null) { foreach (var channel in updates.Presence) + { + channel.Joined.Value = true; HandleJoinedChannel(channel); + } //todo: handle left channels @@ -59,12 +62,7 @@ namespace osu.Game.Online.Notifications return fetchReq; } - protected void HandleJoinedChannel(Channel channel) - { - // we received this from the server so should mark the channel already joined. - channel.Joined.Value = true; - ChannelJoined?.Invoke(channel); - } + protected void HandleJoinedChannel(Channel channel) => ChannelJoined?.Invoke(channel); protected void HandleChannelParted(Channel channel) => ChannelParted?.Invoke(channel); diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index 8f4b3c2f97..71aec942ac 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -119,6 +119,7 @@ namespace osu.Game.Online.Notifications.WebSocket Channel? joinedChannel = JsonConvert.DeserializeObject(message.Data.ToString()); Debug.Assert(joinedChannel != null); + joinedChannel.Joined.Value = true; HandleJoinedChannel(joinedChannel); break; @@ -138,7 +139,7 @@ namespace osu.Game.Online.Notifications.WebSocket Debug.Assert(messageData != null); foreach (var msg in messageData.Messages) - HandleJoinedChannel(new Channel(msg.Sender) { Id = msg.ChannelId, Messages = { msg } }); + HandleJoinedChannel(new Channel { Id = msg.ChannelId }); HandleMessages(messageData.Messages); break; From 391840404de144367f979f4cde1ac59475c972c2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 11:59:43 +0900 Subject: [PATCH 0452/2991] Play exiting transition in both directions --- osu.Game/Screens/Select/SongSelect.cs | 40 +++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index fe9b67a02e..4b2417aab4 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -633,14 +633,32 @@ namespace osu.Game.Screens.Select transferRulesetValue(); ModSelect.SelectedMods.UnbindFrom(selectedMods); + + playExitingTransition(); + base.OnSuspending(e); + } + + public override bool OnExiting(ScreenExitEvent e) + { + if (base.OnExiting(e)) + return true; + + playExitingTransition(); + return false; + } + + private void playExitingTransition() + { ModSelect.Hide(); BeatmapOptions.Hide(); + Carousel.AllowSelection = false; + endLooping(); - FilterControl.MoveToY(-120, 250, Easing.OutQuint); - FilterControl.FadeOut(100); + FilterControl.MoveToY(-120, 500, Easing.OutQuint); + FilterControl.FadeOut(200, Easing.OutQuint); LeftArea.MoveToX(-150, 1800, Easing.OutQuint); LeftArea.FadeOut(200, Easing.OutQuint); @@ -650,24 +668,6 @@ namespace osu.Game.Screens.Select this.FadeOut(400, Easing.OutQuint); FilterControl.Deactivate(); - base.OnSuspending(e); - } - - public override bool OnExiting(ScreenExitEvent e) - { - if (base.OnExiting(e)) - return true; - - beatmapInfoWedge.Hide(); - ModSelect.Hide(); - - this.FadeOut(100); - - FilterControl.Deactivate(); - - endLooping(); - - return false; } private bool isHandlingLooping; From cd8402df72f3945f0b0b56e55691e4117badb282 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 7 Nov 2022 12:11:44 +0900 Subject: [PATCH 0453/2991] Print event type to logs --- .../Notifications/WebSocket/WebSocketNotificationsClient.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index 71aec942ac..c5b11ea94a 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -69,13 +69,14 @@ namespace osu.Game.Online.Notifications.WebSocket break; } + Logger.Log($"{GetType().ReadableName()} handling event: {message.Event}"); await onMessageReceivedAsync(message); } break; case WebSocketMessageType.Binary: - throw new NotImplementedException(); + throw new NotImplementedException("Binary message type not supported."); case WebSocketMessageType.Close: throw new Exception("Connection closed by remote host."); From f931bdc5ff502518a29e7714507245c833b307cc Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 7 Nov 2022 12:25:23 +0900 Subject: [PATCH 0454/2991] Fix channel lookup not considering missing ids --- osu.Game/Online/Chat/ChannelManager.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index ee3194243b..ee6e22fbc1 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -420,7 +420,13 @@ namespace osu.Game.Online.Chat { Channel found = null; - bool lookupCondition(Channel ch) => lookup.Id > 0 ? ch.Id == lookup.Id : ch.Name == lookup.Name; + bool lookupCondition(Channel ch) + { + if (ch.Id > 0 && lookup.Id > 0) + return ch.Id == lookup.Id; + + return ch.Name == lookup.Name; + } var available = AvailableChannels.FirstOrDefault(lookupCondition); if (available != null) From 6085120dc527165241c672176cf98535d788be2a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 12:25:36 +0900 Subject: [PATCH 0455/2991] Fix incorrect handling of storyboard events with `end_time` before `start_time` --- osu.Game/Storyboards/CommandTimeline.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Storyboards/CommandTimeline.cs b/osu.Game/Storyboards/CommandTimeline.cs index d1a1edcd03..0650c97165 100644 --- a/osu.Game/Storyboards/CommandTimeline.cs +++ b/osu.Game/Storyboards/CommandTimeline.cs @@ -28,8 +28,7 @@ namespace osu.Game.Storyboards { if (endTime < startTime) { - (startTime, endTime) = (endTime, startTime); - (startValue, endValue) = (endValue, startValue); + endTime = startTime; } commands.Add(new TypedCommand { Easing = easing, StartTime = startTime, EndTime = endTime, StartValue = startValue, EndValue = endValue }); From b977fc8181372b2d999d354b0dac21f5b17f1410 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 6 Nov 2022 18:24:54 -0800 Subject: [PATCH 0456/2991] Use autosize instead of max width on fixed width timestamps --- osu.Game/Online/Chat/StandAloneChatDisplay.cs | 1 - osu.Game/Overlays/Chat/ChatLine.cs | 43 ++++++++----------- 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs index 76fcb80eb4..81db3f0d53 100644 --- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs +++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs @@ -191,7 +191,6 @@ namespace osu.Game.Online.Chat { protected override float TextSize => 15; protected override float Spacing => 5; - protected override float TimestampWidth => 45; protected override float UsernameWidth => 75; public StandAloneMessage(Message message) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index 4c425d3d4c..b7e3b183dc 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -48,8 +48,6 @@ namespace osu.Game.Overlays.Chat protected virtual float Spacing => 15; - protected virtual float TimestampWidth => 60; - protected virtual float UsernameWidth => 130; private Color4 usernameColour; @@ -93,38 +91,31 @@ namespace osu.Game.Overlays.Chat RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }, ColumnDimensions = new[] { - new Dimension(GridSizeMode.Absolute, TimestampWidth + Spacing + UsernameWidth + Spacing), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Absolute, Spacing + UsernameWidth + Spacing), new Dimension(), }, Content = new[] { new Drawable[] { - new Container + timestamp = new OsuSpriteText { - RelativeSizeAxes = Axes.X, + Shadow = false, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: TextSize * 0.75f, weight: FontWeight.SemiBold, fixedWidth: true), + Colour = colourProvider?.Background1 ?? Colour4.White, + AlwaysPresent = true, + }, + new MessageSender(message.Sender) + { + Width = UsernameWidth, AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - timestamp = new OsuSpriteText - { - Shadow = false, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: TextSize * 0.75f, weight: FontWeight.SemiBold, fixedWidth: true), - MaxWidth = TimestampWidth, - Colour = colourProvider?.Background1 ?? Colour4.White, - }, - new MessageSender(message.Sender) - { - Width = UsernameWidth, - AutoSizeAxes = Axes.Y, - Origin = Anchor.TopRight, - Anchor = Anchor.TopRight, - Child = createUsername(), - Margin = new MarginPadding { Horizontal = Spacing }, - }, - }, + Origin = Anchor.TopRight, + Anchor = Anchor.TopRight, + Child = createUsername(), + Margin = new MarginPadding { Horizontal = Spacing }, }, ContentFlow = new LinkFlowContainer(t => { From 61ec0ba56654e121dc018f1a0b0b2e0d64f56708 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 6 Nov 2022 18:32:13 -0800 Subject: [PATCH 0457/2991] Make chat line timestamp adjust to 24-hour time setting --- osu.Game/Overlays/Chat/ChatLine.cs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index b7e3b183dc..4db02db1bc 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -5,6 +5,7 @@ using System; using System.Linq; using System.Collections.Generic; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -12,6 +13,7 @@ using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; +using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; @@ -60,6 +62,8 @@ namespace osu.Game.Overlays.Chat private Container? highlight; + private readonly Bindable prefer24HourTime = new Bindable(); + private bool senderHasColour => !string.IsNullOrEmpty(message.Sender.Colour); private bool messageHasColour => Message.IsAction && senderHasColour; @@ -78,7 +82,7 @@ namespace osu.Game.Overlays.Chat } [BackgroundDependencyLoader] - private void load(OverlayColourProvider? colourProvider) + private void load(OverlayColourProvider? colourProvider, OsuConfigManager configManager) { usernameColour = senderHasColour ? Color4Extensions.FromHex(message.Sender.Colour) @@ -130,6 +134,8 @@ namespace osu.Game.Overlays.Chat }, } }; + + configManager.BindWith(OsuSetting.Prefer24HourTime, prefer24HourTime); } protected override void LoadComplete() @@ -138,6 +144,8 @@ namespace osu.Game.Overlays.Chat updateMessageContent(); FinishTransforms(true); + + prefer24HourTime.BindValueChanged(_ => updateTimestamp(), true); } /// @@ -167,7 +175,7 @@ namespace osu.Game.Overlays.Chat this.FadeTo(message is LocalEchoMessage ? 0.4f : 1.0f, 500, Easing.OutQuint); timestamp.FadeTo(message is LocalEchoMessage ? 0 : 1, 500, Easing.OutQuint); - timestamp.Text = $@"{message.Timestamp.LocalDateTime:HH:mm:ss}"; + updateTimestamp(); username.Text = $@"{message.Sender.Username}"; // remove non-existent channels from the link list @@ -177,6 +185,13 @@ namespace osu.Game.Overlays.Chat ContentFlow.AddLinks(message.DisplayContent, message.Links); } + private void updateTimestamp() + { + timestamp.Text = prefer24HourTime.Value + ? $@"{message.Timestamp.LocalDateTime:HH:mm:ss}" + : $@"{message.Timestamp.LocalDateTime:hh:mm:ss tt}"; + } + private Drawable createUsername() { username = new OsuSpriteText From 76df61504f6ce6656a9ae01497329333aba8f659 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 6 Nov 2022 19:45:59 -0800 Subject: [PATCH 0458/2991] Remove unnecessary timestamp update Co-authored-by: Dean Herbert --- osu.Game/Overlays/Chat/ChatLine.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index 4db02db1bc..a991103fac 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -145,7 +145,7 @@ namespace osu.Game.Overlays.Chat updateMessageContent(); FinishTransforms(true); - prefer24HourTime.BindValueChanged(_ => updateTimestamp(), true); + prefer24HourTime.BindValueChanged(_ => updateTimestamp()); } /// From f6d93fcd5a76f33ab8d18388fc73743cbed5a6c1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 12:54:02 +0900 Subject: [PATCH 0459/2991] Fix editor hard crash when beatmap file specified out-of-range timeline zoom value --- osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 3a93499527..8befda82e8 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -196,10 +196,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { defaultTimelineZoom = getZoomLevelForVisibleMilliseconds(6000); - float initialZoom = (float)(defaultTimelineZoom * (editorBeatmap.BeatmapInfo.TimelineZoom == 0 ? 1 : editorBeatmap.BeatmapInfo.TimelineZoom)); float minimumZoom = getZoomLevelForVisibleMilliseconds(10000); float maximumZoom = getZoomLevelForVisibleMilliseconds(500); + float initialZoom = (float)Math.Clamp(defaultTimelineZoom * (editorBeatmap.BeatmapInfo.TimelineZoom == 0 ? 1 : editorBeatmap.BeatmapInfo.TimelineZoom), minimumZoom, maximumZoom); + SetupZoom(initialZoom, minimumZoom, maximumZoom); float getZoomLevelForVisibleMilliseconds(double milliseconds) => Math.Max(1, (float)(editorClock.TrackLength / milliseconds)); From c69a4f9333016d3d20d64b7ed5889ecdeafe2734 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 14:18:43 +0900 Subject: [PATCH 0460/2991] Move major barline portion to default implementation to allow for further customisation Of note, this removes the "major" barline triangles from legacy skins. I think this is more correct, as they did not display in stable. --- .../Objects/Drawables/DrawableBarLine.cs | 89 ++---------------- .../Skinning/Default/DefaultBarLine.cs | 94 +++++++++++++++++++ .../Objects/Drawables/DrawableHitObject.cs | 2 +- 3 files changed, 104 insertions(+), 81 deletions(-) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Default/DefaultBarLine.cs diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs index e4806c4a12..5bfe64c73e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs @@ -1,17 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Objects; -using osuTK; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Taiko.Skinning.Default; using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko.Objects.Drawables @@ -28,35 +23,15 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables /// private const float tracker_width = 2f; - /// - /// The vertical offset of the triangles from the line tracker. - /// - private const float triangle_offset = 10f; - - /// - /// The size of the triangles. - /// - private const float triangle_size = 20f; - - /// - /// The visual line tracker. - /// - private SkinnableDrawable line; - - /// - /// Container with triangles. Only visible for major lines. - /// - private Container triangleContainer; - - private readonly Bindable major = new Bindable(); + public readonly Bindable Major = new Bindable(); public DrawableBarLine() : this(null) { } - public DrawableBarLine([CanBeNull] BarLine barLine) - : base(barLine) + public DrawableBarLine(BarLine? barLine) + : base(barLine!) { } @@ -69,69 +44,23 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables RelativeSizeAxes = Axes.Y; Width = tracker_width; - AddRangeInternal(new Drawable[] + AddInternal(new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.BarLine), _ => new DefaultBarLine()) { - line = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.BarLine), _ => new Box - { - RelativeSizeAxes = Axes.Both, - EdgeSmoothness = new Vector2(0.5f, 0), - }) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }, - triangleContainer = new Container - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Children = new[] - { - new EquilateralTriangle - { - Name = "Top", - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Position = new Vector2(0, -triangle_offset), - Size = new Vector2(-triangle_size), - EdgeSmoothness = new Vector2(1), - }, - new EquilateralTriangle - { - Name = "Bottom", - Anchor = Anchor.BottomCentre, - Origin = Anchor.TopCentre, - Position = new Vector2(0, triangle_offset), - Size = new Vector2(triangle_size), - EdgeSmoothness = new Vector2(1), - } - } - } + Anchor = Anchor.Centre, + Origin = Anchor.Centre, }); } - protected override void LoadComplete() - { - base.LoadComplete(); - major.BindValueChanged(updateMajor, true); - } - - private void updateMajor(ValueChangedEvent major) - { - line.Alpha = major.NewValue ? 1f : 0.75f; - triangleContainer.Alpha = major.NewValue ? 1 : 0; - } - protected override void OnApply() { base.OnApply(); - major.BindTo(HitObject.MajorBindable); + Major.BindTo(HitObject.MajorBindable); } protected override void OnFree() { base.OnFree(); - major.UnbindFrom(HitObject.MajorBindable); + Major.UnbindFrom(HitObject.MajorBindable); } protected override void UpdateHitStateTransforms(ArmedState state) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultBarLine.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultBarLine.cs new file mode 100644 index 0000000000..973e685bc7 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultBarLine.cs @@ -0,0 +1,94 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Taiko.Objects.Drawables; +using osuTK; + +namespace osu.Game.Rulesets.Taiko.Skinning.Default +{ + public class DefaultBarLine : CompositeDrawable + { + /// + /// The vertical offset of the triangles from the line tracker. + /// + private const float triangle_offset = 10f; + + /// + /// The size of the triangles. + /// + private const float triangle_size = 20f; + + /// + /// Container with triangles. Only visible for major lines. + /// + private Container triangleContainer = null!; + + private Bindable major = null!; + + [BackgroundDependencyLoader] + private void load(DrawableHitObject drawableHitObject) + { + RelativeSizeAxes = Axes.Both; + + InternalChildren = new Drawable[] + { + line = new Box + { + RelativeSizeAxes = Axes.Both, + EdgeSmoothness = new Vector2(0.5f, 0), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + triangleContainer = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Children = new[] + { + new EquilateralTriangle + { + Name = "Top", + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Position = new Vector2(0, -triangle_offset), + Size = new Vector2(-triangle_size), + EdgeSmoothness = new Vector2(1), + }, + new EquilateralTriangle + { + Name = "Bottom", + Anchor = Anchor.BottomCentre, + Origin = Anchor.TopCentre, + Position = new Vector2(0, triangle_offset), + Size = new Vector2(triangle_size), + EdgeSmoothness = new Vector2(1), + } + } + } + }; + + major = ((DrawableBarLine)drawableHitObject).Major.GetBoundCopy(); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + major.BindValueChanged(updateMajor, true); + } + + private Box line = null!; + + private void updateMajor(ValueChangedEvent major) + { + line.Alpha = major.NewValue ? 1f : 0.75f; + triangleContainer.Alpha = major.NewValue ? 1 : 0; + } + } +} diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index e5150576f2..5062cbc3e6 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -736,7 +736,7 @@ namespace osu.Game.Rulesets.Objects.Drawables { public new TObject HitObject => (TObject)base.HitObject; - protected DrawableHitObject(TObject hitObject) + protected DrawableHitObject([CanBeNull] TObject hitObject) : base(hitObject) { } From 67e99b53448c9311e9aa65543aa94aaf5db031eb Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 7 Nov 2022 14:34:53 +0900 Subject: [PATCH 0461/2991] Lookup channels before calling HandleJoinedChannel() --- osu.Game/Online/Chat/ChannelManager.cs | 18 +++++------- .../Notifications/NotificationsClient.cs | 9 +++--- .../WebSocket/WebSocketNotificationsClient.cs | 29 ++++++++++++++++--- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index ee6e22fbc1..076f79a700 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -86,17 +86,7 @@ namespace osu.Game.Online.Chat [BackgroundDependencyLoader] private void load() { - connector.ChannelJoined += ch => Schedule(() => - { - if (ch.Joined.Value) - JoinChannel(ch); - else - { - var req = new GetChannelRequest(ch.Id); - req.Success += response => JoinChannel(response.Channel); - api.Queue(req); - } - }); + connector.ChannelJoined += ch => Schedule(() => joinChannel(ch)); connector.ChannelParted += ch => Schedule(() => LeaveChannel(getChannel(ch))); @@ -446,6 +436,12 @@ namespace osu.Game.Online.Chat if (foundSelf != null) found.Users.Remove(foundSelf); } + else + { + found.Id = lookup.Id; + found.Name = lookup.Name; + found.LastMessageId = Math.Max(found.LastMessageId ?? 0, lookup.LastMessageId ?? 0); + } if (joined == null && addToJoined) joinedChannels.Add(found); if (available == null && addToAvailable) availableChannels.Add(found); diff --git a/osu.Game/Online/Notifications/NotificationsClient.cs b/osu.Game/Online/Notifications/NotificationsClient.cs index c706124351..e5f477bc1e 100644 --- a/osu.Game/Online/Notifications/NotificationsClient.cs +++ b/osu.Game/Online/Notifications/NotificationsClient.cs @@ -46,10 +46,7 @@ namespace osu.Game.Online.Notifications if (updates?.Presence != null) { foreach (var channel in updates.Presence) - { - channel.Joined.Value = true; HandleJoinedChannel(channel); - } //todo: handle left channels @@ -62,7 +59,11 @@ namespace osu.Game.Online.Notifications return fetchReq; } - protected void HandleJoinedChannel(Channel channel) => ChannelJoined?.Invoke(channel); + protected void HandleJoinedChannel(Channel channel) + { + channel.Joined.Value = true; + ChannelJoined?.Invoke(channel); + } protected void HandleChannelParted(Channel channel) => ChannelParted?.Invoke(channel); diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index c5b11ea94a..788847d368 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Concurrent; using System.Diagnostics; using System.Net.WebSockets; using System.Text; @@ -11,6 +12,7 @@ using Newtonsoft.Json; using osu.Framework.Extensions.TypeExtensions; using osu.Framework.Logging; using osu.Game.Online.API; +using osu.Game.Online.API.Requests; using osu.Game.Online.Chat; namespace osu.Game.Online.Notifications.WebSocket @@ -22,6 +24,7 @@ namespace osu.Game.Online.Notifications.WebSocket { private readonly ClientWebSocket socket; private readonly string endpoint; + private readonly ConcurrentDictionary channelsMap = new ConcurrentDictionary(); public WebSocketNotificationsClient(ClientWebSocket socket, string endpoint, IAPIProvider api) : base(api) @@ -110,7 +113,7 @@ namespace osu.Game.Online.Notifications.WebSocket await socket.SendAsync(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message)), WebSocketMessageType.Text, true, cancellationToken); } - private Task onMessageReceivedAsync(SocketMessage message) + private async Task onMessageReceivedAsync(SocketMessage message) { switch (message.Event) { @@ -120,7 +123,6 @@ namespace osu.Game.Online.Notifications.WebSocket Channel? joinedChannel = JsonConvert.DeserializeObject(message.Data.ToString()); Debug.Assert(joinedChannel != null); - joinedChannel.Joined.Value = true; HandleJoinedChannel(joinedChannel); break; @@ -140,13 +142,32 @@ namespace osu.Game.Online.Notifications.WebSocket Debug.Assert(messageData != null); foreach (var msg in messageData.Messages) - HandleJoinedChannel(new Channel { Id = msg.ChannelId }); + HandleJoinedChannel(await getChannel(msg.ChannelId)); HandleMessages(messageData.Messages); break; } + } - return Task.CompletedTask; + private async Task getChannel(long channelId) + { + if (channelsMap.TryGetValue(channelId, out Channel channel)) + return channel; + + var tsc = new TaskCompletionSource(); + var req = new GetChannelRequest(channelId); + + req.Success += response => + { + channelsMap[channelId] = response.Channel; + tsc.SetResult(response.Channel); + }; + + req.Failure += ex => tsc.SetException(ex); + + API.Queue(req); + + return await tsc.Task; } public override async ValueTask DisposeAsync() From fdca3c2d1c5e6d122e297bd4204b2115f081eb13 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 7 Nov 2022 14:35:42 +0900 Subject: [PATCH 0462/2991] Rename method for consistency --- osu.Game/Online/Notifications/NotificationsClient.cs | 4 ++-- .../Notifications/WebSocket/WebSocketNotificationsClient.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/Notifications/NotificationsClient.cs b/osu.Game/Online/Notifications/NotificationsClient.cs index e5f477bc1e..6198707111 100644 --- a/osu.Game/Online/Notifications/NotificationsClient.cs +++ b/osu.Game/Online/Notifications/NotificationsClient.cs @@ -46,7 +46,7 @@ namespace osu.Game.Online.Notifications if (updates?.Presence != null) { foreach (var channel in updates.Presence) - HandleJoinedChannel(channel); + HandleChannelJoined(channel); //todo: handle left channels @@ -59,7 +59,7 @@ namespace osu.Game.Online.Notifications return fetchReq; } - protected void HandleJoinedChannel(Channel channel) + protected void HandleChannelJoined(Channel channel) { channel.Joined.Value = true; ChannelJoined?.Invoke(channel); diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index 788847d368..86836099d8 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -123,7 +123,7 @@ namespace osu.Game.Online.Notifications.WebSocket Channel? joinedChannel = JsonConvert.DeserializeObject(message.Data.ToString()); Debug.Assert(joinedChannel != null); - HandleJoinedChannel(joinedChannel); + HandleChannelJoined(joinedChannel); break; case @"chat.channel.part": @@ -142,7 +142,7 @@ namespace osu.Game.Online.Notifications.WebSocket Debug.Assert(messageData != null); foreach (var msg in messageData.Messages) - HandleJoinedChannel(await getChannel(msg.ChannelId)); + HandleChannelJoined(await getChannel(msg.ChannelId)); HandleMessages(messageData.Messages); break; From 1975385cc74e0a9a595cb1d31af2319281aa7ee9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 15:21:58 +0900 Subject: [PATCH 0463/2991] Move first tick tracking logic inside `TickPiece` --- .../Objects/Drawables/DrawableDrumRollTick.cs | 16 +++++++--- .../Skinning/Default/TickPiece.cs | 32 ++++++++++++------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 451c5a793b..95b6384274 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -5,6 +5,7 @@ using System; using JetBrains.Annotations; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Input.Events; using osu.Game.Rulesets.Objects; @@ -16,6 +17,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { public class DrawableDrumRollTick : DrawableTaikoStrongableHitObject { + public BindableBool IsFirstTick = new BindableBool(); + /// /// The hit type corresponding to the that the user pressed to hit this . /// @@ -32,14 +35,17 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables FillMode = FillMode.Fit; } - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.DrumRollTick), - _ => new TickPiece - { - Filled = HitObject.FirstTick - }); + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.DrumRollTick), _ => new TickPiece()); public override double MaximumJudgementOffset => HitObject.HitWindow; + protected override void OnApply() + { + base.OnApply(); + + IsFirstTick.Value = HitObject.FirstTick; + } + protected override void CheckForResult(bool userTriggered, double timeOffset) { if (!userTriggered) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs index 09c8243aac..a1eaef53ba 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs @@ -1,9 +1,13 @@ // 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.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Taiko.Objects.Drawables; using osuTK; using osuTK.Graphics; @@ -22,20 +26,10 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default /// private const float tick_size = 0.35f; - private bool filled; - - public bool Filled - { - get => filled; - set - { - filled = value; - fillBox.Alpha = filled ? 1 : 0; - } - } - private readonly Box fillBox; + private Bindable isFirstTick = null!; + public TickPiece() { Anchor = Anchor.Centre; @@ -62,5 +56,19 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default } }; } + + [Resolved] + private DrawableHitObject drawableHitObject { get; set; } = null!; + + protected override void LoadComplete() + { + base.LoadComplete(); + + if (drawableHitObject is DrawableDrumRollTick drumRollTick) + { + isFirstTick = drumRollTick.IsFirstTick.GetBoundCopy(); + isFirstTick.BindValueChanged(first => fillBox.Alpha = first.NewValue ? 1 : 0, true); + } + } } } From 28ab092b6f1d278f406e4e25cc812ac8184f3a74 Mon Sep 17 00:00:00 2001 From: C0D3 M4513R <28912031+C0D3-M4513R@users.noreply.github.com> Date: Mon, 7 Nov 2022 07:55:42 +0100 Subject: [PATCH 0464/2991] Simplify the whole Templating process --- .../Components/BeatmapInfoDrawable.cs | 125 +++--------------- 1 file changed, 17 insertions(+), 108 deletions(-) diff --git a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs index 479124a43d..eda956e6d8 100644 --- a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs +++ b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs @@ -27,29 +27,11 @@ namespace osu.Game.Skinning.Components private const BeatmapInfo default_beatmap_info = BeatmapInfo.StarRating; public bool UsesFixedAnchor { get; set; } - [SettingSource("Tracked Beatmap Info/Label", "Which part of the BeatmapInformation should be displayed. Gets overridden by complex changes to ValueFormat")] + [SettingSource("Tracked Beatmap Info/Label", "Which part of the BeatmapInformation should be displayed.")] public Bindable Type { get; } = new Bindable(default_beatmap_info); - [SettingSource("Show Label", "Should a Label be shown, as to which status is currently Displayed?")] - public BindableBool ShowLabel { get; } = new BindableBool(true); - - [SettingSource("Show Value first?", "Should the Value be shown first?")] - public BindableBool ValueBeforeLabel { get; } = new BindableBool(); - - [SettingSource("Label Prefix", "Add something to be shown before the label")] - public Bindable LabelPrefix { get; set; } = new Bindable(""); - - [SettingSource("Show Label Prefix", "Should the Label Prefix be included?")] - public BindableBool ShowLabelPrefix { get; } = new BindableBool(); - - [SettingSource("Label Suffix", "Add something to be shown after the label")] - public Bindable LabelSuffix { get; set; } = new Bindable(": "); - - [SettingSource("Show Label Suffix", "Should the Label Suffix be included?")] - public BindableBool ShowLabelSuffix { get; } = new BindableBool(true); - - [SettingSource("Value Formatting", "Bypass the restriction of 1 Info per element. Format is '{'+Type+'}' to substitue values. e.g. '{Song}' ")] - public Bindable ValueFormat { get; set; } = new Bindable("{" + default_beatmap_info + "}"); + [SettingSource("Template", "Bypass the restriction of 1 Info per element. Format is '{'+Type+'}' to substitue values. e.g. '{Song}' ")] + public Bindable Template { get; set; } = new Bindable("{Label}: {Value}"); [Resolved] private IBindable beatmap { get; set; } = null!; @@ -76,7 +58,7 @@ namespace osu.Game.Skinning.Components [BeatmapInfo.Length] = ArtistStrings.TracklistLength, [BeatmapInfo.Status] = BeatmapDiscussionsStrings.IndexFormBeatmapsetStatusDefault, [BeatmapInfo.BPM] = BeatmapsetsStrings.ShowStatsBpm, - [BeatmapInfo.Custom] = BeatmapInfo.Custom.ToString() + [BeatmapInfo.None] = BeatmapInfo.None.ToString() }.ToImmutableDictionary(); } @@ -99,102 +81,29 @@ namespace osu.Game.Skinning.Components } } - /// - /// This will return the if the format-String contains of a singular replacement of type info, or not. - /// If there is only one one replacement of type info, it will also return the prefix/suffix (or null if no prefix/suffix exists). - /// - /// The format-String to work on - /// The replacement Type to look for - /// (true, prefix, suffix), if there is only one replacement of type info. Else (false, null, null) - private static (bool, string?, string?) isOnlyPrefixedOrSuffixed(string format, BeatmapInfo info) - { - string[] s = format.Split("{" + info + "}"); - - foreach (string si in s) - { - foreach (var type in Enum.GetValues(typeof(BeatmapInfo)).Cast()) - { - if (si.Contains("{" + type + "}")) return (false, null, null); - } - } - - //Debug.WriteLine($"format:'{format}', type:{info} is only prefixed/suffixed"); - - return (true, - s.Length >= 1 ? s[0] : null, //prefix - s.Length >= 2 ? s[1] : null //suffix - ); - } - protected override void LoadComplete() { base.LoadComplete(); - Type.BindValueChanged(v => - { - string newDefault = "{" + v.NewValue + "}"; - bool custom = v.NewValue == BeatmapInfo.Custom; - - //If the ValueFormat is Default and the user did not change anything we should be able to just swap the strings. - //If it was Default before, it should be default after the Type is changed. - if (ValueFormat.IsDefault && !custom) - ValueFormat.Value = newDefault; - else - { - //In this if statement we decide if the ValueFormat has been trivially changed (so only been prefixed or suffixed) - (bool preOrSuffixed, string? prefix, string? suffix) = isOnlyPrefixedOrSuffixed(ValueFormat.Value, v.OldValue); - if (preOrSuffixed) - //If it has, we can keep the prefix and suffix and just change the thing that would be substituted. - ValueFormat.Value = (prefix ?? "") + newDefault + (suffix ?? ""); - //else we just keep the ValueFormat. I determine here, that the user probably knows what they are doing, and how the ValueFormat works. - } - - //Only if we could preserve the ValueFormat (so nothing was changed except a static prefix/suffix) I want to set the new Default. - ValueFormat.Default = newDefault; - updateLabel(); - }); - ValueFormat.BindValueChanged(f => updateLabel(), true); + Type.BindValueChanged(_ => updateLabel()); + Template.BindValueChanged(f => updateLabel(), true); beatmap.BindValueChanged(b => { UpdateBeatmapContent(b.NewValue); updateLabel(); }, true); - ShowLabel.BindValueChanged(_ => updateLabel()); - ValueBeforeLabel.BindValueChanged(_ => updateLabel()); - LabelPrefix.BindValueChanged(_ => updateLabel()); - ShowLabelPrefix.BindValueChanged(_ => updateLabel()); - LabelSuffix.BindValueChanged(_ => updateLabel()); - ShowLabelSuffix.BindValueChanged(_ => updateLabel()); - } - - private LocalisableString getLabelText() - { - if (!ShowLabel.Value) return new LocalisableString(""); - - return LocalisableString.Format("{0}{1}{2}", - ShowLabelPrefix.Value ? LabelPrefix.Value : "", - label_dictionary[Type.Value], - ShowLabelSuffix.Value ? LabelSuffix.Value : ""); - } - - private LocalisableString getValueText() - { - string value = ValueFormat.Value; - - foreach (var type in Enum.GetValues(typeof(BeatmapInfo)).Cast()) - { - value = value.Replace("{" + type + "}", valueDictionary[type].ToString()); - } - - return value; } private void updateLabel() { - text.Text = LocalisableString.Format( - ValueBeforeLabel.Value ? "{1}{0}" : "{0}{1}", - getLabelText(), - getValueText() - ); + string newText = Template.Value.Replace("{Label}", label_dictionary[Type.Value].ToString()) + .Replace("{Value}", valueDictionary[Type.Value].ToString()); + + foreach (var type in Enum.GetValues(typeof(BeatmapInfo)).Cast()) + { + newText = newText.Replace("{" + type + "}", valueDictionary[type].ToString()); + } + + text.Text = newText; Width = text.Width; Height = text.Height; } @@ -230,7 +139,7 @@ namespace osu.Game.Skinning.Components valueDictionary[BeatmapInfo.Status] = GetBetmapStatus(workingBeatmap.BeatmapInfo.Status); //update BPM valueDictionary[BeatmapInfo.BPM] = workingBeatmap.BeatmapInfo.BPM.ToString("F2"); - valueDictionary[BeatmapInfo.Custom] = BeatmapInfo.Custom.ToString(); + valueDictionary[BeatmapInfo.None] = string.Empty; } public static LocalisableString GetBetmapStatus(BeatmapOnlineStatus status) @@ -284,6 +193,6 @@ namespace osu.Game.Skinning.Components Length, Status, BPM, - Custom, + None, } } From 8745c2f0163760942e573ddae4c940c20c2b67aa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 16:31:06 +0900 Subject: [PATCH 0465/2991] Split out taiko `DefaultJudgementPiece` and move animations across --- .../Skinning/Default/DefaultJudgementPiece.cs | 32 +++++++++++++++++++ .../UI/DrawableTaikoJudgement.cs | 28 ++-------------- 2 files changed, 34 insertions(+), 26 deletions(-) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs new file mode 100644 index 0000000000..a8cead6877 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs @@ -0,0 +1,32 @@ +// 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.Graphics; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Taiko.Skinning.Default +{ + public class DefaultJudgementPiece : Rulesets.Judgements.DefaultJudgementPiece + { + public DefaultJudgementPiece(HitResult result) + : base(result) + { + } + + public override void PlayAnimation() + { + if (Result != HitResult.Miss) + { + this + .MoveToY(0) + .MoveToY(-100, 500); + + JudgementText + .ScaleTo(0.9f) + .ScaleTo(1, 500, Easing.OutElastic); + } + + base.PlayAnimation(); + } + } +} diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs index 876fa207bf..dcb7dc25c0 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs @@ -4,6 +4,7 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; +using DefaultJudgementPiece = osu.Game.Rulesets.Taiko.Skinning.Default.DefaultJudgementPiece; namespace osu.Game.Rulesets.Taiko.UI { @@ -12,31 +13,6 @@ namespace osu.Game.Rulesets.Taiko.UI /// public class DrawableTaikoJudgement : DrawableJudgement { - protected override void ApplyHitAnimations() - { - this.MoveToY(-100, 500); - base.ApplyHitAnimations(); - } - - protected override Drawable CreateDefaultJudgement(HitResult result) => new TaikoJudgementPiece(result); - - private class TaikoJudgementPiece : DefaultJudgementPiece - { - public TaikoJudgementPiece(HitResult result) - : base(result) - { - } - - public override void PlayAnimation() - { - if (Result != HitResult.Miss) - { - JudgementText.ScaleTo(0.9f); - JudgementText.ScaleTo(1, 500, Easing.OutElastic); - } - - base.PlayAnimation(); - } - } + protected override Drawable CreateDefaultJudgement(HitResult result) => new DefaultJudgementPiece(result); } } From 2b72c3833be2c8e8abc1c7dc6222914f7bea00b7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 17:05:16 +0900 Subject: [PATCH 0466/2991] Remove unnecessary centering logic in `DrawableJudgement` --- osu.Game/Rulesets/Judgements/DrawableJudgement.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs index 7e1196d4ca..daf7aafd77 100644 --- a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs +++ b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs @@ -168,11 +168,7 @@ namespace osu.Game.Rulesets.Judgements RemoveInternal(JudgementBody, true); AddInternal(JudgementBody = new SkinnableDrawable(new GameplaySkinComponent(type), _ => - CreateDefaultJudgement(type), confineMode: ConfineMode.NoScaling) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }); + CreateDefaultJudgement(type), confineMode: ConfineMode.NoScaling)); JudgementBody.OnSkinChanged += () => { From 564d0785171a4bc45398896216330506f32b2706 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 17:12:58 +0900 Subject: [PATCH 0467/2991] Fix much brokenness with kiai and justment sizing --- .../Skinning/Default/DefaultJudgementPiece.cs | 11 +++++++---- .../UI/DrawableTaikoJudgement.cs | 10 ++++++++++ osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs | 2 +- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 15 +++++---------- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs index a8cead6877..c85a8db788 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs @@ -11,6 +11,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default public DefaultJudgementPiece(HitResult result) : base(result) { + RelativePositionAxes = Axes.Both; } public override void PlayAnimation() @@ -18,15 +19,17 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default if (Result != HitResult.Miss) { this - .MoveToY(0) - .MoveToY(-100, 500); + .MoveToY(-0.6f) + .MoveToY(-1.5f, 500); JudgementText .ScaleTo(0.9f) .ScaleTo(1, 500, Easing.OutElastic); - } - base.PlayAnimation(); + this.FadeOutFromOne(800, Easing.OutQuint); + } + else + base.PlayAnimation(); } } } diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs index dcb7dc25c0..24d2fd7be7 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs @@ -4,6 +4,7 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; +using osuTK; using DefaultJudgementPiece = osu.Game.Rulesets.Taiko.Skinning.Default.DefaultJudgementPiece; namespace osu.Game.Rulesets.Taiko.UI @@ -13,6 +14,15 @@ namespace osu.Game.Rulesets.Taiko.UI /// public class DrawableTaikoJudgement : DrawableJudgement { + public DrawableTaikoJudgement() + { + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + RelativeSizeAxes = Axes.Both; + Size = Vector2.One; + } + protected override Drawable CreateDefaultJudgement(HitResult result) => new DefaultJudgementPiece(result); } } diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs index c4cff00d2a..faf107de77 100644 --- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Taiko.UI JudgedObject = judgedObject; this.hitType = hitType; - Anchor = Anchor.CentreLeft; + Anchor = Anchor.Centre; Origin = Anchor.Centre; RelativeSizeAxes = Axes.Both; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index cc71ba5401..d6d4a4e3f0 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -146,13 +146,16 @@ namespace osu.Game.Rulesets.Taiko.UI kiaiExplosionContainer = new Container { Name = "Kiai hit explosions", + Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fit, }, judgementContainer = new JudgementContainer { Name = "Judgements", - RelativeSizeAxes = Axes.Y, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fit, }, } }, @@ -320,15 +323,7 @@ namespace osu.Game.Rulesets.Taiko.UI if (!result.Type.IsScorable()) break; - judgementContainer.Add(judgementPools[result.Type].Get(j => - { - j.Apply(result, judgedObject); - - j.Anchor = result.IsHit ? Anchor.TopLeft : Anchor.CentreLeft; - j.Origin = result.IsHit ? Anchor.BottomCentre : Anchor.Centre; - j.RelativePositionAxes = Axes.X; - j.X = result.IsHit ? judgedObject.Position.X : 0; - })); + judgementContainer.Add(judgementPools[result.Type].Get(j => j.Apply(result, judgedObject))); var type = (judgedObject.HitObject as Hit)?.Type ?? HitType.Centre; addExplosion(judgedObject, result.Type, type); From ddc2ed1542a254c619692595ac1ef7330523dc40 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 13:22:01 +0900 Subject: [PATCH 0468/2991] Fix height of playfield in taiko tests --- .../Skinning/TestSceneDrawableBarLine.cs | 6 ++--- .../Skinning/TestSceneTaikoPlayfield.cs | 24 +++++++++++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableBarLine.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableBarLine.cs index ad6f08dbd4..a4aa0e1fad 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableBarLine.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning var cont = new Container { RelativeSizeAxes = Axes.Both, - Height = 0.8f, + Height = 0.2f, Anchor = Anchor.Centre, Origin = Anchor.Centre, Children = new Drawable[] @@ -63,7 +63,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning var cont = new Container { RelativeSizeAxes = Axes.Both, - Height = 0.8f, + Height = 0.2f, Anchor = Anchor.Centre, Origin = Anchor.Centre, Children = new Drawable[] @@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning var barLine = new BarLine { Major = major, - StartTime = Time.Current + 2000, + StartTime = Time.Current + 5000, }; var cpi = new ControlPointInfo(); diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs index 52d24b567f..eff9f58751 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs @@ -4,6 +4,7 @@ #nullable disable using System; +using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; @@ -25,11 +26,10 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning TimeRange = { Value = 5000 }, }; - public TestSceneTaikoPlayfield() + [SetUpSteps] + public void SetUpSteps() { TaikoBeatmap beatmap; - bool kiai = false; - AddStep("set beatmap", () => { Beatmap.Value = CreateWorkingBeatmap(beatmap = new TaikoBeatmap()); @@ -41,12 +41,28 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning AddStep("Load playfield", () => SetContents(_ => new TaikoPlayfield { + Height = 0.2f, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Height = 0.6f, })); + } + [Test] + public void TestBasic() + { + AddStep("do nothing", () => { }); + } + + [Test] + public void TestHeightChanges() + { AddRepeatStep("change height", () => this.ChildrenOfType().ForEach(p => p.Height = Math.Max(0.2f, (p.Height + 0.2f) % 1f)), 50); + } + + [Test] + public void TestKiai() + { + bool kiai = false; AddStep("Toggle kiai", () => { From baf8db8de4ae9a2b26d9401b02b66463ffd39cae Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 15:45:32 +0900 Subject: [PATCH 0469/2991] Add basic setup for taiko argon skinning --- .../Argon/TaikoArgonSkinTransformer.cs | 34 +++++++++++++++++++ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 4 +++ 2 files changed, 38 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs new file mode 100644 index 0000000000..13c484af24 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -0,0 +1,34 @@ +// 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.Graphics; +using osu.Game.Skinning; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class TaikoArgonSkinTransformer : SkinTransformer + { + public TaikoArgonSkinTransformer(ISkin skin) + : base(skin) + { + } + + public override Drawable? GetDrawableComponent(ISkinComponent component) + { + switch (component) + { + case TaikoSkinComponent catchComponent: + // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. + switch (catchComponent.Component) + { + case TaikoSkinComponents.CentreHit: + return Drawable.Empty(); + } + + break; + } + + return base.GetDrawableComponent(component); + } + } +} diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index dc36bc0320..fe12cf9765 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -24,6 +24,7 @@ using osu.Game.Rulesets.Taiko.Mods; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Replays; using osu.Game.Rulesets.Taiko.Scoring; +using osu.Game.Rulesets.Taiko.Skinning.Argon; using osu.Game.Rulesets.Taiko.Skinning.Legacy; using osu.Game.Rulesets.Taiko.UI; using osu.Game.Rulesets.UI; @@ -47,6 +48,9 @@ namespace osu.Game.Rulesets.Taiko { switch (skin) { + case ArgonSkin: + return new TaikoArgonSkinTransformer(skin); + case LegacySkin: return new TaikoLegacySkinTransformer(skin); } From bc0e9375afcc54b108246f6bb60e2b3e50425b82 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 16:52:09 +0900 Subject: [PATCH 0470/2991] Add basic argon hits --- .../Skinning/Argon/ArgonCentreCirclePiece.cs | 21 ++++ .../Skinning/Argon/ArgonCirclePiece.cs | 116 ++++++++++++++++++ .../Skinning/Argon/ArgonRimCirclePiece.cs | 21 ++++ .../Skinning/Argon/RingPiece.cs | 40 ++++++ .../Argon/TaikoArgonSkinTransformer.cs | 5 +- 5 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs new file mode 100644 index 0000000000..234d9f659a --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs @@ -0,0 +1,21 @@ +// 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.Allocation; +using osu.Framework.Graphics.Colour; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonCentreCirclePiece : ArgonCirclePiece + { + [BackgroundDependencyLoader] + private void load() + { + AccentColour = ColourInfo.GradientVertical( + new Color4(241, 0, 0, 255), + new Color4(167, 0, 0, 255) + ); + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs new file mode 100644 index 0000000000..b58b7455fd --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs @@ -0,0 +1,116 @@ +// 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.Allocation; +using osu.Framework.Audio.Track; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Graphics.Containers; +using osu.Game.Rulesets.Objects.Drawables; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public abstract class ArgonCirclePiece : BeatSyncedContainer + { + private const double pre_beat_transition_time = 80; + + private const float flash_opacity = 0.3f; + + private ColourInfo accentColour; + + /// + /// The colour of the inner circle and outer glows. + /// + public ColourInfo AccentColour + { + get => accentColour; + set + { + accentColour = value; + ring.Colour = AccentColour.MultiplyAlpha(0.5f); + ring2.Colour = AccentColour; + } + } + + /// + /// Whether Kiai mode effects are enabled for this circle piece. + /// + public bool KiaiMode { get; set; } + + public Box FlashBox; + + private readonly RingPiece ring; + private readonly RingPiece ring2; + + protected ArgonCirclePiece() + { + RelativeSizeAxes = Axes.Both; + + EarlyActivationMilliseconds = pre_beat_transition_time; + + AddRangeInternal(new Drawable[] + { + new Circle + { + RelativeSizeAxes = Axes.Both, + Colour = new Color4(0, 22, 30, 190) + }, + ring = new RingPiece(20 / 70f), + ring2 = new RingPiece(5 / 70f), + new CircularContainer + { + Name = "Flash layer", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Masking = true, + Children = new[] + { + FlashBox = new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + Blending = BlendingParameters.Additive, + Alpha = 0, + AlwaysPresent = true + } + }, + }, + new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Icon = FontAwesome.Solid.AngleLeft, + Size = new Vector2(20 / 70f), + Scale = new Vector2(0.8f, 1) + } + }); + } + + [Resolved] + private DrawableHitObject drawableHitObject { get; set; } = null!; + + protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) + { + if (!effectPoint.KiaiMode) + return; + + if (drawableHitObject.State.Value == ArmedState.Idle) + { + FlashBox + .FadeTo(flash_opacity) + .Then() + .FadeOut(timingPoint.BeatLength * 0.75, Easing.OutSine); + } + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs new file mode 100644 index 0000000000..5dc955c56e --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs @@ -0,0 +1,21 @@ +// 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.Allocation; +using osu.Framework.Graphics.Colour; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonRimCirclePiece : ArgonCirclePiece + { + [BackgroundDependencyLoader] + private void load() + { + AccentColour = ColourInfo.GradientVertical( + new Color4(0, 161, 241, 255), + new Color4(0, 111, 167, 255) + ); + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs new file mode 100644 index 0000000000..2c5d824ff5 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs @@ -0,0 +1,40 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class RingPiece : CircularContainer + { + private readonly float relativeBorderThickness; + + public RingPiece(float relativeBorderThickness) + { + this.relativeBorderThickness = relativeBorderThickness; + RelativeSizeAxes = Axes.Both; + + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + Masking = true; + BorderColour = Color4.White; + + Child = new Box + { + AlwaysPresent = true, + Alpha = 0, + RelativeSizeAxes = Axes.Both + }; + } + + protected override void Update() + { + base.Update(); + BorderThickness = relativeBorderThickness * DrawSize.X; + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index 13c484af24..f223d35b0a 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -22,7 +22,10 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon switch (catchComponent.Component) { case TaikoSkinComponents.CentreHit: - return Drawable.Empty(); + return new ArgonCentreCirclePiece(); + + case TaikoSkinComponents.RimHit: + return new ArgonRimCirclePiece(); } break; From 421bdd2c1a3736c0583150deb5c585f8d64771a6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 13:16:51 +0900 Subject: [PATCH 0471/2991] Add playfield background implementations --- .../Argon/ArgonPlayfieldBackgroundLeft.cs | 27 ++++++++++++++++++ .../Argon/ArgonPlayfieldBackgroundRight.cs | 28 +++++++++++++++++++ .../Argon/TaikoArgonSkinTransformer.cs | 6 ++++ 3 files changed, 61 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundLeft.cs create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundRight.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundLeft.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundLeft.cs new file mode 100644 index 0000000000..ebde83b607 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundLeft.cs @@ -0,0 +1,27 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonPlayfieldBackgroundLeft : CompositeDrawable + { + public ArgonPlayfieldBackgroundLeft() + { + RelativeSizeAxes = Axes.Both; + + InternalChildren = new Drawable[] + { + new Box + { + Colour = Color4.Black, + RelativeSizeAxes = Axes.Both, + }, + }; + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundRight.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundRight.cs new file mode 100644 index 0000000000..bd0f3ab276 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundRight.cs @@ -0,0 +1,28 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonPlayfieldBackgroundRight : CompositeDrawable + { + public ArgonPlayfieldBackgroundRight() + { + RelativeSizeAxes = Axes.Both; + + InternalChildren = new Drawable[] + { + new Box + { + Colour = Color4.Black, + Alpha = 0.7f, + RelativeSizeAxes = Axes.Both, + }, + }; + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index f223d35b0a..d2a3e19f38 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -26,6 +26,12 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case TaikoSkinComponents.RimHit: return new ArgonRimCirclePiece(); + + case TaikoSkinComponents.PlayfieldBackgroundLeft: + return new ArgonPlayfieldBackgroundLeft(); + + case TaikoSkinComponents.PlayfieldBackgroundRight: + return new ArgonPlayfieldBackgroundRight(); } break; From f1a1f29da78de9d49de56b9fda3728ccd84453b1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 13:43:04 +0900 Subject: [PATCH 0472/2991] Add hit target implementation --- .../Skinning/Argon/ArgonHitTarget.cs | 72 +++++++++++++++++++ .../Argon/TaikoArgonSkinTransformer.cs | 3 + 2 files changed, 75 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitTarget.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitTarget.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitTarget.cs new file mode 100644 index 0000000000..ec2eccd595 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitTarget.cs @@ -0,0 +1,72 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Taiko.Objects; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonHitTarget : CompositeDrawable + { + /// + /// Thickness of all drawn line pieces. + /// + public ArgonHitTarget() + { + RelativeSizeAxes = Axes.Both; + Masking = true; + + const float border_thickness = 4f; + + InternalChildren = new Drawable[] + { + new Circle + { + Name = "Bar Upper", + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Y = -border_thickness, + RelativeSizeAxes = Axes.Y, + Size = new Vector2(border_thickness, (1 - TaikoStrongableHitObject.DEFAULT_STRONG_SIZE)), + }, + new Circle + { + Name = "Outer circle", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + Blending = BlendingParameters.Additive, + Alpha = 0.1f, + Size = new Vector2(TaikoHitObject.DEFAULT_SIZE), + Masking = true, + }, + new Circle + { + Name = "Inner circle", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + Blending = BlendingParameters.Additive, + Alpha = 0.1f, + Size = new Vector2(TaikoHitObject.DEFAULT_SIZE * 0.85f), + Masking = true, + }, + new Circle + { + Name = "Bar Lower", + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.Y, + Y = border_thickness, + Size = new Vector2(border_thickness, (1 - TaikoStrongableHitObject.DEFAULT_STRONG_SIZE)), + }, + }; + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index d2a3e19f38..eec7e92511 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -32,6 +32,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case TaikoSkinComponents.PlayfieldBackgroundRight: return new ArgonPlayfieldBackgroundRight(); + + case TaikoSkinComponents.HitTarget: + return new ArgonHitTarget(); } break; From 529e3217cfea2571d4f405836a592a988fb16a3e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 14:01:18 +0900 Subject: [PATCH 0473/2991] Add barline implementation --- .../Skinning/Argon/ArgonBarLine.cs | 83 +++++++++++++++++++ .../Argon/TaikoArgonSkinTransformer.cs | 3 + 2 files changed, 86 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonBarLine.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonBarLine.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonBarLine.cs new file mode 100644 index 0000000000..402e88b64d --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonBarLine.cs @@ -0,0 +1,83 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Taiko.Objects.Drawables; +using osuTK; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonBarLine : CompositeDrawable + { + private Container majorEdgeContainer = null!; + + private Bindable major = null!; + + [BackgroundDependencyLoader] + private void load(DrawableHitObject drawableHitObject) + { + RelativeSizeAxes = Axes.Both; + + const float line_offset = 8; + var majorPieceSize = new Vector2(6, 20); + + InternalChildren = new Drawable[] + { + line = new Box + { + RelativeSizeAxes = Axes.Both, + EdgeSmoothness = new Vector2(0.5f, 0), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + majorEdgeContainer = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Children = new[] + { + new Circle + { + Name = "Top line", + Anchor = Anchor.TopCentre, + Origin = Anchor.BottomCentre, + Size = majorPieceSize, + Y = -line_offset, + }, + new Circle + { + Name = "Bottom line", + Anchor = Anchor.BottomCentre, + Origin = Anchor.TopCentre, + Size = majorPieceSize, + Y = line_offset, + }, + } + } + }; + + major = ((DrawableBarLine)drawableHitObject).Major.GetBoundCopy(); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + major.BindValueChanged(updateMajor, true); + } + + private Box line = null!; + + private void updateMajor(ValueChangedEvent major) + { + line.Alpha = major.NewValue ? 1f : 0.5f; + line.Width = major.NewValue ? 1 : 0.5f; + majorEdgeContainer.Alpha = major.NewValue ? 1 : 0; + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index eec7e92511..0d5c19a525 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -35,6 +35,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case TaikoSkinComponents.HitTarget: return new ArgonHitTarget(); + + case TaikoSkinComponents.BarLine: + return new ArgonBarLine(); } break; From 66365451952639040590a7d328ce4bb8ea9853a2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 15:07:33 +0900 Subject: [PATCH 0474/2991] Move taiko argon hit icon to respective centre/rim pieces --- .../Skinning/Argon/ArgonCentreCirclePiece.cs | 13 +++++++++++++ .../Skinning/Argon/ArgonCirclePiece.cs | 11 ----------- .../Skinning/Argon/ArgonRimCirclePiece.cs | 13 +++++++++++++ 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs index 234d9f659a..f347863be9 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs @@ -2,7 +2,10 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Sprites; +using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon @@ -16,6 +19,16 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon new Color4(241, 0, 0, 255), new Color4(167, 0, 0, 255) ); + + AddInternal(new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Icon = FontAwesome.Solid.AngleLeft, + Size = new Vector2(20 / 70f), + Scale = new Vector2(0.8f, 1) + }); } } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs index b58b7455fd..ba8ef12902 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs @@ -7,11 +7,9 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; -using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon @@ -84,15 +82,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon } }, }, - new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Icon = FontAwesome.Solid.AngleLeft, - Size = new Vector2(20 / 70f), - Scale = new Vector2(0.8f, 1) - } }); } diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs index 5dc955c56e..390f134d6f 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs @@ -2,7 +2,10 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Sprites; +using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon @@ -16,6 +19,16 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon new Color4(0, 161, 241, 255), new Color4(0, 111, 167, 255) ); + + AddInternal(new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Icon = FontAwesome.Solid.AngleLeft, + Size = new Vector2(20 / 70f), + Scale = new Vector2(0.8f, 1) + }); } } } From f1556c98e3e4ccf5fe89e92f62a8f109b73db730 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 15:07:47 +0900 Subject: [PATCH 0475/2991] Add drum roll implementation --- .../Argon/ArgonElongatedCirclePiece.cs | 33 +++++++++++++++++++ .../Skinning/Argon/RingPiece.cs | 2 +- .../Argon/TaikoArgonSkinTransformer.cs | 3 ++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonElongatedCirclePiece.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonElongatedCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonElongatedCirclePiece.cs new file mode 100644 index 0000000000..f86f181b2e --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonElongatedCirclePiece.cs @@ -0,0 +1,33 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonElongatedCirclePiece : ArgonCirclePiece + { + public ArgonElongatedCirclePiece() + { + RelativeSizeAxes = Axes.Y; + } + + [BackgroundDependencyLoader] + private void load() + { + AccentColour = ColourInfo.GradientVertical( + new Color4(241, 161, 0, 255), + new Color4(167, 111, 0, 255) + ); + } + + protected override void Update() + { + base.Update(); + Width = Parent.DrawSize.X + DrawHeight; + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs index 2c5d824ff5..534a1c71a3 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon protected override void Update() { base.Update(); - BorderThickness = relativeBorderThickness * DrawSize.X; + BorderThickness = relativeBorderThickness * DrawSize.Y; } } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index 0d5c19a525..64f733a969 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -38,6 +38,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case TaikoSkinComponents.BarLine: return new ArgonBarLine(); + + case TaikoSkinComponents.DrumRollBody: + return new ArgonElongatedCirclePiece(); } break; From 938a8f865b51e2df7b2508f3a53cb15d577292a7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 15:11:40 +0900 Subject: [PATCH 0476/2991] Adjust transform of taiko drum roll ticks to not scale to 0 (looks bad) --- .../Objects/Drawables/DrawableDrumRollTick.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 95b6384274..ed89d0a14e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -74,7 +74,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables switch (state) { case ArmedState.Hit: - this.ScaleTo(0, 100, Easing.OutQuint); + this.ScaleTo(1.4f, 200, Easing.OutQuint); + this.FadeOut(200, Easing.OutQuint); break; } } From aa61eb8f4bb61f8f51fef5edb669e62913583f02 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 15:17:20 +0900 Subject: [PATCH 0477/2991] Add note about taiko pooling oversight --- .../Objects/Drawables/DrawableTaikoHitObject.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index c0c80eaa4a..400c2f40b1 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -133,6 +133,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables protected override void OnApply() { base.OnApply(); + + // TODO: THIS CANNOT BE HERE, it makes pooling pointless (see https://github.com/ppy/osu/issues/21072). RecreatePieces(); } From e2046791c2aff7e07532016d8a771f5e4d3b1a3a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 15:39:24 +0900 Subject: [PATCH 0478/2991] Add argon drum roll ticks --- .../Skinning/Argon/ArgonCentreCirclePiece.cs | 2 +- .../Skinning/Argon/ArgonCirclePiece.cs | 2 + .../Skinning/Argon/ArgonRimCirclePiece.cs | 2 +- .../Skinning/Argon/ArgonTickPiece.cs | 68 +++++++++++++++++++ .../Argon/TaikoArgonSkinTransformer.cs | 3 + 5 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonTickPiece.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs index f347863be9..551a5af078 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Icon = FontAwesome.Solid.AngleLeft, - Size = new Vector2(20 / 70f), + Size = new Vector2(ICON_SIZE), Scale = new Vector2(0.8f, 1) }); } diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs index ba8ef12902..8ef7b71069 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs @@ -16,6 +16,8 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon { public abstract class ArgonCirclePiece : BeatSyncedContainer { + public const float ICON_SIZE = 20 / 70f; + private const double pre_beat_transition_time = 80; private const float flash_opacity = 0.3f; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs index 390f134d6f..fd81221be3 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Icon = FontAwesome.Solid.AngleLeft, - Size = new Vector2(20 / 70f), + Size = new Vector2(ICON_SIZE), Scale = new Vector2(0.8f, 1) }); } diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonTickPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonTickPiece.cs new file mode 100644 index 0000000000..df63d4948e --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonTickPiece.cs @@ -0,0 +1,68 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.Objects.Drawables; +using osuTK; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonTickPiece : CompositeDrawable + { + private readonly Bindable isFirstTick = new Bindable(); + + public ArgonTickPiece() + { + const float tick_size = 1 / TaikoHitObject.DEFAULT_SIZE * ArgonCirclePiece.ICON_SIZE; + + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + RelativeSizeAxes = Axes.Both; + FillMode = FillMode.Fit; + Size = new Vector2(tick_size); + } + + [Resolved] + private DrawableHitObject drawableHitObject { get; set; } = null!; + + protected override void LoadComplete() + { + base.LoadComplete(); + + if (drawableHitObject is DrawableDrumRollTick drumRollTick) + isFirstTick.BindTo(drumRollTick.IsFirstTick); + + isFirstTick.BindValueChanged(first => + { + if (first.NewValue) + { + InternalChild = new Circle + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both + }; + } + else + { + InternalChild = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Icon = FontAwesome.Solid.AngleLeft, + Scale = new Vector2(0.8f, 1) + }; + } + }, true); + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index 64f733a969..6782ae67f9 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -41,6 +41,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case TaikoSkinComponents.DrumRollBody: return new ArgonElongatedCirclePiece(); + + case TaikoSkinComponents.DrumRollTick: + return new ArgonTickPiece(); } break; From 37cb187d2eb958167df1397dedda7a53a094f6b6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 16:17:43 +0900 Subject: [PATCH 0479/2991] Move strong hit scale to `DefaultHitExplosion` --- osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs | 2 ++ osu.Game.Rulesets.Taiko/UI/HitExplosion.cs | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs index b7ba76effa..2e76396a4d 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs @@ -10,6 +10,7 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.UI; +using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Default @@ -74,6 +75,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default public void AnimateSecondHit() { + this.ResizeTo(new Vector2(TaikoStrongableHitObject.STRONG_SCALE), 50); } } } diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs index 10a7495c62..d9b6db7734 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs @@ -90,7 +90,6 @@ namespace osu.Game.Rulesets.Taiko.UI { using (BeginAbsoluteSequence(secondHitTime.Value)) { - this.ResizeTo(new Vector2(TaikoStrongableHitObject.DEFAULT_STRONG_SIZE), 50); (skinnable.Drawable as IAnimatableHitExplosion)?.AnimateSecondHit(); } } From d5c375b139f135e9ffc49ae4c9e67f8979b07865 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 16:18:03 +0900 Subject: [PATCH 0480/2991] Add argon hit explosion implementation --- .../Skinning/Argon/ArgonHitExplosion.cs | 87 +++++++++++++++++++ .../Argon/TaikoArgonSkinTransformer.cs | 9 ++ 2 files changed, 96 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitExplosion.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitExplosion.cs new file mode 100644 index 0000000000..05bb9bcb9a --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitExplosion.cs @@ -0,0 +1,87 @@ +// 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.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.UI; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonHitExplosion : CompositeDrawable, IAnimatableHitExplosion + { + private readonly TaikoSkinComponents component; + private readonly Circle outer; + + public ArgonHitExplosion(TaikoSkinComponents component) + { + this.component = component; + + RelativeSizeAxes = Axes.Both; + + InternalChildren = new Drawable[] + { + outer = new Circle + { + Name = "Outer circle", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical( + new Color4(255, 227, 236, 255), + new Color4(255, 198, 211, 255) + ), + Masking = true, + }, + new Circle + { + Name = "Inner circle", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + Size = new Vector2(0.85f), + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = new Color4(255, 132, 191, 255).Opacity(0.5f), + Radius = 45, + }, + Masking = true, + }, + }; + } + + public void Animate(DrawableHitObject drawableHitObject) + { + this.FadeOut(); + + switch (component) + { + case TaikoSkinComponents.TaikoExplosionGreat: + this.FadeIn(30, Easing.In) + .Then() + .FadeOut(450, Easing.OutQuint); + break; + + case TaikoSkinComponents.TaikoExplosionOk: + this.FadeTo(0.2f, 30, Easing.In) + .Then() + .FadeOut(200, Easing.OutQuint); + break; + } + } + + public void AnimateSecondHit() + { + outer.ResizeTo(new Vector2(TaikoStrongableHitObject.STRONG_SCALE), 500, Easing.OutQuint); + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index 6782ae67f9..3b75cfff11 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -44,6 +44,15 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case TaikoSkinComponents.DrumRollTick: return new ArgonTickPiece(); + + case TaikoSkinComponents.TaikoExplosionKiai: + // the drawable needs to expire as soon as possible to avoid accumulating empty drawables on the playfield. + return Drawable.Empty().With(d => d.Expire()); + + case TaikoSkinComponents.TaikoExplosionGreat: + case TaikoSkinComponents.TaikoExplosionMiss: + case TaikoSkinComponents.TaikoExplosionOk: + return new ArgonHitExplosion(catchComponent.Component); } break; From b15d1bc333c9a379c56e0bd7466a4b7795b9fc77 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 16:31:24 +0900 Subject: [PATCH 0481/2991] Add argon result display implementation --- .../Skinning/Argon/ArgonJudgementPiece.cs | 198 ++++++++++++++++++ .../Argon/TaikoArgonSkinTransformer.cs | 4 + 2 files changed, 202 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs new file mode 100644 index 0000000000..0ea0473023 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs @@ -0,0 +1,198 @@ +// 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.Allocation; +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Utils; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Scoring; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonJudgementPiece : CompositeDrawable, IAnimatableJudgement + { + protected readonly HitResult Result; + + protected SpriteText JudgementText { get; private set; } = null!; + + private RingExplosion? ringExplosion; + + [Resolved] + private OsuColour colours { get; set; } = null!; + + public ArgonJudgementPiece(HitResult result) + { + Result = result; + RelativePositionAxes = Axes.Both; + RelativeSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader] + private void load() + { + InternalChildren = new Drawable[] + { + JudgementText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Text = Result.GetDescription().ToUpperInvariant(), + Colour = colours.ForHitResult(Result), + Blending = BlendingParameters.Additive, + Spacing = new Vector2(10, 0), + RelativePositionAxes = Axes.Both, + Font = OsuFont.Default.With(size: 20, weight: FontWeight.Regular), + }, + }; + + if (Result.IsHit()) + { + AddInternal(ringExplosion = new RingExplosion(Result) + { + Colour = colours.ForHitResult(Result), + RelativePositionAxes = Axes.Y, + }); + } + } + + /// + /// Plays the default animation for this judgement piece. + /// + /// + /// The base implementation only handles fade (for all result types) and misses. + /// Individual rulesets are recommended to implement their appropriate hit animations. + /// + public virtual void PlayAnimation() + { + const double duration = 800; + + switch (Result) + { + default: + JudgementText.MoveToY(-0.2f) + .MoveToY(-0.8f, duration, Easing.OutQuint); + + JudgementText + .ScaleTo(Vector2.One) + .ScaleTo(new Vector2(1.8f), duration, Easing.OutQuint); + break; + + case HitResult.Miss: + this.ScaleTo(1.6f); + this.ScaleTo(1, 100, Easing.In); + + JudgementText.MoveTo(Vector2.Zero); + JudgementText.MoveToOffset(new Vector2(0, 100), duration, Easing.InQuint); + + this.RotateTo(0); + this.RotateTo(40, duration, Easing.InQuint); + break; + } + + this.FadeOutFromOne(duration, Easing.OutQuint); + + ringExplosion?.PlayAnimation(); + } + + public Drawable? GetAboveHitObjectsProxiedContent() => null; + + private class RingExplosion : CompositeDrawable + { + private readonly float travel = 58; + + public RingExplosion(HitResult result) + { + const float thickness = 4; + + const float small_size = 9; + const float large_size = 14; + + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + Blending = BlendingParameters.Additive; + + int countSmall = 0; + int countLarge = 0; + + switch (result) + { + case HitResult.Meh: + countSmall = 3; + travel *= 0.3f; + break; + + case HitResult.Ok: + case HitResult.Good: + countSmall = 4; + travel *= 0.6f; + break; + + case HitResult.Great: + case HitResult.Perfect: + countSmall = 4; + countLarge = 4; + break; + } + + for (int i = 0; i < countSmall; i++) + AddInternal(new RingPiece(thickness) { Size = new Vector2(small_size) }); + + for (int i = 0; i < countLarge; i++) + AddInternal(new RingPiece(thickness) { Size = new Vector2(large_size) }); + } + + public void PlayAnimation() + { + foreach (var c in InternalChildren) + { + const float start_position_ratio = 0.6f; + + float direction = RNG.NextSingle(0, 360); + float distance = RNG.NextSingle(travel / 2, travel); + + c.MoveTo(new Vector2( + MathF.Cos(direction) * distance * start_position_ratio, + MathF.Sin(direction) * distance * start_position_ratio + )); + + c.MoveTo(new Vector2( + MathF.Cos(direction) * distance, + MathF.Sin(direction) * distance + ), 600, Easing.OutQuint); + } + + this.FadeOutFromOne(1000, Easing.OutQuint); + } + + public class RingPiece : CircularContainer + { + public RingPiece(float thickness = 9) + { + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + Masking = true; + BorderThickness = thickness; + BorderColour = Color4.White; + + Child = new Box + { + AlwaysPresent = true, + Alpha = 0, + RelativeSizeAxes = Axes.Both + }; + } + } + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index 3b75cfff11..a6e053f0df 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics; +using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko.Skinning.Argon @@ -17,6 +18,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon { switch (component) { + case GameplaySkinComponent resultComponent: + return new ArgonJudgementPiece(resultComponent.Component); + case TaikoSkinComponent catchComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. switch (catchComponent.Component) From d57ec4b227331f6264671cfb6776261aca76c4a2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 17:29:27 +0900 Subject: [PATCH 0482/2991] Add argon input drum implementation --- .../Skinning/Argon/ArgonInputDrum.cs | 218 ++++++++++++++++++ .../Argon/TaikoArgonSkinTransformer.cs | 3 + 2 files changed, 221 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonInputDrum.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonInputDrum.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonInputDrum.cs new file mode 100644 index 0000000000..528e75aabb --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonInputDrum.cs @@ -0,0 +1,218 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Input.Bindings; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Screens.Ranking; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonInputDrum : AspectContainer + { + private const float rim_size = 0.3f; + + public ArgonInputDrum() + { + RelativeSizeAxes = Axes.Y; + } + + [BackgroundDependencyLoader] + private void load() + { + const float middle_split = 6; + + InternalChild = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Scale = new Vector2(0.9f), + Children = new Drawable[] + { + new TaikoHalfDrum(false) + { + Name = "Left Half", + Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + RelativeSizeAxes = Axes.Both, + RimAction = TaikoAction.LeftRim, + CentreAction = TaikoAction.LeftCentre + }, + new TaikoHalfDrum(true) + { + Name = "Right Half", + Anchor = Anchor.Centre, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.Both, + RimAction = TaikoAction.RightRim, + CentreAction = TaikoAction.RightCentre + }, + new CircularContainer + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Masking = true, + Children = new Drawable[] + { + new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Colour = OsuColour.Gray(38 / 255f), + Width = middle_split, + RelativeSizeAxes = Axes.Y, + }, + new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Colour = OsuColour.Gray(48 / 255f), + Width = middle_split, + Height = 1 - rim_size, + RelativeSizeAxes = Axes.Y, + }, + }, + } + } + }; + } + + /// + /// A half-drum. Contains one centre and one rim hit. + /// + private class TaikoHalfDrum : CompositeDrawable, IKeyBindingHandler + { + /// + /// The key to be used for the rim of the half-drum. + /// + public TaikoAction RimAction; + + /// + /// The key to be used for the centre of the half-drum. + /// + public TaikoAction CentreAction; + + private readonly Drawable rimHit; + private readonly Drawable centreHit; + + public TaikoHalfDrum(bool flipped) + { + Anchor anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight; + + Masking = true; + + Anchor = anchor; + Origin = anchor; + + RelativeSizeAxes = Axes.Both; + // Extend maskable region for glow. + Height = 2f; + + InternalChildren = new Drawable[] + { + new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Height = 0.5f, + Children = new[] + { + new Circle + { + Anchor = anchor, + Colour = OsuColour.Gray(51 / 255f), + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both + }, + rimHit = new Circle + { + Anchor = anchor, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientHorizontal( + new Color4(227, 248, 255, 255), + new Color4(198, 245, 255, 255) + ), + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = new Color4(126, 215, 253, 170), + Radius = 50, + }, + Alpha = 0, + }, + new Circle + { + Anchor = anchor, + Origin = Anchor.Centre, + Colour = OsuColour.Gray(64 / 255f), + RelativeSizeAxes = Axes.Both, + Size = new Vector2(1 - rim_size) + }, + centreHit = new Circle + { + Anchor = anchor, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientHorizontal( + new Color4(255, 227, 236, 255), + new Color4(255, 198, 211, 255) + ), + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = new Color4(255, 147, 199, 255), + Radius = 50, + }, + Size = new Vector2(1 - rim_size), + Alpha = 0, + } + }, + }, + }; + } + + public bool OnPressed(KeyBindingPressEvent e) + { + Drawable? target = null; + + if (e.Action == CentreAction) + target = centreHit; + else if (e.Action == RimAction) + target = rimHit; + + if (target != null) + { + const float alpha_amount = 0.5f; + + const float down_time = 40; + const float up_time = 750; + + target.Animate( + t => t.FadeTo(Math.Min(target.Alpha + alpha_amount, 1), down_time, Easing.OutQuint) + ).Then( + t => t.FadeOut(up_time, Easing.OutQuint) + ); + } + + return false; + } + + public void OnReleased(KeyBindingReleaseEvent e) + { + } + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index a6e053f0df..f0d14f657d 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -37,6 +37,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case TaikoSkinComponents.PlayfieldBackgroundRight: return new ArgonPlayfieldBackgroundRight(); + case TaikoSkinComponents.InputDrum: + return new ArgonInputDrum(); + case TaikoSkinComponents.HitTarget: return new ArgonHitTarget(); From de2dac22b86fea188daa886a01e65adcf136e2cf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 18:46:04 +0900 Subject: [PATCH 0483/2991] Ensure seeding screen is refreshed on entering --- .../Screens/TeamIntro/SeedingScreen.cs | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs index 9262cab098..8bc28e1068 100644 --- a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs +++ b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs @@ -70,16 +70,16 @@ namespace osu.Game.Tournament.Screens.TeamIntro currentTeam.BindValueChanged(teamChanged, true); } - private void teamChanged(ValueChangedEvent team) => Scheduler.AddOnce(() => - { - if (team.NewValue == null) - { - mainContainer.Clear(); - return; - } + private void teamChanged(ValueChangedEvent team) => updateTeamDisplay(); - showTeam(team.NewValue); - }); + public override void Show() + { + base.Show(); + + // Changes could have been made on editor screen. + // Rather than trying to track all the possibilities (teams / players / scores) just force a full refresh. + updateTeamDisplay(); + } protected override void CurrentMatchChanged(ValueChangedEvent match) { @@ -91,14 +91,20 @@ namespace osu.Game.Tournament.Screens.TeamIntro currentTeam.Value = match.NewValue.Team1.Value; } - private void showTeam(TournamentTeam team) + private void updateTeamDisplay() => Scheduler.AddOnce(() => { + if (currentTeam.Value == null) + { + mainContainer.Clear(); + return; + } + mainContainer.Children = new Drawable[] { - new LeftInfo(team) { Position = new Vector2(55, 150), }, - new RightInfo(team) { Position = new Vector2(500, 150), }, + new LeftInfo(currentTeam.Value) { Position = new Vector2(55, 150), }, + new RightInfo(currentTeam.Value) { Position = new Vector2(500, 150), }, }; - } + }); private class RightInfo : CompositeDrawable { From 64f9d6c8916d13e225e7631b8662793d7edb3220 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 19:03:56 +0900 Subject: [PATCH 0484/2991] Fix potential cross-thread drawable operation in round editor screen --- osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs index 1b670f4b69..0bd5ddb257 100644 --- a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs @@ -256,7 +256,7 @@ namespace osu.Game.Tournament.Screens.Editors mods.BindValueChanged(modString => Model.Mods = modString.NewValue); } - private void updatePanel() + private void updatePanel() => Schedule(() => { drawableContainer.Clear(); @@ -269,7 +269,7 @@ namespace osu.Game.Tournament.Screens.Editors Width = 300 }; } - } + }); } } } From d77b6b3603e5a302efe8c960427516106f78e985 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 19:04:06 +0900 Subject: [PATCH 0485/2991] Fix seeding screen buttons crashing the game if no match is selected --- .../Screens/TeamIntro/SeedingScreen.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs index 8bc28e1068..ba75b6a2ed 100644 --- a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs +++ b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs @@ -26,6 +26,9 @@ namespace osu.Game.Tournament.Screens.TeamIntro private readonly Bindable currentTeam = new Bindable(); + private TourneyButton showFirstTeamButton; + private TourneyButton showSecondTeamButton; + [BackgroundDependencyLoader] private void load() { @@ -46,13 +49,13 @@ namespace osu.Game.Tournament.Screens.TeamIntro { Children = new Drawable[] { - new TourneyButton + showFirstTeamButton = new TourneyButton { RelativeSizeAxes = Axes.X, Text = "Show first team", Action = () => currentTeam.Value = CurrentMatch.Value.Team1.Value, }, - new TourneyButton + showSecondTeamButton = new TourneyButton { RelativeSizeAxes = Axes.X, Text = "Show second team", @@ -86,7 +89,14 @@ namespace osu.Game.Tournament.Screens.TeamIntro base.CurrentMatchChanged(match); if (match.NewValue == null) + { + showFirstTeamButton.Enabled.Value = false; + showSecondTeamButton.Enabled.Value = false; return; + } + + showFirstTeamButton.Enabled.Value = true; + showSecondTeamButton.Enabled.Value = true; currentTeam.Value = match.NewValue.Team1.Value; } From 1e2e0dea74fbbdf53b0eb04a5913b6bdd4f15a52 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 7 Nov 2022 19:04:19 +0900 Subject: [PATCH 0486/2991] Ensure seeding results get beatmaps populated if `BeatmapIno` model is null --- osu.Game.Tournament/TournamentGameBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tournament/TournamentGameBase.cs b/osu.Game.Tournament/TournamentGameBase.cs index 1861e39c60..98ba3ca60f 100644 --- a/osu.Game.Tournament/TournamentGameBase.cs +++ b/osu.Game.Tournament/TournamentGameBase.cs @@ -238,7 +238,7 @@ namespace osu.Game.Tournament var beatmapsRequiringPopulation = ladder.Teams .SelectMany(r => r.SeedingResults) .SelectMany(r => r.Beatmaps) - .Where(b => b.Beatmap?.OnlineID == 0 && b.ID > 0).ToList(); + .Where(b => (b.Beatmap == null || b.Beatmap.OnlineID == 0) && b.ID > 0).ToList(); if (beatmapsRequiringPopulation.Count == 0) return false; From ab650d8a1bf790616c6bbf5f2d082f2b9277497c Mon Sep 17 00:00:00 2001 From: C0D3 M4513R <28912031+C0D3-M4513R@users.noreply.github.com> Date: Mon, 7 Nov 2022 15:22:20 +0100 Subject: [PATCH 0487/2991] Use AutoSizeAxes --- osu.Game/Skinning/Components/BeatmapInfoDrawable.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs index eda956e6d8..379bdec333 100644 --- a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs +++ b/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs @@ -64,6 +64,7 @@ namespace osu.Game.Skinning.Components public BeatmapInfoDrawable() { + AutoSizeAxes = Axes.Both; InternalChildren = new Drawable[] { text = new OsuSpriteText @@ -104,8 +105,6 @@ namespace osu.Game.Skinning.Components } text.Text = newText; - Width = text.Width; - Height = text.Height; } public void UpdateBeatmapContent(WorkingBeatmap workingBeatmap) From 7ee9018a94c0e2bfb81c9fca6d3a067d1075f437 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 8 Nov 2022 03:18:12 +0300 Subject: [PATCH 0488/2991] Always display menu cursor when game is not focused --- .../Graphics/Cursor/MenuCursorContainer.cs | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/osu.Game/Graphics/Cursor/MenuCursorContainer.cs b/osu.Game/Graphics/Cursor/MenuCursorContainer.cs index af542989ff..adc0f81daf 100644 --- a/osu.Game/Graphics/Cursor/MenuCursorContainer.cs +++ b/osu.Game/Graphics/Cursor/MenuCursorContainer.cs @@ -70,7 +70,8 @@ namespace osu.Game.Graphics.Cursor private OsuGame? game { get; set; } private readonly IBindable lastInputWasMouse = new BindableBool(); - private readonly IBindable isIdle = new BindableBool(); + private readonly IBindable gameActive = new BindableBool(true); + private readonly IBindable gameIdle = new BindableBool(); protected override void LoadComplete() { @@ -81,8 +82,11 @@ namespace osu.Game.Graphics.Cursor if (game != null) { - isIdle.BindTo(game.IsIdle); - isIdle.BindValueChanged(_ => updateState()); + gameIdle.BindTo(game.IsIdle); + gameIdle.BindValueChanged(_ => updateState()); + + gameActive.BindTo(game.IsActive); + gameActive.BindValueChanged(_ => updateState()); } } @@ -90,7 +94,7 @@ namespace osu.Game.Graphics.Cursor private void updateState() { - bool combinedVisibility = State.Value == Visibility.Visible && (lastInputWasMouse.Value || !hideCursorOnNonMouseInput) && !isIdle.Value; + bool combinedVisibility = getCursorVisibility(); if (visible == combinedVisibility) return; @@ -103,6 +107,27 @@ namespace osu.Game.Graphics.Cursor PopOut(); } + private bool getCursorVisibility() + { + // do not display when explicitly set to hidden state. + if (State.Value == Visibility.Hidden) + return false; + + // only hide cursor when game is focused, otherwise it should always be displayed. + if (gameActive.Value) + { + // do not display when last input is not mouse. + if (hideCursorOnNonMouseInput && !lastInputWasMouse.Value) + return false; + + // do not display when game is idle. + if (gameIdle.Value) + return false; + } + + return true; + } + protected override void Update() { base.Update(); From 8568520c33db332cb21d479342e334809ee49104 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Tue, 8 Nov 2022 01:34:06 +0100 Subject: [PATCH 0489/2991] Fix `Prefer24HourTime` default value Will use the system culture so it always matches the rest of the OS. --- osu.Game/Configuration/OsuConfigManager.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 093eaa0f31..5137214d62 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -5,7 +5,6 @@ using System; using System.Diagnostics; -using System.Globalization; using osu.Framework.Configuration; using osu.Framework.Configuration.Tracking; using osu.Framework.Extensions; @@ -115,7 +114,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.MenuParallax, true); // See https://stackoverflow.com/a/63307411 for default sourcing. - SetDefault(OsuSetting.Prefer24HourTime, CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern.Contains(@"tt")); + SetDefault(OsuSetting.Prefer24HourTime, !CultureInfoHelper.SystemCulture.DateTimeFormat.ShortTimePattern.Contains(@"tt")); // Gameplay SetDefault(OsuSetting.PositionalHitsoundsLevel, 0.2f, 0, 1); From 3af48352c98e1602b55fee988482122b2e2fbcba Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 8 Nov 2022 04:05:06 +0300 Subject: [PATCH 0490/2991] Fix taiko major barlines no longer rendering correctly --- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 30 ++++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index cc71ba5401..f2d7811f44 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -60,8 +60,9 @@ namespace osu.Game.Rulesets.Taiko.UI /// private BarLinePlayfield barLinePlayfield; - private Container playfieldContent; - private Container playfieldOverlay; + private Container barLineContent; + private Container hitObjectContent; + private Container overlayContent; [BackgroundDependencyLoader] private void load(OsuColour colours) @@ -121,22 +122,20 @@ namespace osu.Game.Rulesets.Taiko.UI } } }, - new Container + barLineContent = new Container + { + Name = "Bar line content", + RelativeSizeAxes = Axes.Both, + Child = barLinePlayfield = new BarLinePlayfield(), + }, + hitObjectContent = new Container { Name = "Masked hit objects content", RelativeSizeAxes = Axes.Both, Masking = true, - Child = playfieldContent = new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - barLinePlayfield = new BarLinePlayfield(), - HitObjectContainer, - } - } + Child = HitObjectContainer, }, - playfieldOverlay = new Container + overlayContent = new Container { Name = "Elements after hit objects", RelativeSizeAxes = Axes.Both, @@ -215,8 +214,9 @@ namespace osu.Game.Rulesets.Taiko.UI // Padding is required to be updated for elements which are based on "absolute" X sized elements. // This is basically allowing for correct alignment as relative pieces move around them. rightArea.Padding = new MarginPadding { Left = inputDrum.Width }; - playfieldContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 }; - playfieldOverlay.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 }; + barLineContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 }; + hitObjectContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 }; + overlayContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 }; mascot.Scale = new Vector2(DrawHeight / DEFAULT_HEIGHT); } From 2163cd212b57a1fb7e2156621973bde5251ea4e4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 12:03:25 +0900 Subject: [PATCH 0491/2991] Automatically close settings and notification overlays when opening main overlay Closes #21162. --- osu.Game/OsuGame.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 4f8098136f..0015de7da1 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1006,6 +1006,9 @@ namespace osu.Game if (overlay.IsPresent) return; + Settings.Hide(); + Notifications.Hide(); + // Show above all other overlays. if (overlay.IsLoaded) overlayContent.ChangeChildDepth(overlay, (float)-Clock.CurrentTime); From 64e627639762201399595de37d595fcc614db6fc Mon Sep 17 00:00:00 2001 From: maromalo <54760464+maromalo@users.noreply.github.com> Date: Tue, 8 Nov 2022 01:10:21 -0300 Subject: [PATCH 0492/2991] Fix score rounding issue --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index f619c89368..02512d857d 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -341,13 +341,13 @@ namespace osu.Game.Rulesets.Scoring case ScoringMode.Standardised: double accuracyScore = accuracyPortion * accuracyRatio; double comboScore = comboPortion * comboRatio; - return (long)((max_score * (accuracyScore + comboScore) + bonusScore) * scoreMultiplier); + return (long)Math.Round((max_score * (accuracyScore + comboScore) + bonusScore) * scoreMultiplier); case ScoringMode.Classic: // This gives a similar feeling to osu!stable scoring (ScoreV1) while keeping classic scoring as only a constant multiple of standardised scoring. // The invariant is important to ensure that scores don't get re-ordered on leaderboards between the two scoring modes. double scaledStandardised = ComputeScore(ScoringMode.Standardised, accuracyRatio, comboRatio, bonusScore, totalBasicHitObjects) / max_score; - return (long)(Math.Pow(scaledStandardised * Math.Max(1, totalBasicHitObjects), 2) * ClassicScoreMultiplier); + return (long)Math.Round(Math.Pow(scaledStandardised * Math.Max(1, totalBasicHitObjects), 2) * ClassicScoreMultiplier); } } From b764d1bd0469f8136c4abc4c30683117f3d67d99 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 13:29:25 +0900 Subject: [PATCH 0493/2991] Decode variables earlier in flow in case they include indent logic Without this change, the `depth` calculation could be incorrect. --- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index b8f60f0bc6..4d407bb5f0 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -79,6 +79,8 @@ namespace osu.Game.Beatmaps.Formats private void handleEvents(string line) { + decodeVariables(ref line); + int depth = 0; foreach (char c in line) @@ -91,8 +93,6 @@ namespace osu.Game.Beatmaps.Formats line = line.Substring(depth); - decodeVariables(ref line); - string[] split = line.Split(','); if (depth == 0) From 064a245c50c4e3a92e2fcbf87e7dc014864322ab Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 13:30:11 +0900 Subject: [PATCH 0494/2991] Don't trim whitespace from variable keys / values --- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 12 +++++++++--- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index ed7ca47cfd..6991500df5 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -130,14 +130,20 @@ namespace osu.Game.Beatmaps.Formats } } - protected KeyValuePair SplitKeyVal(string line, char separator = ':') + protected KeyValuePair SplitKeyVal(string line, char separator = ':', bool shouldTrim = true) { string[] split = line.Split(separator, 2); + if (shouldTrim) + { + for (int i = 0; i < split.Length; i++) + split[i] = split[i].Trim(); + } + return new KeyValuePair ( - split[0].Trim(), - split.Length > 1 ? split[1].Trim() : string.Empty + split[0], + split.Length > 1 ? split[1] : string.Empty ); } diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 4d407bb5f0..2b4f377ab6 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -349,7 +349,7 @@ namespace osu.Game.Beatmaps.Formats private void handleVariables(string line) { - var pair = SplitKeyVal(line, '='); + var pair = SplitKeyVal(line, '=', false); variables[pair.Key] = pair.Value; } From 0b343404472d26ecbe243e7529a8615d5dd961ff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 14:34:28 +0900 Subject: [PATCH 0495/2991] Fix sprites not displaying in storyboard if filename extension is missing in script --- osu.Game/Storyboards/Storyboard.cs | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/osu.Game/Storyboards/Storyboard.cs b/osu.Game/Storyboards/Storyboard.cs index 473f1ce97f..8133244e89 100644 --- a/osu.Game/Storyboards/Storyboard.cs +++ b/osu.Game/Storyboards/Storyboard.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.IO; using System.Linq; using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; @@ -89,12 +90,31 @@ namespace osu.Game.Storyboards public DrawableStoryboard CreateDrawable(IReadOnlyList? mods = null) => new DrawableStoryboard(this, mods); + private static readonly string[] image_extensions = { @".png", @".jpg" }; + public Texture? GetTextureFromPath(string path, TextureStore textureStore) { - string? storyboardPath = BeatmapInfo.BeatmapSet?.GetPathForFile(path); + string? resolvedPath = null; - if (!string.IsNullOrEmpty(storyboardPath)) - return textureStore.Get(storyboardPath); + if (Path.HasExtension(path)) + { + resolvedPath = BeatmapInfo.BeatmapSet?.GetPathForFile(path); + } + else + { + // Just doing this extension logic locally here for simplicity. + // + // A more "sane" path may be to use the ISkinSource.GetTexture path (which will use the extensions of the underlying TextureStore), + // but comes with potential complexity (what happens if the user has beatmap skins disabled?). + foreach (string ext in image_extensions) + { + if ((resolvedPath = BeatmapInfo.BeatmapSet?.GetPathForFile($"{path}{ext}")) != null) + break; + } + } + + if (!string.IsNullOrEmpty(resolvedPath)) + return textureStore.Get(resolvedPath); return null; } From b9374cae55ade91632302f64eacef6bf9ab9f64a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 14:38:02 +0900 Subject: [PATCH 0496/2991] Hide settings/notifications regardless of `IsPresent` state of new overlay --- osu.Game/OsuGame.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 0015de7da1..7476324e11 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1002,13 +1002,13 @@ namespace osu.Game { otherOverlays.Where(o => o != overlay).ForEach(o => o.Hide()); + Settings.Hide(); + Notifications.Hide(); + // Partially visible so leave it at the current depth. if (overlay.IsPresent) return; - Settings.Hide(); - Notifications.Hide(); - // Show above all other overlays. if (overlay.IsLoaded) overlayContent.ChangeChildDepth(overlay, (float)-Clock.CurrentTime); From 4c157946941a26b1ecab092c826390dd741c3342 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 14:58:52 +0900 Subject: [PATCH 0497/2991] Add test coverage of overlay interplay --- .../Navigation/TestSceneScreenNavigation.cs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 8fce43f9b0..e69bdfb7ac 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -513,6 +513,40 @@ namespace osu.Game.Tests.Visual.Navigation AddWaitStep("wait two frames", 2); } + [Test] + public void TestMainOverlaysClosesNotificationOverlay() + { + ChangelogOverlay getChangelogOverlay() => Game.ChildrenOfType().FirstOrDefault(); + + AddUntilStep("Wait for options to load", () => Game.Notifications.IsLoaded); + AddStep("Show notifications", () => Game.Notifications.Show()); + AddUntilStep("wait for notifications shown", () => Game.Notifications.IsPresent && Game.Notifications.State.Value == Visibility.Visible); + AddStep("Show changelog listing", () => Game.ShowChangelogListing()); + AddUntilStep("wait for changelog shown", () => getChangelogOverlay()?.IsPresent == true && getChangelogOverlay()?.State.Value == Visibility.Visible); + AddAssert("Notifications is hidden", () => Game.Notifications.State.Value == Visibility.Hidden); + + AddStep("Show notifications", () => Game.Notifications.Show()); + AddUntilStep("wait for notifications shown", () => Game.Notifications.State.Value == Visibility.Visible); + AddUntilStep("changelog still visible", () => getChangelogOverlay().State.Value == Visibility.Visible); + } + + [Test] + public void TestMainOverlaysClosesSettingsOverlay() + { + ChangelogOverlay getChangelogOverlay() => Game.ChildrenOfType().FirstOrDefault(); + + AddUntilStep("Wait for options to load", () => Game.Settings.IsLoaded); + AddStep("Show settings", () => Game.Settings.Show()); + AddUntilStep("wait for settings shown", () => Game.Settings.IsPresent && Game.Settings.State.Value == Visibility.Visible); + AddStep("Show changelog listing", () => Game.ShowChangelogListing()); + AddUntilStep("wait for changelog shown", () => getChangelogOverlay()?.IsPresent == true && getChangelogOverlay()?.State.Value == Visibility.Visible); + AddAssert("Settings is hidden", () => Game.Settings.State.Value == Visibility.Hidden); + + AddStep("Show settings", () => Game.Settings.Show()); + AddUntilStep("wait for settings shown", () => Game.Settings.State.Value == Visibility.Visible); + AddUntilStep("changelog still visible", () => getChangelogOverlay().State.Value == Visibility.Visible); + } + [Test] public void TestOverlayClosing() { From 01803c3f13f0a46907401a5b1a3b670944d1ff09 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 15:08:52 +0900 Subject: [PATCH 0498/2991] Adjust judgement text to be more visible --- .../Skinning/Argon/ArgonJudgementPiece.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs index 0ea0473023..baaf9e41e2 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs @@ -78,12 +78,12 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon switch (Result) { default: - JudgementText.MoveToY(-0.2f) - .MoveToY(-0.8f, duration, Easing.OutQuint); + JudgementText.MoveToY(-0.6f) + .MoveToY(-1.0f, duration, Easing.OutQuint); JudgementText .ScaleTo(Vector2.One) - .ScaleTo(new Vector2(1.8f), duration, Easing.OutQuint); + .ScaleTo(new Vector2(1.4f), duration, Easing.OutQuint); break; case HitResult.Miss: From aa7d0e2c9699743d220828962d7a2c63d4433e57 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 15:19:08 +0900 Subject: [PATCH 0499/2991] Remove triangles skin specific implementation from base `DrawableHit` --- .../Objects/Drawables/DrawableHit.cs | 5 +--- .../Skinning/Default/CirclePiece.cs | 25 ++++++++++++++++--- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index 484f125a09..02ac054b52 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -201,12 +201,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables break; case ArmedState.Hit: - // If we're far enough away from the left stage, we should bring outselves in front of it + // If we're far enough away from the left stage, we should bring ourselves in front of it ProxyContent(); - var flash = (MainPiece.Drawable as CirclePiece)?.FlashBox; - flash?.FadeTo(0.9f).FadeOut(300); - const float gravity_time = 300; const float gravity_travel_height = 200; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs index 6b5a9ae6d2..e8edf94e76 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs @@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default private readonly Container background; - public Box FlashBox; + private readonly Box flashBox; protected CirclePiece() { @@ -122,7 +122,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default Masking = true, Children = new[] { - FlashBox = new Box + flashBox = new Box { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -144,6 +144,25 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default }); } + protected override void LoadComplete() + { + base.LoadComplete(); + + drawableHitObject.ApplyCustomUpdateState += updateStateTransforms; + updateStateTransforms(drawableHitObject, drawableHitObject.State.Value); + } + + private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state) + { + switch (state) + { + case ArmedState.Hit: + using (BeginAbsoluteSequence(drawableHitObject.HitStateUpdateTime)) + flashBox?.FadeTo(0.9f).FadeOut(300); + break; + } + } + private const float edge_alpha_kiai = 0.5f; private void resetEdgeEffects() @@ -166,7 +185,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default if (drawableHitObject.State.Value == ArmedState.Idle) { - FlashBox + flashBox .FadeTo(flash_opacity) .Then() .FadeOut(timingPoint.BeatLength * 0.75, Easing.OutSine); From 30890644a8c417119199de6f24fcd63cd366543b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 15:21:20 +0900 Subject: [PATCH 0500/2991] Flash piece when hit --- .../Skinning/Argon/ArgonCirclePiece.cs | 55 ++++++++++--------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs index 8ef7b71069..91f34e1f0e 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs @@ -5,7 +5,6 @@ using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.Containers; @@ -33,17 +32,16 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon set { accentColour = value; + ring.Colour = AccentColour.MultiplyAlpha(0.5f); ring2.Colour = AccentColour; } } - /// - /// Whether Kiai mode effects are enabled for this circle piece. - /// - public bool KiaiMode { get; set; } + [Resolved] + private DrawableHitObject drawableHitObject { get; set; } = null!; - public Box FlashBox; + private readonly Drawable flash; private readonly RingPiece ring; private readonly RingPiece ring2; @@ -59,36 +57,43 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon new Circle { RelativeSizeAxes = Axes.Both, - Colour = new Color4(0, 22, 30, 190) + Colour = new Color4(0, 0, 0, 190) }, ring = new RingPiece(20 / 70f), ring2 = new RingPiece(5 / 70f), - new CircularContainer + flash = new Circle { Name = "Flash layer", Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - Masking = true, - Children = new[] - { - FlashBox = new Box - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Colour = Color4.White, - Blending = BlendingParameters.Additive, - Alpha = 0, - AlwaysPresent = true - } - }, + Blending = BlendingParameters.Additive, + Alpha = 0, }, }); } - [Resolved] - private DrawableHitObject drawableHitObject { get; set; } = null!; + protected override void LoadComplete() + { + base.LoadComplete(); + + drawableHitObject.ApplyCustomUpdateState += updateStateTransforms; + updateStateTransforms(drawableHitObject, drawableHitObject.State.Value); + } + + private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state) + { + switch (state) + { + case ArmedState.Hit: + using (BeginAbsoluteSequence(drawableHitObject.HitStateUpdateTime)) + { + flash.FadeTo(0.9f).FadeOut(500, Easing.OutQuint); + } + + break; + } + } protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) { @@ -97,7 +102,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon if (drawableHitObject.State.Value == ArmedState.Idle) { - FlashBox + flash .FadeTo(flash_opacity) .Then() .FadeOut(timingPoint.BeatLength * 0.75, Easing.OutSine); From 349d262c1820d5056282bc2a3a2014a6535a17af Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 2 Nov 2022 18:05:22 +0900 Subject: [PATCH 0501/2991] Remove commented unbind --- osu.Game/Screens/Edit/Editor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 990152471a..df3c1f7ec4 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -667,9 +667,9 @@ namespace osu.Game.Screens.Edit ApplyToBackground(b => { - //b.DimAmount.UnbindAll(); b.DimWhenUserSettingsIgnored.Value = 0; }); + resetTrack(); refetchBeatmap(); From 9650ae1329b07cf8801601186d4dae91c1fe7929 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 17:20:37 +0900 Subject: [PATCH 0502/2991] Limit editor background dim to 75% maximum --- osu.Game/Configuration/OsuConfigManager.cs | 2 +- osu.Game/Screens/Edit/BackgroundDimMenuItem.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 3c619d2ddd..fccd1a8715 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -121,7 +121,6 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.PositionalHitsoundsLevel, 0.2f, 0, 1); SetDefault(OsuSetting.DimLevel, 0.7, 0, 1, 0.01); SetDefault(OsuSetting.BlurLevel, 0, 0, 1, 0.01); - SetDefault(OsuSetting.EditorDim, 0.25f, 0f, 1f, 0.25f); SetDefault(OsuSetting.LightenDuringBreaks, true); SetDefault(OsuSetting.HitLighting, true); @@ -172,6 +171,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.DiscordRichPresence, DiscordRichPresenceMode.Full); + SetDefault(OsuSetting.EditorDim, 0.25f, 0f, 0.75f, 0.25f); SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f, 0f, 1f, 0.25f); SetDefault(OsuSetting.LastProcessedMetadataId, -1); diff --git a/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs b/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs index b8644ed690..b5a33f06e7 100644 --- a/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs +++ b/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs @@ -23,7 +23,6 @@ namespace osu.Game.Screens.Edit createMenuItem(0.25f), createMenuItem(0.5f), createMenuItem(0.75f), - createMenuItem(1f), }; this.backgroudDim = backgroudDim; From ada039151b80f73d678161ec0f10f13f0c79ffab Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 18:07:06 +0900 Subject: [PATCH 0503/2991] Add the ability to toggle off hit marker displays in the editor --- .../Components/HitCircleOverlapMarker.cs | 50 +++++++++++++------ .../Edit/Blueprints/OsuSelectionBlueprint.cs | 2 +- osu.Game/Configuration/OsuConfigManager.cs | 2 + .../Edit/HitObjectSelectionBlueprint.cs | 14 ++++++ osu.Game/Screens/Edit/Editor.cs | 6 +++ 5 files changed, 59 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs index 71cdbc276e..f16b6c138e 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs @@ -4,9 +4,12 @@ #nullable disable using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Utils; +using osu.Game.Configuration; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Skinning.Default; @@ -27,31 +30,45 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components private readonly RingPiece ring; + private readonly Container content; + [Resolved] private EditorClock editorClock { get; set; } + private Bindable showHitMarkers; + public HitCircleOverlapMarker() { Origin = Anchor.Centre; Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); - InternalChildren = new Drawable[] + InternalChild = content = new Container { - new Circle + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Colour = Color4.White, - }, - ring = new RingPiece - { - BorderThickness = 4, + new Circle + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + }, + ring = new RingPiece + { + BorderThickness = 4, + } } }; } + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + showHitMarkers = config.GetBindable(OsuSetting.EditorShowHitMarkers); + } + [Resolved] private ISkinSource skin { get; set; } @@ -68,21 +85,26 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components double hitObjectTime = hitObject.StartTime; bool hasReachedObject = editorTime >= hitObjectTime; - if (hasReachedObject) + if (hasReachedObject && showHitMarkers.Value) { float alpha = Interpolation.ValueAt(editorTime, 0, 1f, hitObjectTime, hitObjectTime + FADE_OUT_EXTENSION, Easing.In); float ringScale = MathHelper.Clamp(Interpolation.ValueAt(editorTime, 0, 1f, hitObjectTime, hitObjectTime + FADE_OUT_EXTENSION / 2, Easing.OutQuint), 0, 1); ring.Scale = new Vector2(1 + 0.1f * ringScale); - Alpha = 0.9f * (1 - alpha); + content.Alpha = 0.9f * (1 - alpha); } else - Alpha = 0; + content.Alpha = 0; + } + + public override void Show() + { + // intentional no op so SelectionBlueprint Selection/Deselection logic doesn't touch us. } public override void Hide() { - // intentional no op so we are not hidden when not selected. + // intentional no op so SelectionBlueprint Selection/Deselection logic doesn't touch us. } } } diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs index 422287918e..11527c9537 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints protected override bool AlwaysShowWhenSelected => true; protected override bool ShouldBeAlive => base.ShouldBeAlive - || (editorClock.CurrentTime >= Item.StartTime && editorClock.CurrentTime - Item.GetEndTime() < HitCircleOverlapMarker.FADE_OUT_EXTENSION); + || (ShowHitMarkers.Value && editorClock.CurrentTime >= Item.StartTime && editorClock.CurrentTime - Item.GetEndTime() < HitCircleOverlapMarker.FADE_OUT_EXTENSION); protected OsuSelectionBlueprint(T hitObject) : base(hitObject) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index fccd1a8715..2aa369cf78 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -173,6 +173,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.EditorDim, 0.25f, 0f, 0.75f, 0.25f); SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f, 0f, 1f, 0.25f); + SetDefault(OsuSetting.EditorShowHitMarkers, true); SetDefault(OsuSetting.LastProcessedMetadataId, -1); } @@ -367,5 +368,6 @@ namespace osu.Game.Configuration ShowOnlineExplicitContent, LastProcessedMetadataId, SafeAreaConsiderations, + EditorShowHitMarkers } } diff --git a/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs b/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs index c74fb83d58..408fbfc04f 100644 --- a/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs @@ -3,7 +3,10 @@ #nullable disable +using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics.Primitives; +using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; @@ -23,6 +26,11 @@ namespace osu.Game.Rulesets.Edit /// protected virtual bool AlwaysShowWhenSelected => false; + /// + /// Whether extra animations should be shown to convey hit position / state in addition to gameplay animations. + /// + protected Bindable ShowHitMarkers { get; private set; } + protected override bool ShouldBeAlive => (DrawableObject?.IsAlive == true && DrawableObject.IsPresent) || (AlwaysShowWhenSelected && State == SelectionState.Selected); protected HitObjectSelectionBlueprint(HitObject hitObject) @@ -30,6 +38,12 @@ namespace osu.Game.Rulesets.Edit { } + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + ShowHitMarkers = config.GetBindable(OsuSetting.EditorShowHitMarkers); + } + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => DrawableObject.ReceivePositionalInputAt(screenSpacePos); public override Vector2 ScreenSpaceSelectionPoint => DrawableObject.ScreenSpaceDrawQuad.Centre; diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index df3c1f7ec4..7f94370bb2 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -176,6 +176,7 @@ namespace osu.Game.Screens.Edit private OnScreenDisplay onScreenDisplay { get; set; } private Bindable editorBackgroundDim; + private Bindable editorHitMarkers; public Editor(EditorLoader loader = null) { @@ -262,6 +263,7 @@ namespace osu.Game.Screens.Edit OsuMenuItem redoMenuItem; editorBackgroundDim = config.GetBindable(OsuSetting.EditorDim); + editorHitMarkers = config.GetBindable(OsuSetting.EditorShowHitMarkers); AddInternal(new OsuContextMenuContainer { @@ -316,6 +318,10 @@ namespace osu.Game.Screens.Edit { new WaveformOpacityMenuItem(config.GetBindable(OsuSetting.EditorWaveformOpacity)), new BackgroundDimMenuItem(editorBackgroundDim), + new ToggleMenuItem("Show hit markers") + { + State = { BindTarget = editorHitMarkers }, + } } } } From dd4cd3cf8e5be9f5c413efa67be780a2a931e08c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 18:24:57 +0900 Subject: [PATCH 0504/2991] Move gameplay configuration to interface to allow editor overriding --- osu.Game/Configuration/IGameplaySettings.cs | 23 +++++++++++++++++++ osu.Game/Configuration/OsuConfigManager.cs | 6 ++++- osu.Game/OsuGameBase.cs | 1 + .../Objects/Drawables/DrawableHitObject.cs | 10 ++++---- 4 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 osu.Game/Configuration/IGameplaySettings.cs diff --git a/osu.Game/Configuration/IGameplaySettings.cs b/osu.Game/Configuration/IGameplaySettings.cs new file mode 100644 index 0000000000..a35bdd20d0 --- /dev/null +++ b/osu.Game/Configuration/IGameplaySettings.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 osu.Framework.Allocation; +using osu.Framework.Bindables; + +namespace osu.Game.Configuration +{ + /// + /// A settings provider which generally sources from (global user settings) + /// but can allow overriding settings by caching more locally. For instance, in the editor. + /// + /// + /// More settings can be moved into this interface as required. + /// + [Cached] + public interface IGameplaySettings + { + IBindable ComboColourNormalisationAmount { get; } + + IBindable PositionalHitsoundsLevel { get; } + } +} diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index fdaad8cf70..1286a07eeb 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -6,6 +6,7 @@ using System; using System.Diagnostics; using System.Globalization; +using osu.Framework.Bindables; using osu.Framework.Configuration; using osu.Framework.Configuration.Tracking; using osu.Framework.Extensions; @@ -27,7 +28,7 @@ using osu.Game.Skinning; namespace osu.Game.Configuration { [ExcludeFromDynamicCompile] - public class OsuConfigManager : IniConfigManager + public class OsuConfigManager : IniConfigManager, IGameplaySettings { public OsuConfigManager(Storage storage) : base(storage) @@ -276,6 +277,9 @@ namespace osu.Game.Configuration public Func LookupSkinName { private get; set; } = _ => @"unknown"; public Func LookupKeyBindings { get; set; } = _ => @"unknown"; + + IBindable IGameplaySettings.ComboColourNormalisationAmount => GetOriginalBindable(OsuSetting.ComboColourNormalisationAmount); + IBindable IGameplaySettings.PositionalHitsoundsLevel => GetOriginalBindable(OsuSetting.PositionalHitsoundsLevel); } // IMPORTANT: These are used in user configuration files. diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 511f492b8a..1d5f5a75e5 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -262,6 +262,7 @@ namespace osu.Game dependencies.Cache(largeStore); dependencies.CacheAs(LocalConfig); + dependencies.CacheAs(LocalConfig); InitialiseFonts(); diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 15d3e63be1..6795a07cb4 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -129,8 +129,8 @@ namespace osu.Game.Rulesets.Objects.Drawables private readonly BindableList samplesBindable = new BindableList(); private readonly Bindable comboIndexBindable = new Bindable(); - private readonly Bindable positionalHitsoundsLevel = new Bindable(); - private readonly Bindable comboColourBrightness = new Bindable(); + private readonly IBindable positionalHitsoundsLevel = new Bindable(); + private readonly IBindable comboColourBrightness = new Bindable(); private readonly Bindable comboIndexWithOffsetsBindable = new Bindable(); protected override bool RequiresChildrenUpdate => true; @@ -171,10 +171,10 @@ namespace osu.Game.Rulesets.Objects.Drawables } [BackgroundDependencyLoader] - private void load(OsuConfigManager config, ISkinSource skinSource) + private void load(IGameplaySettings gameplaySettings, ISkinSource skinSource) { - config.BindWith(OsuSetting.PositionalHitsoundsLevel, positionalHitsoundsLevel); - config.BindWith(OsuSetting.ComboColourNormalisationAmount, comboColourBrightness); + positionalHitsoundsLevel.BindTo(gameplaySettings.PositionalHitsoundsLevel); + comboColourBrightness.BindTo(gameplaySettings.ComboColourNormalisationAmount); // Explicit non-virtual function call in case a DrawableHitObject overrides AddInternal. base.AddInternal(Samples = new PausableSkinnableSound()); From 4448fcb3c876241428f2015f51f35a735fe21740 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 8 Nov 2022 18:28:48 +0900 Subject: [PATCH 0505/2991] Override combo colour brightness normalisation setting only in editor --- osu.Game/Screens/Edit/Editor.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 912681e114..65d2371551 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -59,7 +59,8 @@ namespace osu.Game.Screens.Edit { [Cached(typeof(IBeatSnapProvider))] [Cached] - public class Editor : ScreenWithBeatmapBackground, IKeyBindingHandler, IKeyBindingHandler, IBeatSnapProvider, ISamplePlaybackDisabler, IBeatSyncProvider + public class Editor : ScreenWithBeatmapBackground, IKeyBindingHandler, IKeyBindingHandler, IBeatSnapProvider, ISamplePlaybackDisabler, IBeatSyncProvider, + IGameplaySettings { public override float BackgroundParallaxAmount => 0.1f; @@ -99,6 +100,9 @@ namespace osu.Game.Screens.Edit [Resolved(canBeNull: true)] private INotificationOverlay notifications { get; set; } + [Resolved] + private IGameplaySettings globalGameplaySettings { get; set; } + public readonly Bindable Mode = new Bindable(); public IBindable SamplePlaybackDisabled => samplePlaybackDisabled; @@ -1031,5 +1035,11 @@ namespace osu.Game.Screens.Edit { } } + + // Combo colour normalisation should not be applied in the editor. + IBindable IGameplaySettings.ComboColourNormalisationAmount => new Bindable(); + + // Arguable. + IBindable IGameplaySettings.PositionalHitsoundsLevel => globalGameplaySettings.PositionalHitsoundsLevel; } } From d48c56818ff8ac446e67f7b0d12eb2088564c6c0 Mon Sep 17 00:00:00 2001 From: Piggey Date: Tue, 8 Nov 2022 20:02:21 +0100 Subject: [PATCH 0506/2991] change `positionText` to display "#?" if tracked score is being 51st on the leaderboard --- osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs | 4 ++++ osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs index 48908fb9a0..10049c7718 100644 --- a/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs @@ -174,6 +174,10 @@ namespace osu.Game.Screens.Play.HUD orderedByScore[i].ScorePosition = i + 1; } + // change displayed potision to '#?' when there are 50 already submitted scores and tracked score is last + if (TrackedScore?.ScorePosition == Flow.Count && Flow.Count == 51) + TrackedScore.ScorePosition = null; + sorting.Validate(); } diff --git a/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs b/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs index 2eec8253b3..dc2c0620c8 100644 --- a/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs +++ b/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs @@ -72,10 +72,8 @@ namespace osu.Game.Screens.Play.HUD scorePosition = value; - if (scorePosition.HasValue) - positionText.Text = $"#{scorePosition.Value.FormatRank()}"; + positionText.Text = scorePosition.HasValue ? $"#{scorePosition.Value.FormatRank()}" : "#?"; - positionText.FadeTo(scorePosition.HasValue ? 1 : 0); updateState(); } } From 9da57c66a2b29a0674c10659ba500c5758d40513 Mon Sep 17 00:00:00 2001 From: Piggey Date: Tue, 8 Nov 2022 20:03:09 +0100 Subject: [PATCH 0507/2991] add visual tests --- .../Visual/Gameplay/TestSceneGameplayLeaderboard.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs index 171ae829a9..a385060d62 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs @@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("add many scores in one go", () => { - for (int i = 0; i < 32; i++) + for (int i = 0; i < 49; i++) createRandomScore(new APIUser { Username = $"Player {i + 1}" }); // Add player at end to force an animation down the whole list. @@ -61,6 +61,12 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for tracked score fully visible", () => leaderboard.ScreenSpaceDrawQuad.Intersects(leaderboard.TrackedScore!.ScreenSpaceDrawQuad)); + AddUntilStep("ensure player is #50", () => leaderboard.CheckPositionByUsername("You", 50)); + + AddStep("add one more player", () => createRandomScore(new APIUser { Username = "Player 50" })); + + AddUntilStep("ensure player is #?", () => leaderboard.CheckPositionByUsername("You", null)); + AddStep("change score to middle", () => playerScore.Value = 1000000); AddWaitStep("wait for movement", 5); AddUntilStep("wait for tracked score fully visible", () => leaderboard.ScreenSpaceDrawQuad.Intersects(leaderboard.TrackedScore!.ScreenSpaceDrawQuad)); From 710c224de45988649feca86275669b0e2c607d55 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 13:18:24 +0900 Subject: [PATCH 0508/2991] Remove unused `IHasMainCirclePiece` interface --- .../Objects/Drawables/DrawableHitCircle.cs | 2 +- .../Objects/Drawables/DrawableSliderRepeat.cs | 2 +- .../Objects/Drawables/DrawableSliderTail.cs | 3 +-- .../Skinning/Default/IHasMainCirclePiece.cs | 14 -------------- 4 files changed, 3 insertions(+), 18 deletions(-) delete mode 100644 osu.Game.Rulesets.Osu/Skinning/Default/IHasMainCirclePiece.cs diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index 841a52da7b..d420091499 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -24,7 +24,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableHitCircle : DrawableOsuHitObject, IHasMainCirclePiece, IHasApproachCircle + public class DrawableHitCircle : DrawableOsuHitObject, IHasApproachCircle { public OsuAction? HitAction => HitArea.HitAction; protected virtual OsuSkinComponents CirclePieceComponent => OsuSkinComponents.HitCircle; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs index 7b9c0c7e40..a02cc9227e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableSliderRepeat : DrawableOsuHitObject, ITrackSnaking, IHasMainCirclePiece + public class DrawableSliderRepeat : DrawableOsuHitObject, ITrackSnaking { public new SliderRepeat HitObject => (SliderRepeat)base.HitObject; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs index 063d297f5a..6270d6709b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs @@ -10,13 +10,12 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; -using osu.Game.Rulesets.Osu.Skinning.Default; using osu.Game.Skinning; using osuTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableSliderTail : DrawableOsuHitObject, IRequireTracking, IHasMainCirclePiece + public class DrawableSliderTail : DrawableOsuHitObject, IRequireTracking { public new SliderTailCircle HitObject => (SliderTailCircle)base.HitObject; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/IHasMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/IHasMainCirclePiece.cs deleted file mode 100644 index 0ba7998d43..0000000000 --- a/osu.Game.Rulesets.Osu/Skinning/Default/IHasMainCirclePiece.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -#nullable disable - -using osu.Game.Skinning; - -namespace osu.Game.Rulesets.Osu.Skinning.Default -{ - public interface IHasMainCirclePiece - { - SkinnableDrawable CirclePiece { get; } - } -} From 5e7dc34d05c5a6ab644d88bbf7e014c012505b7a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 13:23:53 +0900 Subject: [PATCH 0509/2991] Move some non-default skin files to correct namespace --- osu.Game.Rulesets.Osu/Skinning/{Default => }/SliderBody.cs | 3 ++- .../Skinning/{Default => }/SnakingSliderBody.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) rename osu.Game.Rulesets.Osu/Skinning/{Default => }/SliderBody.cs (97%) rename osu.Game.Rulesets.Osu/Skinning/{Default => }/SnakingSliderBody.cs (99%) diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs similarity index 97% rename from osu.Game.Rulesets.Osu/Skinning/Default/SliderBody.cs rename to osu.Game.Rulesets.Osu/Skinning/SliderBody.cs index 9841cc7cdf..1411b27c09 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs @@ -8,10 +8,11 @@ using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Lines; +using osu.Game.Rulesets.Osu.Skinning.Default; using osuTK; using osuTK.Graphics; -namespace osu.Game.Rulesets.Osu.Skinning.Default +namespace osu.Game.Rulesets.Osu.Skinning { public abstract class SliderBody : CompositeDrawable { diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SnakingSliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs similarity index 99% rename from osu.Game.Rulesets.Osu/Skinning/Default/SnakingSliderBody.cs rename to osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs index 86dd5f5c74..a4a3316927 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SnakingSliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs @@ -14,7 +14,7 @@ using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osuTK; -namespace osu.Game.Rulesets.Osu.Skinning.Default +namespace osu.Game.Rulesets.Osu.Skinning { /// /// A which changes its curve depending on the snaking progress. From 20b8ab324fcd92129c501e12ebb189cdca9ca02d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 13:36:46 +0900 Subject: [PATCH 0510/2991] Apply nullability to osu!taiko skinning classes --- .../Skinning/Default/CentreHitCirclePiece.cs | 2 -- osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs | 8 +++----- .../Skinning/Default/DefaultInputDrum.cs | 5 ++--- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs index 958f4b3a17..339ab35795 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs index 6b5a9ae6d2..72809ffd57 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Extensions.Color4Extensions; @@ -36,6 +34,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default private const float flash_opacity = 0.3f; + [Resolved] + private DrawableHitObject drawableHitObject { get; set; } = null!; + private Color4 accentColour; /// @@ -156,9 +157,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default }; } - [Resolved] - private DrawableHitObject drawableHitObject { get; set; } - protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) { if (!effectPoint.KiaiMode) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs index fa60d209e7..3d0578dbc0 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.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. -#nullable disable using System; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -135,8 +134,8 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default public bool OnPressed(KeyBindingPressEvent e) { - Drawable target = null; - Drawable back = null; + Drawable? target = null; + Drawable? back = null; if (e.Action == CentreAction) { From 82ff142b1b379de24550f314241ddbc82965d4c4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 13:36:52 +0900 Subject: [PATCH 0511/2991] Apply nullability to osu! skinning classes --- osu.Game.Rulesets.Osu/OsuSkinComponent.cs | 2 -- osu.Game.Rulesets.Osu/OsuSkinComponents.cs | 2 -- .../Skinning/Default/CirclePiece.cs | 9 +++---- .../Skinning/Default/DefaultApproachCircle.cs | 4 +-- .../Skinning/Default/DefaultSpinner.cs | 17 ++++++------- .../Skinning/Default/DefaultSpinnerDisc.cs | 17 ++++++------- .../Skinning/Default/DrawableSliderPath.cs | 2 -- .../Skinning/Default/ExplodePiece.cs | 9 +++---- .../Skinning/Default/FlashPiece.cs | 2 -- .../Skinning/Default/GlowPiece.cs | 2 -- .../Skinning/Default/KiaiFlash.cs | 2 -- .../Skinning/Default/MainCirclePiece.cs | 7 +++--- .../Skinning/Default/ManualSliderBody.cs | 2 -- .../Skinning/Default/NumberPiece.cs | 2 -- .../Skinning/Default/PlaySliderBody.cs | 6 ++--- .../Skinning/Default/ReverseArrowPiece.cs | 4 +-- .../Default/SpinnerBackgroundLayer.cs | 2 -- .../Skinning/Default/SpinnerCentreLayer.cs | 10 +++----- .../Skinning/Default/SpinnerFill.cs | 2 -- .../Default/SpinnerRotationTracker.cs | 25 +++++++++---------- .../Skinning/Default/SpinnerSpmCalculator.cs | 7 +++--- .../Skinning/Default/SpinnerTicks.cs | 2 -- .../Skinning/Default/TrianglesPiece.cs | 2 -- .../Skinning/IHasApproachCircle.cs | 4 +-- .../Skinning/Legacy/LegacyApproachCircle.cs | 4 +-- .../Skinning/Legacy/LegacyCursor.cs | 2 -- .../Skinning/Legacy/LegacyCursorParticles.cs | 18 ++++++------- .../Skinning/Legacy/LegacyCursorTrail.cs | 9 +++---- .../Skinning/Legacy/LegacyNewStyleSpinner.cs | 14 +++++------ .../Skinning/Legacy/LegacyOldStyleSpinner.cs | 8 +++--- .../Skinning/Legacy/LegacyReverseArrow.cs | 6 ++--- .../Skinning/Legacy/LegacySliderBody.cs | 2 -- .../Legacy/LegacySliderHeadHitCircle.cs | 6 ++--- .../Skinning/Legacy/LegacySpinner.cs | 23 ++++++++--------- .../Legacy/OsuLegacySkinTransformer.cs | 6 ++--- .../Skinning/NonPlayfieldSprite.cs | 4 +-- .../Skinning/OsuSkinColour.cs | 2 -- .../Skinning/OsuSkinConfiguration.cs | 2 -- .../Skinning/SnakingSliderBody.cs | 8 +++--- 39 files changed, 94 insertions(+), 163 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuSkinComponent.cs b/osu.Game.Rulesets.Osu/OsuSkinComponent.cs index 0abaf2c924..aa59bd572e 100644 --- a/osu.Game.Rulesets.Osu/OsuSkinComponent.cs +++ b/osu.Game.Rulesets.Osu/OsuSkinComponent.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu diff --git a/osu.Game.Rulesets.Osu/OsuSkinComponents.cs b/osu.Game.Rulesets.Osu/OsuSkinComponents.cs index 4248cce55a..8fdf3821fa 100644 --- a/osu.Game.Rulesets.Osu/OsuSkinComponents.cs +++ b/osu.Game.Rulesets.Osu/OsuSkinComponents.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Osu { public enum OsuSkinComponents diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/CirclePiece.cs index 40e9f69963..4a679cda2c 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/CirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/CirclePiece.cs @@ -1,9 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; @@ -17,9 +16,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default public class CirclePiece : CompositeDrawable { [Resolved] - private DrawableHitObject drawableObject { get; set; } + private DrawableHitObject drawableObject { get; set; } = null!; - private TrianglesPiece triangles; + private TrianglesPiece triangles = null!; public CirclePiece() { @@ -72,7 +71,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { base.Dispose(isDisposing); - if (drawableObject != null) + if (drawableObject.IsNotNull()) drawableObject.HitObjectApplied -= onHitObjectApplied; } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs index 251fd8d948..e991bc6cf3 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -18,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default private readonly IBindable accentColour = new Bindable(); [Resolved] - private DrawableHitObject drawableObject { get; set; } + private DrawableHitObject drawableObject { get; set; } = null!; public DefaultApproachCircle() : base("Gameplay/osu/approachcircle") diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinner.cs index a215b3b1f0..a975030630 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinner.cs @@ -1,12 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Globalization; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; @@ -18,12 +17,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { public class DefaultSpinner : CompositeDrawable { - private DrawableSpinner drawableSpinner; + private DrawableSpinner drawableSpinner = null!; - private OsuSpriteText bonusCounter; + private OsuSpriteText bonusCounter = null!; - private Container spmContainer; - private OsuSpriteText spmCounter; + private Container spmContainer = null!; + private OsuSpriteText spmCounter = null!; public DefaultSpinner() { @@ -81,8 +80,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default }); } - private IBindable gainedBonus; - private IBindable spinsPerMinute; + private IBindable gainedBonus = null!; + private IBindable spinsPerMinute = null!; protected override void LoadComplete() { @@ -135,7 +134,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { base.Dispose(isDisposing); - if (drawableSpinner != null) + if (drawableSpinner.IsNotNull()) drawableSpinner.ApplyCustomUpdateState -= updateStateTransforms; } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinnerDisc.cs index 60489c1b22..b58daf7174 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinnerDisc.cs @@ -1,12 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Utils; @@ -21,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { public class DefaultSpinnerDisc : CompositeDrawable { - private DrawableSpinner drawableSpinner; + private DrawableSpinner drawableSpinner = null!; private const float initial_scale = 1.3f; private const float idle_alpha = 0.2f; @@ -30,15 +29,15 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default private Color4 normalColour; private Color4 completeColour; - private SpinnerTicks ticks; + private SpinnerTicks ticks = null!; private int wholeRotationCount; private readonly BindableBool complete = new BindableBool(); - private SpinnerFill fill; - private Container mainContainer; - private SpinnerCentreLayer centre; - private SpinnerBackgroundLayer background; + private SpinnerFill fill = null!; + private Container mainContainer = null!; + private SpinnerCentreLayer centre = null!; + private SpinnerBackgroundLayer background = null!; public DefaultSpinnerDisc() { @@ -214,7 +213,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { base.Dispose(isDisposing); - if (drawableSpinner != null) + if (drawableSpinner.IsNotNull()) drawableSpinner.ApplyCustomUpdateState -= updateStateTransforms; } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DrawableSliderPath.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DrawableSliderPath.cs index e3a83a9280..883524f334 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DrawableSliderPath.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DrawableSliderPath.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics.Lines; using osuTK.Graphics; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/ExplodePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/ExplodePiece.cs index 6ee8a12132..f8010a9971 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/ExplodePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/ExplodePiece.cs @@ -1,9 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; @@ -15,9 +14,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default public class ExplodePiece : Container { [Resolved] - private DrawableHitObject drawableObject { get; set; } + private DrawableHitObject drawableObject { get; set; } = null!; - private TrianglesPiece triangles; + private TrianglesPiece triangles = null!; public ExplodePiece() { @@ -56,7 +55,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { base.Dispose(isDisposing); - if (drawableObject != null) + if (drawableObject.IsNotNull()) drawableObject.HitObjectApplied -= onHitObjectApplied; } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/FlashPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/FlashPiece.cs index 98a8b39f6f..06ee64d8b3 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/FlashPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/FlashPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/GlowPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/GlowPiece.cs index 2360bc2238..f5e01b802e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/GlowPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/GlowPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/KiaiFlash.cs b/osu.Game.Rulesets.Osu/Skinning/Default/KiaiFlash.cs index a1cfd170a6..506f679836 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/KiaiFlash.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/KiaiFlash.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Audio.Track; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs index 4acc406ae1..6d56d21349 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs @@ -1,10 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; @@ -46,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default private readonly IBindable indexInCurrentCombo = new Bindable(); [Resolved] - private DrawableHitObject drawableObject { get; set; } + private DrawableHitObject drawableObject { get; set; } = null!; [BackgroundDependencyLoader] private void load() @@ -113,7 +112,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { base.Dispose(isDisposing); - if (drawableObject != null) + if (drawableObject.IsNotNull()) drawableObject.ApplyCustomUpdateState -= updateStateTransforms; } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/ManualSliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/Default/ManualSliderBody.cs index 8d8d9e0d94..d73c94eb9b 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/ManualSliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/ManualSliderBody.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osuTK; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs index f6759c1093..43d8d1e27f 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/PlaySliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/Default/PlaySliderBody.cs index 6c422cf127..96af59abe2 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/PlaySliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/PlaySliderBody.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Game.Rulesets.Objects.Drawables; @@ -20,10 +18,10 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default protected IBindable AccentColourBindable { get; private set; } = null!; - private IBindable pathVersion; + private IBindable pathVersion = null!; [Resolved(CanBeNull = true)] - private OsuRulesetConfigManager config { get; set; } + private OsuRulesetConfigManager? config { get; set; } private readonly Bindable configSnakingOut = new Bindable(); diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs index 8f682d02f6..1fce512f53 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Graphics; @@ -19,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default public class ReverseArrowPiece : BeatSyncedContainer { [Resolved] - private DrawableHitObject drawableRepeat { get; set; } + private DrawableHitObject drawableRepeat { get; set; } = null!; public ReverseArrowPiece() { diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs index a9b7ddf86f..a1184a15cd 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerCentreLayer.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerCentreLayer.cs index ef7b4c2c96..3dd5aed6ae 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerCentreLayer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerCentreLayer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -19,11 +17,11 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { public class SpinnerCentreLayer : CompositeDrawable, IHasAccentColour { - private DrawableSpinner spinner; + private DrawableSpinner spinner = null!; - private CirclePiece circle; - private GlowPiece glow; - private SpriteIcon symbol; + private CirclePiece circle = null!; + private GlowPiece glow = null!; + private SpriteIcon symbol = null!; [BackgroundDependencyLoader] private void load(DrawableHitObject drawableHitObject) diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerFill.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerFill.cs index b7ec9e9799..f574ae589e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerFill.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerFill.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerRotationTracker.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerRotationTracker.cs index 97cebc3123..3a9f73404d 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerRotationTracker.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerRotationTracker.cs @@ -1,11 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; @@ -23,6 +22,16 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default private readonly DrawableSpinner drawableSpinner; + private Vector2 mousePosition; + + private float lastAngle; + private float currentRotation; + + private bool rotationTransferred; + + [Resolved(canBeNull: true)] + private IGameplayClock? gameplayClock { get; set; } + public SpinnerRotationTracker(DrawableSpinner drawableSpinner) { this.drawableSpinner = drawableSpinner; @@ -51,16 +60,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default return base.OnMouseMove(e); } - private Vector2 mousePosition; - - private float lastAngle; - private float currentRotation; - - private bool rotationTransferred; - - [Resolved(canBeNull: true)] - private IGameplayClock gameplayClock { get; set; } - protected override void Update() { base.Update(); @@ -126,7 +125,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { base.Dispose(isDisposing); - if (drawableSpinner != null) + if (drawableSpinner.IsNotNull()) drawableSpinner.HitObjectApplied -= resetState; } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs index df72223214..9feaa0966a 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs @@ -1,12 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Utils; using osu.Game.Rulesets.Objects.Drawables; @@ -26,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default private readonly Bindable result = new BindableDouble(); [Resolved] - private DrawableHitObject drawableSpinner { get; set; } + private DrawableHitObject drawableSpinner { get; set; } = null!; protected override void LoadComplete() { @@ -66,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default { base.Dispose(isDisposing); - if (drawableSpinner != null) + if (drawableSpinner.IsNotNull()) drawableSpinner.HitObjectApplied -= resetState; } diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerTicks.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerTicks.cs index b66cbe41b6..e518ae1da8 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerTicks.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerTicks.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using osu.Framework.Extensions.Color4Extensions; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs index 7399ddbd1b..fa23c60d57 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Graphics.Backgrounds; namespace osu.Game.Rulesets.Osu.Skinning.Default diff --git a/osu.Game.Rulesets.Osu/Skinning/IHasApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/IHasApproachCircle.cs index 8ebab97503..5ddca03fa1 100644 --- a/osu.Game.Rulesets.Osu/Skinning/IHasApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/IHasApproachCircle.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; namespace osu.Game.Rulesets.Osu.Skinning @@ -15,6 +13,6 @@ namespace osu.Game.Rulesets.Osu.Skinning /// /// The approach circle drawable. /// - Drawable ApproachCircle { get; } + Drawable? ApproachCircle { get; } } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs index 03406d37ff..fa5c5b84e4 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -18,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy private readonly IBindable accentColour = new Bindable(); [Resolved] - private DrawableHitObject drawableObject { get; set; } + private DrawableHitObject drawableObject { get; set; } = null!; public LegacyApproachCircle() : base("Gameplay/osu/approachcircle") diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs index 4465f9c266..b2ffc171be 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Rulesets.Osu.UI.Cursor; diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs index ee75b8a857..a28b480753 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using osu.Framework.Allocation; @@ -27,19 +25,19 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { public class LegacyCursorParticles : CompositeDrawable, IKeyBindingHandler { - public bool Active => breakSpewer?.Active.Value == true || kiaiSpewer?.Active.Value == true; + public bool Active => breakSpewer.Active.Value || kiaiSpewer.Active.Value; - private LegacyCursorParticleSpewer breakSpewer; - private LegacyCursorParticleSpewer kiaiSpewer; + private LegacyCursorParticleSpewer breakSpewer = null!; + private LegacyCursorParticleSpewer kiaiSpewer = null!; [Resolved(canBeNull: true)] - private Player player { get; set; } + private Player? player { get; set; } [Resolved(canBeNull: true)] - private OsuPlayfield playfield { get; set; } + private OsuPlayfield? playfield { get; set; } [Resolved(canBeNull: true)] - private GameplayState gameplayState { get; set; } + private GameplayState? gameplayState { get; set; } [BackgroundDependencyLoader] private void load(ISkinSource skin) @@ -79,7 +77,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { if (playfield == null || gameplayState == null) return; - DrawableHitObject kiaiHitObject = null; + DrawableHitObject? kiaiHitObject = null; // Check whether currently in a kiai section first. This is only done as an optimisation to avoid enumerating AliveObjects when not necessary. if (gameplayState.Beatmap.ControlPointInfo.EffectPointAt(Time.Current).KiaiMode) @@ -152,7 +150,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy protected override bool CanSpawnParticles => base.CanSpawnParticles && cursorScreenPosition.HasValue; protected override float ParticleGravity => 240; - public LegacyCursorParticleSpewer(Texture texture, int perSecond) + public LegacyCursorParticleSpewer(Texture? texture, int perSecond) : base(texture, perSecond, particle_duration_max) { Active.BindValueChanged(_ => resetVelocityCalculation()); diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs index e62754c6ce..9a59fd73b2 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -22,7 +20,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy private bool disjointTrail; private double lastTrailTime; - private IBindable cursorSize; + + private IBindable cursorSize = null!; private Vector2? currentPosition; @@ -34,6 +33,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy [BackgroundDependencyLoader] private void load(OsuConfigManager config) { + cursorSize = config.GetBindable(OsuSetting.GameplayCursorSize).GetBoundCopy(); + Texture = skin.GetTexture("cursortrail"); disjointTrail = skin.GetTexture("cursormiddle") == null; @@ -54,8 +55,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy // stable "magic ratio". see OsuPlayfieldAdjustmentContainer for full explanation. Texture.ScaleAdjust *= 1.6f; } - - cursorSize = config.GetBindable(OsuSetting.GameplayCursorSize).GetBoundCopy(); } protected override double FadeDuration => disjointTrail ? 150 : 500; diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyNewStyleSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyNewStyleSpinner.cs index 71c3e4c9f0..f950d3e43e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyNewStyleSpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyNewStyleSpinner.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -23,15 +21,15 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy /// public class LegacyNewStyleSpinner : LegacySpinner { - private Sprite glow; - private Sprite discBottom; - private Sprite discTop; - private Sprite spinningMiddle; - private Sprite fixedMiddle; + private Sprite glow = null!; + private Sprite discBottom = null!; + private Sprite discTop = null!; + private Sprite spinningMiddle = null!; + private Sprite fixedMiddle = null!; private readonly Color4 glowColour = new Color4(3, 151, 255, 255); - private Container scaleContainer; + private Container scaleContainer = null!; [BackgroundDependencyLoader] private void load(ISkinSource source) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs index a5a765fc02..e5efb668bc 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -23,9 +21,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy /// public class LegacyOldStyleSpinner : LegacySpinner { - private Sprite disc; - private Sprite metreSprite; - private Container metre; + private Sprite disc = null!; + private Sprite metreSprite = null!; + private Container metre = null!; private bool spinnerBlink; diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs index ff384ee7fc..7e9626eb7f 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -16,9 +14,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy public class LegacyReverseArrow : CompositeDrawable { [Resolved(canBeNull: true)] - private DrawableHitObject drawableHitObject { get; set; } + private DrawableHitObject? drawableHitObject { get; set; } - private Drawable proxy; + private Drawable proxy = null!; [BackgroundDependencyLoader] private void load(ISkinSource skinSource) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBody.cs index dbfec14eb2..29a0745193 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBody.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Extensions.Color4Extensions; using osu.Game.Rulesets.Osu.Objects; diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs index ab39d7c6ef..08b579697c 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -14,9 +12,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy public class LegacySliderHeadHitCircle : LegacyMainCirclePiece { [Resolved(canBeNull: true)] - private DrawableHitObject drawableHitObject { get; set; } + private DrawableHitObject? drawableHitObject { get; set; } - private Drawable proxiedOverlayLayer; + private Drawable proxiedOverlayLayer = null!; public LegacySliderHeadHitCircle() : base("sliderstartcircle") diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs index a817e5f2b7..66b195962b 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs @@ -1,12 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Globalization; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; @@ -32,17 +31,17 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy private const float spm_hide_offset = 50f; - protected DrawableSpinner DrawableSpinner { get; private set; } + protected DrawableSpinner DrawableSpinner { get; private set; } = null!; - public Drawable ApproachCircle { get; protected set; } + public Drawable? ApproachCircle { get; protected set; } - private Sprite spin; - private Sprite clear; + private Sprite spin = null!; + private Sprite clear = null!; - private LegacySpriteText bonusCounter; + private LegacySpriteText bonusCounter = null!; - private Sprite spmBackground; - private LegacySpriteText spmCounter; + private Sprite spmBackground = null!; + private LegacySpriteText spmCounter = null!; [BackgroundDependencyLoader] private void load(DrawableHitObject drawableHitObject, ISkinSource source) @@ -108,8 +107,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy }); } - private IBindable gainedBonus; - private IBindable spinsPerMinute; + private IBindable gainedBonus = null!; + private IBindable spinsPerMinute = null!; private readonly Bindable completed = new Bindable(); @@ -207,7 +206,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { base.Dispose(isDisposing); - if (DrawableSpinner != null) + if (DrawableSpinner.IsNotNull()) DrawableSpinner.ApplyCustomUpdateState -= UpdateStateTransforms; } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs index 856ccb5044..3bc2668733 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -30,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy hasHitCircle = new Lazy(() => GetTexture("hitcircle") != null); } - public override Drawable GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinComponent component) { if (component is OsuSkinComponent osuComponent) { @@ -145,7 +143,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy return base.GetDrawableComponent(component); } - public override IBindable GetConfig(TLookup lookup) + public override IBindable? GetConfig(TLookup lookup) { switch (lookup) { diff --git a/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs b/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs index 0b45c770ba..2a13f07cdb 100644 --- a/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs +++ b/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.Rulesets.UI; @@ -15,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Skinning /// public class NonPlayfieldSprite : Sprite { - public override Texture Texture + public override Texture? Texture { get => base.Texture; set diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuSkinColour.cs b/osu.Game.Rulesets.Osu/Skinning/OsuSkinColour.cs index 5d8a2ff606..24f9217a5f 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuSkinColour.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuSkinColour.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Osu.Skinning { public enum OsuSkinColour diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs index 1c0a62454b..77fea9d8f7 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Osu.Skinning { public enum OsuSkinConfiguration diff --git a/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs index a4a3316927..8ba9e75d19 100644 --- a/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using osu.Framework.Allocation; @@ -55,7 +53,7 @@ namespace osu.Game.Rulesets.Osu.Skinning /// private Vector2 snakedPathOffset; - private DrawableSlider drawableSlider; + private DrawableSlider drawableSlider = null!; [BackgroundDependencyLoader] private void load(DrawableHitObject drawableObject) @@ -67,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Skinning public void UpdateProgress(double completionProgress) { - if (drawableSlider?.HitObject == null) + if (drawableSlider.HitObject == null) return; Slider slider = drawableSlider.HitObject; @@ -96,7 +94,7 @@ namespace osu.Game.Rulesets.Osu.Skinning public void Refresh() { - if (drawableSlider?.HitObject == null) + if (drawableSlider.HitObject == null) return; // Generate the entire curve From a6165ea78ab06518eed3410b15869401943a4dd9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 13:37:04 +0900 Subject: [PATCH 0512/2991] Apply nullability to osu!mania skinning classes --- osu.Game.Rulesets.Mania/ManiaSkinComponent.cs | 2 -- .../Skinning/Default/DefaultBodyPiece.cs | 15 ++++++--------- .../Skinning/Default/DefaultNotePiece.cs | 5 +---- .../Skinning/Default/IHoldNoteBody.cs | 2 -- .../Skinning/Legacy/HitTargetInsetContainer.cs | 2 -- .../Skinning/Legacy/LegacyBodyPiece.cs | 17 ++++++----------- .../Skinning/Legacy/LegacyColumnBackground.cs | 6 ++---- .../Skinning/Legacy/LegacyHitExplosion.cs | 4 +--- .../Skinning/Legacy/LegacyHitTarget.cs | 4 +--- .../Skinning/Legacy/LegacyHoldNoteHeadPiece.cs | 4 +--- .../Skinning/Legacy/LegacyHoldNoteTailPiece.cs | 4 +--- .../Skinning/Legacy/LegacyKeyArea.cs | 10 ++++------ .../Legacy/LegacyManiaColumnElement.cs | 10 ++++------ .../Legacy/LegacyManiaJudgementPiece.cs | 18 +++++------------- .../Skinning/Legacy/LegacyNotePiece.cs | 16 +++++----------- .../Skinning/Legacy/LegacyStageForeground.cs | 4 +--- .../Legacy/ManiaClassicSkinTransformer.cs | 2 +- .../Skinning/ManiaSkinConfigExtensions.cs | 8 +++----- .../Skinning/ManiaSkinConfigurationLookup.cs | 2 -- 19 files changed, 42 insertions(+), 93 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs b/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs index f05edb4677..a074aab9da 100644 --- a/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs +++ b/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania diff --git a/osu.Game.Rulesets.Mania/Skinning/Default/DefaultBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Default/DefaultBodyPiece.cs index 7476af3c3c..f0e214b190 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Default/DefaultBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Default/DefaultBodyPiece.cs @@ -1,10 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; @@ -27,8 +24,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Default protected readonly Bindable AccentColour = new Bindable(); protected readonly IBindable IsHitting = new Bindable(); - protected Drawable Background { get; private set; } - private Container foregroundContainer; + protected Drawable Background { get; private set; } = null!; + private Container foregroundContainer = null!; public DefaultBodyPiece() { @@ -36,7 +33,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Default } [BackgroundDependencyLoader(true)] - private void load([CanBeNull] DrawableHitObject drawableObject) + private void load(DrawableHitObject? drawableObject) { InternalChildren = new[] { @@ -74,9 +71,9 @@ namespace osu.Game.Rulesets.Mania.Skinning.Default private readonly LayoutValue subtractionCache = new LayoutValue(Invalidation.DrawSize); - private BufferedContainer foregroundBuffer; - private BufferedContainer subtractionBuffer; - private Container subtractionLayer; + private BufferedContainer foregroundBuffer = null!; + private BufferedContainer subtractionBuffer = null!; + private Container subtractionLayer = null!; public ForegroundPiece() { diff --git a/osu.Game.Rulesets.Mania/Skinning/Default/DefaultNotePiece.cs b/osu.Game.Rulesets.Mania/Skinning/Default/DefaultNotePiece.cs index 72bb05de49..569740deee 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Default/DefaultNotePiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Default/DefaultNotePiece.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; @@ -53,7 +50,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Default } [BackgroundDependencyLoader(true)] - private void load([NotNull] IScrollingInfo scrollingInfo, [CanBeNull] DrawableHitObject drawableObject) + private void load(IScrollingInfo scrollingInfo, DrawableHitObject? drawableObject) { direction.BindTo(scrollingInfo.Direction); direction.BindValueChanged(onDirectionChanged, true); diff --git a/osu.Game.Rulesets.Mania/Skinning/Default/IHoldNoteBody.cs b/osu.Game.Rulesets.Mania/Skinning/Default/IHoldNoteBody.cs index 9168a96b95..1f290f1f1c 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Default/IHoldNoteBody.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Default/IHoldNoteBody.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Mania.Skinning.Default { /// diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/HitTargetInsetContainer.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/HitTargetInsetContainer.cs index 362a265789..3c89e2c04a 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/HitTargetInsetContainer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/HitTargetInsetContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs index 49ba503cb5..52bca2aaa0 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs @@ -1,12 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Textures; @@ -20,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { public class LegacyBodyPiece : LegacyManiaColumnElement { - private DrawableHoldNote holdNote; + private DrawableHoldNote holdNote = null!; private readonly IBindable direction = new Bindable(); private readonly IBindable isHitting = new Bindable(); @@ -31,14 +29,11 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy /// private readonly Bindable missFadeTime = new Bindable(); - [CanBeNull] - private Drawable bodySprite; + private Drawable? bodySprite; - [CanBeNull] - private Drawable lightContainer; + private Drawable? lightContainer; - [CanBeNull] - private Drawable light; + private Drawable? light; public LegacyBodyPiece() { @@ -214,7 +209,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { base.Dispose(isDisposing); - if (holdNote != null) + if (holdNote.IsNotNull()) holdNote.ApplyCustomUpdateState -= applyCustomUpdateState; lightContainer?.Expire(); diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyColumnBackground.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyColumnBackground.cs index f35cedab08..0ed96cf6f1 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyColumnBackground.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -21,8 +19,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { private readonly IBindable direction = new Bindable(); - private Container lightContainer; - private Sprite light; + private Container lightContainer = null!; + private Sprite light = null!; public LegacyColumnBackground() { diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitExplosion.cs index 278cf0707c..6b0e1e5d8a 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitExplosion.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -23,7 +21,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy private readonly IBindable direction = new Bindable(); - private Drawable explosion; + private Drawable? explosion; public LegacyHitExplosion() { diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitTarget.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitTarget.cs index 611dac30b3..ed78cb6086 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitTarget.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitTarget.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -20,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { private readonly IBindable direction = new Bindable(); - private Container directionContainer; + private Container directionContainer = null!; [BackgroundDependencyLoader] private void load(ISkinSource skin, IScrollingInfo scrollingInfo) diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteHeadPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteHeadPiece.cs index a653e2ce36..c3ed0111be 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteHeadPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteHeadPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Skinning; @@ -10,7 +8,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { public class LegacyHoldNoteHeadPiece : LegacyNotePiece { - protected override Drawable GetAnimation(ISkinSource skin) + protected override Drawable? GetAnimation(ISkinSource skin) { // TODO: Should fallback to the head from default legacy skin instead of note. return GetAnimationFromLookup(skin, LegacyManiaSkinConfigurationLookups.HoldNoteHeadImage) diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteTailPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteTailPiece.cs index 7511b008f0..13edc6e495 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteTailPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteTailPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Rulesets.UI.Scrolling; @@ -20,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy : new ValueChangedEvent(ScrollingDirection.Up, ScrollingDirection.Up)); } - protected override Drawable GetAnimation(ISkinSource skin) + protected override Drawable? GetAnimation(ISkinSource skin) { // TODO: Should fallback to the head from default legacy skin instead of note. return GetAnimationFromLookup(skin, LegacyManiaSkinConfigurationLookups.HoldNoteTailImage) diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyKeyArea.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyKeyArea.cs index dfd5af89c1..e7dca3d946 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyKeyArea.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyKeyArea.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -21,12 +19,12 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { private readonly IBindable direction = new Bindable(); - private Container directionContainer; - private Sprite upSprite; - private Sprite downSprite; + private Container directionContainer = null!; + private Sprite upSprite = null!; + private Sprite downSprite = null!; [Resolved] - private Column column { get; set; } + private Column column { get; set; } = null!; public LegacyKeyArea() { diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaColumnElement.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaColumnElement.cs index e227c80845..4ffef18781 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaColumnElement.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaColumnElement.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -19,15 +17,15 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy public class LegacyManiaColumnElement : CompositeDrawable { [Resolved] - protected Column Column { get; private set; } + protected Column Column { get; private set; } = null!; [Resolved] - private StageDefinition stage { get; set; } + private StageDefinition stage { get; set; } = null!; /// /// The column type identifier to use for texture lookups, in the case of no user-provided configuration. /// - protected string FallbackColumnIndex { get; private set; } + protected string FallbackColumnIndex { get; private set; } = null!; [BackgroundDependencyLoader] private void load() @@ -41,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy } } - protected IBindable GetColumnSkinConfig(ISkin skin, LegacyManiaSkinConfigurationLookups lookup) + protected IBindable? GetColumnSkinConfig(ISkin skin, LegacyManiaSkinConfigurationLookups lookup) where T : notnull => skin.GetManiaSkinConfig(lookup, Column.Index); } } diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaJudgementPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaJudgementPiece.cs index d09a73a693..670a0aad6e 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaJudgementPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaJudgementPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; @@ -41,21 +39,15 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy Y = scorePosition ?? 0; - if (animation != null) + InternalChild = animation.With(d => { - InternalChild = animation.With(d => - { - d.Anchor = Anchor.Centre; - d.Origin = Anchor.Centre; - }); - } + d.Anchor = Anchor.Centre; + d.Origin = Anchor.Centre; + }); } public void PlayAnimation() { - if (animation == null) - return; - (animation as IFramedAnimation)?.GotoFrame(0); this.FadeInFromZero(20, Easing.Out) @@ -86,6 +78,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy } } - public Drawable GetAboveHitObjectsProxiedContent() => null; + public Drawable? GetAboveHitObjectsProxiedContent() => null; } } diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyNotePiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyNotePiece.cs index 41e149ea2f..8c5a594b3b 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyNotePiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyNotePiece.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -21,10 +18,9 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { private readonly IBindable direction = new Bindable(); - private Container directionContainer; + private Container directionContainer = null!; - [CanBeNull] - private Drawable noteAnimation; + private Drawable noteAnimation = null!; private float? minimumColumnWidth; @@ -55,7 +51,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { base.Update(); - Texture texture = null; + Texture? texture = null; if (noteAnimation is Sprite sprite) texture = sprite.Texture; @@ -84,11 +80,9 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy } } - [CanBeNull] - protected virtual Drawable GetAnimation(ISkinSource skin) => GetAnimationFromLookup(skin, LegacyManiaSkinConfigurationLookups.NoteImage); + protected virtual Drawable? GetAnimation(ISkinSource skin) => GetAnimationFromLookup(skin, LegacyManiaSkinConfigurationLookups.NoteImage); - [CanBeNull] - protected Drawable GetAnimationFromLookup(ISkin skin, LegacyManiaSkinConfigurationLookups lookup) + protected Drawable? GetAnimationFromLookup(ISkin skin, LegacyManiaSkinConfigurationLookups lookup) { string suffix = string.Empty; diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageForeground.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageForeground.cs index f7c611d551..8e72e970ab 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageForeground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageForeground.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -17,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { private readonly IBindable direction = new Bindable(); - private Drawable sprite; + private Drawable? sprite; public LegacyStageForeground() { diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaClassicSkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaClassicSkinTransformer.cs index e57927897c..be3372fe58 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaClassicSkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaClassicSkinTransformer.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy { } - public override IBindable GetConfig(TLookup lookup) + public override IBindable? GetConfig(TLookup lookup) { if (lookup is ManiaSkinConfigurationLookup maniaLookup) { diff --git a/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigExtensions.cs b/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigExtensions.cs index e22bf63049..0f15bfe12b 100644 --- a/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigExtensions.cs +++ b/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigExtensions.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osu.Game.Skinning; @@ -16,8 +14,8 @@ namespace osu.Game.Rulesets.Mania.Skinning /// The skin from which configuration is retrieved. /// The value to retrieve. /// If not null, denotes the index of the column to which the entry applies. - public static IBindable GetManiaSkinConfig(this ISkin skin, LegacyManiaSkinConfigurationLookups lookup, int? columnIndex = null) - => skin.GetConfig( - new ManiaSkinConfigurationLookup(lookup, columnIndex)); + public static IBindable? GetManiaSkinConfig(this ISkin skin, LegacyManiaSkinConfigurationLookups lookup, int? columnIndex = null) + where T : notnull + => skin.GetConfig(new ManiaSkinConfigurationLookup(lookup, columnIndex)); } } diff --git a/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigurationLookup.cs b/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigurationLookup.cs index 59188f02f9..6c39ffdcc3 100644 --- a/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigurationLookup.cs +++ b/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigurationLookup.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Mania.UI; using osu.Game.Skinning; From 2952dbc8fb9ffd0e7c3475dcdf5ea123431d559a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 13:37:19 +0900 Subject: [PATCH 0513/2991] Apply nullability to osu!catch skinning classes --- osu.Game.Rulesets.Catch/CatchInputManager.cs | 2 -- osu.Game.Rulesets.Catch/CatchSkinComponent.cs | 2 -- .../CatchSkinComponents.cs | 2 -- .../Skinning/CatchSkinColour.cs | 2 -- .../Skinning/CatchSkinConfiguration.cs | 2 -- .../Skinning/Default/BananaPulpFormation.cs | 2 -- .../Skinning/Default/BorderPiece.cs | 2 -- .../Skinning/Default/CatchHitObjectPiece.cs | 11 +++------ .../Skinning/Default/DefaultCatcher.cs | 2 -- .../Skinning/Default/DefaultHitExplosion.cs | 10 ++++---- .../Skinning/Default/DropletPiece.cs | 2 -- .../Skinning/Default/FruitPiece.cs | 2 -- .../Skinning/Default/FruitPulpFormation.cs | 2 -- .../Skinning/Default/HyperBorderPiece.cs | 2 -- .../Default/HyperDropletBorderPiece.cs | 2 -- .../Skinning/Default/Pulp.cs | 2 -- .../Skinning/Default/PulpFormation.cs | 2 -- .../Legacy/CatchLegacySkinTransformer.cs | 8 +++---- .../Skinning/Legacy/LegacyBananaPiece.cs | 6 ++--- .../Legacy/LegacyCatchHitObjectPiece.cs | 23 +++++++++---------- .../Skinning/Legacy/LegacyCatcherNew.cs | 9 ++++---- .../Skinning/Legacy/LegacyCatcherOld.cs | 4 +--- .../Skinning/Legacy/LegacyDropletPiece.cs | 6 ++--- .../Skinning/Legacy/LegacyFruitPiece.cs | 2 -- .../Skinning/Legacy/LegacyHitExplosion.cs | 4 +--- 25 files changed, 31 insertions(+), 82 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchInputManager.cs b/osu.Game.Rulesets.Catch/CatchInputManager.cs index 5b62154a34..0f76953003 100644 --- a/osu.Game.Rulesets.Catch/CatchInputManager.cs +++ b/osu.Game.Rulesets.Catch/CatchInputManager.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.ComponentModel; using osu.Framework.Allocation; using osu.Framework.Input.Bindings; diff --git a/osu.Game.Rulesets.Catch/CatchSkinComponent.cs b/osu.Game.Rulesets.Catch/CatchSkinComponent.cs index e79da667da..07c613d6ff 100644 --- a/osu.Game.Rulesets.Catch/CatchSkinComponent.cs +++ b/osu.Game.Rulesets.Catch/CatchSkinComponent.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch diff --git a/osu.Game.Rulesets.Catch/CatchSkinComponents.cs b/osu.Game.Rulesets.Catch/CatchSkinComponents.cs index 7587de5803..371e901c69 100644 --- a/osu.Game.Rulesets.Catch/CatchSkinComponents.cs +++ b/osu.Game.Rulesets.Catch/CatchSkinComponents.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Catch { public enum CatchSkinComponents diff --git a/osu.Game.Rulesets.Catch/Skinning/CatchSkinColour.cs b/osu.Game.Rulesets.Catch/Skinning/CatchSkinColour.cs index d038ccb31c..4506111498 100644 --- a/osu.Game.Rulesets.Catch/Skinning/CatchSkinColour.cs +++ b/osu.Game.Rulesets.Catch/Skinning/CatchSkinColour.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Catch.Skinning { public enum CatchSkinColour diff --git a/osu.Game.Rulesets.Catch/Skinning/CatchSkinConfiguration.cs b/osu.Game.Rulesets.Catch/Skinning/CatchSkinConfiguration.cs index 65d6acd88d..ea8d742b1a 100644 --- a/osu.Game.Rulesets.Catch/Skinning/CatchSkinConfiguration.cs +++ b/osu.Game.Rulesets.Catch/Skinning/CatchSkinConfiguration.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Catch.Skinning { public enum CatchSkinConfiguration diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/BananaPulpFormation.cs b/osu.Game.Rulesets.Catch/Skinning/Default/BananaPulpFormation.cs index ffeed80615..ee1cc68f7d 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/BananaPulpFormation.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/BananaPulpFormation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osuTK; namespace osu.Game.Rulesets.Catch.Skinning.Default diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/BorderPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/BorderPiece.cs index 60a13bee59..8d8ee49af7 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/BorderPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/BorderPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Catch.Objects; diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs index 3b8df6ee6f..e84e4d4ad2 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs @@ -1,10 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -21,19 +18,17 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default public readonly Bindable IndexInBeatmap = new Bindable(); [Resolved] - protected IHasCatchObjectState ObjectState { get; private set; } + protected IHasCatchObjectState ObjectState { get; private set; } = null!; /// /// A part of this piece that will be faded out while falling in the playfield. /// - [CanBeNull] - protected virtual Drawable BorderPiece => null; + protected virtual Drawable? BorderPiece => null; /// /// A part of this piece that will be only visible when is true. /// - [CanBeNull] - protected virtual Drawable HyperBorderPiece => null; + protected virtual Drawable? HyperBorderPiece => null; protected override void LoadComplete() { diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultCatcher.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultCatcher.cs index 4148fed11c..e423f21b98 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultCatcher.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultCatcher.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs index 7ea99b3ed9..2650ba765b 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -18,10 +16,10 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default { public class DefaultHitExplosion : CompositeDrawable, IHitExplosion { - private CircularContainer largeFaint; - private CircularContainer smallFaint; - private CircularContainer directionalGlow1; - private CircularContainer directionalGlow2; + private CircularContainer largeFaint = null!; + private CircularContainer smallFaint = null!; + private CircularContainer directionalGlow1 = null!; + private CircularContainer directionalGlow2 = null!; [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs index b8ae062382..59e74bff74 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Objects; using osuTK; diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs index adee960c3c..3bd8032649 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Objects; diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPulpFormation.cs b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPulpFormation.cs index db51195f11..f097361d2a 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPulpFormation.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPulpFormation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osu.Game.Rulesets.Catch.Objects; using osuTK; diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/HyperBorderPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/HyperBorderPiece.cs index 42b0b85495..c8895f32f4 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/HyperBorderPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/HyperBorderPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.UI; diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/HyperDropletBorderPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/HyperDropletBorderPiece.cs index 29cb339625..53a487b97f 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/HyperDropletBorderPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/HyperDropletBorderPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Catch.Skinning.Default { public class HyperDropletBorderPiece : HyperBorderPiece diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/Pulp.cs b/osu.Game.Rulesets.Catch/Skinning/Default/Pulp.cs index 8ea54617d9..96c6233b41 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/Pulp.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/Pulp.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/PulpFormation.cs b/osu.Game.Rulesets.Catch/Skinning/Default/PulpFormation.cs index aa5ef5fb66..8753aa4077 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/PulpFormation.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/PulpFormation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Bindables; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs index a73b34c9b6..ef83e67876 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -27,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { } - public override Drawable GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinComponent component) { if (component is SkinnableTargetComponent targetComponent) { @@ -112,12 +110,12 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy GetTexture(@"fruit-catcher-idle") != null || GetTexture(@"fruit-catcher-idle-0") != null; - public override IBindable GetConfig(TLookup lookup) + public override IBindable? GetConfig(TLookup lookup) { switch (lookup) { case CatchSkinColour colour: - var result = (Bindable)base.GetConfig(new SkinCustomColourLookup(colour)); + var result = (Bindable?)base.GetConfig(new SkinCustomColourLookup(colour)); if (result == null) return null; diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyBananaPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyBananaPiece.cs index 9f64a2129e..310da8bf78 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyBananaPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyBananaPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics.Textures; namespace osu.Game.Rulesets.Catch.Skinning.Legacy @@ -13,8 +11,8 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { base.LoadComplete(); - Texture texture = Skin.GetTexture("fruit-bananas"); - Texture overlayTexture = Skin.GetTexture("fruit-bananas-overlay"); + Texture? texture = Skin.GetTexture("fruit-bananas"); + Texture? overlayTexture = Skin.GetTexture("fruit-bananas-overlay"); SetTexture(texture, overlayTexture); } diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchHitObjectPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchHitObjectPiece.cs index 5a5288105d..1231ed6d5a 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchHitObjectPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchHitObjectPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -19,19 +17,20 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { public abstract class LegacyCatchHitObjectPiece : PoolableDrawable { - public readonly Bindable AccentColour = new Bindable(); - public readonly Bindable HyperDash = new Bindable(); - public readonly Bindable IndexInBeatmap = new Bindable(); + protected readonly Bindable IndexInBeatmap = new Bindable(); + + private readonly Bindable accentColour = new Bindable(); + private readonly Bindable hyperDash = new Bindable(); private readonly Sprite colouredSprite; private readonly Sprite overlaySprite; private readonly Sprite hyperSprite; [Resolved] - protected ISkinSource Skin { get; private set; } + protected ISkinSource Skin { get; private set; } = null!; [Resolved] - protected IHasCatchObjectState ObjectState { get; private set; } + protected IHasCatchObjectState ObjectState { get; private set; } = null!; protected LegacyCatchHitObjectPiece() { @@ -65,26 +64,26 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { base.LoadComplete(); - AccentColour.BindTo(ObjectState.AccentColour); - HyperDash.BindTo(ObjectState.HyperDash); + accentColour.BindTo(ObjectState.AccentColour); + hyperDash.BindTo(ObjectState.HyperDash); IndexInBeatmap.BindTo(ObjectState.IndexInBeatmap); hyperSprite.Colour = Skin.GetConfig(CatchSkinColour.HyperDashFruit)?.Value ?? Skin.GetConfig(CatchSkinColour.HyperDash)?.Value ?? Catcher.DEFAULT_HYPER_DASH_COLOUR; - AccentColour.BindValueChanged(colour => + accentColour.BindValueChanged(colour => { colouredSprite.Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue); }, true); - HyperDash.BindValueChanged(hyper => + hyperDash.BindValueChanged(hyper => { hyperSprite.Alpha = hyper.NewValue ? 0.7f : 0; }, true); } - protected void SetTexture(Texture texture, Texture overlayTexture) + protected void SetTexture(Texture? texture, Texture? overlayTexture) { colouredSprite.Texture = texture; overlaySprite.Texture = overlayTexture; diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs index 93d79f00d3..667622e6f2 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -20,11 +18,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy public class LegacyCatcherNew : CompositeDrawable { [Resolved] - private Bindable currentState { get; set; } + private Bindable currentState { get; set; } = null!; private readonly Dictionary drawables = new Dictionary(); - private Drawable currentDrawable; + private Drawable currentDrawable = null!; public LegacyCatcherNew() { @@ -51,7 +49,8 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy Drawable getDrawableFor(CatcherAnimationState state) => skin.GetAnimation(@$"fruit-catcher-{state.ToString().ToLowerInvariant()}", true, true, true) ?? - skin.GetAnimation(@"fruit-catcher-idle", true, true, true); + skin.GetAnimation(@"fruit-catcher-idle", true, true, true) ?? + Empty(); } protected override void LoadComplete() diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherOld.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherOld.cs index 736e9cfddf..5f09d1e254 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherOld.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherOld.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -21,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy [BackgroundDependencyLoader] private void load(ISkinSource skin) { - InternalChild = skin.GetAnimation(@"fruit-ryuuta", true, true, true).With(d => + InternalChild = (skin.GetAnimation(@"fruit-ryuuta", true, true, true) ?? Empty()).With(d => { d.Anchor = Anchor.TopCentre; d.Origin = Anchor.TopCentre; diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyDropletPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyDropletPiece.cs index f99cedab3f..7007f1cc29 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyDropletPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyDropletPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics.Textures; using osuTK; @@ -19,8 +17,8 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { base.LoadComplete(); - Texture texture = Skin.GetTexture("fruit-drop"); - Texture overlayTexture = Skin.GetTexture("fruit-drop-overlay"); + Texture? texture = Skin.GetTexture("fruit-drop"); + Texture? overlayTexture = Skin.GetTexture("fruit-drop-overlay"); SetTexture(texture, overlayTexture); } diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyFruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyFruitPiece.cs index 125a96a446..f002bab219 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyFruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyFruitPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Objects; namespace osu.Game.Rulesets.Catch.Skinning.Legacy diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs index 8f46bdbe6e..393a1076af 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -18,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy public class LegacyHitExplosion : CompositeDrawable, IHitExplosion { [Resolved] - private Catcher catcher { get; set; } + private Catcher catcher { get; set; } = null!; private const float catch_margin = (1 - Catcher.ALLOWED_CATCH_RANGE) / 2; From bf26dbffc2e48458f48d4e8433d2b96f49eacf82 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 13:44:59 +0900 Subject: [PATCH 0514/2991] Apply nullability to skinning support classes --- .../Judgements/IAnimatableJudgement.cs | 6 +-- osu.Game/Skinning/ArgonSkin.cs | 13 +++--- osu.Game/Skinning/DefaultLegacySkin.cs | 2 - osu.Game/Skinning/GameplaySkinComponent.cs | 3 +- osu.Game/Skinning/GlobalSkinColours.cs | 2 - osu.Game/Skinning/IAnimationTimeReference.cs | 2 - osu.Game/Skinning/IPooledSampleProvider.cs | 6 +-- osu.Game/Skinning/ISkinComponent.cs | 2 - osu.Game/Skinning/ISkinSource.cs | 6 +-- osu.Game/Skinning/ISkinnableDrawable.cs | 2 - osu.Game/Skinning/ISkinnableTarget.cs | 2 - osu.Game/Skinning/LegacyAccuracyCounter.cs | 2 - .../Skinning/LegacyColourCompatibility.cs | 2 - osu.Game/Skinning/LegacyComboCounter.cs | 2 - osu.Game/Skinning/LegacyFont.cs | 2 - osu.Game/Skinning/LegacyJudgementPieceNew.cs | 10 ++--- osu.Game/Skinning/LegacySkin.cs | 8 ++-- osu.Game/Skinning/SkinComboColourLookup.cs | 2 - osu.Game/Skinning/SkinConfigManager.cs | 2 - osu.Game/Skinning/SkinConfiguration.cs | 4 +- osu.Game/Skinning/SkinProvidingContainer.cs | 40 +++++++++---------- osu.Game/Skinning/SkinReloadableDrawable.cs | 9 ++--- osu.Game/Skinning/SkinUtils.cs | 4 +- osu.Game/Skinning/SkinnableSprite.cs | 16 ++++---- osu.Game/Skinning/SkinnableSpriteText.cs | 2 - osu.Game/Skinning/SkinnableTarget.cs | 2 - osu.Game/Skinning/SkinnableTargetComponent.cs | 2 - .../SkinnableTargetComponentsContainer.cs | 4 +- osu.Game/Skinning/SkinnableTargetContainer.cs | 6 +-- osu.Game/Skinning/TrianglesSkin.cs | 12 +++--- .../UnsupportedSkinComponentException.cs | 2 - 31 files changed, 60 insertions(+), 119 deletions(-) diff --git a/osu.Game/Rulesets/Judgements/IAnimatableJudgement.cs b/osu.Game/Rulesets/Judgements/IAnimatableJudgement.cs index 2bc5a62983..0aa337bc20 100644 --- a/osu.Game/Rulesets/Judgements/IAnimatableJudgement.cs +++ b/osu.Game/Rulesets/Judgements/IAnimatableJudgement.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Graphics; namespace osu.Game.Rulesets.Judgements @@ -21,7 +18,6 @@ namespace osu.Game.Rulesets.Judgements /// /// Get proxied content which should be displayed above all hitobjects. /// - [CanBeNull] - Drawable GetAboveHitObjectsProxiedContent(); + Drawable? GetAboveHitObjectsProxiedContent(); } } diff --git a/osu.Game/Skinning/ArgonSkin.cs b/osu.Game/Skinning/ArgonSkin.cs index 010e2175e1..20e4290725 100644 --- a/osu.Game/Skinning/ArgonSkin.cs +++ b/osu.Game/Skinning/ArgonSkin.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. -#nullable disable using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; @@ -25,7 +24,7 @@ namespace osu.Game.Skinning { public static SkinInfo CreateInfo() => new SkinInfo { - ID = osu.Game.Skinning.SkinInfo.ARGON_SKIN, + ID = Skinning.SkinInfo.ARGON_SKIN, Name = "osu! \"argon\" (2022)", Creator = "team osu!", Protected = true, @@ -68,9 +67,9 @@ namespace osu.Game.Skinning }; } - public override Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => Textures?.Get(componentName, wrapModeS, wrapModeT); + public override Texture? GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => Textures?.Get(componentName, wrapModeS, wrapModeT); - public override ISample GetSample(ISampleInfo sampleInfo) + public override ISample? GetSample(ISampleInfo sampleInfo) { foreach (string lookup in sampleInfo.LookupNames) { @@ -82,7 +81,7 @@ namespace osu.Game.Skinning return null; } - public override Drawable GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinComponent component) { if (base.GetDrawableComponent(component) is Drawable c) return c; @@ -192,7 +191,7 @@ namespace osu.Game.Skinning return null; } - public override IBindable GetConfig(TLookup lookup) + public override IBindable? GetConfig(TLookup lookup) { // todo: this code is pulled from LegacySkin and should not exist. // will likely change based on how databased storage of skin configuration goes. @@ -202,7 +201,7 @@ namespace osu.Game.Skinning switch (global) { case GlobalSkinColours.ComboColours: - return SkinUtils.As(new Bindable>(Configuration.ComboColours)); + return SkinUtils.As(new Bindable?>(Configuration.ComboColours)); } break; diff --git a/osu.Game/Skinning/DefaultLegacySkin.cs b/osu.Game/Skinning/DefaultLegacySkin.cs index b80275a1e8..fd9653e3e5 100644 --- a/osu.Game/Skinning/DefaultLegacySkin.cs +++ b/osu.Game/Skinning/DefaultLegacySkin.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using JetBrains.Annotations; using osu.Framework.IO.Stores; diff --git a/osu.Game/Skinning/GameplaySkinComponent.cs b/osu.Game/Skinning/GameplaySkinComponent.cs index cdd3638375..6f5dad2207 100644 --- a/osu.Game/Skinning/GameplaySkinComponent.cs +++ b/osu.Game/Skinning/GameplaySkinComponent.cs @@ -1,13 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; namespace osu.Game.Skinning { public class GameplaySkinComponent : ISkinComponent + where T : notnull { public readonly T Component; diff --git a/osu.Game/Skinning/GlobalSkinColours.cs b/osu.Game/Skinning/GlobalSkinColours.cs index e2b5799048..f889371b98 100644 --- a/osu.Game/Skinning/GlobalSkinColours.cs +++ b/osu.Game/Skinning/GlobalSkinColours.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Skinning { public enum GlobalSkinColours diff --git a/osu.Game/Skinning/IAnimationTimeReference.cs b/osu.Game/Skinning/IAnimationTimeReference.cs index a65d15d24b..b6a944ddf8 100644 --- a/osu.Game/Skinning/IAnimationTimeReference.cs +++ b/osu.Game/Skinning/IAnimationTimeReference.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Textures; diff --git a/osu.Game/Skinning/IPooledSampleProvider.cs b/osu.Game/Skinning/IPooledSampleProvider.cs index 46cd824e95..3ea299f5e2 100644 --- a/osu.Game/Skinning/IPooledSampleProvider.cs +++ b/osu.Game/Skinning/IPooledSampleProvider.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Game.Audio; namespace osu.Game.Skinning @@ -18,7 +15,6 @@ namespace osu.Game.Skinning /// /// The describing the sample to retrieve. /// The . - [CanBeNull] - PoolableSkinnableSample GetPooledSample(ISampleInfo sampleInfo); + PoolableSkinnableSample? GetPooledSample(ISampleInfo sampleInfo); } } diff --git a/osu.Game/Skinning/ISkinComponent.cs b/osu.Game/Skinning/ISkinComponent.cs index 34922b98b6..4bd9f21b6b 100644 --- a/osu.Game/Skinning/ISkinComponent.cs +++ b/osu.Game/Skinning/ISkinComponent.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Skinning { public interface ISkinComponent diff --git a/osu.Game/Skinning/ISkinSource.cs b/osu.Game/Skinning/ISkinSource.cs index 94940fd549..89f656a12c 100644 --- a/osu.Game/Skinning/ISkinSource.cs +++ b/osu.Game/Skinning/ISkinSource.cs @@ -1,11 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; -using JetBrains.Annotations; namespace osu.Game.Skinning { @@ -24,8 +21,7 @@ namespace osu.Game.Skinning /// This should be used for cases where subsequent lookups (for related components) need to occur on the same skin. /// /// The skin to be used for subsequent lookups, or null if none is available. - [CanBeNull] - ISkin FindProvider(Func lookupFunction); + ISkin? FindProvider(Func lookupFunction); /// /// Retrieve all sources available for lookup, with highest priority source first. diff --git a/osu.Game/Skinning/ISkinnableDrawable.cs b/osu.Game/Skinning/ISkinnableDrawable.cs index ca643af17a..3fc6a2fdd8 100644 --- a/osu.Game/Skinning/ISkinnableDrawable.cs +++ b/osu.Game/Skinning/ISkinnableDrawable.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Bindables; using osu.Framework.Extensions.TypeExtensions; diff --git a/osu.Game/Skinning/ISkinnableTarget.cs b/osu.Game/Skinning/ISkinnableTarget.cs index 17279ef178..8d4f4dd0c3 100644 --- a/osu.Game/Skinning/ISkinnableTarget.cs +++ b/osu.Game/Skinning/ISkinnableTarget.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Framework.Bindables; diff --git a/osu.Game/Skinning/LegacyAccuracyCounter.cs b/osu.Game/Skinning/LegacyAccuracyCounter.cs index ffb463faae..bdcb85456a 100644 --- a/osu.Game/Skinning/LegacyAccuracyCounter.cs +++ b/osu.Game/Skinning/LegacyAccuracyCounter.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Screens.Play.HUD; diff --git a/osu.Game/Skinning/LegacyColourCompatibility.cs b/osu.Game/Skinning/LegacyColourCompatibility.cs index 0673d0a8d3..38e43432ce 100644 --- a/osu.Game/Skinning/LegacyColourCompatibility.cs +++ b/osu.Game/Skinning/LegacyColourCompatibility.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osuTK.Graphics; diff --git a/osu.Game/Skinning/LegacyComboCounter.cs b/osu.Game/Skinning/LegacyComboCounter.cs index bfa6d5a255..f4caef26c2 100644 --- a/osu.Game/Skinning/LegacyComboCounter.cs +++ b/osu.Game/Skinning/LegacyComboCounter.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; diff --git a/osu.Game/Skinning/LegacyFont.cs b/osu.Game/Skinning/LegacyFont.cs index f738caf3f3..d1971cb84c 100644 --- a/osu.Game/Skinning/LegacyFont.cs +++ b/osu.Game/Skinning/LegacyFont.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Skinning { /// diff --git a/osu.Game/Skinning/LegacyJudgementPieceNew.cs b/osu.Game/Skinning/LegacyJudgementPieceNew.cs index 2cb055d8ba..39b266ab9f 100644 --- a/osu.Game/Skinning/LegacyJudgementPieceNew.cs +++ b/osu.Game/Skinning/LegacyJudgementPieceNew.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; @@ -20,13 +18,13 @@ namespace osu.Game.Skinning { private readonly HitResult result; - private readonly LegacyJudgementPieceOld temporaryOldStyle; + private readonly LegacyJudgementPieceOld? temporaryOldStyle; private readonly Drawable mainPiece; - private readonly ParticleExplosion particles; + private readonly ParticleExplosion? particles; - public LegacyJudgementPieceNew(HitResult result, Func createMainDrawable, Texture particleTexture) + public LegacyJudgementPieceNew(HitResult result, Func createMainDrawable, Texture? particleTexture) { this.result = result; @@ -124,6 +122,6 @@ namespace osu.Game.Skinning } } - public Drawable GetAboveHitObjectsProxiedContent() => temporaryOldStyle?.CreateProxy(); // for new style judgements, only the old style temporary display is in front of objects. + public Drawable? GetAboveHitObjectsProxiedContent() => temporaryOldStyle?.CreateProxy(); // for new style judgements, only the old style temporary display is in front of objects. } } diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index eaca0de11a..bfc60de2c9 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -9,6 +9,7 @@ using System.Linq; using JetBrains.Annotations; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; @@ -379,12 +380,13 @@ namespace osu.Game.Skinning return null; case GameplaySkinComponent resultComponent: - // TODO: this should be inside the judgement pieces. - Func createDrawable = () => getJudgementAnimation(resultComponent.Component); // kind of wasteful that we throw this away, but should do for now. - if (createDrawable() != null) + if (getJudgementAnimation(resultComponent.Component) != null) { + // TODO: this should be inside the judgement pieces. + Func createDrawable = () => getJudgementAnimation(resultComponent.Component).AsNonNull(); + var particle = getParticleTexture(resultComponent.Component); if (particle != null) diff --git a/osu.Game/Skinning/SkinComboColourLookup.cs b/osu.Game/Skinning/SkinComboColourLookup.cs index 2eb4af6289..33e35a96fb 100644 --- a/osu.Game/Skinning/SkinComboColourLookup.cs +++ b/osu.Game/Skinning/SkinComboColourLookup.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Skinning diff --git a/osu.Game/Skinning/SkinConfigManager.cs b/osu.Game/Skinning/SkinConfigManager.cs index 8a34ab3db4..682138a2e9 100644 --- a/osu.Game/Skinning/SkinConfigManager.cs +++ b/osu.Game/Skinning/SkinConfigManager.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Configuration; diff --git a/osu.Game/Skinning/SkinConfiguration.cs b/osu.Game/Skinning/SkinConfiguration.cs index a9f660312e..937cca0aeb 100644 --- a/osu.Game/Skinning/SkinConfiguration.cs +++ b/osu.Game/Skinning/SkinConfiguration.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Beatmaps.Formats; using osuTK.Graphics; @@ -52,7 +50,7 @@ namespace osu.Game.Skinning public List CustomComboColours { get; set; } = new List(); - public IReadOnlyList ComboColours + public IReadOnlyList? ComboColours { get { diff --git a/osu.Game/Skinning/SkinProvidingContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs index 42c39e581f..5c5e9ae0fc 100644 --- a/osu.Game/Skinning/SkinProvidingContainer.cs +++ b/osu.Game/Skinning/SkinProvidingContainer.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; @@ -22,10 +19,9 @@ namespace osu.Game.Skinning /// public class SkinProvidingContainer : Container, ISkinSource { - public event Action SourceChanged; + public event Action? SourceChanged; - [CanBeNull] - protected ISkinSource ParentSource { get; private set; } + protected ISkinSource? ParentSource { get; private set; } /// /// Whether falling back to parent s is allowed in this container. @@ -52,7 +48,7 @@ namespace osu.Game.Skinning /// /// Constructs a new initialised with a single skin source. /// - public SkinProvidingContainer([CanBeNull] ISkin skin) + public SkinProvidingContainer(ISkin? skin) : this() { if (skin != null) @@ -82,7 +78,7 @@ namespace osu.Game.Skinning return dependencies; } - public ISkin FindProvider(Func lookupFunction) + public ISkin? FindProvider(Func lookupFunction) { foreach (var (skin, lookupWrapper) in skinSources) { @@ -111,11 +107,11 @@ namespace osu.Game.Skinning } } - public Drawable GetDrawableComponent(ISkinComponent component) + public Drawable? GetDrawableComponent(ISkinComponent component) { foreach (var (_, lookupWrapper) in skinSources) { - Drawable sourceDrawable; + Drawable? sourceDrawable; if ((sourceDrawable = lookupWrapper.GetDrawableComponent(component)) != null) return sourceDrawable; } @@ -126,11 +122,11 @@ namespace osu.Game.Skinning return ParentSource?.GetDrawableComponent(component); } - public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) + public Texture? GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) { foreach (var (_, lookupWrapper) in skinSources) { - Texture sourceTexture; + Texture? sourceTexture; if ((sourceTexture = lookupWrapper.GetTexture(componentName, wrapModeS, wrapModeT)) != null) return sourceTexture; } @@ -141,11 +137,11 @@ namespace osu.Game.Skinning return ParentSource?.GetTexture(componentName, wrapModeS, wrapModeT); } - public ISample GetSample(ISampleInfo sampleInfo) + public ISample? GetSample(ISampleInfo sampleInfo) { foreach (var (_, lookupWrapper) in skinSources) { - ISample sourceSample; + ISample? sourceSample; if ((sourceSample = lookupWrapper.GetSample(sampleInfo)) != null) return sourceSample; } @@ -156,11 +152,13 @@ namespace osu.Game.Skinning return ParentSource?.GetSample(sampleInfo); } - public IBindable GetConfig(TLookup lookup) + public IBindable? GetConfig(TLookup lookup) + where TLookup : notnull + where TValue : notnull { foreach (var (_, lookupWrapper) in skinSources) { - IBindable bindable; + IBindable? bindable; if ((bindable = lookupWrapper.GetConfig(lookup)) != null) return bindable; } @@ -240,7 +238,7 @@ namespace osu.Game.Skinning this.provider = provider; } - public Drawable GetDrawableComponent(ISkinComponent component) + public Drawable? GetDrawableComponent(ISkinComponent component) { if (provider.AllowDrawableLookup(component)) return skin.GetDrawableComponent(component); @@ -248,7 +246,7 @@ namespace osu.Game.Skinning return null; } - public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) + public Texture? GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) { if (provider.AllowTextureLookup(componentName)) return skin.GetTexture(componentName, wrapModeS, wrapModeT); @@ -256,7 +254,7 @@ namespace osu.Game.Skinning return null; } - public ISample GetSample(ISampleInfo sampleInfo) + public ISample? GetSample(ISampleInfo sampleInfo) { if (provider.AllowSampleLookup(sampleInfo)) return skin.GetSample(sampleInfo); @@ -264,7 +262,9 @@ namespace osu.Game.Skinning return null; } - public IBindable GetConfig(TLookup lookup) + public IBindable? GetConfig(TLookup lookup) + where TLookup : notnull + where TValue : notnull { switch (lookup) { diff --git a/osu.Game/Skinning/SkinReloadableDrawable.cs b/osu.Game/Skinning/SkinReloadableDrawable.cs index c6332fc4d2..f1c8388f71 100644 --- a/osu.Game/Skinning/SkinReloadableDrawable.cs +++ b/osu.Game/Skinning/SkinReloadableDrawable.cs @@ -1,10 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.Pooling; namespace osu.Game.Skinning @@ -17,12 +16,12 @@ namespace osu.Game.Skinning /// /// Invoked when has changed. /// - public event Action OnSkinChanged; + public event Action? OnSkinChanged; /// /// The current skin source. /// - protected ISkinSource CurrentSkin { get; private set; } + protected ISkinSource CurrentSkin { get; private set; } = null!; [BackgroundDependencyLoader] private void load(ISkinSource source) @@ -60,7 +59,7 @@ namespace osu.Game.Skinning { base.Dispose(isDisposing); - if (CurrentSkin != null) + if (CurrentSkin.IsNotNull()) CurrentSkin.SourceChanged -= onChange; OnSkinChanged = null; diff --git a/osu.Game/Skinning/SkinUtils.cs b/osu.Game/Skinning/SkinUtils.cs index 8e01bd2853..75eae82401 100644 --- a/osu.Game/Skinning/SkinUtils.cs +++ b/osu.Game/Skinning/SkinUtils.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; namespace osu.Game.Skinning @@ -18,6 +16,6 @@ namespace osu.Game.Skinning /// The value. /// The type of value , and the type of the resulting bindable. /// The resulting bindable. - public static Bindable As(object value) => (Bindable)value; + public static Bindable? As(object? value) => (Bindable?)value; } } diff --git a/osu.Game/Skinning/SkinnableSprite.cs b/osu.Game/Skinning/SkinnableSprite.cs index 5a39121b16..f8130f31c3 100644 --- a/osu.Game/Skinning/SkinnableSprite.cs +++ b/osu.Game/Skinning/SkinnableSprite.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -27,13 +25,13 @@ namespace osu.Game.Skinning protected override bool ApplySizeRestrictionsToDefault => true; [Resolved] - private TextureStore textures { get; set; } + private TextureStore textures { get; set; } = null!; [SettingSource("Sprite name", "The filename of the sprite", SettingControlType = typeof(SpriteSelectorControl))] public Bindable SpriteName { get; } = new Bindable(string.Empty); [Resolved] - private ISkinSource source { get; set; } + private ISkinSource source { get; set; } = null!; public SkinnableSprite(string textureName, ConfineMode confineMode = ConfineMode.NoScaling) : base(new SpriteComponent(textureName), confineMode) @@ -88,15 +86,15 @@ namespace osu.Game.Skinning // but that requires further thought. var highestPrioritySkin = getHighestPriorityUserSkin(((SkinnableSprite)SettingSourceObject).source.AllSources) as Skin; - string[] availableFiles = highestPrioritySkin?.SkinInfo.PerformRead(s => s.Files - .Where(f => f.Filename.EndsWith(".png", StringComparison.Ordinal) - || f.Filename.EndsWith(".jpg", StringComparison.Ordinal)) - .Select(f => f.Filename).Distinct()).ToArray(); + string[]? availableFiles = highestPrioritySkin?.SkinInfo.PerformRead(s => s.Files + .Where(f => f.Filename.EndsWith(".png", StringComparison.Ordinal) + || f.Filename.EndsWith(".jpg", StringComparison.Ordinal)) + .Select(f => f.Filename).Distinct()).ToArray(); if (availableFiles?.Length > 0) Items = availableFiles; - static ISkin getHighestPriorityUserSkin(IEnumerable skins) + static ISkin? getHighestPriorityUserSkin(IEnumerable skins) { foreach (var skin in skins) { diff --git a/osu.Game/Skinning/SkinnableSpriteText.cs b/osu.Game/Skinning/SkinnableSpriteText.cs index 3e9462b83e..2bde3c4180 100644 --- a/osu.Game/Skinning/SkinnableSpriteText.cs +++ b/osu.Game/Skinning/SkinnableSpriteText.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; diff --git a/osu.Game/Skinning/SkinnableTarget.cs b/osu.Game/Skinning/SkinnableTarget.cs index bca0d499f7..09de8a5d71 100644 --- a/osu.Game/Skinning/SkinnableTarget.cs +++ b/osu.Game/Skinning/SkinnableTarget.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Skinning { public enum SkinnableTarget diff --git a/osu.Game/Skinning/SkinnableTargetComponent.cs b/osu.Game/Skinning/SkinnableTargetComponent.cs index 51af1c23c9..a17aafe6e7 100644 --- a/osu.Game/Skinning/SkinnableTargetComponent.cs +++ b/osu.Game/Skinning/SkinnableTargetComponent.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Skinning { public class SkinnableTargetComponent : ISkinComponent diff --git a/osu.Game/Skinning/SkinnableTargetComponentsContainer.cs b/osu.Game/Skinning/SkinnableTargetComponentsContainer.cs index dd7290a858..e38afedeb9 100644 --- a/osu.Game/Skinning/SkinnableTargetComponentsContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetComponentsContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using Newtonsoft.Json; using osu.Framework.Graphics; @@ -21,7 +19,7 @@ namespace osu.Game.Skinning public bool UsesFixedAnchor { get; set; } - private readonly Action applyDefaults; + private readonly Action? applyDefaults; /// /// Construct a wrapper with defaults that should be applied once. diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index 2faaa9a905..708ad4ec47 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using System.Threading; @@ -13,7 +11,7 @@ namespace osu.Game.Skinning { public class SkinnableTargetContainer : SkinReloadableDrawable, ISkinnableTarget { - private SkinnableTargetComponentsContainer content; + private SkinnableTargetComponentsContainer? content; public SkinnableTarget Target { get; } @@ -25,7 +23,7 @@ namespace osu.Game.Skinning public bool ComponentsLoaded { get; private set; } - private CancellationTokenSource cancellationSource; + private CancellationTokenSource? cancellationSource; public SkinnableTargetContainer(SkinnableTarget target) { diff --git a/osu.Game/Skinning/TrianglesSkin.cs b/osu.Game/Skinning/TrianglesSkin.cs index 2c70963524..d00874aa8f 100644 --- a/osu.Game/Skinning/TrianglesSkin.cs +++ b/osu.Game/Skinning/TrianglesSkin.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; @@ -47,9 +45,9 @@ namespace osu.Game.Skinning this.resources = resources; } - public override Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => Textures?.Get(componentName, wrapModeS, wrapModeT); + public override Texture? GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => Textures?.Get(componentName, wrapModeS, wrapModeT); - public override ISample GetSample(ISampleInfo sampleInfo) + public override ISample? GetSample(ISampleInfo sampleInfo) { foreach (string lookup in sampleInfo.LookupNames) { @@ -61,7 +59,7 @@ namespace osu.Game.Skinning return null; } - public override Drawable GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinComponent component) { if (base.GetDrawableComponent(component) is Drawable c) return c; @@ -171,7 +169,7 @@ namespace osu.Game.Skinning return null; } - public override IBindable GetConfig(TLookup lookup) + public override IBindable? GetConfig(TLookup lookup) { // todo: this code is pulled from LegacySkin and should not exist. // will likely change based on how databased storage of skin configuration goes. @@ -181,7 +179,7 @@ namespace osu.Game.Skinning switch (global) { case GlobalSkinColours.ComboColours: - return SkinUtils.As(new Bindable>(Configuration.ComboColours)); + return SkinUtils.As(new Bindable?>(Configuration.ComboColours)); } break; diff --git a/osu.Game/Skinning/UnsupportedSkinComponentException.cs b/osu.Game/Skinning/UnsupportedSkinComponentException.cs index 3713b7c200..7f0dd51d5b 100644 --- a/osu.Game/Skinning/UnsupportedSkinComponentException.cs +++ b/osu.Game/Skinning/UnsupportedSkinComponentException.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; namespace osu.Game.Skinning From d4251271d87b1244ac31a5ac04f75db669d739c0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 13:50:39 +0900 Subject: [PATCH 0515/2991] Apply nullability to `SkinnableDrawable` --- osu.Game/Skinning/SkinnableDrawable.cs | 44 ++++++++++++-------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/osu.Game/Skinning/SkinnableDrawable.cs b/osu.Game/Skinning/SkinnableDrawable.cs index 480d66c557..c6321553c7 100644 --- a/osu.Game/Skinning/SkinnableDrawable.cs +++ b/osu.Game/Skinning/SkinnableDrawable.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Caching; using osu.Framework.Graphics; @@ -19,7 +17,7 @@ namespace osu.Game.Skinning /// /// The displayed component. /// - public Drawable Drawable { get; private set; } + public Drawable Drawable { get; private set; } = null!; /// /// Whether the drawable component should be centered in available space. @@ -43,7 +41,7 @@ namespace osu.Game.Skinning /// The namespace-complete resource name for this skinnable element. /// A function to create the default skin implementation of this element. /// How (if at all) the should be resize to fit within our own bounds. - public SkinnableDrawable(ISkinComponent component, Func defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) + public SkinnableDrawable(ISkinComponent component, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) : this(component, confineMode) { createDefault = defaultImplementation; @@ -62,7 +60,7 @@ namespace osu.Game.Skinning /// public void ResetAnimation() => (Drawable as IFramedAnimation)?.GotoFrame(0); - private readonly Func createDefault; + private readonly Func? createDefault; private readonly Cached scaling = new Cached(); @@ -77,30 +75,28 @@ namespace osu.Game.Skinning protected override void SkinChanged(ISkinSource skin) { - Drawable = skin.GetDrawableComponent(Component); + var retrieved = skin.GetDrawableComponent(Component); - isDefault = false; - - if (Drawable == null) + if (retrieved == null) { Drawable = CreateDefault(Component); isDefault = true; } - - if (Drawable != null) - { - scaling.Invalidate(); - - if (CentreComponent) - { - Drawable.Origin = Anchor.Centre; - Drawable.Anchor = Anchor.Centre; - } - - InternalChild = Drawable; - } else - ClearInternal(); + { + Drawable = retrieved; + isDefault = false; + } + + scaling.Invalidate(); + + if (CentreComponent) + { + Drawable.Origin = Anchor.Centre; + Drawable.Anchor = Anchor.Centre; + } + + InternalChild = Drawable; } protected override void Update() @@ -111,7 +107,7 @@ namespace osu.Game.Skinning { try { - if (Drawable == null || (isDefault && !ApplySizeRestrictionsToDefault)) return; + if (isDefault && !ApplySizeRestrictionsToDefault) return; switch (confineMode) { From 4457648b1cc45d0752b26730edff24e4b1829d02 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 17:42:33 +0900 Subject: [PATCH 0516/2991] Fix editor playing too many sounds when user performs a manual seek during playback --- osu.Game/Screens/Edit/Editor.cs | 48 +++++++++++++++------------------ 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index df3c1f7ec4..d7406e6289 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -234,7 +234,7 @@ namespace osu.Game.Screens.Edit AddInternal(editorBeatmap = new EditorBeatmap(playableBeatmap, loadableBeatmap.GetSkin(), loadableBeatmap.BeatmapInfo)); dependencies.CacheAs(editorBeatmap); - editorBeatmap.UpdateInProgress.BindValueChanged(updateInProgress); + editorBeatmap.UpdateInProgress.BindValueChanged(_ => updateSampleDisabledState()); canSave = editorBeatmap.BeatmapInfo.Ruleset.CreateInstance() is ILegacyRuleset; @@ -659,7 +659,7 @@ namespace osu.Game.Screens.Edit if (isNewBeatmap || HasUnsavedChanges) { - samplePlaybackDisabled.Value = true; + updateSampleDisabledState(); dialogOverlay?.Push(new PromptForSaveDialog(confirmExit, confirmExitWithSave, cancelExit)); return true; } @@ -729,27 +729,6 @@ namespace osu.Game.Screens.Edit this.Exit(); } - #region Mute from update application - - private ScheduledDelegate temporaryMuteRestorationDelegate; - private bool temporaryMuteFromUpdateInProgress; - - private void updateInProgress(ValueChangedEvent obj) - { - temporaryMuteFromUpdateInProgress = true; - updateSampleDisabledState(); - - // Debounce is arbitrarily high enough to avoid flip-flopping the value each other frame. - temporaryMuteRestorationDelegate?.Cancel(); - temporaryMuteRestorationDelegate = Scheduler.AddDelayed(() => - { - temporaryMuteFromUpdateInProgress = false; - updateSampleDisabledState(); - }, 50); - } - - #endregion - #region Clipboard support private EditorMenuItem cutMenuItem; @@ -883,11 +862,28 @@ namespace osu.Game.Screens.Edit } } + [CanBeNull] + private ScheduledDelegate playbackDisabledDebounce; + private void updateSampleDisabledState() { - samplePlaybackDisabled.Value = clock.SeekingOrStopped.Value - || currentScreen is not ComposeScreen - || temporaryMuteFromUpdateInProgress; + bool shouldDisableSamples = clock.SeekingOrStopped.Value + || currentScreen is not ComposeScreen + || editorBeatmap.UpdateInProgress.Value + || dialogOverlay?.CurrentDialog != null; + + playbackDisabledDebounce?.Cancel(); + + if (shouldDisableSamples) + { + samplePlaybackDisabled.Value = true; + } + else + { + // Debounce re-enabling arbitrarily high enough to avoid flip-flopping during beatmap updates + // or rapid user seeks. + playbackDisabledDebounce = Scheduler.AddDelayed(() => samplePlaybackDisabled.Value = false, 50); + } } private void seek(UIEvent e, int direction) From ab458320c46b461de0a43c50cb8d3f654e3f9b42 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 16:45:06 +0900 Subject: [PATCH 0517/2991] Fix some lingering inspections --- .../TestSceneCatchSkinConfiguration.cs | 2 +- osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs | 2 +- .../Objects/Drawables/DrawableOsuJudgement.cs | 2 +- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 2 +- osu.Game.Tests/Skins/LegacySkinDecoderTest.cs | 4 ++-- osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs | 3 ++- osu.Game/Skinning/PoolableSkinnableSample.cs | 3 ++- 7 files changed, 10 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs index a4b2b26624..a2d4e7fb1e 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs @@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Catch.Tests public bool FlipCatcherPlate { get; set; } public TestSkin() - : base(null) + : base(null!) { } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs index 57734236da..20aed514db 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu.Tests hitCircle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); - Child = new SkinProvidingContainer(new TrianglesSkin(null)) + Child = new SkinProvidingContainer(new TrianglesSkin(null!)) { RelativeSizeAxes = Axes.Both, Child = drawableHitCircle = new DrawableHitCircle(hitCircle) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs index e137a503a5..b4abdde911 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs @@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Lighting.Alpha = 0; - if (hitLightingEnabled && Lighting.Drawable != null) + if (hitLightingEnabled) { // todo: this animation changes slightly based on new/old legacy skin versions. Lighting.ScaleTo(0.8f).ScaleTo(1.2f, 600, Easing.Out); diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index fdd0167ed3..c6bdd25e8b 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -308,7 +308,7 @@ namespace osu.Game.Tests.Beatmaps.Formats new Color4(255, 177, 140, 255), new Color4(100, 100, 100, 255), // alpha is specified as 100, but should be ignored. }; - Assert.AreEqual(expectedColors.Length, comboColors.Count); + Assert.AreEqual(expectedColors.Length, comboColors?.Count); for (int i = 0; i < expectedColors.Length; i++) Assert.AreEqual(expectedColors[i], comboColors[i]); } diff --git a/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs b/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs index 6756f27ecd..9466fdf888 100644 --- a/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs +++ b/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs @@ -32,7 +32,7 @@ namespace osu.Game.Tests.Skins new Color4(100, 100, 100, 255), // alpha is specified as 100, but should be ignored. }; - Assert.AreEqual(expectedColors.Count, comboColors.Count); + Assert.AreEqual(expectedColors.Count, comboColors?.Count); for (int i = 0; i < expectedColors.Count; i++) Assert.AreEqual(expectedColors[i], comboColors[i]); } @@ -49,7 +49,7 @@ namespace osu.Game.Tests.Skins var comboColors = decoder.Decode(stream).ComboColours; var expectedColors = SkinConfiguration.DefaultComboColours; - Assert.AreEqual(expectedColors.Count, comboColors.Count); + Assert.AreEqual(expectedColors.Count, comboColors?.Count); for (int i = 0; i < expectedColors.Count; i++) Assert.AreEqual(expectedColors[i], comboColors[i]); } diff --git a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs index b0c26f7280..3f62bd038f 100644 --- a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs +++ b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs @@ -146,7 +146,8 @@ namespace osu.Game.Tests.Skins AddStep("Disallow default colours fallback in beatmap skin", () => beatmapSource.Configuration.AllowDefaultComboColoursFallback = false); AddAssert("Check retrieved combo colours from user skin", () => - requester.GetConfig>(GlobalSkinColours.ComboColours)?.Value?.SequenceEqual(userSource.Configuration.ComboColours) ?? false); + userSource.Configuration.ComboColours != null && + (requester.GetConfig>(GlobalSkinColours.ComboColours)?.Value?.SequenceEqual(userSource.Configuration.ComboColours) ?? false)); } [Test] diff --git a/osu.Game/Skinning/PoolableSkinnableSample.cs b/osu.Game/Skinning/PoolableSkinnableSample.cs index 49bc71064c..d0a22f9656 100644 --- a/osu.Game/Skinning/PoolableSkinnableSample.cs +++ b/osu.Game/Skinning/PoolableSkinnableSample.cs @@ -9,6 +9,7 @@ using JetBrains.Annotations; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Containers; @@ -175,7 +176,7 @@ namespace osu.Game.Skinning { base.Dispose(isDisposing); - if (CurrentSkin != null) + if (CurrentSkin.IsNotNull()) CurrentSkin.SourceChanged -= skinChangedImmediate; } From c908969d9b78f36538dc0cd2a788dfa311fc6c50 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 14:11:41 +0900 Subject: [PATCH 0518/2991] Rename `ISkinComponent` to `ISkinLookup` --- ...tchSkinComponent.cs => CatchSkinLookup.cs} | 4 ++-- .../Objects/Drawables/CaughtObject.cs | 4 ++-- .../Objects/Drawables/DrawableBanana.cs | 2 +- .../Objects/Drawables/DrawableDroplet.cs | 2 +- .../Objects/Drawables/DrawableFruit.cs | 2 +- .../Argon/CatchArgonSkinTransformer.cs | 8 +++---- .../Legacy/CatchLegacySkinTransformer.cs | 14 ++++++------ .../UI/CatchComboDisplay.cs | 2 +- osu.Game.Rulesets.Catch/UI/HitExplosion.cs | 2 +- .../UI/SkinnableCatcher.cs | 2 +- .../Skinning/TestSceneColumnBackground.cs | 4 ++-- .../Skinning/TestSceneStageBackground.cs | 2 +- .../Skinning/TestSceneStageForeground.cs | 2 +- ...niaSkinComponent.cs => ManiaSkinLookup.cs} | 6 ++--- .../Objects/Drawables/DrawableHoldNote.cs | 2 +- .../Objects/Drawables/DrawableNote.cs | 2 +- .../Argon/ManiaArgonSkinTransformer.cs | 10 ++++----- .../Legacy/ManiaLegacySkinTransformer.cs | 12 +++++----- osu.Game.Rulesets.Mania/UI/Column.cs | 4 ++-- .../UI/Components/ColumnHitObjectArea.cs | 2 +- .../UI/PoolableHitExplosion.cs | 2 +- osu.Game.Rulesets.Mania/UI/Stage.cs | 4 ++-- .../TestSceneCursorTrail.cs | 2 +- .../TestSceneGameplayCursor.cs | 2 +- .../TestSceneSkinFallbacks.cs | 4 ++-- .../Drawables/Connections/FollowPoint.cs | 2 +- .../Objects/Drawables/DrawableHitCircle.cs | 8 +++---- .../Objects/Drawables/DrawableSlider.cs | 2 +- .../Objects/Drawables/DrawableSliderBall.cs | 4 ++-- .../Objects/Drawables/DrawableSliderRepeat.cs | 2 +- .../Objects/Drawables/DrawableSliderTail.cs | 2 +- .../Objects/Drawables/DrawableSliderTick.cs | 2 +- .../Objects/Drawables/DrawableSpinner.cs | 2 +- .../{OsuSkinComponent.cs => OsuSkinLookup.cs} | 4 ++-- .../Skinning/Argon/OsuArgonSkinTransformer.cs | 10 ++++----- .../Skinning/Default/DefaultApproachCircle.cs | 4 ++-- .../Skinning/Default/NumberPiece.cs | 2 +- .../Skinning/Default/ReverseArrowPiece.cs | 2 +- .../Skinning/Legacy/LegacyApproachCircle.cs | 4 ++-- .../Skinning/Legacy/LegacyMainCirclePiece.cs | 2 +- .../Skinning/Legacy/LegacyReverseArrow.cs | 2 +- .../Legacy/OsuLegacySkinTransformer.cs | 12 +++++----- osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs | 2 +- .../UI/Cursor/OsuCursorContainer.cs | 4 ++-- osu.Game.Rulesets.Osu/UI/SmokeContainer.cs | 6 ++--- .../Skinning/TestSceneTaikoScroller.cs | 2 +- .../Objects/Drawables/DrawableBarLine.cs | 2 +- .../Objects/Drawables/DrawableDrumRoll.cs | 2 +- .../Objects/Drawables/DrawableDrumRollTick.cs | 2 +- .../Objects/Drawables/DrawableHit.cs | 4 ++-- .../Objects/Drawables/DrawableSwell.cs | 2 +- .../Objects/Drawables/DrawableSwellTick.cs | 2 +- .../Legacy/TaikoLegacySkinTransformer.cs | 10 ++++----- ...ikoSkinComponent.cs => TaikoSkinLookup.cs} | 4 ++-- .../UI/DrawableTaikoRuleset.cs | 2 +- osu.Game.Rulesets.Taiko/UI/HitExplosion.cs | 2 +- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 2 +- .../UI/KiaiHitExplosion.cs | 2 +- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 8 +++---- .../TestSceneHitObjectAccentColour.cs | 2 +- .../Skinning/LegacySkinAnimationTest.cs | 2 +- .../TestSceneRulesetSkinProvidingContainer.cs | 2 +- .../TestSceneBeatmapSkinLookupDisables.cs | 12 +++++----- .../Skins/TestSceneSkinConfigurationLookup.cs | 2 +- .../Skins/TestSceneSkinProvidingContainer.cs | 2 +- .../Gameplay/TestSceneBeatmapSkinFallbacks.cs | 2 +- .../Gameplay/TestSceneSkinnableDrawable.cs | 22 +++++++++---------- .../Gameplay/TestSceneSkinnableSound.cs | 2 +- .../Rulesets/Judgements/DrawableJudgement.cs | 2 +- osu.Game/Screens/Edit/EditorBeatmapSkin.cs | 2 +- osu.Game/Skinning/ArgonSkin.cs | 12 +++++----- .../Skinning/BeatmapSkinProvidingContainer.cs | 2 +- ...SkinComponent.cs => GameplaySkinLookup.cs} | 4 ++-- osu.Game/Skinning/ISkin.cs | 4 ++-- osu.Game/Skinning/ISkinComponent.cs | 10 --------- osu.Game/Skinning/ISkinLookup.cs | 21 ++++++++++++++++++ osu.Game/Skinning/LegacyBeatmapSkin.cs | 6 ++--- osu.Game/Skinning/LegacySkin.cs | 12 +++++----- osu.Game/Skinning/ResourceStoreBackedSkin.cs | 2 +- osu.Game/Skinning/Skin.cs | 6 ++--- osu.Game/Skinning/SkinManager.cs | 2 +- osu.Game/Skinning/SkinProvidingContainer.cs | 14 ++++++------ osu.Game/Skinning/SkinTransformer.cs | 2 +- osu.Game/Skinning/SkinnableDrawable.cs | 20 ++++++++--------- osu.Game/Skinning/SkinnableSprite.cs | 16 +++++++------- osu.Game/Skinning/SkinnableSpriteText.cs | 4 ++-- osu.Game/Skinning/SkinnableTargetContainer.cs | 2 +- ...tComponent.cs => SkinnableTargetLookup.cs} | 4 ++-- osu.Game/Skinning/TrianglesSkin.cs | 12 +++++----- .../UnsupportedSkinComponentException.cs | 4 ++-- 90 files changed, 224 insertions(+), 213 deletions(-) rename osu.Game.Rulesets.Catch/{CatchSkinComponent.cs => CatchSkinLookup.cs} (76%) rename osu.Game.Rulesets.Mania/{ManiaSkinComponent.cs => ManiaSkinLookup.cs} (79%) rename osu.Game.Rulesets.Osu/{OsuSkinComponent.cs => OsuSkinLookup.cs} (76%) rename osu.Game.Rulesets.Taiko/{TaikoSkinComponent.cs => TaikoSkinLookup.cs} (75%) rename osu.Game/Skinning/{GameplaySkinComponent.cs => GameplaySkinLookup.cs} (85%) delete mode 100644 osu.Game/Skinning/ISkinComponent.cs create mode 100644 osu.Game/Skinning/ISkinLookup.cs rename osu.Game/Skinning/{SkinnableTargetComponent.cs => SkinnableTargetLookup.cs} (73%) diff --git a/osu.Game.Rulesets.Catch/CatchSkinComponent.cs b/osu.Game.Rulesets.Catch/CatchSkinLookup.cs similarity index 76% rename from osu.Game.Rulesets.Catch/CatchSkinComponent.cs rename to osu.Game.Rulesets.Catch/CatchSkinLookup.cs index 07c613d6ff..65bfc7ee30 100644 --- a/osu.Game.Rulesets.Catch/CatchSkinComponent.cs +++ b/osu.Game.Rulesets.Catch/CatchSkinLookup.cs @@ -5,9 +5,9 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch { - public class CatchSkinComponent : GameplaySkinComponent + public class CatchSkinLookup : GameplaySkinLookup { - public CatchSkinComponent(CatchSkinComponents component) + public CatchSkinLookup(CatchSkinComponents component) : base(component) { } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs index ddfbb34435..20d348fe3d 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs @@ -37,8 +37,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables public override bool RemoveWhenNotAlive => true; - protected CaughtObject(CatchSkinComponents skinComponent, Func defaultImplementation) - : base(new CatchSkinComponent(skinComponent), defaultImplementation) + protected CaughtObject(CatchSkinComponents skinComponent, Func defaultImplementation) + : base(new CatchSkinLookup(skinComponent), defaultImplementation) { Origin = Anchor.Centre; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs index b46a452bd0..a2b32ea9e4 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables private void load() { ScalingContainer.Child = new SkinnableDrawable( - new CatchSkinComponent(CatchSkinComponents.Banana), + new CatchSkinLookup(CatchSkinComponents.Banana), _ => new BananaPiece()); } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs index d367ad0a00..210a4495e4 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables private void load() { ScalingContainer.Child = new SkinnableDrawable( - new CatchSkinComponent(CatchSkinComponents.Droplet), + new CatchSkinLookup(CatchSkinComponents.Droplet), _ => new DropletPiece()); } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs index ce4c7e5aff..6359a5b35c 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables private void load() { ScalingContainer.Child = new SkinnableDrawable( - new CatchSkinComponent(CatchSkinComponents.Fruit), + new CatchSkinLookup(CatchSkinComponents.Fruit), _ => new FruitPiece()); } diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs index 8dae0a2b78..606cd339a9 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs @@ -13,11 +13,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon { } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - switch (component) + switch (lookup) { - case CatchSkinComponent catchComponent: + case CatchSkinLookup catchComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. switch (catchComponent.Component) { @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon break; } - return base.GetDrawableComponent(component); + return base.GetDrawableComponent(lookup); } } } diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs index ef83e67876..5fda40d8c0 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs @@ -25,14 +25,14 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (component is SkinnableTargetComponent targetComponent) + if (lookup is SkinnableTargetLookup targetComponent) { switch (targetComponent.Target) { case SkinnableTarget.MainHUDComponents: - var components = base.GetDrawableComponent(component) as SkinnableTargetComponentsContainer; + var components = base.GetDrawableComponent(lookup) as SkinnableTargetComponentsContainer; if (providesComboCounter && components != null) { @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy } } - if (component is CatchSkinComponent catchSkinComponent) + if (lookup is CatchSkinLookup catchSkinComponent) { switch (catchSkinComponent.Component) { @@ -95,11 +95,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy return null; default: - throw new UnsupportedSkinComponentException(component); + throw new UnsupportedSkinComponentException(lookup); } } - return base.GetDrawableComponent(component); + return base.GetDrawableComponent(lookup); } private bool hasOldStyleCatcherSprite() => @@ -127,7 +127,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { case CatchSkinConfiguration.FlipCatcherPlate: // Don't flip catcher plate contents if the catcher is provided by this legacy skin. - if (GetDrawableComponent(new CatchSkinComponent(CatchSkinComponents.Catcher)) != null) + if (GetDrawableComponent(new CatchSkinLookup(CatchSkinComponents.Catcher)) != null) return (IBindable)new Bindable(); break; diff --git a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs index a5b7d8d0af..802e837746 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.UI private readonly IBindable showCombo = new BindableBool(true); public CatchComboDisplay() - : base(new CatchSkinComponent(CatchSkinComponents.CatchComboCounter), _ => Empty()) + : base(new CatchSkinLookup(CatchSkinComponents.CatchComboCounter), _ => Empty()) { } diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs index 1ea188d463..fb55864c49 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.UI Anchor = Anchor.BottomCentre; Origin = Anchor.BottomCentre; - InternalChild = skinnableExplosion = new SkinnableDrawable(new CatchSkinComponent(CatchSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) + InternalChild = skinnableExplosion = new SkinnableDrawable(new CatchSkinLookup(CatchSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) { CentreComponent = false, Anchor = Anchor.BottomCentre, diff --git a/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs b/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs index 25bbc814bf..2e07e39943 100644 --- a/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs +++ b/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.UI public readonly Bindable AnimationState = new Bindable(); public SkinnableCatcher() - : base(new CatchSkinComponent(CatchSkinComponents.Catcher), _ => new DefaultCatcher()) + : base(new CatchSkinLookup(CatchSkinComponents.Catcher), _ => new DefaultCatcher()) { Anchor = Anchor.TopCentre; // Sets the origin roughly to the centre of the catcher's plate to allow for correct scaling. diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs index cd26e2a9de..8dc8e72479 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning { RelativeSizeAxes = Axes.Both, Width = 0.5f, - Child = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) + Child = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) { RelativeSizeAxes = Axes.Both } @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning { RelativeSizeAxes = Axes.Both, Width = 0.5f, - Child = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) + Child = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) { RelativeSizeAxes = Axes.Both } diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs index 0744d7e2e7..19ccf20870 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning [BackgroundDependencyLoader] private void load() { - SetContents(_ => new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageBackground), + SetContents(_ => new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.StageBackground), _ => new DefaultStageBackground()) { Anchor = Anchor.Centre, diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs index 979c90c802..171d2951be 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning [BackgroundDependencyLoader] private void load() { - SetContents(_ => new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageForeground), _ => null) + SetContents(_ => new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.StageForeground), _ => null) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs b/osu.Game.Rulesets.Mania/ManiaSkinLookup.cs similarity index 79% rename from osu.Game.Rulesets.Mania/ManiaSkinComponent.cs rename to osu.Game.Rulesets.Mania/ManiaSkinLookup.cs index a074aab9da..6e6d00fee6 100644 --- a/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs +++ b/osu.Game.Rulesets.Mania/ManiaSkinLookup.cs @@ -5,13 +5,13 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania { - public class ManiaSkinComponent : GameplaySkinComponent + public class ManiaSkinLookup : GameplaySkinLookup { /// - /// Creates a new . + /// Creates a new . /// /// The component. - public ManiaSkinComponent(ManiaSkinComponents component) + public ManiaSkinLookup(ManiaSkinComponents component) : base(component) { } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 14dbc432ff..5b003e3c19 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables headContainer = new Container { RelativeSizeAxes = Axes.Both } } }, - bodyPiece = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HoldNoteBody), _ => new DefaultBodyPiece + bodyPiece = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.HoldNoteBody), _ => new DefaultBodyPiece { RelativeSizeAxes = Axes.Both, }) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 3c8b1b53b7..25347d3dfa 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { rulesetConfig?.BindWith(ManiaRulesetSetting.TimingBasedNoteColouring, configTimingBasedNoteColouring); - AddInternal(headPiece = new SkinnableDrawable(new ManiaSkinComponent(Component), _ => new DefaultNotePiece()) + AddInternal(headPiece = new SkinnableDrawable(new ManiaSkinLookup(Component), _ => new DefaultNotePiece()) { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs index ae313e0b91..cf9f9f36f0 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs @@ -22,14 +22,14 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon this.beatmap = (ManiaBeatmap)beatmap; } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - switch (component) + switch (lookup) { - case GameplaySkinComponent resultComponent: + case GameplaySkinLookup resultComponent: return new ArgonJudgementPiece(resultComponent.Component); - case ManiaSkinComponent maniaComponent: + case ManiaSkinLookup maniaComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. switch (maniaComponent.Component) { @@ -62,7 +62,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon break; } - return base.GetDrawableComponent(component); + return base.GetDrawableComponent(lookup); } public override IBindable? GetConfig(TLookup lookup) diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs index a07dbea368..5b7ccc7bb6 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs @@ -74,14 +74,14 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy }); } - public override Drawable GetDrawableComponent(ISkinComponent component) + public override Drawable GetDrawableComponent(ISkinLookup lookup) { - switch (component) + switch (lookup) { - case GameplaySkinComponent resultComponent: + case GameplaySkinLookup resultComponent: return getResult(resultComponent.Component); - case ManiaSkinComponent maniaComponent: + case ManiaSkinLookup maniaComponent: if (!isLegacySkin.Value || !hasKeyTexture.Value) return null; @@ -120,11 +120,11 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy return new LegacyStageForeground(); default: - throw new UnsupportedSkinComponentException(component); + throw new UnsupportedSkinComponentException(lookup); } } - return base.GetDrawableComponent(component); + return base.GetDrawableComponent(lookup); } private Drawable getResult(HitResult result) diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 3d46bdaa7b..4eed75a90d 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Mania.UI skin.SourceChanged += onSourceChanged; onSourceChanged(); - Drawable background = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) + Drawable background = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) { RelativeSizeAxes = Axes.Both, }; @@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.Mania.UI // For input purposes, the background is added at the highest depth, but is then proxied back below all other elements background.CreateProxy(), HitObjectArea, - keyArea = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.KeyArea), _ => new DefaultKeyArea()) + keyArea = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.KeyArea), _ => new DefaultKeyArea()) { RelativeSizeAxes = Axes.Both, }, diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs index b26b62f8a5..d02e4afc81 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components RelativeSizeAxes = Axes.Both, Depth = 2, }, - hitTarget = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HitTarget), _ => new DefaultHitTarget()) + hitTarget = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.HitTarget), _ => new DefaultHitTarget()) { RelativeSizeAxes = Axes.X, Depth = 1 diff --git a/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs b/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs index a7b94f9f22..faf345545d 100644 --- a/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs +++ b/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.UI [BackgroundDependencyLoader] private void load() { - InternalChild = skinnableExplosion = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) + InternalChild = skinnableExplosion = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) { RelativeSizeAxes = Axes.Both }; diff --git a/osu.Game.Rulesets.Mania/UI/Stage.cs b/osu.Game.Rulesets.Mania/UI/Stage.cs index 1273cb3d32..5d08e38aef 100644 --- a/osu.Game.Rulesets.Mania/UI/Stage.cs +++ b/osu.Game.Rulesets.Mania/UI/Stage.cs @@ -73,7 +73,7 @@ namespace osu.Game.Rulesets.Mania.UI AutoSizeAxes = Axes.X, Children = new Drawable[] { - new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageBackground), _ => new DefaultStageBackground()) + new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.StageBackground), _ => new DefaultStageBackground()) { RelativeSizeAxes = Axes.Both }, @@ -98,7 +98,7 @@ namespace osu.Game.Rulesets.Mania.UI RelativeSizeAxes = Axes.Y, } }, - new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageForeground), _ => null) + new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.StageForeground), _ => null) { RelativeSizeAxes = Axes.Both }, diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs index d3e70a0a01..aeadbea510 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs @@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.Tests RelativeSizeAxes = Axes.Both; } - public Drawable GetDrawableComponent(ISkinComponent component) => null; + public Drawable GetDrawableComponent(ISkinLookup lookup) => null; public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) { diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs index 360815afbf..f88948ce13 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs @@ -116,7 +116,7 @@ namespace osu.Game.Rulesets.Osu.Tests private class TopLeftCursorSkin : ISkin { - public Drawable GetDrawableComponent(ISkinComponent component) => null; + public Drawable GetDrawableComponent(ISkinLookup lookup) => null; public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => null; public ISample GetSample(ISampleInfo sampleInfo) => null; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs index 036f90b962..c012dae635 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -149,11 +149,11 @@ namespace osu.Game.Rulesets.Osu.Tests this.identifier = identifier; } - public Drawable GetDrawableComponent(ISkinComponent component) + public Drawable GetDrawableComponent(ISkinLookup lookup) { if (!enabled) return null; - if (component is OsuSkinComponent osuComponent && osuComponent.Component == OsuSkinComponents.SliderBody) + if (lookup is OsuSkinLookup osuComponent && osuComponent.Component == OsuSkinComponents.SliderBody) return null; return new OsuSpriteText diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs index 36d8ba0189..22037c873c 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections { Origin = Anchor.Centre; - InternalChild = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.FollowPoint), _ => new CircularContainer + InternalChild = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.FollowPoint), _ => new CircularContainer { Masking = true, AutoSizeAxes = Axes.Both, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index d420091499..bcb3ccae41 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -81,12 +81,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - CirclePiece = new SkinnableDrawable(new OsuSkinComponent(CirclePieceComponent), _ => new MainCirclePiece()) + CirclePiece = new SkinnableDrawable(new OsuSkinLookup(CirclePieceComponent), _ => new MainCirclePiece()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, }, - ApproachCircle = new ProxyableSkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.ApproachCircle), _ => new DefaultApproachCircle()) + ApproachCircle = new ProxyableSkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.ApproachCircle), _ => new DefaultApproachCircle()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -278,8 +278,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { public override bool RemoveWhenNotAlive => false; - public ProxyableSkinnableDrawable(ISkinComponent component, Func defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) - : base(component, defaultImplementation, confineMode) + public ProxyableSkinnableDrawable(ISkinLookup lookup, Func defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) + : base(lookup, defaultImplementation, confineMode) { } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 785d15c15b..3fdbc3dacd 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - Body = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderBody), _ => new DefaultSliderBody(), confineMode: ConfineMode.NoScaling), + Body = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderBody), _ => new DefaultSliderBody(), confineMode: ConfineMode.NoScaling), tailContainer = new Container { RelativeSizeAxes = Axes.Both }, tickContainer = new Container { RelativeSizeAxes = Axes.Both }, repeatContainer = new Container { RelativeSizeAxes = Axes.Both }, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs index 9966ad3a90..86d41f0cbf 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Children = new[] { - new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderFollowCircle), _ => new DefaultFollowCircle()) + new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderFollowCircle), _ => new DefaultFollowCircle()) { Origin = Anchor.Centre, Anchor = Anchor.Centre, @@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RelativeSizeAxes = Axes.Both, Masking = true }, - ball = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderBall), _ => new DefaultSliderBall()) + ball = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderBall), _ => new DefaultSliderBall()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs index a02cc9227e..1b8a17b6df 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs @@ -60,7 +60,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Children = new Drawable[] { // no default for this; only visible in legacy skins. - CirclePiece = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderTailHitCircle), _ => Empty()) + CirclePiece = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderTailHitCircle), _ => Empty()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs index 6270d6709b..e8c6e80109 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs @@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Children = new Drawable[] { // no default for this; only visible in legacy skins. - CirclePiece = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderTailHitCircle), _ => Empty()) + CirclePiece = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderTailHitCircle), _ => Empty()) } }, }); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index 4bd98fc8b2..f591cd15d4 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); Origin = Anchor.Centre; - AddInternal(scaleContainer = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderScorePoint), _ => new CircularContainer + AddInternal(scaleContainer = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderScorePoint), _ => new CircularContainer { Masking = true, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 6ae9d5bc34..7d0e29bd93 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RelativeSizeAxes = Axes.Y, Children = new Drawable[] { - Body = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SpinnerBody), _ => new DefaultSpinner()), + Body = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SpinnerBody), _ => new DefaultSpinner()), RotationTracker = new SpinnerRotationTracker(this) } }, diff --git a/osu.Game.Rulesets.Osu/OsuSkinComponent.cs b/osu.Game.Rulesets.Osu/OsuSkinLookup.cs similarity index 76% rename from osu.Game.Rulesets.Osu/OsuSkinComponent.cs rename to osu.Game.Rulesets.Osu/OsuSkinLookup.cs index aa59bd572e..4048e95e4b 100644 --- a/osu.Game.Rulesets.Osu/OsuSkinComponent.cs +++ b/osu.Game.Rulesets.Osu/OsuSkinLookup.cs @@ -5,9 +5,9 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu { - public class OsuSkinComponent : GameplaySkinComponent + public class OsuSkinLookup : GameplaySkinLookup { - public OsuSkinComponent(OsuSkinComponents component) + public OsuSkinLookup(OsuSkinComponents component) : base(component) { } diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs index bf507db50c..bf664bb606 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs @@ -14,14 +14,14 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon { } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - switch (component) + switch (lookup) { - case GameplaySkinComponent resultComponent: + case GameplaySkinLookup resultComponent: return new ArgonJudgementPiece(resultComponent.Component); - case OsuSkinComponent osuComponent: + case OsuSkinLookup osuComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. switch (osuComponent.Component) { @@ -62,7 +62,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon break; } - return base.GetDrawableComponent(component); + return base.GetDrawableComponent(lookup); } } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs index e991bc6cf3..2b2c31dcf7 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs @@ -35,9 +35,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default accentColour.BindValueChanged(colour => Colour = colour.NewValue, true); } - protected override Drawable CreateDefault(ISkinComponent component) + protected override Drawable CreateDefault(ISkinLookup lookup) { - var drawable = base.CreateDefault(component); + var drawable = base.CreateDefault(lookup); // Although this is a non-legacy component, osu-resources currently stores approach circle as a legacy-like texture. // See LegacyApproachCircle for documentation as to why this is required. diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs index 43d8d1e27f..39e07ebb99 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default Colour = Color4.White.Opacity(0.5f), }, }, - number = new SkinnableSpriteText(new OsuSkinComponent(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText + number = new SkinnableSpriteText(new OsuSkinLookup(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText { Font = OsuFont.Numeric.With(size: 40), UseFullGlyphHeight = false, diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs index 1fce512f53..338e7abcfc 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); - Child = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.ReverseArrow), _ => new SpriteIcon + Child = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.ReverseArrow), _ => new SpriteIcon { RelativeSizeAxes = Axes.Both, Blending = BlendingParameters.Additive, diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs index fa5c5b84e4..20a1e3064e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs @@ -35,9 +35,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy accentColour.BindValueChanged(colour => Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue), true); } - protected override Drawable CreateDefault(ISkinComponent component) + protected override Drawable CreateDefault(ISkinLookup lookup) { - var drawable = base.CreateDefault(component); + var drawable = base.CreateDefault(lookup); // account for the sprite being used for the default approach circle being taken from stable, // when hitcircles have 5px padding on each size. this should be removed if we update the sprite. diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs index a6e62b83e4..357be4cda8 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy if (hasNumber) { - OverlayLayer.Add(hitCircleText = new SkinnableSpriteText(new OsuSkinComponent(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText + OverlayLayer.Add(hitCircleText = new SkinnableSpriteText(new OsuSkinLookup(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText { Font = OsuFont.Numeric.With(size: 40), UseFullGlyphHeight = false, diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs index 7e9626eb7f..f374af1cba 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { AutoSizeAxes = Axes.Both; - string lookupName = new OsuSkinComponent(OsuSkinComponents.ReverseArrow).LookupName; + string lookupName = new OsuSkinLookup(OsuSkinComponents.ReverseArrow).LookupName; var skin = skinSource.FindProvider(s => s.GetTexture(lookupName) != null); InternalChild = skin?.GetAnimation(lookupName, true, true) ?? Empty(); diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs index 3bc2668733..2faa2d678e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs @@ -28,17 +28,17 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy hasHitCircle = new Lazy(() => GetTexture("hitcircle") != null); } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (component is OsuSkinComponent osuComponent) + if (lookup is OsuSkinLookup osuComponent) { switch (osuComponent.Component) { case OsuSkinComponents.FollowPoint: - return this.GetAnimation(component.LookupName, true, true, true, startAtCurrentTime: false); + return this.GetAnimation(lookup.LookupName, true, true, true, startAtCurrentTime: false); case OsuSkinComponents.SliderScorePoint: - return this.GetAnimation(component.LookupName, false, false); + return this.GetAnimation(lookup.LookupName, false, false); case OsuSkinComponents.SliderFollowCircle: var followCircleContent = this.GetAnimation("sliderfollowcircle", true, true, true); @@ -136,11 +136,11 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy return new LegacyApproachCircle(); default: - throw new UnsupportedSkinComponentException(component); + throw new UnsupportedSkinComponentException(lookup); } } - return base.GetDrawableComponent(component); + return base.GetDrawableComponent(lookup); } public override IBindable? GetConfig(TLookup lookup) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs index 15ef7e538b..78b920c771 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor RelativeSizeAxes = Axes.Both, Origin = Anchor.Centre, Anchor = Anchor.Centre, - Child = cursorSprite = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.Cursor), _ => new DefaultCursor(), confineMode: ConfineMode.NoScaling) + Child = cursorSprite = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.Cursor), _ => new DefaultCursor(), confineMode: ConfineMode.NoScaling) { Origin = Anchor.Centre, Anchor = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs index 533db3ddfe..396492c104 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs @@ -47,8 +47,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor RelativeSizeAxes = Axes.Both, Children = new[] { - cursorTrail = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.CursorTrail), _ => new DefaultCursorTrail(), confineMode: ConfineMode.NoScaling), - new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.CursorParticles), confineMode: ConfineMode.NoScaling), + cursorTrail = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.CursorTrail), _ => new DefaultCursorTrail(), confineMode: ConfineMode.NoScaling), + new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.CursorParticles), confineMode: ConfineMode.NoScaling), } }; } diff --git a/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs b/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs index beba834e88..2616bb0325 100644 --- a/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.UI { if (e.Action == OsuAction.Smoke) { - AddInternal(currentSegmentSkinnable = new SmokeSkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.CursorSmoke), _ => new DefaultSmokeSegment())); + AddInternal(currentSegmentSkinnable = new SmokeSkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.CursorSmoke), _ => new DefaultSmokeSegment())); // Add initial position immediately. addPosition(); @@ -68,8 +68,8 @@ namespace osu.Game.Rulesets.Osu.UI public override double LifetimeStart => Drawable.LifetimeStart; public override double LifetimeEnd => Drawable.LifetimeEnd; - public SmokeSkinnableDrawable(ISkinComponent component, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) - : base(component, defaultImplementation, confineMode) + public SmokeSkinnableDrawable(ISkinLookup lookup, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) + : base(lookup, defaultImplementation, confineMode) { } } diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs index 954b4be7f3..3076172d46 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning public TestSceneTaikoScroller() { AddStep("Load scroller", () => SetContents(_ => - new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Scroller), _ => Empty()) + new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.Scroller), _ => Empty()) { Clock = new FramedClock(clock), Height = 0.4f, diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs index e4806c4a12..715add7914 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs @@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables AddRangeInternal(new Drawable[] { - line = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.BarLine), _ => new Box + line = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.BarLine), _ => new Box { RelativeSizeAxes = Axes.Both, EdgeSmoothness = new Vector2(0.5f, 0), diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index 98dad96cf6..f5ebecdee5 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -115,7 +115,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables return base.CreateNestedHitObject(hitObject); } - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.DrumRollBody), + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.DrumRollBody), _ => new ElongatedCirclePiece()); public override bool OnPressed(KeyBindingPressEvent e) => false; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 451c5a793b..1ec2562f67 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables FillMode = FillMode.Fit; } - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.DrumRollTick), + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece { Filled = HitObject.FirstTick diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index 484f125a09..0fe17f81f5 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -90,8 +90,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } protected override SkinnableDrawable CreateMainPiece() => HitObject.Type == HitType.Centre - ? new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.CentreHit), _ => new CentreHitCirclePiece(), confineMode: ConfineMode.ScaleToFit) - : new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.RimHit), _ => new RimHitCirclePiece(), confineMode: ConfineMode.ScaleToFit); + ? new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.CentreHit), _ => new CentreHitCirclePiece(), confineMode: ConfineMode.ScaleToFit) + : new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.RimHit), _ => new RimHitCirclePiece(), confineMode: ConfineMode.ScaleToFit); public override IEnumerable GetSamples() { diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index a6f6edba09..5b498e4cb3 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -125,7 +125,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables targetRing.BorderColour = colours.YellowDark.Opacity(0.25f); } - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Swell), + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.Swell), _ => new SwellCirclePiece { // to allow for rotation transform diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs index b2a54176fb..4d915c91d3 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public override bool OnPressed(KeyBindingPressEvent e) => false; - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.DrumRollTick), + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece()); } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs index 020cdab4dc..6cf7d3da0a 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs @@ -27,16 +27,16 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy hasExplosion = new Lazy(() => GetTexture(getHitName(TaikoSkinComponents.TaikoExplosionGreat)) != null); } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (component is GameplaySkinComponent) + if (lookup is GameplaySkinLookup) { // if a taiko skin is providing explosion sprites, hide the judgements completely if (hasExplosion.Value) return Drawable.Empty().With(d => d.Expire()); } - if (component is TaikoSkinComponent taikoComponent) + if (lookup is TaikoSkinLookup taikoComponent) { switch (taikoComponent.Component) { @@ -130,11 +130,11 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy return new DrawableTaikoMascot(); default: - throw new UnsupportedSkinComponentException(component); + throw new UnsupportedSkinComponentException(lookup); } } - return base.GetDrawableComponent(component); + return base.GetDrawableComponent(lookup); } private string getHitName(TaikoSkinComponents component) diff --git a/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs b/osu.Game.Rulesets.Taiko/TaikoSkinLookup.cs similarity index 75% rename from osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs rename to osu.Game.Rulesets.Taiko/TaikoSkinLookup.cs index 30bfb605aa..cb8bbd8b18 100644 --- a/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs +++ b/osu.Game.Rulesets.Taiko/TaikoSkinLookup.cs @@ -5,9 +5,9 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko { - public class TaikoSkinComponent : GameplaySkinComponent + public class TaikoSkinLookup : GameplaySkinLookup { - public TaikoSkinComponent(TaikoSkinComponents component) + public TaikoSkinLookup(TaikoSkinComponents component) : base(component) { } diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs index 58e703b8be..db45c8bb70 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs @@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Taiko.UI { new BarLineGenerator(Beatmap).BarLines.ForEach(bar => Playfield.Add(bar)); - FrameStableComponents.Add(scroller = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Scroller), _ => Empty()) + FrameStableComponents.Add(scroller = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.Scroller), _ => Empty()) { RelativeSizeAxes = Axes.X, Depth = float.MaxValue diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs index 10a7495c62..560f7b1748 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load() { - InternalChild = skinnable = new SkinnableDrawable(new TaikoSkinComponent(getComponentName(result)), _ => new DefaultHitExplosion(result)); + InternalChild = skinnable = new SkinnableDrawable(new TaikoSkinLookup(getComponentName(result)), _ => new DefaultHitExplosion(result)); skinnable.OnSkinChanged += runAnimation; } diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 6d5b6c5f5d..4458fb1bc0 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Taiko.UI { Children = new Drawable[] { - new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.InputDrum), _ => new DefaultInputDrum()) + new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.InputDrum), _ => new DefaultInputDrum()) { RelativeSizeAxes = Axes.Y, AutoSizeAxes = Axes.X, diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs index c4cff00d2a..b0d853f1f1 100644 --- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load() { - Child = skinnable = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.TaikoExplosionKiai), _ => new DefaultKiaiHitExplosion(hitType)); + Child = skinnable = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.TaikoExplosionKiai), _ => new DefaultKiaiHitExplosion(hitType)); } } } diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index f2d7811f44..0de7bf233d 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Taiko.UI InternalChildren = new[] { - new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.PlayfieldBackgroundRight), _ => new PlayfieldBackgroundRight()), + new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.PlayfieldBackgroundRight), _ => new PlayfieldBackgroundRight()), new Container { Name = "Left overlay", @@ -86,11 +86,11 @@ namespace osu.Game.Rulesets.Taiko.UI BorderColour = colours.Gray0, Children = new[] { - new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.PlayfieldBackgroundLeft), _ => new PlayfieldBackgroundLeft()), + new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.PlayfieldBackgroundLeft), _ => new PlayfieldBackgroundLeft()), inputDrum.CreateProxy(), } }, - mascot = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Mascot), _ => Empty()) + mascot = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.Mascot), _ => Empty()) { Origin = Anchor.BottomLeft, Anchor = Anchor.TopLeft, @@ -116,7 +116,7 @@ namespace osu.Game.Rulesets.Taiko.UI { RelativeSizeAxes = Axes.Both, }, - HitTarget = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.HitTarget), _ => new TaikoHitTarget()) + HitTarget = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.HitTarget), _ => new TaikoHitTarget()) { RelativeSizeAxes = Axes.Both, } diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs index 9701a32951..fc72fddcae 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs @@ -126,7 +126,7 @@ namespace osu.Game.Tests.Gameplay Color4.Green }; - public Drawable GetDrawableComponent(ISkinComponent component) => throw new NotImplementedException(); + public Drawable GetDrawableComponent(ISkinLookup lookup) => throw new NotImplementedException(); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => throw new NotImplementedException(); diff --git a/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs b/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs index 6297d9cdc7..9e03663a49 100644 --- a/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs +++ b/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs @@ -73,7 +73,7 @@ namespace osu.Game.Tests.NonVisual.Skinning return lookup_names.Contains(componentName) ? renderer.WhitePixel : null; } - public Drawable GetDrawableComponent(ISkinComponent component) => throw new NotSupportedException(); + public Drawable GetDrawableComponent(ISkinLookup lookup) => throw new NotSupportedException(); public ISample GetSample(ISampleInfo sampleInfo) => throw new NotSupportedException(); public IBindable GetConfig(TLookup lookup) => throw new NotSupportedException(); } diff --git a/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs b/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs index 320373699d..6f14b933ee 100644 --- a/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs +++ b/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs @@ -78,7 +78,7 @@ namespace osu.Game.Tests.Rulesets OnLoadAsync?.Invoke(); } - public Drawable GetDrawableComponent(ISkinComponent component) => skin.GetDrawableComponent(component); + public Drawable GetDrawableComponent(ISkinLookup lookup) => skin.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS = default, WrapMode wrapModeT = default) => skin.GetTexture(componentName); diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs index 004e253c1f..7c02d34b1c 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs @@ -48,7 +48,7 @@ namespace osu.Game.Tests.Skins string expected = allowBeatmapLookups ? "beatmap" : "user"; - AddAssert($"Check lookup is from {expected}", () => requester.GetDrawableComponent(new TestSkinComponent())?.Name == expected); + AddAssert($"Check lookup is from {expected}", () => requester.GetDrawableComponent(new TestSkinLookup())?.Name == expected); } [TestCase(false)] @@ -59,7 +59,7 @@ namespace osu.Game.Tests.Skins ISkin expected() => allowBeatmapLookups ? beatmapSource : userSource; - AddAssert("Check lookup is from correct source", () => requester.FindProvider(s => s.GetDrawableComponent(new TestSkinComponent()) != null) == expected()); + AddAssert("Check lookup is from correct source", () => requester.FindProvider(s => s.GetDrawableComponent(new TestSkinLookup()) != null) == expected()); } public class UserSkinSource : LegacySkin @@ -69,7 +69,7 @@ namespace osu.Game.Tests.Skins { } - public override Drawable GetDrawableComponent(ISkinComponent component) + public override Drawable GetDrawableComponent(ISkinLookup lookup) { return new Container { Name = "user" }; } @@ -82,7 +82,7 @@ namespace osu.Game.Tests.Skins { } - public override Drawable GetDrawableComponent(ISkinComponent component) + public override Drawable GetDrawableComponent(ISkinLookup lookup) { return new Container { Name = "beatmap" }; } @@ -98,7 +98,7 @@ namespace osu.Game.Tests.Skins this.skin = skin; } - public Drawable GetDrawableComponent(ISkinComponent component) => skin.GetDrawableComponent(component); + public Drawable GetDrawableComponent(ISkinLookup lookup) => skin.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => skin.GetTexture(componentName, wrapModeS, wrapModeT); @@ -109,7 +109,7 @@ namespace osu.Game.Tests.Skins public ISkin FindProvider(Func lookupFunction) => skin.FindProvider(lookupFunction); } - private class TestSkinComponent : ISkinComponent + private class TestSkinLookup : ISkinLookup { public string LookupName => string.Empty; } diff --git a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs index 3f62bd038f..4cbc1cf4df 100644 --- a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs +++ b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs @@ -221,7 +221,7 @@ namespace osu.Game.Tests.Skins this.skin = skin; } - public Drawable GetDrawableComponent(ISkinComponent component) => skin.GetDrawableComponent(component); + public Drawable GetDrawableComponent(ISkinLookup lookup) => skin.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => skin.GetTexture(componentName, wrapModeS, wrapModeT); diff --git a/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs b/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs index f7c88643fe..712d5ce969 100644 --- a/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs +++ b/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs @@ -87,7 +87,7 @@ namespace osu.Game.Tests.Skins this.renderer = renderer; } - public Drawable GetDrawableComponent(ISkinComponent component) => throw new System.NotImplementedException(); + public Drawable GetDrawableComponent(ISkinLookup lookup) => throw new System.NotImplementedException(); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs index 01cc856a4a..6fe6a85b8f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs @@ -65,7 +65,7 @@ namespace osu.Game.Tests.Visual.Gameplay var actualInfo = actualComponentsContainer.CreateSkinnableInfo(); - var expectedComponentsContainer = (SkinnableTargetComponentsContainer)expectedSource.GetDrawableComponent(new SkinnableTargetComponent(target)); + var expectedComponentsContainer = (SkinnableTargetComponentsContainer)expectedSource.GetDrawableComponent(new SkinnableTargetLookup(target)); if (expectedComponentsContainer == null) return false; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs index d4fba76c37..81c5211878 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs @@ -164,7 +164,7 @@ namespace osu.Game.Tests.Visual.Gameplay { private bool allow = true; - protected override bool AllowDrawableLookup(ISkinComponent component) => allow; + protected override bool AllowDrawableLookup(ISkinLookup lookup) => allow; public void Disable() { @@ -182,8 +182,8 @@ namespace osu.Game.Tests.Visual.Gameplay { public new Drawable Drawable => base.Drawable; - public ExposedSkinnableDrawable(string name, Func defaultImplementation, ConfineMode confineMode = ConfineMode.ScaleToFit) - : base(new TestSkinComponent(name), defaultImplementation, confineMode) + public ExposedSkinnableDrawable(string name, Func defaultImplementation, ConfineMode confineMode = ConfineMode.ScaleToFit) + : base(new TestSkinLookup(name), defaultImplementation, confineMode) { } } @@ -251,8 +251,8 @@ namespace osu.Game.Tests.Visual.Gameplay public new Drawable Drawable => base.Drawable; public int SkinChangedCount { get; private set; } - public SkinConsumer(string name, Func defaultImplementation) - : base(new TestSkinComponent(name), defaultImplementation) + public SkinConsumer(string name, Func defaultImplementation) + : base(new TestSkinLookup(name), defaultImplementation) { } @@ -288,8 +288,8 @@ namespace osu.Game.Tests.Visual.Gameplay this.size = size; } - public Drawable GetDrawableComponent(ISkinComponent componentName) => - componentName.LookupName == "available" + public Drawable GetDrawableComponent(ISkinLookup lookupName) => + lookupName.LookupName == "available" ? new DrawWidthBox { Colour = Color4.Yellow, @@ -306,7 +306,7 @@ namespace osu.Game.Tests.Visual.Gameplay private class SecondarySource : ISkin { - public Drawable GetDrawableComponent(ISkinComponent componentName) => new SecondarySourceBox(); + public Drawable GetDrawableComponent(ISkinLookup lookupName) => new SecondarySourceBox(); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => throw new NotImplementedException(); @@ -318,7 +318,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Cached(typeof(ISkinSource))] private class SkinSourceContainer : Container, ISkinSource { - public Drawable GetDrawableComponent(ISkinComponent componentName) => new BaseSourceBox(); + public Drawable GetDrawableComponent(ISkinLookup lookupName) => new BaseSourceBox(); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => throw new NotImplementedException(); @@ -337,9 +337,9 @@ namespace osu.Game.Tests.Visual.Gameplay } } - private class TestSkinComponent : ISkinComponent + private class TestSkinLookup : ISkinLookup { - public TestSkinComponent(string name) + public TestSkinLookup(string name) { LookupName = name; } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs index 0ba112ec40..43206ac591 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs @@ -142,7 +142,7 @@ namespace osu.Game.Tests.Visual.Gameplay IBindable ISamplePlaybackDisabler.SamplePlaybackDisabled => SamplePlaybackDisabled; - public Drawable GetDrawableComponent(ISkinComponent component) => source?.GetDrawableComponent(component); + public Drawable GetDrawableComponent(ISkinLookup lookup) => source?.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => source?.GetTexture(componentName, wrapModeS, wrapModeT); public ISample GetSample(ISampleInfo sampleInfo) => source?.GetSample(sampleInfo); public IBindable GetConfig(TLookup lookup) => source?.GetConfig(lookup); diff --git a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs index 7e1196d4ca..bfcdd384a0 100644 --- a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs +++ b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs @@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.Judgements if (JudgementBody != null) RemoveInternal(JudgementBody, true); - AddInternal(JudgementBody = new SkinnableDrawable(new GameplaySkinComponent(type), _ => + AddInternal(JudgementBody = new SkinnableDrawable(new GameplaySkinLookup(type), _ => CreateDefaultJudgement(type), confineMode: ConfineMode.NoScaling) { Anchor = Anchor.Centre, diff --git a/osu.Game/Screens/Edit/EditorBeatmapSkin.cs b/osu.Game/Screens/Edit/EditorBeatmapSkin.cs index a106a60379..bc63ad063c 100644 --- a/osu.Game/Screens/Edit/EditorBeatmapSkin.cs +++ b/osu.Game/Screens/Edit/EditorBeatmapSkin.cs @@ -53,7 +53,7 @@ namespace osu.Game.Screens.Edit #region Delegated ISkin implementation - public Drawable GetDrawableComponent(ISkinComponent component) => Skin.GetDrawableComponent(component); + public Drawable GetDrawableComponent(ISkinLookup lookup) => Skin.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => Skin.GetTexture(componentName, wrapModeS, wrapModeT); public ISample GetSample(ISampleInfo sampleInfo) => Skin.GetSample(sampleInfo); public IBindable GetConfig(TLookup lookup) => Skin.GetConfig(lookup); diff --git a/osu.Game/Skinning/ArgonSkin.cs b/osu.Game/Skinning/ArgonSkin.cs index 20e4290725..f65cee8a69 100644 --- a/osu.Game/Skinning/ArgonSkin.cs +++ b/osu.Game/Skinning/ArgonSkin.cs @@ -81,14 +81,14 @@ namespace osu.Game.Skinning return null; } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (base.GetDrawableComponent(component) is Drawable c) + if (base.GetDrawableComponent(lookup) is Drawable c) return c; - switch (component) + switch (lookup) { - case SkinnableTargetComponent target: + case SkinnableTargetLookup target: switch (target.Target) { case SkinnableTarget.SongSelect: @@ -178,14 +178,14 @@ namespace osu.Game.Skinning return null; } - switch (component.LookupName) + switch (lookup.LookupName) { // Temporary until default skin has a valid hit lighting. case @"lighting": return Drawable.Empty(); } - if (GetTexture(component.LookupName) is Texture t) + if (GetTexture(lookup.LookupName) is Texture t) return new Sprite { Texture = t }; return null; diff --git a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs index f0caef9fa1..ec9d52f5c6 100644 --- a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs +++ b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs @@ -43,7 +43,7 @@ namespace osu.Game.Skinning } } - protected override bool AllowDrawableLookup(ISkinComponent component) + protected override bool AllowDrawableLookup(ISkinLookup lookup) { if (beatmapSkins == null) throw new InvalidOperationException($"{nameof(BeatmapSkinProvidingContainer)} needs to be loaded before being consumed."); diff --git a/osu.Game/Skinning/GameplaySkinComponent.cs b/osu.Game/Skinning/GameplaySkinLookup.cs similarity index 85% rename from osu.Game/Skinning/GameplaySkinComponent.cs rename to osu.Game/Skinning/GameplaySkinLookup.cs index 6f5dad2207..cec9dbde7d 100644 --- a/osu.Game/Skinning/GameplaySkinComponent.cs +++ b/osu.Game/Skinning/GameplaySkinLookup.cs @@ -5,12 +5,12 @@ using System.Linq; namespace osu.Game.Skinning { - public class GameplaySkinComponent : ISkinComponent + public class GameplaySkinLookup : ISkinLookup where T : notnull { public readonly T Component; - public GameplaySkinComponent(T component) + public GameplaySkinLookup(T component) { Component = component; } diff --git a/osu.Game/Skinning/ISkin.cs b/osu.Game/Skinning/ISkin.cs index c093dc2f32..c352dfef5c 100644 --- a/osu.Game/Skinning/ISkin.cs +++ b/osu.Game/Skinning/ISkin.cs @@ -17,9 +17,9 @@ namespace osu.Game.Skinning /// /// Retrieve a component implementation. /// - /// The requested component. + /// The requested component. /// A drawable representation for the requested component, or null if unavailable. - Drawable? GetDrawableComponent(ISkinComponent component); + Drawable? GetDrawableComponent(ISkinLookup lookup); /// /// Retrieve a . diff --git a/osu.Game/Skinning/ISkinComponent.cs b/osu.Game/Skinning/ISkinComponent.cs deleted file mode 100644 index 4bd9f21b6b..0000000000 --- a/osu.Game/Skinning/ISkinComponent.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Skinning -{ - public interface ISkinComponent - { - string LookupName { get; } - } -} diff --git a/osu.Game/Skinning/ISkinLookup.cs b/osu.Game/Skinning/ISkinLookup.cs new file mode 100644 index 0000000000..4daea35e82 --- /dev/null +++ b/osu.Game/Skinning/ISkinLookup.cs @@ -0,0 +1,21 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Skinning +{ + /// + /// A lookup type which can be used with . + /// + /// + /// Implementations of should match on types implementing this interface + /// to scope particular lookup variations. Using this, a ruleset or skin implementation could make its own lookup + /// type to scope away from more global contexts. + /// + /// More commonly, a ruleset could make use of to do a simple lookup based on + /// a provided enum. + /// + public interface ISkinLookup + { + string LookupName { get; } + } +} diff --git a/osu.Game/Skinning/LegacyBeatmapSkin.cs b/osu.Game/Skinning/LegacyBeatmapSkin.cs index e8414b4c11..2aa76b5871 100644 --- a/osu.Game/Skinning/LegacyBeatmapSkin.cs +++ b/osu.Game/Skinning/LegacyBeatmapSkin.cs @@ -43,9 +43,9 @@ namespace osu.Game.Skinning return new RealmBackedResourceStore(beatmapInfo.BeatmapSet.ToLive(resources.RealmAccess), resources.Files, resources.RealmAccess); } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (component is SkinnableTargetComponent targetComponent) + if (lookup is SkinnableTargetLookup targetComponent) { switch (targetComponent.Target) { @@ -59,7 +59,7 @@ namespace osu.Game.Skinning } } - return base.GetDrawableComponent(component); + return base.GetDrawableComponent(lookup); } public override IBindable? GetConfig(TLookup lookup) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index bfc60de2c9..97833d0e28 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -322,14 +322,14 @@ namespace osu.Game.Skinning return null; } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (base.GetDrawableComponent(component) is Drawable c) + if (base.GetDrawableComponent(lookup) is Drawable c) return c; - switch (component) + switch (lookup) { - case SkinnableTargetComponent target: + case SkinnableTargetLookup target: switch (target.Target) { case SkinnableTarget.MainHUDComponents: @@ -379,7 +379,7 @@ namespace osu.Game.Skinning return null; - case GameplaySkinComponent resultComponent: + case GameplaySkinLookup resultComponent: // kind of wasteful that we throw this away, but should do for now. if (getJudgementAnimation(resultComponent.Component) != null) @@ -397,7 +397,7 @@ namespace osu.Game.Skinning return null; - case SkinnableSprite.SpriteComponent sprite: + case SkinnableSprite.SpriteLookup sprite: return this.GetAnimation(sprite.LookupName, false, false); } diff --git a/osu.Game/Skinning/ResourceStoreBackedSkin.cs b/osu.Game/Skinning/ResourceStoreBackedSkin.cs index efdbb0a207..1b846438f5 100644 --- a/osu.Game/Skinning/ResourceStoreBackedSkin.cs +++ b/osu.Game/Skinning/ResourceStoreBackedSkin.cs @@ -27,7 +27,7 @@ namespace osu.Game.Skinning samples = audio.GetSampleStore(new NamespacedResourceStore(resources, @"Samples")); } - public Drawable? GetDrawableComponent(ISkinComponent component) => null; + public Drawable? GetDrawableComponent(ISkinLookup lookup) => null; public Texture? GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => textures.Get(componentName, wrapModeS, wrapModeT); diff --git a/osu.Game/Skinning/Skin.cs b/osu.Game/Skinning/Skin.cs index dd43e4dc54..a14b1e1359 100644 --- a/osu.Game/Skinning/Skin.cs +++ b/osu.Game/Skinning/Skin.cs @@ -154,11 +154,11 @@ namespace osu.Game.Skinning DrawableComponentInfo[targetContainer.Target] = targetContainer.CreateSkinnableInfo().ToArray(); } - public virtual Drawable? GetDrawableComponent(ISkinComponent component) + public virtual Drawable? GetDrawableComponent(ISkinLookup lookup) { - switch (component) + switch (lookup) { - case SkinnableTargetComponent target: + case SkinnableTargetLookup target: if (!DrawableComponentInfo.TryGetValue(target.Target, out var skinnableInfo)) return null; diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index 0e66278fc0..bd4078b985 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -201,7 +201,7 @@ namespace osu.Game.Skinning public event Action SourceChanged; - public Drawable GetDrawableComponent(ISkinComponent component) => lookupWithFallback(s => s.GetDrawableComponent(component)); + public Drawable GetDrawableComponent(ISkinLookup lookup) => lookupWithFallback(s => s.GetDrawableComponent(lookup)); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => lookupWithFallback(s => s.GetTexture(componentName, wrapModeS, wrapModeT)); diff --git a/osu.Game/Skinning/SkinProvidingContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs index 5c5e9ae0fc..0ed5c6b736 100644 --- a/osu.Game/Skinning/SkinProvidingContainer.cs +++ b/osu.Game/Skinning/SkinProvidingContainer.cs @@ -28,7 +28,7 @@ namespace osu.Game.Skinning /// protected virtual bool AllowFallingBackToParent => true; - protected virtual bool AllowDrawableLookup(ISkinComponent component) => true; + protected virtual bool AllowDrawableLookup(ISkinLookup lookup) => true; protected virtual bool AllowTextureLookup(string componentName) => true; @@ -107,19 +107,19 @@ namespace osu.Game.Skinning } } - public Drawable? GetDrawableComponent(ISkinComponent component) + public Drawable? GetDrawableComponent(ISkinLookup lookup) { foreach (var (_, lookupWrapper) in skinSources) { Drawable? sourceDrawable; - if ((sourceDrawable = lookupWrapper.GetDrawableComponent(component)) != null) + if ((sourceDrawable = lookupWrapper.GetDrawableComponent(lookup)) != null) return sourceDrawable; } if (!AllowFallingBackToParent) return null; - return ParentSource?.GetDrawableComponent(component); + return ParentSource?.GetDrawableComponent(lookup); } public Texture? GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) @@ -238,10 +238,10 @@ namespace osu.Game.Skinning this.provider = provider; } - public Drawable? GetDrawableComponent(ISkinComponent component) + public Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (provider.AllowDrawableLookup(component)) - return skin.GetDrawableComponent(component); + if (provider.AllowDrawableLookup(lookup)) + return skin.GetDrawableComponent(lookup); return null; } diff --git a/osu.Game/Skinning/SkinTransformer.cs b/osu.Game/Skinning/SkinTransformer.cs index 4da60f1e43..9772d98fde 100644 --- a/osu.Game/Skinning/SkinTransformer.cs +++ b/osu.Game/Skinning/SkinTransformer.cs @@ -19,7 +19,7 @@ namespace osu.Game.Skinning Skin = skin ?? throw new ArgumentNullException(nameof(skin)); } - public virtual Drawable? GetDrawableComponent(ISkinComponent component) => Skin.GetDrawableComponent(component); + public virtual Drawable? GetDrawableComponent(ISkinLookup lookup) => Skin.GetDrawableComponent(lookup); public virtual Texture? GetTexture(string componentName) => GetTexture(componentName, default, default); diff --git a/osu.Game/Skinning/SkinnableDrawable.cs b/osu.Game/Skinning/SkinnableDrawable.cs index c6321553c7..4398dda413 100644 --- a/osu.Game/Skinning/SkinnableDrawable.cs +++ b/osu.Game/Skinning/SkinnableDrawable.cs @@ -31,25 +31,25 @@ namespace osu.Game.Skinning set => base.AutoSizeAxes = value; } - protected readonly ISkinComponent Component; + protected readonly ISkinLookup Lookup; private readonly ConfineMode confineMode; /// /// Create a new skinnable drawable. /// - /// The namespace-complete resource name for this skinnable element. + /// The namespace-complete resource name for this skinnable element. /// A function to create the default skin implementation of this element. /// How (if at all) the should be resize to fit within our own bounds. - public SkinnableDrawable(ISkinComponent component, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) - : this(component, confineMode) + public SkinnableDrawable(ISkinLookup lookup, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) + : this(lookup, confineMode) { createDefault = defaultImplementation; } - protected SkinnableDrawable(ISkinComponent component, ConfineMode confineMode = ConfineMode.NoScaling) + protected SkinnableDrawable(ISkinLookup lookup, ConfineMode confineMode = ConfineMode.NoScaling) { - Component = component; + Lookup = lookup; this.confineMode = confineMode; RelativeSizeAxes = Axes.Both; @@ -60,13 +60,13 @@ namespace osu.Game.Skinning /// public void ResetAnimation() => (Drawable as IFramedAnimation)?.GotoFrame(0); - private readonly Func? createDefault; + private readonly Func? createDefault; private readonly Cached scaling = new Cached(); private bool isDefault; - protected virtual Drawable CreateDefault(ISkinComponent component) => createDefault?.Invoke(component) ?? Empty(); + protected virtual Drawable CreateDefault(ISkinLookup lookup) => createDefault?.Invoke(lookup) ?? Empty(); /// /// Whether to apply size restrictions (specified via ) to the default implementation. @@ -75,11 +75,11 @@ namespace osu.Game.Skinning protected override void SkinChanged(ISkinSource skin) { - var retrieved = skin.GetDrawableComponent(Component); + var retrieved = skin.GetDrawableComponent(Lookup); if (retrieved == null) { - Drawable = CreateDefault(Component); + Drawable = CreateDefault(Lookup); isDefault = true; } else diff --git a/osu.Game/Skinning/SkinnableSprite.cs b/osu.Game/Skinning/SkinnableSprite.cs index f8130f31c3..8f456fce0a 100644 --- a/osu.Game/Skinning/SkinnableSprite.cs +++ b/osu.Game/Skinning/SkinnableSprite.cs @@ -34,42 +34,42 @@ namespace osu.Game.Skinning private ISkinSource source { get; set; } = null!; public SkinnableSprite(string textureName, ConfineMode confineMode = ConfineMode.NoScaling) - : base(new SpriteComponent(textureName), confineMode) + : base(new SpriteLookup(textureName), confineMode) { SpriteName.Value = textureName; } public SkinnableSprite() - : base(new SpriteComponent(string.Empty), ConfineMode.NoScaling) + : base(new SpriteLookup(string.Empty), ConfineMode.NoScaling) { RelativeSizeAxes = Axes.None; AutoSizeAxes = Axes.Both; SpriteName.BindValueChanged(name => { - ((SpriteComponent)Component).LookupName = name.NewValue ?? string.Empty; + ((SpriteLookup)Lookup).LookupName = name.NewValue ?? string.Empty; if (IsLoaded) SkinChanged(CurrentSkin); }); } - protected override Drawable CreateDefault(ISkinComponent component) + protected override Drawable CreateDefault(ISkinLookup lookup) { - var texture = textures.Get(component.LookupName); + var texture = textures.Get(lookup.LookupName); if (texture == null) - return new SpriteNotFound(component.LookupName); + return new SpriteNotFound(lookup.LookupName); return new Sprite { Texture = texture }; } public bool UsesFixedAnchor { get; set; } - internal class SpriteComponent : ISkinComponent + internal class SpriteLookup : ISkinLookup { public string LookupName { get; set; } - public SpriteComponent(string textureName) + public SpriteLookup(string textureName) { LookupName = textureName; } diff --git a/osu.Game/Skinning/SkinnableSpriteText.cs b/osu.Game/Skinning/SkinnableSpriteText.cs index 2bde3c4180..8cc48a76ed 100644 --- a/osu.Game/Skinning/SkinnableSpriteText.cs +++ b/osu.Game/Skinning/SkinnableSpriteText.cs @@ -9,8 +9,8 @@ namespace osu.Game.Skinning { public class SkinnableSpriteText : SkinnableDrawable, IHasText { - public SkinnableSpriteText(ISkinComponent component, Func defaultImplementation, ConfineMode confineMode = ConfineMode.NoScaling) - : base(component, defaultImplementation, confineMode) + public SkinnableSpriteText(ISkinLookup lookup, Func defaultImplementation, ConfineMode confineMode = ConfineMode.NoScaling) + : base(lookup, defaultImplementation, confineMode) { } diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index 708ad4ec47..b0262ce07a 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -39,7 +39,7 @@ namespace osu.Game.Skinning components.Clear(); ComponentsLoaded = false; - content = CurrentSkin.GetDrawableComponent(new SkinnableTargetComponent(Target)) as SkinnableTargetComponentsContainer; + content = CurrentSkin.GetDrawableComponent(new SkinnableTargetLookup(Target)) as SkinnableTargetComponentsContainer; cancellationSource?.Cancel(); cancellationSource = null; diff --git a/osu.Game/Skinning/SkinnableTargetComponent.cs b/osu.Game/Skinning/SkinnableTargetLookup.cs similarity index 73% rename from osu.Game/Skinning/SkinnableTargetComponent.cs rename to osu.Game/Skinning/SkinnableTargetLookup.cs index a17aafe6e7..df03123e85 100644 --- a/osu.Game/Skinning/SkinnableTargetComponent.cs +++ b/osu.Game/Skinning/SkinnableTargetLookup.cs @@ -3,13 +3,13 @@ namespace osu.Game.Skinning { - public class SkinnableTargetComponent : ISkinComponent + public class SkinnableTargetLookup : ISkinLookup { public readonly SkinnableTarget Target; public string LookupName => Target.ToString(); - public SkinnableTargetComponent(SkinnableTarget target) + public SkinnableTargetLookup(SkinnableTarget target) { Target = target; } diff --git a/osu.Game/Skinning/TrianglesSkin.cs b/osu.Game/Skinning/TrianglesSkin.cs index d00874aa8f..32b4b6b4d4 100644 --- a/osu.Game/Skinning/TrianglesSkin.cs +++ b/osu.Game/Skinning/TrianglesSkin.cs @@ -59,14 +59,14 @@ namespace osu.Game.Skinning return null; } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (base.GetDrawableComponent(component) is Drawable c) + if (base.GetDrawableComponent(lookup) is Drawable c) return c; - switch (component) + switch (lookup) { - case SkinnableTargetComponent target: + case SkinnableTargetLookup target: switch (target.Target) { case SkinnableTarget.SongSelect: @@ -156,14 +156,14 @@ namespace osu.Game.Skinning return null; } - switch (component.LookupName) + switch (lookup.LookupName) { // Temporary until default skin has a valid hit lighting. case @"lighting": return Drawable.Empty(); } - if (GetTexture(component.LookupName) is Texture t) + if (GetTexture(lookup.LookupName) is Texture t) return new Sprite { Texture = t }; return null; diff --git a/osu.Game/Skinning/UnsupportedSkinComponentException.cs b/osu.Game/Skinning/UnsupportedSkinComponentException.cs index 7f0dd51d5b..32fc6661b0 100644 --- a/osu.Game/Skinning/UnsupportedSkinComponentException.cs +++ b/osu.Game/Skinning/UnsupportedSkinComponentException.cs @@ -7,8 +7,8 @@ namespace osu.Game.Skinning { public class UnsupportedSkinComponentException : Exception { - public UnsupportedSkinComponentException(ISkinComponent component) - : base($@"Unsupported component type: {component.GetType()} (lookup: ""{component.LookupName}"").") + public UnsupportedSkinComponentException(ISkinLookup lookup) + : base($@"Unsupported component type: {lookup.GetType()} (lookup: ""{lookup.LookupName}"").") { } } From e75c3b3f94fa17bd18ff58e0c9ec2419453e606d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 16:03:29 +0900 Subject: [PATCH 0519/2991] Rename `SkinnableTarget` to `GlobalSkinLookup` --- .../Legacy/CatchLegacySkinTransformer.cs | 6 ++--- .../Skins/SkinDeserialisationTest.cs | 16 ++++++------- .../Gameplay/TestSceneBeatmapSkinFallbacks.cs | 6 ++--- osu.Game/Screens/Play/HUDOverlay.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 2 +- osu.Game/Skinning/ArgonSkin.cs | 8 +++---- osu.Game/Skinning/Editor/SkinEditor.cs | 2 +- osu.Game/Skinning/GlobalSkinLookup.cs | 23 +++++++++++++++++++ osu.Game/Skinning/ISkinnableDrawable.cs | 5 ++++ osu.Game/Skinning/ISkinnableTarget.cs | 2 +- osu.Game/Skinning/LegacyBeatmapSkin.cs | 6 ++--- osu.Game/Skinning/LegacySkin.cs | 6 ++--- osu.Game/Skinning/Skin.cs | 10 ++++---- osu.Game/Skinning/SkinnableTarget.cs | 11 --------- osu.Game/Skinning/SkinnableTargetContainer.cs | 6 ++--- osu.Game/Skinning/SkinnableTargetLookup.cs | 17 -------------- osu.Game/Skinning/TrianglesSkin.cs | 8 +++---- 17 files changed, 68 insertions(+), 68 deletions(-) create mode 100644 osu.Game/Skinning/GlobalSkinLookup.cs delete mode 100644 osu.Game/Skinning/SkinnableTarget.cs delete mode 100644 osu.Game/Skinning/SkinnableTargetLookup.cs diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs index 5fda40d8c0..83a8a37676 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs @@ -27,11 +27,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (lookup is SkinnableTargetLookup targetComponent) + if (lookup is GlobalSkinLookup targetComponent) { - switch (targetComponent.Target) + switch (targetComponent.Lookup) { - case SkinnableTarget.MainHUDComponents: + case GlobalSkinLookup.LookupType.MainHUDComponents: var components = base.GetDrawableComponent(lookup) as SkinnableTargetComponentsContainer; if (providesComboCounter && components != null) diff --git a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs index 989459632e..4398d870a0 100644 --- a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs +++ b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs @@ -80,7 +80,7 @@ namespace osu.Game.Tests.Skins var skin = new TestSkin(new SkinInfo(), null, storage); Assert.That(skin.DrawableComponentInfo, Has.Count.EqualTo(2)); - Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents], Has.Length.EqualTo(9)); + Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(9)); } } @@ -93,10 +93,10 @@ namespace osu.Game.Tests.Skins var skin = new TestSkin(new SkinInfo(), null, storage); Assert.That(skin.DrawableComponentInfo, Has.Count.EqualTo(2)); - Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents], Has.Length.EqualTo(6)); - Assert.That(skin.DrawableComponentInfo[SkinnableTarget.SongSelect], Has.Length.EqualTo(1)); + Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(6)); + Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.SongSelect], Has.Length.EqualTo(1)); - var skinnableInfo = skin.DrawableComponentInfo[SkinnableTarget.SongSelect].First(); + var skinnableInfo = skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.SongSelect].First(); Assert.That(skinnableInfo.Type, Is.EqualTo(typeof(SkinnableSprite))); Assert.That(skinnableInfo.Settings.First().Key, Is.EqualTo("sprite_name")); @@ -107,10 +107,10 @@ namespace osu.Game.Tests.Skins using (var storage = new ZipArchiveReader(stream)) { var skin = new TestSkin(new SkinInfo(), null, storage); - Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents], Has.Length.EqualTo(8)); - Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(UnstableRateCounter))); - Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(ColourHitErrorMeter))); - Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(LegacySongProgress))); + Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(8)); + Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(UnstableRateCounter))); + Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(ColourHitErrorMeter))); + Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(LegacySongProgress))); } } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs index 6fe6a85b8f..69a50a1cd1 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs @@ -40,7 +40,7 @@ namespace osu.Game.Tests.Visual.Gameplay { CreateSkinTest(TrianglesSkin.CreateInfo(), () => new LegacyBeatmapSkin(new BeatmapInfo(), null)); AddUntilStep("wait for hud load", () => Player.ChildrenOfType().All(c => c.ComponentsLoaded)); - AddAssert("hud from default skin", () => AssertComponentsFromExpectedSource(SkinnableTarget.MainHUDComponents, skinManager.CurrentSkin.Value)); + AddAssert("hud from default skin", () => AssertComponentsFromExpectedSource(GlobalSkinLookup.LookupType.MainHUDComponents, skinManager.CurrentSkin.Value)); } protected void CreateSkinTest(SkinInfo gameCurrentSkin, Func getBeatmapSkin) @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual.Gameplay }); } - protected bool AssertComponentsFromExpectedSource(SkinnableTarget target, ISkin expectedSource) + protected bool AssertComponentsFromExpectedSource(GlobalSkinLookup.LookupType target, ISkin expectedSource) { var actualComponentsContainer = Player.ChildrenOfType().First(s => s.Target == target) .ChildrenOfType().SingleOrDefault(); @@ -65,7 +65,7 @@ namespace osu.Game.Tests.Visual.Gameplay var actualInfo = actualComponentsContainer.CreateSkinnableInfo(); - var expectedComponentsContainer = (SkinnableTargetComponentsContainer)expectedSource.GetDrawableComponent(new SkinnableTargetLookup(target)); + var expectedComponentsContainer = (SkinnableTargetComponentsContainer)expectedSource.GetDrawableComponent(new GlobalSkinLookup(target)); if (expectedComponentsContainer == null) return false; diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 2791f5ff8f..932ebe7d18 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -391,7 +391,7 @@ namespace osu.Game.Screens.Play private OsuConfigManager config { get; set; } public MainComponentsContainer() - : base(SkinnableTarget.MainHUDComponents) + : base(GlobalSkinLookup.LookupType.MainHUDComponents) { RelativeSizeAxes = Axes.Both; } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 4b2417aab4..e525d5a368 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -250,7 +250,7 @@ namespace osu.Game.Screens.Select } } }, - new SkinnableTargetContainer(SkinnableTarget.SongSelect) + new SkinnableTargetContainer(GlobalSkinLookup.LookupType.SongSelect) { RelativeSizeAxes = Axes.Both, }, diff --git a/osu.Game/Skinning/ArgonSkin.cs b/osu.Game/Skinning/ArgonSkin.cs index f65cee8a69..7aaf1a0e89 100644 --- a/osu.Game/Skinning/ArgonSkin.cs +++ b/osu.Game/Skinning/ArgonSkin.cs @@ -88,10 +88,10 @@ namespace osu.Game.Skinning switch (lookup) { - case SkinnableTargetLookup target: - switch (target.Target) + case GlobalSkinLookup globalLookup: + switch (globalLookup.Lookup) { - case SkinnableTarget.SongSelect: + case GlobalSkinLookup.LookupType.SongSelect: var songSelectComponents = new SkinnableTargetComponentsContainer(_ => { // do stuff when we need to. @@ -99,7 +99,7 @@ namespace osu.Game.Skinning return songSelectComponents; - case SkinnableTarget.MainHUDComponents: + case GlobalSkinLookup.LookupType.MainHUDComponents: var skinnableTargetWrapper = new SkinnableTargetComponentsContainer(container => { var score = container.OfType().FirstOrDefault(); diff --git a/osu.Game/Skinning/Editor/SkinEditor.cs b/osu.Game/Skinning/Editor/SkinEditor.cs index c1ff161f25..fdc8b6b2ad 100644 --- a/osu.Game/Skinning/Editor/SkinEditor.cs +++ b/osu.Game/Skinning/Editor/SkinEditor.cs @@ -314,7 +314,7 @@ namespace osu.Game.Skinning.Editor private ISkinnableTarget getFirstTarget() => availableTargets.FirstOrDefault(); - private ISkinnableTarget getTarget(SkinnableTarget target) + private ISkinnableTarget getTarget(GlobalSkinLookup.LookupType target) { return availableTargets.FirstOrDefault(c => c.Target == target); } diff --git a/osu.Game/Skinning/GlobalSkinLookup.cs b/osu.Game/Skinning/GlobalSkinLookup.cs new file mode 100644 index 0000000000..c63c0315a3 --- /dev/null +++ b/osu.Game/Skinning/GlobalSkinLookup.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. + +namespace osu.Game.Skinning +{ + public class GlobalSkinLookup : ISkinLookup + { + public readonly LookupType Lookup; + + public string LookupName => Lookup.ToString(); + + public GlobalSkinLookup(LookupType lookup) + { + Lookup = lookup; + } + + public enum LookupType + { + MainHUDComponents, + SongSelect + } + } +} diff --git a/osu.Game/Skinning/ISkinnableDrawable.cs b/osu.Game/Skinning/ISkinnableDrawable.cs index 3fc6a2fdd8..1ecd6f967e 100644 --- a/osu.Game/Skinning/ISkinnableDrawable.cs +++ b/osu.Game/Skinning/ISkinnableDrawable.cs @@ -5,12 +5,17 @@ using System; using osu.Framework.Bindables; using osu.Framework.Extensions.TypeExtensions; using osu.Framework.Graphics; +using osu.Game.Configuration; namespace osu.Game.Skinning { /// /// Denotes a drawable which, as a drawable, can be adjusted via skinning specifications. /// + /// + /// Attaching this interface to any will make it serialisable to skin settings. + /// Adding annotated bindables will also serialise these settings alongside each instance. + /// public interface ISkinnableDrawable : IDrawable { /// diff --git a/osu.Game/Skinning/ISkinnableTarget.cs b/osu.Game/Skinning/ISkinnableTarget.cs index 8d4f4dd0c3..b1a0f6714b 100644 --- a/osu.Game/Skinning/ISkinnableTarget.cs +++ b/osu.Game/Skinning/ISkinnableTarget.cs @@ -18,7 +18,7 @@ namespace osu.Game.Skinning /// /// The definition of this target. /// - SkinnableTarget Target { get; } + GlobalSkinLookup.LookupType Target { get; } /// /// A bindable list of components which are being tracked by this skinnable target. diff --git a/osu.Game/Skinning/LegacyBeatmapSkin.cs b/osu.Game/Skinning/LegacyBeatmapSkin.cs index 2aa76b5871..1d6ded6fee 100644 --- a/osu.Game/Skinning/LegacyBeatmapSkin.cs +++ b/osu.Game/Skinning/LegacyBeatmapSkin.cs @@ -45,11 +45,11 @@ namespace osu.Game.Skinning public override Drawable? GetDrawableComponent(ISkinLookup lookup) { - if (lookup is SkinnableTargetLookup targetComponent) + if (lookup is GlobalSkinLookup targetComponent) { - switch (targetComponent.Target) + switch (targetComponent.Lookup) { - case SkinnableTarget.MainHUDComponents: + case GlobalSkinLookup.LookupType.MainHUDComponents: // this should exist in LegacySkin instead, but there isn't a fallback skin for LegacySkins yet. // therefore keep the check here until fallback default legacy skin is supported. if (!this.HasFont(LegacyFont.Score)) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 97833d0e28..75957bb560 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -329,10 +329,10 @@ namespace osu.Game.Skinning switch (lookup) { - case SkinnableTargetLookup target: - switch (target.Target) + case GlobalSkinLookup target: + switch (target.Lookup) { - case SkinnableTarget.MainHUDComponents: + case GlobalSkinLookup.LookupType.MainHUDComponents: var skinnableTargetWrapper = new SkinnableTargetComponentsContainer(container => { var score = container.OfType().FirstOrDefault(); diff --git a/osu.Game/Skinning/Skin.cs b/osu.Game/Skinning/Skin.cs index a14b1e1359..67b74229bb 100644 --- a/osu.Game/Skinning/Skin.cs +++ b/osu.Game/Skinning/Skin.cs @@ -37,9 +37,9 @@ namespace osu.Game.Skinning public SkinConfiguration Configuration { get; set; } - public IDictionary DrawableComponentInfo => drawableComponentInfo; + public IDictionary DrawableComponentInfo => drawableComponentInfo; - private readonly Dictionary drawableComponentInfo = new Dictionary(); + private readonly Dictionary drawableComponentInfo = new Dictionary(); public abstract ISample? GetSample(ISampleInfo sampleInfo); @@ -97,7 +97,7 @@ namespace osu.Game.Skinning Configuration = new SkinConfiguration(); // skininfo files may be null for default skin. - foreach (SkinnableTarget skinnableTarget in Enum.GetValues(typeof(SkinnableTarget))) + foreach (GlobalSkinLookup.LookupType skinnableTarget in Enum.GetValues(typeof(GlobalSkinLookup.LookupType))) { string filename = $"{skinnableTarget}.json"; @@ -158,8 +158,8 @@ namespace osu.Game.Skinning { switch (lookup) { - case SkinnableTargetLookup target: - if (!DrawableComponentInfo.TryGetValue(target.Target, out var skinnableInfo)) + case GlobalSkinLookup target: + if (!DrawableComponentInfo.TryGetValue(target.Lookup, out var skinnableInfo)) return null; var components = new List(); diff --git a/osu.Game/Skinning/SkinnableTarget.cs b/osu.Game/Skinning/SkinnableTarget.cs deleted file mode 100644 index 09de8a5d71..0000000000 --- a/osu.Game/Skinning/SkinnableTarget.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Skinning -{ - public enum SkinnableTarget - { - MainHUDComponents, - SongSelect - } -} diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index b0262ce07a..bea29b0da3 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -13,7 +13,7 @@ namespace osu.Game.Skinning { private SkinnableTargetComponentsContainer? content; - public SkinnableTarget Target { get; } + public GlobalSkinLookup.LookupType Target { get; } public IBindableList Components => components; @@ -25,7 +25,7 @@ namespace osu.Game.Skinning private CancellationTokenSource? cancellationSource; - public SkinnableTargetContainer(SkinnableTarget target) + public SkinnableTargetContainer(GlobalSkinLookup.LookupType target) { Target = target; } @@ -39,7 +39,7 @@ namespace osu.Game.Skinning components.Clear(); ComponentsLoaded = false; - content = CurrentSkin.GetDrawableComponent(new SkinnableTargetLookup(Target)) as SkinnableTargetComponentsContainer; + content = CurrentSkin.GetDrawableComponent(new GlobalSkinLookup(Target)) as SkinnableTargetComponentsContainer; cancellationSource?.Cancel(); cancellationSource = null; diff --git a/osu.Game/Skinning/SkinnableTargetLookup.cs b/osu.Game/Skinning/SkinnableTargetLookup.cs deleted file mode 100644 index df03123e85..0000000000 --- a/osu.Game/Skinning/SkinnableTargetLookup.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Skinning -{ - public class SkinnableTargetLookup : ISkinLookup - { - public readonly SkinnableTarget Target; - - public string LookupName => Target.ToString(); - - public SkinnableTargetLookup(SkinnableTarget target) - { - Target = target; - } - } -} diff --git a/osu.Game/Skinning/TrianglesSkin.cs b/osu.Game/Skinning/TrianglesSkin.cs index 32b4b6b4d4..e3729136b9 100644 --- a/osu.Game/Skinning/TrianglesSkin.cs +++ b/osu.Game/Skinning/TrianglesSkin.cs @@ -66,10 +66,10 @@ namespace osu.Game.Skinning switch (lookup) { - case SkinnableTargetLookup target: - switch (target.Target) + case GlobalSkinLookup target: + switch (target.Lookup) { - case SkinnableTarget.SongSelect: + case GlobalSkinLookup.LookupType.SongSelect: var songSelectComponents = new SkinnableTargetComponentsContainer(_ => { // do stuff when we need to. @@ -77,7 +77,7 @@ namespace osu.Game.Skinning return songSelectComponents; - case SkinnableTarget.MainHUDComponents: + case GlobalSkinLookup.LookupType.MainHUDComponents: var skinnableTargetWrapper = new SkinnableTargetComponentsContainer(container => { var score = container.OfType().FirstOrDefault(); From 1aa0e40f2f4111d6c52e6aca33fb8190662689b2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 16:04:56 +0900 Subject: [PATCH 0520/2991] Add "Component" prefix to lookup naming --- ...nLookup.cs => CatchSkinComponentLookup.cs} | 4 ++-- .../Objects/Drawables/CaughtObject.cs | 4 ++-- .../Objects/Drawables/DrawableBanana.cs | 2 +- .../Objects/Drawables/DrawableDroplet.cs | 2 +- .../Objects/Drawables/DrawableFruit.cs | 2 +- .../Argon/CatchArgonSkinTransformer.cs | 4 ++-- .../Legacy/CatchLegacySkinTransformer.cs | 10 ++++----- .../UI/CatchComboDisplay.cs | 2 +- osu.Game.Rulesets.Catch/UI/HitExplosion.cs | 2 +- .../UI/SkinnableCatcher.cs | 2 +- .../Skinning/TestSceneColumnBackground.cs | 4 ++-- .../Skinning/TestSceneStageBackground.cs | 2 +- .../Skinning/TestSceneStageForeground.cs | 2 +- ...nLookup.cs => ManiaSkinComponentLookup.cs} | 6 ++--- .../Objects/Drawables/DrawableHoldNote.cs | 2 +- .../Objects/Drawables/DrawableNote.cs | 2 +- .../Argon/ManiaArgonSkinTransformer.cs | 6 ++--- .../Legacy/ManiaLegacySkinTransformer.cs | 6 ++--- osu.Game.Rulesets.Mania/UI/Column.cs | 4 ++-- .../UI/Components/ColumnHitObjectArea.cs | 2 +- .../UI/PoolableHitExplosion.cs | 2 +- osu.Game.Rulesets.Mania/UI/Stage.cs | 4 ++-- .../TestSceneCursorTrail.cs | 2 +- .../TestSceneGameplayCursor.cs | 2 +- .../TestSceneSkinFallbacks.cs | 4 ++-- .../Drawables/Connections/FollowPoint.cs | 2 +- .../Objects/Drawables/DrawableHitCircle.cs | 6 ++--- .../Objects/Drawables/DrawableSlider.cs | 2 +- .../Objects/Drawables/DrawableSliderBall.cs | 4 ++-- .../Objects/Drawables/DrawableSliderRepeat.cs | 2 +- .../Objects/Drawables/DrawableSliderTail.cs | 2 +- .../Objects/Drawables/DrawableSliderTick.cs | 2 +- .../Objects/Drawables/DrawableSpinner.cs | 2 +- ...kinLookup.cs => OsuSkinComponentLookup.cs} | 4 ++-- .../Skinning/Argon/OsuArgonSkinTransformer.cs | 6 ++--- .../Skinning/Default/DefaultApproachCircle.cs | 2 +- .../Skinning/Default/NumberPiece.cs | 2 +- .../Skinning/Default/ReverseArrowPiece.cs | 2 +- .../Skinning/Legacy/LegacyApproachCircle.cs | 2 +- .../Skinning/Legacy/LegacyMainCirclePiece.cs | 2 +- .../Skinning/Legacy/LegacyReverseArrow.cs | 2 +- .../Legacy/OsuLegacySkinTransformer.cs | 4 ++-- osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs | 2 +- .../UI/Cursor/OsuCursorContainer.cs | 4 ++-- osu.Game.Rulesets.Osu/UI/SmokeContainer.cs | 4 ++-- .../Skinning/TestSceneTaikoScroller.cs | 2 +- .../Objects/Drawables/DrawableBarLine.cs | 2 +- .../Objects/Drawables/DrawableDrumRoll.cs | 2 +- .../Objects/Drawables/DrawableDrumRollTick.cs | 2 +- .../Objects/Drawables/DrawableHit.cs | 4 ++-- .../Objects/Drawables/DrawableSwell.cs | 2 +- .../Objects/Drawables/DrawableSwellTick.cs | 2 +- .../Legacy/TaikoLegacySkinTransformer.cs | 6 ++--- ...nLookup.cs => TaikoSkinComponentLookup.cs} | 4 ++-- .../UI/DrawableTaikoRuleset.cs | 2 +- osu.Game.Rulesets.Taiko/UI/HitExplosion.cs | 2 +- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 2 +- .../UI/KiaiHitExplosion.cs | 2 +- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 8 +++---- .../TestSceneHitObjectAccentColour.cs | 2 +- .../Skinning/LegacySkinAnimationTest.cs | 2 +- .../TestSceneRulesetSkinProvidingContainer.cs | 2 +- .../Skins/SkinDeserialisationTest.cs | 16 +++++++------- .../TestSceneBeatmapSkinLookupDisables.cs | 12 +++++----- .../Skins/TestSceneSkinConfigurationLookup.cs | 2 +- .../Skins/TestSceneSkinProvidingContainer.cs | 2 +- .../Gameplay/TestSceneBeatmapSkinFallbacks.cs | 6 ++--- .../Gameplay/TestSceneSkinnableDrawable.cs | 22 +++++++++---------- .../Gameplay/TestSceneSkinnableSound.cs | 2 +- .../Rulesets/Judgements/DrawableJudgement.cs | 2 +- osu.Game/Screens/Edit/EditorBeatmapSkin.cs | 2 +- osu.Game/Screens/Play/HUDOverlay.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 2 +- osu.Game/Skinning/ArgonSkin.cs | 8 +++---- .../Skinning/BeatmapSkinProvidingContainer.cs | 2 +- osu.Game/Skinning/Editor/SkinEditor.cs | 2 +- ...okup.cs => GameplaySkinComponentLookup.cs} | 4 ++-- ...Lookup.cs => GlobalSkinComponentLookup.cs} | 4 ++-- osu.Game/Skinning/ISkin.cs | 2 +- ...ISkinLookup.cs => ISkinComponentLookup.cs} | 4 ++-- osu.Game/Skinning/ISkinnableTarget.cs | 2 +- osu.Game/Skinning/LegacyBeatmapSkin.cs | 6 ++--- osu.Game/Skinning/LegacySkin.cs | 10 ++++----- osu.Game/Skinning/ResourceStoreBackedSkin.cs | 2 +- osu.Game/Skinning/Skin.cs | 10 ++++----- osu.Game/Skinning/SkinManager.cs | 2 +- osu.Game/Skinning/SkinProvidingContainer.cs | 6 ++--- osu.Game/Skinning/SkinTransformer.cs | 2 +- osu.Game/Skinning/SkinnableDrawable.cs | 16 +++++++------- osu.Game/Skinning/SkinnableSprite.cs | 12 +++++----- osu.Game/Skinning/SkinnableSpriteText.cs | 2 +- osu.Game/Skinning/SkinnableTargetContainer.cs | 6 ++--- osu.Game/Skinning/TrianglesSkin.cs | 8 +++---- .../UnsupportedSkinComponentException.cs | 2 +- 94 files changed, 186 insertions(+), 186 deletions(-) rename osu.Game.Rulesets.Catch/{CatchSkinLookup.cs => CatchSkinComponentLookup.cs} (74%) rename osu.Game.Rulesets.Mania/{ManiaSkinLookup.cs => ManiaSkinComponentLookup.cs} (77%) rename osu.Game.Rulesets.Osu/{OsuSkinLookup.cs => OsuSkinComponentLookup.cs} (73%) rename osu.Game.Rulesets.Taiko/{TaikoSkinLookup.cs => TaikoSkinComponentLookup.cs} (73%) rename osu.Game/Skinning/{GameplaySkinLookup.cs => GameplaySkinComponentLookup.cs} (83%) rename osu.Game/Skinning/{GlobalSkinLookup.cs => GlobalSkinComponentLookup.cs} (78%) rename osu.Game/Skinning/{ISkinLookup.cs => ISkinComponentLookup.cs} (88%) diff --git a/osu.Game.Rulesets.Catch/CatchSkinLookup.cs b/osu.Game.Rulesets.Catch/CatchSkinComponentLookup.cs similarity index 74% rename from osu.Game.Rulesets.Catch/CatchSkinLookup.cs rename to osu.Game.Rulesets.Catch/CatchSkinComponentLookup.cs index 65bfc7ee30..149aae1cb4 100644 --- a/osu.Game.Rulesets.Catch/CatchSkinLookup.cs +++ b/osu.Game.Rulesets.Catch/CatchSkinComponentLookup.cs @@ -5,9 +5,9 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch { - public class CatchSkinLookup : GameplaySkinLookup + public class CatchSkinComponentLookup : GameplaySkinComponentLookup { - public CatchSkinLookup(CatchSkinComponents component) + public CatchSkinComponentLookup(CatchSkinComponents component) : base(component) { } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs index 20d348fe3d..8ac5eac227 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs @@ -37,8 +37,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables public override bool RemoveWhenNotAlive => true; - protected CaughtObject(CatchSkinComponents skinComponent, Func defaultImplementation) - : base(new CatchSkinLookup(skinComponent), defaultImplementation) + protected CaughtObject(CatchSkinComponents skinComponent, Func defaultImplementation) + : base(new CatchSkinComponentLookup(skinComponent), defaultImplementation) { Origin = Anchor.Centre; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs index a2b32ea9e4..80a4150d98 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables private void load() { ScalingContainer.Child = new SkinnableDrawable( - new CatchSkinLookup(CatchSkinComponents.Banana), + new CatchSkinComponentLookup(CatchSkinComponents.Banana), _ => new BananaPiece()); } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs index 210a4495e4..a81d87480a 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables private void load() { ScalingContainer.Child = new SkinnableDrawable( - new CatchSkinLookup(CatchSkinComponents.Droplet), + new CatchSkinComponentLookup(CatchSkinComponents.Droplet), _ => new DropletPiece()); } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs index 6359a5b35c..d7fd79929b 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables private void load() { ScalingContainer.Child = new SkinnableDrawable( - new CatchSkinLookup(CatchSkinComponents.Fruit), + new CatchSkinComponentLookup(CatchSkinComponents.Fruit), _ => new FruitPiece()); } diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs index 606cd339a9..520c2de248 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs @@ -13,11 +13,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon { } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { switch (lookup) { - case CatchSkinLookup catchComponent: + case CatchSkinComponentLookup catchComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. switch (catchComponent.Component) { diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs index 83a8a37676..08ac55508a 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs @@ -25,13 +25,13 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { - if (lookup is GlobalSkinLookup targetComponent) + if (lookup is GlobalSkinComponentLookup targetComponent) { switch (targetComponent.Lookup) { - case GlobalSkinLookup.LookupType.MainHUDComponents: + case GlobalSkinComponentLookup.LookupType.MainHUDComponents: var components = base.GetDrawableComponent(lookup) as SkinnableTargetComponentsContainer; if (providesComboCounter && components != null) @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy } } - if (lookup is CatchSkinLookup catchSkinComponent) + if (lookup is CatchSkinComponentLookup catchSkinComponent) { switch (catchSkinComponent.Component) { @@ -127,7 +127,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { case CatchSkinConfiguration.FlipCatcherPlate: // Don't flip catcher plate contents if the catcher is provided by this legacy skin. - if (GetDrawableComponent(new CatchSkinLookup(CatchSkinComponents.Catcher)) != null) + if (GetDrawableComponent(new CatchSkinComponentLookup(CatchSkinComponents.Catcher)) != null) return (IBindable)new Bindable(); break; diff --git a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs index 802e837746..03f0bc6a55 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.UI private readonly IBindable showCombo = new BindableBool(true); public CatchComboDisplay() - : base(new CatchSkinLookup(CatchSkinComponents.CatchComboCounter), _ => Empty()) + : base(new CatchSkinComponentLookup(CatchSkinComponents.CatchComboCounter), _ => Empty()) { } diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs index fb55864c49..9b32893efe 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.UI Anchor = Anchor.BottomCentre; Origin = Anchor.BottomCentre; - InternalChild = skinnableExplosion = new SkinnableDrawable(new CatchSkinLookup(CatchSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) + InternalChild = skinnableExplosion = new SkinnableDrawable(new CatchSkinComponentLookup(CatchSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) { CentreComponent = false, Anchor = Anchor.BottomCentre, diff --git a/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs b/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs index 2e07e39943..fa6ccf6bd6 100644 --- a/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs +++ b/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.UI public readonly Bindable AnimationState = new Bindable(); public SkinnableCatcher() - : base(new CatchSkinLookup(CatchSkinComponents.Catcher), _ => new DefaultCatcher()) + : base(new CatchSkinComponentLookup(CatchSkinComponents.Catcher), _ => new DefaultCatcher()) { Anchor = Anchor.TopCentre; // Sets the origin roughly to the centre of the catcher's plate to allow for correct scaling. diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs index 8dc8e72479..3dece20308 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning { RelativeSizeAxes = Axes.Both, Width = 0.5f, - Child = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) + Child = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) { RelativeSizeAxes = Axes.Both } @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning { RelativeSizeAxes = Axes.Both, Width = 0.5f, - Child = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) + Child = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) { RelativeSizeAxes = Axes.Both } diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs index 19ccf20870..5c8e038eed 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning [BackgroundDependencyLoader] private void load() { - SetContents(_ => new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.StageBackground), + SetContents(_ => new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.StageBackground), _ => new DefaultStageBackground()) { Anchor = Anchor.Centre, diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs index 171d2951be..f9c17ee7f4 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning [BackgroundDependencyLoader] private void load() { - SetContents(_ => new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.StageForeground), _ => null) + SetContents(_ => new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.StageForeground), _ => null) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Mania/ManiaSkinLookup.cs b/osu.Game.Rulesets.Mania/ManiaSkinComponentLookup.cs similarity index 77% rename from osu.Game.Rulesets.Mania/ManiaSkinLookup.cs rename to osu.Game.Rulesets.Mania/ManiaSkinComponentLookup.cs index 6e6d00fee6..c9ee5af809 100644 --- a/osu.Game.Rulesets.Mania/ManiaSkinLookup.cs +++ b/osu.Game.Rulesets.Mania/ManiaSkinComponentLookup.cs @@ -5,13 +5,13 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania { - public class ManiaSkinLookup : GameplaySkinLookup + public class ManiaSkinComponentLookup : GameplaySkinComponentLookup { /// - /// Creates a new . + /// Creates a new . /// /// The component. - public ManiaSkinLookup(ManiaSkinComponents component) + public ManiaSkinComponentLookup(ManiaSkinComponents component) : base(component) { } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 5b003e3c19..c68eec610c 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables headContainer = new Container { RelativeSizeAxes = Axes.Both } } }, - bodyPiece = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.HoldNoteBody), _ => new DefaultBodyPiece + bodyPiece = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.HoldNoteBody), _ => new DefaultBodyPiece { RelativeSizeAxes = Axes.Both, }) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 25347d3dfa..cf3149b065 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { rulesetConfig?.BindWith(ManiaRulesetSetting.TimingBasedNoteColouring, configTimingBasedNoteColouring); - AddInternal(headPiece = new SkinnableDrawable(new ManiaSkinLookup(Component), _ => new DefaultNotePiece()) + AddInternal(headPiece = new SkinnableDrawable(new ManiaSkinComponentLookup(Component), _ => new DefaultNotePiece()) { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs index cf9f9f36f0..eb7f63fbe2 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs @@ -22,14 +22,14 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon this.beatmap = (ManiaBeatmap)beatmap; } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { switch (lookup) { - case GameplaySkinLookup resultComponent: + case GameplaySkinComponentLookup resultComponent: return new ArgonJudgementPiece(resultComponent.Component); - case ManiaSkinLookup maniaComponent: + case ManiaSkinComponentLookup maniaComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. switch (maniaComponent.Component) { diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs index 5b7ccc7bb6..f8519beb22 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs @@ -74,14 +74,14 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy }); } - public override Drawable GetDrawableComponent(ISkinLookup lookup) + public override Drawable GetDrawableComponent(ISkinComponentLookup lookup) { switch (lookup) { - case GameplaySkinLookup resultComponent: + case GameplaySkinComponentLookup resultComponent: return getResult(resultComponent.Component); - case ManiaSkinLookup maniaComponent: + case ManiaSkinComponentLookup maniaComponent: if (!isLegacySkin.Value || !hasKeyTexture.Value) return null; diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 4eed75a90d..de7424773b 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Mania.UI skin.SourceChanged += onSourceChanged; onSourceChanged(); - Drawable background = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) + Drawable background = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground()) { RelativeSizeAxes = Axes.Both, }; @@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.Mania.UI // For input purposes, the background is added at the highest depth, but is then proxied back below all other elements background.CreateProxy(), HitObjectArea, - keyArea = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.KeyArea), _ => new DefaultKeyArea()) + keyArea = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.KeyArea), _ => new DefaultKeyArea()) { RelativeSizeAxes = Axes.Both, }, diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs index d02e4afc81..e5a9ca1e85 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components RelativeSizeAxes = Axes.Both, Depth = 2, }, - hitTarget = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.HitTarget), _ => new DefaultHitTarget()) + hitTarget = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.HitTarget), _ => new DefaultHitTarget()) { RelativeSizeAxes = Axes.X, Depth = 1 diff --git a/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs b/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs index faf345545d..8e5c8f9b75 100644 --- a/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs +++ b/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.UI [BackgroundDependencyLoader] private void load() { - InternalChild = skinnableExplosion = new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) + InternalChild = skinnableExplosion = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) { RelativeSizeAxes = Axes.Both }; diff --git a/osu.Game.Rulesets.Mania/UI/Stage.cs b/osu.Game.Rulesets.Mania/UI/Stage.cs index 5d08e38aef..8aeaa9cf35 100644 --- a/osu.Game.Rulesets.Mania/UI/Stage.cs +++ b/osu.Game.Rulesets.Mania/UI/Stage.cs @@ -73,7 +73,7 @@ namespace osu.Game.Rulesets.Mania.UI AutoSizeAxes = Axes.X, Children = new Drawable[] { - new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.StageBackground), _ => new DefaultStageBackground()) + new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.StageBackground), _ => new DefaultStageBackground()) { RelativeSizeAxes = Axes.Both }, @@ -98,7 +98,7 @@ namespace osu.Game.Rulesets.Mania.UI RelativeSizeAxes = Axes.Y, } }, - new SkinnableDrawable(new ManiaSkinLookup(ManiaSkinComponents.StageForeground), _ => null) + new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.StageForeground), _ => null) { RelativeSizeAxes = Axes.Both }, diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs index aeadbea510..30f0891344 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs @@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.Tests RelativeSizeAxes = Axes.Both; } - public Drawable GetDrawableComponent(ISkinLookup lookup) => null; + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => null; public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) { diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs index f88948ce13..628082c2a9 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs @@ -116,7 +116,7 @@ namespace osu.Game.Rulesets.Osu.Tests private class TopLeftCursorSkin : ISkin { - public Drawable GetDrawableComponent(ISkinLookup lookup) => null; + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => null; public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => null; public ISample GetSample(ISampleInfo sampleInfo) => null; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs index c012dae635..878150e467 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -149,11 +149,11 @@ namespace osu.Game.Rulesets.Osu.Tests this.identifier = identifier; } - public Drawable GetDrawableComponent(ISkinLookup lookup) + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) { if (!enabled) return null; - if (lookup is OsuSkinLookup osuComponent && osuComponent.Component == OsuSkinComponents.SliderBody) + if (lookup is OsuSkinComponentLookup osuComponent && osuComponent.Component == OsuSkinComponents.SliderBody) return null; return new OsuSpriteText diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs index 22037c873c..8c95da9be1 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections { Origin = Anchor.Centre; - InternalChild = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.FollowPoint), _ => new CircularContainer + InternalChild = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.FollowPoint), _ => new CircularContainer { Masking = true, AutoSizeAxes = Axes.Both, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index bcb3ccae41..6201199cc3 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -81,12 +81,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - CirclePiece = new SkinnableDrawable(new OsuSkinLookup(CirclePieceComponent), _ => new MainCirclePiece()) + CirclePiece = new SkinnableDrawable(new OsuSkinComponentLookup(CirclePieceComponent), _ => new MainCirclePiece()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, }, - ApproachCircle = new ProxyableSkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.ApproachCircle), _ => new DefaultApproachCircle()) + ApproachCircle = new ProxyableSkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.ApproachCircle), _ => new DefaultApproachCircle()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -278,7 +278,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { public override bool RemoveWhenNotAlive => false; - public ProxyableSkinnableDrawable(ISkinLookup lookup, Func defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) + public ProxyableSkinnableDrawable(ISkinComponentLookup lookup, Func defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) : base(lookup, defaultImplementation, confineMode) { } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 3fdbc3dacd..a4745b365b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - Body = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderBody), _ => new DefaultSliderBody(), confineMode: ConfineMode.NoScaling), + Body = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderBody), _ => new DefaultSliderBody(), confineMode: ConfineMode.NoScaling), tailContainer = new Container { RelativeSizeAxes = Axes.Both }, tickContainer = new Container { RelativeSizeAxes = Axes.Both }, repeatContainer = new Container { RelativeSizeAxes = Axes.Both }, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs index 86d41f0cbf..35d5c1f478 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Children = new[] { - new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderFollowCircle), _ => new DefaultFollowCircle()) + new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderFollowCircle), _ => new DefaultFollowCircle()) { Origin = Anchor.Centre, Anchor = Anchor.Centre, @@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RelativeSizeAxes = Axes.Both, Masking = true }, - ball = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderBall), _ => new DefaultSliderBall()) + ball = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderBall), _ => new DefaultSliderBall()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs index 1b8a17b6df..08602e168c 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs @@ -60,7 +60,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Children = new Drawable[] { // no default for this; only visible in legacy skins. - CirclePiece = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderTailHitCircle), _ => Empty()) + CirclePiece = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderTailHitCircle), _ => Empty()) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs index e8c6e80109..a59cd92d62 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs @@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Children = new Drawable[] { // no default for this; only visible in legacy skins. - CirclePiece = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderTailHitCircle), _ => Empty()) + CirclePiece = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderTailHitCircle), _ => Empty()) } }, }); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index f591cd15d4..563c7e85aa 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); Origin = Anchor.Centre; - AddInternal(scaleContainer = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SliderScorePoint), _ => new CircularContainer + AddInternal(scaleContainer = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderScorePoint), _ => new CircularContainer { Masking = true, Origin = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 7d0e29bd93..83a9408570 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables RelativeSizeAxes = Axes.Y, Children = new Drawable[] { - Body = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.SpinnerBody), _ => new DefaultSpinner()), + Body = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SpinnerBody), _ => new DefaultSpinner()), RotationTracker = new SpinnerRotationTracker(this) } }, diff --git a/osu.Game.Rulesets.Osu/OsuSkinLookup.cs b/osu.Game.Rulesets.Osu/OsuSkinComponentLookup.cs similarity index 73% rename from osu.Game.Rulesets.Osu/OsuSkinLookup.cs rename to osu.Game.Rulesets.Osu/OsuSkinComponentLookup.cs index 4048e95e4b..81d5811f85 100644 --- a/osu.Game.Rulesets.Osu/OsuSkinLookup.cs +++ b/osu.Game.Rulesets.Osu/OsuSkinComponentLookup.cs @@ -5,9 +5,9 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu { - public class OsuSkinLookup : GameplaySkinLookup + public class OsuSkinComponentLookup : GameplaySkinComponentLookup { - public OsuSkinLookup(OsuSkinComponents component) + public OsuSkinComponentLookup(OsuSkinComponents component) : base(component) { } diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs index bf664bb606..86194d2c43 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs @@ -14,14 +14,14 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon { } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { switch (lookup) { - case GameplaySkinLookup resultComponent: + case GameplaySkinComponentLookup resultComponent: return new ArgonJudgementPiece(resultComponent.Component); - case OsuSkinLookup osuComponent: + case OsuSkinComponentLookup osuComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. switch (osuComponent.Component) { diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs index 2b2c31dcf7..3a67ad526e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default accentColour.BindValueChanged(colour => Colour = colour.NewValue, true); } - protected override Drawable CreateDefault(ISkinLookup lookup) + protected override Drawable CreateDefault(ISkinComponentLookup lookup) { var drawable = base.CreateDefault(lookup); diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs index 39e07ebb99..60cfecfb5a 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default Colour = Color4.White.Opacity(0.5f), }, }, - number = new SkinnableSpriteText(new OsuSkinLookup(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText + number = new SkinnableSpriteText(new OsuSkinComponentLookup(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText { Font = OsuFont.Numeric.With(size: 40), UseFullGlyphHeight = false, diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs index 338e7abcfc..222e8d4348 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2); - Child = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.ReverseArrow), _ => new SpriteIcon + Child = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.ReverseArrow), _ => new SpriteIcon { RelativeSizeAxes = Axes.Both, Blending = BlendingParameters.Additive, diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs index 20a1e3064e..4dd4f9562a 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy accentColour.BindValueChanged(colour => Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue), true); } - protected override Drawable CreateDefault(ISkinLookup lookup) + protected override Drawable CreateDefault(ISkinComponentLookup lookup) { var drawable = base.CreateDefault(lookup); diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs index 357be4cda8..e155c1b816 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy if (hasNumber) { - OverlayLayer.Add(hitCircleText = new SkinnableSpriteText(new OsuSkinLookup(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText + OverlayLayer.Add(hitCircleText = new SkinnableSpriteText(new OsuSkinComponentLookup(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText { Font = OsuFont.Numeric.With(size: 40), UseFullGlyphHeight = false, diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs index f374af1cba..773cc7ae3c 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { AutoSizeAxes = Axes.Both; - string lookupName = new OsuSkinLookup(OsuSkinComponents.ReverseArrow).LookupName; + string lookupName = new OsuSkinComponentLookup(OsuSkinComponents.ReverseArrow).LookupName; var skin = skinSource.FindProvider(s => s.GetTexture(lookupName) != null); InternalChild = skin?.GetAnimation(lookupName, true, true) ?? Empty(); diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs index 2faa2d678e..ab0e9ab1c0 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs @@ -28,9 +28,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy hasHitCircle = new Lazy(() => GetTexture("hitcircle") != null); } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { - if (lookup is OsuSkinLookup osuComponent) + if (lookup is OsuSkinComponentLookup osuComponent) { switch (osuComponent.Component) { diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs index 78b920c771..6d435f01b0 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor RelativeSizeAxes = Axes.Both, Origin = Anchor.Centre, Anchor = Anchor.Centre, - Child = cursorSprite = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.Cursor), _ => new DefaultCursor(), confineMode: ConfineMode.NoScaling) + Child = cursorSprite = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.Cursor), _ => new DefaultCursor(), confineMode: ConfineMode.NoScaling) { Origin = Anchor.Centre, Anchor = Anchor.Centre, diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs index 396492c104..26fe08972e 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs @@ -47,8 +47,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor RelativeSizeAxes = Axes.Both, Children = new[] { - cursorTrail = new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.CursorTrail), _ => new DefaultCursorTrail(), confineMode: ConfineMode.NoScaling), - new SkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.CursorParticles), confineMode: ConfineMode.NoScaling), + cursorTrail = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorTrail), _ => new DefaultCursorTrail(), confineMode: ConfineMode.NoScaling), + new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorParticles), confineMode: ConfineMode.NoScaling), } }; } diff --git a/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs b/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs index 2616bb0325..bf5618dc90 100644 --- a/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.UI { if (e.Action == OsuAction.Smoke) { - AddInternal(currentSegmentSkinnable = new SmokeSkinnableDrawable(new OsuSkinLookup(OsuSkinComponents.CursorSmoke), _ => new DefaultSmokeSegment())); + AddInternal(currentSegmentSkinnable = new SmokeSkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorSmoke), _ => new DefaultSmokeSegment())); // Add initial position immediately. addPosition(); @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Osu.UI public override double LifetimeStart => Drawable.LifetimeStart; public override double LifetimeEnd => Drawable.LifetimeEnd; - public SmokeSkinnableDrawable(ISkinLookup lookup, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) + public SmokeSkinnableDrawable(ISkinComponentLookup lookup, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) : base(lookup, defaultImplementation, confineMode) { } diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs index 3076172d46..a9304b01ad 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning public TestSceneTaikoScroller() { AddStep("Load scroller", () => SetContents(_ => - new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.Scroller), _ => Empty()) + new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Scroller), _ => Empty()) { Clock = new FramedClock(clock), Height = 0.4f, diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs index 715add7914..f6c541982e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs @@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables AddRangeInternal(new Drawable[] { - line = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.BarLine), _ => new Box + line = new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.BarLine), _ => new Box { RelativeSizeAxes = Axes.Both, EdgeSmoothness = new Vector2(0.5f, 0), diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index f5ebecdee5..0bb14c791e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -115,7 +115,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables return base.CreateNestedHitObject(hitObject); } - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.DrumRollBody), + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollBody), _ => new ElongatedCirclePiece()); public override bool OnPressed(KeyBindingPressEvent e) => false; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 1ec2562f67..8dbcbf1ffc 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables FillMode = FillMode.Fit; } - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.DrumRollTick), + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece { Filled = HitObject.FirstTick diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index 0fe17f81f5..1e39c69acf 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -90,8 +90,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } protected override SkinnableDrawable CreateMainPiece() => HitObject.Type == HitType.Centre - ? new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.CentreHit), _ => new CentreHitCirclePiece(), confineMode: ConfineMode.ScaleToFit) - : new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.RimHit), _ => new RimHitCirclePiece(), confineMode: ConfineMode.ScaleToFit); + ? new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.CentreHit), _ => new CentreHitCirclePiece(), confineMode: ConfineMode.ScaleToFit) + : new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.RimHit), _ => new RimHitCirclePiece(), confineMode: ConfineMode.ScaleToFit); public override IEnumerable GetSamples() { diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 5b498e4cb3..753f85f23f 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -125,7 +125,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables targetRing.BorderColour = colours.YellowDark.Opacity(0.25f); } - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.Swell), + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Swell), _ => new SwellCirclePiece { // to allow for rotation transform diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs index 4d915c91d3..5d44fce254 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public override bool OnPressed(KeyBindingPressEvent e) => false; - protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.DrumRollTick), + protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece()); } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs index 6cf7d3da0a..7bf99306f0 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs @@ -27,16 +27,16 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy hasExplosion = new Lazy(() => GetTexture(getHitName(TaikoSkinComponents.TaikoExplosionGreat)) != null); } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { - if (lookup is GameplaySkinLookup) + if (lookup is GameplaySkinComponentLookup) { // if a taiko skin is providing explosion sprites, hide the judgements completely if (hasExplosion.Value) return Drawable.Empty().With(d => d.Expire()); } - if (lookup is TaikoSkinLookup taikoComponent) + if (lookup is TaikoSkinComponentLookup taikoComponent) { switch (taikoComponent.Component) { diff --git a/osu.Game.Rulesets.Taiko/TaikoSkinLookup.cs b/osu.Game.Rulesets.Taiko/TaikoSkinComponentLookup.cs similarity index 73% rename from osu.Game.Rulesets.Taiko/TaikoSkinLookup.cs rename to osu.Game.Rulesets.Taiko/TaikoSkinComponentLookup.cs index cb8bbd8b18..c35971e9fd 100644 --- a/osu.Game.Rulesets.Taiko/TaikoSkinLookup.cs +++ b/osu.Game.Rulesets.Taiko/TaikoSkinComponentLookup.cs @@ -5,9 +5,9 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko { - public class TaikoSkinLookup : GameplaySkinLookup + public class TaikoSkinComponentLookup : GameplaySkinComponentLookup { - public TaikoSkinLookup(TaikoSkinComponents component) + public TaikoSkinComponentLookup(TaikoSkinComponents component) : base(component) { } diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs index db45c8bb70..c3d93a344d 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs @@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Taiko.UI { new BarLineGenerator(Beatmap).BarLines.ForEach(bar => Playfield.Add(bar)); - FrameStableComponents.Add(scroller = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.Scroller), _ => Empty()) + FrameStableComponents.Add(scroller = new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Scroller), _ => Empty()) { RelativeSizeAxes = Axes.X, Depth = float.MaxValue diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs index 560f7b1748..d2b5811b56 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load() { - InternalChild = skinnable = new SkinnableDrawable(new TaikoSkinLookup(getComponentName(result)), _ => new DefaultHitExplosion(result)); + InternalChild = skinnable = new SkinnableDrawable(new TaikoSkinComponentLookup(getComponentName(result)), _ => new DefaultHitExplosion(result)); skinnable.OnSkinChanged += runAnimation; } diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 4458fb1bc0..2f42a5aaf6 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Taiko.UI { Children = new Drawable[] { - new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.InputDrum), _ => new DefaultInputDrum()) + new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.InputDrum), _ => new DefaultInputDrum()) { RelativeSizeAxes = Axes.Y, AutoSizeAxes = Axes.X, diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs index b0d853f1f1..d2427b952c 100644 --- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load() { - Child = skinnable = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.TaikoExplosionKiai), _ => new DefaultKiaiHitExplosion(hitType)); + Child = skinnable = new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.TaikoExplosionKiai), _ => new DefaultKiaiHitExplosion(hitType)); } } } diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 0de7bf233d..11349d8bd3 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Taiko.UI InternalChildren = new[] { - new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.PlayfieldBackgroundRight), _ => new PlayfieldBackgroundRight()), + new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.PlayfieldBackgroundRight), _ => new PlayfieldBackgroundRight()), new Container { Name = "Left overlay", @@ -86,11 +86,11 @@ namespace osu.Game.Rulesets.Taiko.UI BorderColour = colours.Gray0, Children = new[] { - new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.PlayfieldBackgroundLeft), _ => new PlayfieldBackgroundLeft()), + new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.PlayfieldBackgroundLeft), _ => new PlayfieldBackgroundLeft()), inputDrum.CreateProxy(), } }, - mascot = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.Mascot), _ => Empty()) + mascot = new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Mascot), _ => Empty()) { Origin = Anchor.BottomLeft, Anchor = Anchor.TopLeft, @@ -116,7 +116,7 @@ namespace osu.Game.Rulesets.Taiko.UI { RelativeSizeAxes = Axes.Both, }, - HitTarget = new SkinnableDrawable(new TaikoSkinLookup(TaikoSkinComponents.HitTarget), _ => new TaikoHitTarget()) + HitTarget = new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.HitTarget), _ => new TaikoHitTarget()) { RelativeSizeAxes = Axes.Both, } diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs index fc72fddcae..cccf640e27 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs @@ -126,7 +126,7 @@ namespace osu.Game.Tests.Gameplay Color4.Green }; - public Drawable GetDrawableComponent(ISkinLookup lookup) => throw new NotImplementedException(); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => throw new NotImplementedException(); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => throw new NotImplementedException(); diff --git a/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs b/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs index 9e03663a49..5c247bace9 100644 --- a/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs +++ b/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs @@ -73,7 +73,7 @@ namespace osu.Game.Tests.NonVisual.Skinning return lookup_names.Contains(componentName) ? renderer.WhitePixel : null; } - public Drawable GetDrawableComponent(ISkinLookup lookup) => throw new NotSupportedException(); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => throw new NotSupportedException(); public ISample GetSample(ISampleInfo sampleInfo) => throw new NotSupportedException(); public IBindable GetConfig(TLookup lookup) => throw new NotSupportedException(); } diff --git a/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs b/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs index 6f14b933ee..a29fc9f1fb 100644 --- a/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs +++ b/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs @@ -78,7 +78,7 @@ namespace osu.Game.Tests.Rulesets OnLoadAsync?.Invoke(); } - public Drawable GetDrawableComponent(ISkinLookup lookup) => skin.GetDrawableComponent(lookup); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => skin.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS = default, WrapMode wrapModeT = default) => skin.GetTexture(componentName); diff --git a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs index 4398d870a0..cd6895b176 100644 --- a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs +++ b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs @@ -80,7 +80,7 @@ namespace osu.Game.Tests.Skins var skin = new TestSkin(new SkinInfo(), null, storage); Assert.That(skin.DrawableComponentInfo, Has.Count.EqualTo(2)); - Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(9)); + Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(9)); } } @@ -93,10 +93,10 @@ namespace osu.Game.Tests.Skins var skin = new TestSkin(new SkinInfo(), null, storage); Assert.That(skin.DrawableComponentInfo, Has.Count.EqualTo(2)); - Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(6)); - Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.SongSelect], Has.Length.EqualTo(1)); + Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(6)); + Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.SongSelect], Has.Length.EqualTo(1)); - var skinnableInfo = skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.SongSelect].First(); + var skinnableInfo = skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.SongSelect].First(); Assert.That(skinnableInfo.Type, Is.EqualTo(typeof(SkinnableSprite))); Assert.That(skinnableInfo.Settings.First().Key, Is.EqualTo("sprite_name")); @@ -107,10 +107,10 @@ namespace osu.Game.Tests.Skins using (var storage = new ZipArchiveReader(stream)) { var skin = new TestSkin(new SkinInfo(), null, storage); - Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(8)); - Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(UnstableRateCounter))); - Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(ColourHitErrorMeter))); - Assert.That(skin.DrawableComponentInfo[GlobalSkinLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(LegacySongProgress))); + Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(8)); + Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(UnstableRateCounter))); + Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(ColourHitErrorMeter))); + Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(LegacySongProgress))); } } diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs index 7c02d34b1c..a31c624f78 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs @@ -48,7 +48,7 @@ namespace osu.Game.Tests.Skins string expected = allowBeatmapLookups ? "beatmap" : "user"; - AddAssert($"Check lookup is from {expected}", () => requester.GetDrawableComponent(new TestSkinLookup())?.Name == expected); + AddAssert($"Check lookup is from {expected}", () => requester.GetDrawableComponent(new TestSkinComponentLookup())?.Name == expected); } [TestCase(false)] @@ -59,7 +59,7 @@ namespace osu.Game.Tests.Skins ISkin expected() => allowBeatmapLookups ? beatmapSource : userSource; - AddAssert("Check lookup is from correct source", () => requester.FindProvider(s => s.GetDrawableComponent(new TestSkinLookup()) != null) == expected()); + AddAssert("Check lookup is from correct source", () => requester.FindProvider(s => s.GetDrawableComponent(new TestSkinComponentLookup()) != null) == expected()); } public class UserSkinSource : LegacySkin @@ -69,7 +69,7 @@ namespace osu.Game.Tests.Skins { } - public override Drawable GetDrawableComponent(ISkinLookup lookup) + public override Drawable GetDrawableComponent(ISkinComponentLookup lookup) { return new Container { Name = "user" }; } @@ -82,7 +82,7 @@ namespace osu.Game.Tests.Skins { } - public override Drawable GetDrawableComponent(ISkinLookup lookup) + public override Drawable GetDrawableComponent(ISkinComponentLookup lookup) { return new Container { Name = "beatmap" }; } @@ -98,7 +98,7 @@ namespace osu.Game.Tests.Skins this.skin = skin; } - public Drawable GetDrawableComponent(ISkinLookup lookup) => skin.GetDrawableComponent(lookup); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => skin.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => skin.GetTexture(componentName, wrapModeS, wrapModeT); @@ -109,7 +109,7 @@ namespace osu.Game.Tests.Skins public ISkin FindProvider(Func lookupFunction) => skin.FindProvider(lookupFunction); } - private class TestSkinLookup : ISkinLookup + private class TestSkinComponentLookup : ISkinComponentLookup { public string LookupName => string.Empty; } diff --git a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs index 4cbc1cf4df..8c6f137dc0 100644 --- a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs +++ b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs @@ -221,7 +221,7 @@ namespace osu.Game.Tests.Skins this.skin = skin; } - public Drawable GetDrawableComponent(ISkinLookup lookup) => skin.GetDrawableComponent(lookup); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => skin.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => skin.GetTexture(componentName, wrapModeS, wrapModeT); diff --git a/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs b/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs index 712d5ce969..ad71296a11 100644 --- a/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs +++ b/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs @@ -87,7 +87,7 @@ namespace osu.Game.Tests.Skins this.renderer = renderer; } - public Drawable GetDrawableComponent(ISkinLookup lookup) => throw new System.NotImplementedException(); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => throw new System.NotImplementedException(); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs index 69a50a1cd1..8ad97eb33c 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs @@ -40,7 +40,7 @@ namespace osu.Game.Tests.Visual.Gameplay { CreateSkinTest(TrianglesSkin.CreateInfo(), () => new LegacyBeatmapSkin(new BeatmapInfo(), null)); AddUntilStep("wait for hud load", () => Player.ChildrenOfType().All(c => c.ComponentsLoaded)); - AddAssert("hud from default skin", () => AssertComponentsFromExpectedSource(GlobalSkinLookup.LookupType.MainHUDComponents, skinManager.CurrentSkin.Value)); + AddAssert("hud from default skin", () => AssertComponentsFromExpectedSource(GlobalSkinComponentLookup.LookupType.MainHUDComponents, skinManager.CurrentSkin.Value)); } protected void CreateSkinTest(SkinInfo gameCurrentSkin, Func getBeatmapSkin) @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual.Gameplay }); } - protected bool AssertComponentsFromExpectedSource(GlobalSkinLookup.LookupType target, ISkin expectedSource) + protected bool AssertComponentsFromExpectedSource(GlobalSkinComponentLookup.LookupType target, ISkin expectedSource) { var actualComponentsContainer = Player.ChildrenOfType().First(s => s.Target == target) .ChildrenOfType().SingleOrDefault(); @@ -65,7 +65,7 @@ namespace osu.Game.Tests.Visual.Gameplay var actualInfo = actualComponentsContainer.CreateSkinnableInfo(); - var expectedComponentsContainer = (SkinnableTargetComponentsContainer)expectedSource.GetDrawableComponent(new GlobalSkinLookup(target)); + var expectedComponentsContainer = (SkinnableTargetComponentsContainer)expectedSource.GetDrawableComponent(new GlobalSkinComponentLookup(target)); if (expectedComponentsContainer == null) return false; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs index 81c5211878..e050273652 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs @@ -164,7 +164,7 @@ namespace osu.Game.Tests.Visual.Gameplay { private bool allow = true; - protected override bool AllowDrawableLookup(ISkinLookup lookup) => allow; + protected override bool AllowDrawableLookup(ISkinComponentLookup lookup) => allow; public void Disable() { @@ -182,8 +182,8 @@ namespace osu.Game.Tests.Visual.Gameplay { public new Drawable Drawable => base.Drawable; - public ExposedSkinnableDrawable(string name, Func defaultImplementation, ConfineMode confineMode = ConfineMode.ScaleToFit) - : base(new TestSkinLookup(name), defaultImplementation, confineMode) + public ExposedSkinnableDrawable(string name, Func defaultImplementation, ConfineMode confineMode = ConfineMode.ScaleToFit) + : base(new TestSkinComponentLookup(name), defaultImplementation, confineMode) { } } @@ -251,8 +251,8 @@ namespace osu.Game.Tests.Visual.Gameplay public new Drawable Drawable => base.Drawable; public int SkinChangedCount { get; private set; } - public SkinConsumer(string name, Func defaultImplementation) - : base(new TestSkinLookup(name), defaultImplementation) + public SkinConsumer(string name, Func defaultImplementation) + : base(new TestSkinComponentLookup(name), defaultImplementation) { } @@ -288,8 +288,8 @@ namespace osu.Game.Tests.Visual.Gameplay this.size = size; } - public Drawable GetDrawableComponent(ISkinLookup lookupName) => - lookupName.LookupName == "available" + public Drawable GetDrawableComponent(ISkinComponentLookup componentLookupName) => + componentLookupName.LookupName == "available" ? new DrawWidthBox { Colour = Color4.Yellow, @@ -306,7 +306,7 @@ namespace osu.Game.Tests.Visual.Gameplay private class SecondarySource : ISkin { - public Drawable GetDrawableComponent(ISkinLookup lookupName) => new SecondarySourceBox(); + public Drawable GetDrawableComponent(ISkinComponentLookup componentLookupName) => new SecondarySourceBox(); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => throw new NotImplementedException(); @@ -318,7 +318,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Cached(typeof(ISkinSource))] private class SkinSourceContainer : Container, ISkinSource { - public Drawable GetDrawableComponent(ISkinLookup lookupName) => new BaseSourceBox(); + public Drawable GetDrawableComponent(ISkinComponentLookup componentLookupName) => new BaseSourceBox(); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => throw new NotImplementedException(); @@ -337,9 +337,9 @@ namespace osu.Game.Tests.Visual.Gameplay } } - private class TestSkinLookup : ISkinLookup + private class TestSkinComponentLookup : ISkinComponentLookup { - public TestSkinLookup(string name) + public TestSkinComponentLookup(string name) { LookupName = name; } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs index 43206ac591..8122d8defb 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs @@ -142,7 +142,7 @@ namespace osu.Game.Tests.Visual.Gameplay IBindable ISamplePlaybackDisabler.SamplePlaybackDisabled => SamplePlaybackDisabled; - public Drawable GetDrawableComponent(ISkinLookup lookup) => source?.GetDrawableComponent(lookup); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => source?.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => source?.GetTexture(componentName, wrapModeS, wrapModeT); public ISample GetSample(ISampleInfo sampleInfo) => source?.GetSample(sampleInfo); public IBindable GetConfig(TLookup lookup) => source?.GetConfig(lookup); diff --git a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs index bfcdd384a0..6fc1deaf11 100644 --- a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs +++ b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs @@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.Judgements if (JudgementBody != null) RemoveInternal(JudgementBody, true); - AddInternal(JudgementBody = new SkinnableDrawable(new GameplaySkinLookup(type), _ => + AddInternal(JudgementBody = new SkinnableDrawable(new GameplaySkinComponentLookup(type), _ => CreateDefaultJudgement(type), confineMode: ConfineMode.NoScaling) { Anchor = Anchor.Centre, diff --git a/osu.Game/Screens/Edit/EditorBeatmapSkin.cs b/osu.Game/Screens/Edit/EditorBeatmapSkin.cs index bc63ad063c..80239504d8 100644 --- a/osu.Game/Screens/Edit/EditorBeatmapSkin.cs +++ b/osu.Game/Screens/Edit/EditorBeatmapSkin.cs @@ -53,7 +53,7 @@ namespace osu.Game.Screens.Edit #region Delegated ISkin implementation - public Drawable GetDrawableComponent(ISkinLookup lookup) => Skin.GetDrawableComponent(lookup); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => Skin.GetDrawableComponent(lookup); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => Skin.GetTexture(componentName, wrapModeS, wrapModeT); public ISample GetSample(ISampleInfo sampleInfo) => Skin.GetSample(sampleInfo); public IBindable GetConfig(TLookup lookup) => Skin.GetConfig(lookup); diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 932ebe7d18..fa38eeb9aa 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -391,7 +391,7 @@ namespace osu.Game.Screens.Play private OsuConfigManager config { get; set; } public MainComponentsContainer() - : base(GlobalSkinLookup.LookupType.MainHUDComponents) + : base(GlobalSkinComponentLookup.LookupType.MainHUDComponents) { RelativeSizeAxes = Axes.Both; } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index e525d5a368..1add51e725 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -250,7 +250,7 @@ namespace osu.Game.Screens.Select } } }, - new SkinnableTargetContainer(GlobalSkinLookup.LookupType.SongSelect) + new SkinnableTargetContainer(GlobalSkinComponentLookup.LookupType.SongSelect) { RelativeSizeAxes = Axes.Both, }, diff --git a/osu.Game/Skinning/ArgonSkin.cs b/osu.Game/Skinning/ArgonSkin.cs index 7aaf1a0e89..c3361093a9 100644 --- a/osu.Game/Skinning/ArgonSkin.cs +++ b/osu.Game/Skinning/ArgonSkin.cs @@ -81,17 +81,17 @@ namespace osu.Game.Skinning return null; } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { if (base.GetDrawableComponent(lookup) is Drawable c) return c; switch (lookup) { - case GlobalSkinLookup globalLookup: + case GlobalSkinComponentLookup globalLookup: switch (globalLookup.Lookup) { - case GlobalSkinLookup.LookupType.SongSelect: + case GlobalSkinComponentLookup.LookupType.SongSelect: var songSelectComponents = new SkinnableTargetComponentsContainer(_ => { // do stuff when we need to. @@ -99,7 +99,7 @@ namespace osu.Game.Skinning return songSelectComponents; - case GlobalSkinLookup.LookupType.MainHUDComponents: + case GlobalSkinComponentLookup.LookupType.MainHUDComponents: var skinnableTargetWrapper = new SkinnableTargetComponentsContainer(container => { var score = container.OfType().FirstOrDefault(); diff --git a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs index ec9d52f5c6..e14287c318 100644 --- a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs +++ b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs @@ -43,7 +43,7 @@ namespace osu.Game.Skinning } } - protected override bool AllowDrawableLookup(ISkinLookup lookup) + protected override bool AllowDrawableLookup(ISkinComponentLookup lookup) { if (beatmapSkins == null) throw new InvalidOperationException($"{nameof(BeatmapSkinProvidingContainer)} needs to be loaded before being consumed."); diff --git a/osu.Game/Skinning/Editor/SkinEditor.cs b/osu.Game/Skinning/Editor/SkinEditor.cs index fdc8b6b2ad..410f5d9347 100644 --- a/osu.Game/Skinning/Editor/SkinEditor.cs +++ b/osu.Game/Skinning/Editor/SkinEditor.cs @@ -314,7 +314,7 @@ namespace osu.Game.Skinning.Editor private ISkinnableTarget getFirstTarget() => availableTargets.FirstOrDefault(); - private ISkinnableTarget getTarget(GlobalSkinLookup.LookupType target) + private ISkinnableTarget getTarget(GlobalSkinComponentLookup.LookupType target) { return availableTargets.FirstOrDefault(c => c.Target == target); } diff --git a/osu.Game/Skinning/GameplaySkinLookup.cs b/osu.Game/Skinning/GameplaySkinComponentLookup.cs similarity index 83% rename from osu.Game/Skinning/GameplaySkinLookup.cs rename to osu.Game/Skinning/GameplaySkinComponentLookup.cs index cec9dbde7d..2d1dec4691 100644 --- a/osu.Game/Skinning/GameplaySkinLookup.cs +++ b/osu.Game/Skinning/GameplaySkinComponentLookup.cs @@ -5,12 +5,12 @@ using System.Linq; namespace osu.Game.Skinning { - public class GameplaySkinLookup : ISkinLookup + public class GameplaySkinComponentLookup : ISkinComponentLookup where T : notnull { public readonly T Component; - public GameplaySkinLookup(T component) + public GameplaySkinComponentLookup(T component) { Component = component; } diff --git a/osu.Game/Skinning/GlobalSkinLookup.cs b/osu.Game/Skinning/GlobalSkinComponentLookup.cs similarity index 78% rename from osu.Game/Skinning/GlobalSkinLookup.cs rename to osu.Game/Skinning/GlobalSkinComponentLookup.cs index c63c0315a3..3d8b61eba2 100644 --- a/osu.Game/Skinning/GlobalSkinLookup.cs +++ b/osu.Game/Skinning/GlobalSkinComponentLookup.cs @@ -3,13 +3,13 @@ namespace osu.Game.Skinning { - public class GlobalSkinLookup : ISkinLookup + public class GlobalSkinComponentLookup : ISkinComponentLookup { public readonly LookupType Lookup; public string LookupName => Lookup.ToString(); - public GlobalSkinLookup(LookupType lookup) + public GlobalSkinComponentLookup(LookupType lookup) { Lookup = lookup; } diff --git a/osu.Game/Skinning/ISkin.cs b/osu.Game/Skinning/ISkin.cs index c352dfef5c..45be5582f6 100644 --- a/osu.Game/Skinning/ISkin.cs +++ b/osu.Game/Skinning/ISkin.cs @@ -19,7 +19,7 @@ namespace osu.Game.Skinning /// /// The requested component. /// A drawable representation for the requested component, or null if unavailable. - Drawable? GetDrawableComponent(ISkinLookup lookup); + Drawable? GetDrawableComponent(ISkinComponentLookup lookup); /// /// Retrieve a . diff --git a/osu.Game/Skinning/ISkinLookup.cs b/osu.Game/Skinning/ISkinComponentLookup.cs similarity index 88% rename from osu.Game/Skinning/ISkinLookup.cs rename to osu.Game/Skinning/ISkinComponentLookup.cs index 4daea35e82..ae56fb0b1c 100644 --- a/osu.Game/Skinning/ISkinLookup.cs +++ b/osu.Game/Skinning/ISkinComponentLookup.cs @@ -11,10 +11,10 @@ namespace osu.Game.Skinning /// to scope particular lookup variations. Using this, a ruleset or skin implementation could make its own lookup /// type to scope away from more global contexts. /// - /// More commonly, a ruleset could make use of to do a simple lookup based on + /// More commonly, a ruleset could make use of to do a simple lookup based on /// a provided enum. /// - public interface ISkinLookup + public interface ISkinComponentLookup { string LookupName { get; } } diff --git a/osu.Game/Skinning/ISkinnableTarget.cs b/osu.Game/Skinning/ISkinnableTarget.cs index b1a0f6714b..57c78bfe1c 100644 --- a/osu.Game/Skinning/ISkinnableTarget.cs +++ b/osu.Game/Skinning/ISkinnableTarget.cs @@ -18,7 +18,7 @@ namespace osu.Game.Skinning /// /// The definition of this target. /// - GlobalSkinLookup.LookupType Target { get; } + GlobalSkinComponentLookup.LookupType Target { get; } /// /// A bindable list of components which are being tracked by this skinnable target. diff --git a/osu.Game/Skinning/LegacyBeatmapSkin.cs b/osu.Game/Skinning/LegacyBeatmapSkin.cs index 1d6ded6fee..8407b144f8 100644 --- a/osu.Game/Skinning/LegacyBeatmapSkin.cs +++ b/osu.Game/Skinning/LegacyBeatmapSkin.cs @@ -43,13 +43,13 @@ namespace osu.Game.Skinning return new RealmBackedResourceStore(beatmapInfo.BeatmapSet.ToLive(resources.RealmAccess), resources.Files, resources.RealmAccess); } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { - if (lookup is GlobalSkinLookup targetComponent) + if (lookup is GlobalSkinComponentLookup targetComponent) { switch (targetComponent.Lookup) { - case GlobalSkinLookup.LookupType.MainHUDComponents: + case GlobalSkinComponentLookup.LookupType.MainHUDComponents: // this should exist in LegacySkin instead, but there isn't a fallback skin for LegacySkins yet. // therefore keep the check here until fallback default legacy skin is supported. if (!this.HasFont(LegacyFont.Score)) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 75957bb560..98618e3dcd 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -322,17 +322,17 @@ namespace osu.Game.Skinning return null; } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { if (base.GetDrawableComponent(lookup) is Drawable c) return c; switch (lookup) { - case GlobalSkinLookup target: + case GlobalSkinComponentLookup target: switch (target.Lookup) { - case GlobalSkinLookup.LookupType.MainHUDComponents: + case GlobalSkinComponentLookup.LookupType.MainHUDComponents: var skinnableTargetWrapper = new SkinnableTargetComponentsContainer(container => { var score = container.OfType().FirstOrDefault(); @@ -379,7 +379,7 @@ namespace osu.Game.Skinning return null; - case GameplaySkinLookup resultComponent: + case GameplaySkinComponentLookup resultComponent: // kind of wasteful that we throw this away, but should do for now. if (getJudgementAnimation(resultComponent.Component) != null) @@ -397,7 +397,7 @@ namespace osu.Game.Skinning return null; - case SkinnableSprite.SpriteLookup sprite: + case SkinnableSprite.SpriteComponentLookup sprite: return this.GetAnimation(sprite.LookupName, false, false); } diff --git a/osu.Game/Skinning/ResourceStoreBackedSkin.cs b/osu.Game/Skinning/ResourceStoreBackedSkin.cs index 1b846438f5..f5c6192ba5 100644 --- a/osu.Game/Skinning/ResourceStoreBackedSkin.cs +++ b/osu.Game/Skinning/ResourceStoreBackedSkin.cs @@ -27,7 +27,7 @@ namespace osu.Game.Skinning samples = audio.GetSampleStore(new NamespacedResourceStore(resources, @"Samples")); } - public Drawable? GetDrawableComponent(ISkinLookup lookup) => null; + public Drawable? GetDrawableComponent(ISkinComponentLookup lookup) => null; public Texture? GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => textures.Get(componentName, wrapModeS, wrapModeT); diff --git a/osu.Game/Skinning/Skin.cs b/osu.Game/Skinning/Skin.cs index 67b74229bb..e222b9017c 100644 --- a/osu.Game/Skinning/Skin.cs +++ b/osu.Game/Skinning/Skin.cs @@ -37,9 +37,9 @@ namespace osu.Game.Skinning public SkinConfiguration Configuration { get; set; } - public IDictionary DrawableComponentInfo => drawableComponentInfo; + public IDictionary DrawableComponentInfo => drawableComponentInfo; - private readonly Dictionary drawableComponentInfo = new Dictionary(); + private readonly Dictionary drawableComponentInfo = new Dictionary(); public abstract ISample? GetSample(ISampleInfo sampleInfo); @@ -97,7 +97,7 @@ namespace osu.Game.Skinning Configuration = new SkinConfiguration(); // skininfo files may be null for default skin. - foreach (GlobalSkinLookup.LookupType skinnableTarget in Enum.GetValues(typeof(GlobalSkinLookup.LookupType))) + foreach (GlobalSkinComponentLookup.LookupType skinnableTarget in Enum.GetValues(typeof(GlobalSkinComponentLookup.LookupType))) { string filename = $"{skinnableTarget}.json"; @@ -154,11 +154,11 @@ namespace osu.Game.Skinning DrawableComponentInfo[targetContainer.Target] = targetContainer.CreateSkinnableInfo().ToArray(); } - public virtual Drawable? GetDrawableComponent(ISkinLookup lookup) + public virtual Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { switch (lookup) { - case GlobalSkinLookup target: + case GlobalSkinComponentLookup target: if (!DrawableComponentInfo.TryGetValue(target.Lookup, out var skinnableInfo)) return null; diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index bd4078b985..4a5277f3bf 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -201,7 +201,7 @@ namespace osu.Game.Skinning public event Action SourceChanged; - public Drawable GetDrawableComponent(ISkinLookup lookup) => lookupWithFallback(s => s.GetDrawableComponent(lookup)); + public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => lookupWithFallback(s => s.GetDrawableComponent(lookup)); public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => lookupWithFallback(s => s.GetTexture(componentName, wrapModeS, wrapModeT)); diff --git a/osu.Game/Skinning/SkinProvidingContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs index 0ed5c6b736..e7d0683005 100644 --- a/osu.Game/Skinning/SkinProvidingContainer.cs +++ b/osu.Game/Skinning/SkinProvidingContainer.cs @@ -28,7 +28,7 @@ namespace osu.Game.Skinning /// protected virtual bool AllowFallingBackToParent => true; - protected virtual bool AllowDrawableLookup(ISkinLookup lookup) => true; + protected virtual bool AllowDrawableLookup(ISkinComponentLookup lookup) => true; protected virtual bool AllowTextureLookup(string componentName) => true; @@ -107,7 +107,7 @@ namespace osu.Game.Skinning } } - public Drawable? GetDrawableComponent(ISkinLookup lookup) + public Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { foreach (var (_, lookupWrapper) in skinSources) { @@ -238,7 +238,7 @@ namespace osu.Game.Skinning this.provider = provider; } - public Drawable? GetDrawableComponent(ISkinLookup lookup) + public Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { if (provider.AllowDrawableLookup(lookup)) return skin.GetDrawableComponent(lookup); diff --git a/osu.Game/Skinning/SkinTransformer.cs b/osu.Game/Skinning/SkinTransformer.cs index 9772d98fde..e05961d404 100644 --- a/osu.Game/Skinning/SkinTransformer.cs +++ b/osu.Game/Skinning/SkinTransformer.cs @@ -19,7 +19,7 @@ namespace osu.Game.Skinning Skin = skin ?? throw new ArgumentNullException(nameof(skin)); } - public virtual Drawable? GetDrawableComponent(ISkinLookup lookup) => Skin.GetDrawableComponent(lookup); + public virtual Drawable? GetDrawableComponent(ISkinComponentLookup lookup) => Skin.GetDrawableComponent(lookup); public virtual Texture? GetTexture(string componentName) => GetTexture(componentName, default, default); diff --git a/osu.Game/Skinning/SkinnableDrawable.cs b/osu.Game/Skinning/SkinnableDrawable.cs index 4398dda413..15d371cdd5 100644 --- a/osu.Game/Skinning/SkinnableDrawable.cs +++ b/osu.Game/Skinning/SkinnableDrawable.cs @@ -31,7 +31,7 @@ namespace osu.Game.Skinning set => base.AutoSizeAxes = value; } - protected readonly ISkinLookup Lookup; + protected readonly ISkinComponentLookup ComponentLookup; private readonly ConfineMode confineMode; @@ -41,15 +41,15 @@ namespace osu.Game.Skinning /// The namespace-complete resource name for this skinnable element. /// A function to create the default skin implementation of this element. /// How (if at all) the should be resize to fit within our own bounds. - public SkinnableDrawable(ISkinLookup lookup, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) + public SkinnableDrawable(ISkinComponentLookup lookup, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling) : this(lookup, confineMode) { createDefault = defaultImplementation; } - protected SkinnableDrawable(ISkinLookup lookup, ConfineMode confineMode = ConfineMode.NoScaling) + protected SkinnableDrawable(ISkinComponentLookup lookup, ConfineMode confineMode = ConfineMode.NoScaling) { - Lookup = lookup; + ComponentLookup = lookup; this.confineMode = confineMode; RelativeSizeAxes = Axes.Both; @@ -60,13 +60,13 @@ namespace osu.Game.Skinning /// public void ResetAnimation() => (Drawable as IFramedAnimation)?.GotoFrame(0); - private readonly Func? createDefault; + private readonly Func? createDefault; private readonly Cached scaling = new Cached(); private bool isDefault; - protected virtual Drawable CreateDefault(ISkinLookup lookup) => createDefault?.Invoke(lookup) ?? Empty(); + protected virtual Drawable CreateDefault(ISkinComponentLookup lookup) => createDefault?.Invoke(lookup) ?? Empty(); /// /// Whether to apply size restrictions (specified via ) to the default implementation. @@ -75,11 +75,11 @@ namespace osu.Game.Skinning protected override void SkinChanged(ISkinSource skin) { - var retrieved = skin.GetDrawableComponent(Lookup); + var retrieved = skin.GetDrawableComponent(ComponentLookup); if (retrieved == null) { - Drawable = CreateDefault(Lookup); + Drawable = CreateDefault(ComponentLookup); isDefault = true; } else diff --git a/osu.Game/Skinning/SkinnableSprite.cs b/osu.Game/Skinning/SkinnableSprite.cs index 8f456fce0a..43fec11b14 100644 --- a/osu.Game/Skinning/SkinnableSprite.cs +++ b/osu.Game/Skinning/SkinnableSprite.cs @@ -34,26 +34,26 @@ namespace osu.Game.Skinning private ISkinSource source { get; set; } = null!; public SkinnableSprite(string textureName, ConfineMode confineMode = ConfineMode.NoScaling) - : base(new SpriteLookup(textureName), confineMode) + : base(new SpriteComponentLookup(textureName), confineMode) { SpriteName.Value = textureName; } public SkinnableSprite() - : base(new SpriteLookup(string.Empty), ConfineMode.NoScaling) + : base(new SpriteComponentLookup(string.Empty), ConfineMode.NoScaling) { RelativeSizeAxes = Axes.None; AutoSizeAxes = Axes.Both; SpriteName.BindValueChanged(name => { - ((SpriteLookup)Lookup).LookupName = name.NewValue ?? string.Empty; + ((SpriteComponentLookup)ComponentLookup).LookupName = name.NewValue ?? string.Empty; if (IsLoaded) SkinChanged(CurrentSkin); }); } - protected override Drawable CreateDefault(ISkinLookup lookup) + protected override Drawable CreateDefault(ISkinComponentLookup lookup) { var texture = textures.Get(lookup.LookupName); @@ -65,11 +65,11 @@ namespace osu.Game.Skinning public bool UsesFixedAnchor { get; set; } - internal class SpriteLookup : ISkinLookup + internal class SpriteComponentLookup : ISkinComponentLookup { public string LookupName { get; set; } - public SpriteLookup(string textureName) + public SpriteComponentLookup(string textureName) { LookupName = textureName; } diff --git a/osu.Game/Skinning/SkinnableSpriteText.cs b/osu.Game/Skinning/SkinnableSpriteText.cs index 8cc48a76ed..c01cec2f0c 100644 --- a/osu.Game/Skinning/SkinnableSpriteText.cs +++ b/osu.Game/Skinning/SkinnableSpriteText.cs @@ -9,7 +9,7 @@ namespace osu.Game.Skinning { public class SkinnableSpriteText : SkinnableDrawable, IHasText { - public SkinnableSpriteText(ISkinLookup lookup, Func defaultImplementation, ConfineMode confineMode = ConfineMode.NoScaling) + public SkinnableSpriteText(ISkinComponentLookup lookup, Func defaultImplementation, ConfineMode confineMode = ConfineMode.NoScaling) : base(lookup, defaultImplementation, confineMode) { } diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index bea29b0da3..a8038f5f5c 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -13,7 +13,7 @@ namespace osu.Game.Skinning { private SkinnableTargetComponentsContainer? content; - public GlobalSkinLookup.LookupType Target { get; } + public GlobalSkinComponentLookup.LookupType Target { get; } public IBindableList Components => components; @@ -25,7 +25,7 @@ namespace osu.Game.Skinning private CancellationTokenSource? cancellationSource; - public SkinnableTargetContainer(GlobalSkinLookup.LookupType target) + public SkinnableTargetContainer(GlobalSkinComponentLookup.LookupType target) { Target = target; } @@ -39,7 +39,7 @@ namespace osu.Game.Skinning components.Clear(); ComponentsLoaded = false; - content = CurrentSkin.GetDrawableComponent(new GlobalSkinLookup(Target)) as SkinnableTargetComponentsContainer; + content = CurrentSkin.GetDrawableComponent(new GlobalSkinComponentLookup(Target)) as SkinnableTargetComponentsContainer; cancellationSource?.Cancel(); cancellationSource = null; diff --git a/osu.Game/Skinning/TrianglesSkin.cs b/osu.Game/Skinning/TrianglesSkin.cs index e3729136b9..3df85b6880 100644 --- a/osu.Game/Skinning/TrianglesSkin.cs +++ b/osu.Game/Skinning/TrianglesSkin.cs @@ -59,17 +59,17 @@ namespace osu.Game.Skinning return null; } - public override Drawable? GetDrawableComponent(ISkinLookup lookup) + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { if (base.GetDrawableComponent(lookup) is Drawable c) return c; switch (lookup) { - case GlobalSkinLookup target: + case GlobalSkinComponentLookup target: switch (target.Lookup) { - case GlobalSkinLookup.LookupType.SongSelect: + case GlobalSkinComponentLookup.LookupType.SongSelect: var songSelectComponents = new SkinnableTargetComponentsContainer(_ => { // do stuff when we need to. @@ -77,7 +77,7 @@ namespace osu.Game.Skinning return songSelectComponents; - case GlobalSkinLookup.LookupType.MainHUDComponents: + case GlobalSkinComponentLookup.LookupType.MainHUDComponents: var skinnableTargetWrapper = new SkinnableTargetComponentsContainer(container => { var score = container.OfType().FirstOrDefault(); diff --git a/osu.Game/Skinning/UnsupportedSkinComponentException.cs b/osu.Game/Skinning/UnsupportedSkinComponentException.cs index 32fc6661b0..1fb6641668 100644 --- a/osu.Game/Skinning/UnsupportedSkinComponentException.cs +++ b/osu.Game/Skinning/UnsupportedSkinComponentException.cs @@ -7,7 +7,7 @@ namespace osu.Game.Skinning { public class UnsupportedSkinComponentException : Exception { - public UnsupportedSkinComponentException(ISkinLookup lookup) + public UnsupportedSkinComponentException(ISkinComponentLookup lookup) : base($@"Unsupported component type: {lookup.GetType()} (lookup: ""{lookup.LookupName}"").") { } From e19ba65f9186afab21aec536a636d7d152636dde Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 9 Nov 2022 16:39:33 +0900 Subject: [PATCH 0521/2991] Remove `LookupName` from base `ISkinComponentLookup` --- .../Legacy/OsuLegacySkinTransformer.cs | 4 ++-- .../Gameplay/TestSceneSkinnableDrawable.cs | 2 +- osu.Game/Skinning/ArgonSkin.cs | 21 +++++++++---------- .../Skinning/GlobalSkinComponentLookup.cs | 2 -- osu.Game/Skinning/ISkinComponentLookup.cs | 1 - osu.Game/Skinning/SkinnableSprite.cs | 4 ++-- osu.Game/Skinning/TrianglesSkin.cs | 21 +++++++++---------- .../UnsupportedSkinComponentException.cs | 2 +- 8 files changed, 26 insertions(+), 31 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs index ab0e9ab1c0..620540b8ef 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs @@ -35,10 +35,10 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy switch (osuComponent.Component) { case OsuSkinComponents.FollowPoint: - return this.GetAnimation(lookup.LookupName, true, true, true, startAtCurrentTime: false); + return this.GetAnimation("followpoint", true, true, true, startAtCurrentTime: false); case OsuSkinComponents.SliderScorePoint: - return this.GetAnimation(lookup.LookupName, false, false); + return this.GetAnimation("sliderscorepoint", false, false); case OsuSkinComponents.SliderFollowCircle: var followCircleContent = this.GetAnimation("sliderfollowcircle", true, true, true); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs index e050273652..97974d2368 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs @@ -289,7 +289,7 @@ namespace osu.Game.Tests.Visual.Gameplay } public Drawable GetDrawableComponent(ISkinComponentLookup componentLookupName) => - componentLookupName.LookupName == "available" + (componentLookupName as TestSkinComponentLookup)?.LookupName == "available" ? new DrawWidthBox { Colour = Color4.Yellow, diff --git a/osu.Game/Skinning/ArgonSkin.cs b/osu.Game/Skinning/ArgonSkin.cs index c3361093a9..a2eb07eba3 100644 --- a/osu.Game/Skinning/ArgonSkin.cs +++ b/osu.Game/Skinning/ArgonSkin.cs @@ -7,7 +7,6 @@ using JetBrains.Annotations; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.Audio; using osu.Game.Beatmaps.Formats; @@ -88,6 +87,16 @@ namespace osu.Game.Skinning switch (lookup) { + case SkinnableSprite.SpriteComponentLookup spriteLookup: + switch (spriteLookup.LookupName) + { + // Temporary until default skin has a valid hit lighting. + case @"lighting": + return Drawable.Empty(); + } + + break; + case GlobalSkinComponentLookup globalLookup: switch (globalLookup.Lookup) { @@ -178,16 +187,6 @@ namespace osu.Game.Skinning return null; } - switch (lookup.LookupName) - { - // Temporary until default skin has a valid hit lighting. - case @"lighting": - return Drawable.Empty(); - } - - if (GetTexture(lookup.LookupName) is Texture t) - return new Sprite { Texture = t }; - return null; } diff --git a/osu.Game/Skinning/GlobalSkinComponentLookup.cs b/osu.Game/Skinning/GlobalSkinComponentLookup.cs index 3d8b61eba2..7dcc3c4f14 100644 --- a/osu.Game/Skinning/GlobalSkinComponentLookup.cs +++ b/osu.Game/Skinning/GlobalSkinComponentLookup.cs @@ -7,8 +7,6 @@ namespace osu.Game.Skinning { public readonly LookupType Lookup; - public string LookupName => Lookup.ToString(); - public GlobalSkinComponentLookup(LookupType lookup) { Lookup = lookup; diff --git a/osu.Game/Skinning/ISkinComponentLookup.cs b/osu.Game/Skinning/ISkinComponentLookup.cs index ae56fb0b1c..be4043d7cf 100644 --- a/osu.Game/Skinning/ISkinComponentLookup.cs +++ b/osu.Game/Skinning/ISkinComponentLookup.cs @@ -16,6 +16,5 @@ namespace osu.Game.Skinning /// public interface ISkinComponentLookup { - string LookupName { get; } } } diff --git a/osu.Game/Skinning/SkinnableSprite.cs b/osu.Game/Skinning/SkinnableSprite.cs index 43fec11b14..7fd0e43562 100644 --- a/osu.Game/Skinning/SkinnableSprite.cs +++ b/osu.Game/Skinning/SkinnableSprite.cs @@ -55,10 +55,10 @@ namespace osu.Game.Skinning protected override Drawable CreateDefault(ISkinComponentLookup lookup) { - var texture = textures.Get(lookup.LookupName); + var texture = textures.Get(((SpriteComponentLookup)lookup).LookupName); if (texture == null) - return new SpriteNotFound(lookup.LookupName); + return new SpriteNotFound(((SpriteComponentLookup)lookup).LookupName); return new Sprite { Texture = texture }; } diff --git a/osu.Game/Skinning/TrianglesSkin.cs b/osu.Game/Skinning/TrianglesSkin.cs index 3df85b6880..2075cfb6f2 100644 --- a/osu.Game/Skinning/TrianglesSkin.cs +++ b/osu.Game/Skinning/TrianglesSkin.cs @@ -7,7 +7,6 @@ using JetBrains.Annotations; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.Audio; using osu.Game.Beatmaps.Formats; @@ -66,6 +65,16 @@ namespace osu.Game.Skinning switch (lookup) { + case SkinnableSprite.SpriteComponentLookup spriteLookup: + switch (spriteLookup.LookupName) + { + // Temporary until default skin has a valid hit lighting. + case @"lighting": + return Drawable.Empty(); + } + + break; + case GlobalSkinComponentLookup target: switch (target.Lookup) { @@ -156,16 +165,6 @@ namespace osu.Game.Skinning return null; } - switch (lookup.LookupName) - { - // Temporary until default skin has a valid hit lighting. - case @"lighting": - return Drawable.Empty(); - } - - if (GetTexture(lookup.LookupName) is Texture t) - return new Sprite { Texture = t }; - return null; } diff --git a/osu.Game/Skinning/UnsupportedSkinComponentException.cs b/osu.Game/Skinning/UnsupportedSkinComponentException.cs index 1fb6641668..b8dfb7a31d 100644 --- a/osu.Game/Skinning/UnsupportedSkinComponentException.cs +++ b/osu.Game/Skinning/UnsupportedSkinComponentException.cs @@ -8,7 +8,7 @@ namespace osu.Game.Skinning public class UnsupportedSkinComponentException : Exception { public UnsupportedSkinComponentException(ISkinComponentLookup lookup) - : base($@"Unsupported component type: {lookup.GetType()} (lookup: ""{lookup.LookupName}"").") + : base($@"Unsupported component type: {lookup.GetType()} (lookup: ""{lookup}"").") { } } From 533a2db5ea34df67750886e8aa0632a7f9dc5071 Mon Sep 17 00:00:00 2001 From: Samaoo Date: Wed, 9 Nov 2022 18:48:47 +0100 Subject: [PATCH 0522/2991] fix inaccurate tablet area dimensions when applying aspect ratio --- .../Overlays/Settings/Sections/Input/TabletSettings.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs index f1e216f538..a9eeae7cc7 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs @@ -3,6 +3,7 @@ #nullable disable +using System; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -308,9 +309,9 @@ namespace osu.Game.Overlays.Settings.Sections.Input // if lock is applied (or the specified values were out of range) aim to adjust the axis the user was not adjusting to conform. if (sizeChanged == sizeX) - sizeY.Value = (int)(areaSize.Value.X / aspectRatio.Value); + sizeY.Value = (int)Math.Round(areaSize.Value.X / aspectRatio.Value); else - sizeX.Value = (int)(areaSize.Value.Y * aspectRatio.Value); + sizeX.Value = (int)Math.Round(areaSize.Value.Y * aspectRatio.Value); } finally { @@ -324,12 +325,12 @@ namespace osu.Game.Overlays.Settings.Sections.Input { aspectLock.Value = false; - int proposedHeight = (int)(sizeX.Value / aspectRatio); + int proposedHeight = (int)Math.Round(sizeX.Value / aspectRatio); if (proposedHeight < sizeY.MaxValue) sizeY.Value = proposedHeight; else - sizeX.Value = (int)(sizeY.Value * aspectRatio); + sizeX.Value = (int)Math.Round(sizeY.Value * aspectRatio); updateAspectRatio(); From 3909e5730ea1168709d15331b6a780bdd1c86b6f Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 9 Nov 2022 21:33:28 +0300 Subject: [PATCH 0523/2991] Rename test steps Co-authored-by: Joseph Madamba --- osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index e69bdfb7ac..d58887c090 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -518,7 +518,7 @@ namespace osu.Game.Tests.Visual.Navigation { ChangelogOverlay getChangelogOverlay() => Game.ChildrenOfType().FirstOrDefault(); - AddUntilStep("Wait for options to load", () => Game.Notifications.IsLoaded); + AddUntilStep("Wait for notifications to load", () => Game.Notifications.IsLoaded); AddStep("Show notifications", () => Game.Notifications.Show()); AddUntilStep("wait for notifications shown", () => Game.Notifications.IsPresent && Game.Notifications.State.Value == Visibility.Visible); AddStep("Show changelog listing", () => Game.ShowChangelogListing()); @@ -535,7 +535,7 @@ namespace osu.Game.Tests.Visual.Navigation { ChangelogOverlay getChangelogOverlay() => Game.ChildrenOfType().FirstOrDefault(); - AddUntilStep("Wait for options to load", () => Game.Settings.IsLoaded); + AddUntilStep("Wait for settings to load", () => Game.Settings.IsLoaded); AddStep("Show settings", () => Game.Settings.Show()); AddUntilStep("wait for settings shown", () => Game.Settings.IsPresent && Game.Settings.State.Value == Visibility.Visible); AddStep("Show changelog listing", () => Game.ShowChangelogListing()); From ab53fb17d390fc8cc8667d720b5e8f7c8a5b9142 Mon Sep 17 00:00:00 2001 From: Piggey Date: Wed, 9 Nov 2022 19:53:36 +0100 Subject: [PATCH 0524/2991] change displayed text from `#?` to `-` --- osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs b/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs index dc2c0620c8..062b31e05a 100644 --- a/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs +++ b/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs @@ -72,7 +72,7 @@ namespace osu.Game.Screens.Play.HUD scorePosition = value; - positionText.Text = scorePosition.HasValue ? $"#{scorePosition.Value.FormatRank()}" : "#?"; + positionText.Text = scorePosition.HasValue ? $"#{scorePosition.Value.FormatRank()}" : "-"; updateState(); } From 0011f4e7be99561ac22a3eb8d07cd32adce71ed3 Mon Sep 17 00:00:00 2001 From: Piggey Date: Wed, 9 Nov 2022 19:59:04 +0100 Subject: [PATCH 0525/2991] fix comment lol --- osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs index 10049c7718..c8631880ac 100644 --- a/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs @@ -174,7 +174,7 @@ namespace osu.Game.Screens.Play.HUD orderedByScore[i].ScorePosition = i + 1; } - // change displayed potision to '#?' when there are 50 already submitted scores and tracked score is last + // change displayed potision to '-' when there are 50 already submitted scores and tracked score is last if (TrackedScore?.ScorePosition == Flow.Count && Flow.Count == 51) TrackedScore.ScorePosition = null; From be81c658af8f20cf7618c73011f8c55a4f627798 Mon Sep 17 00:00:00 2001 From: Samaoo Date: Wed, 9 Nov 2022 20:14:01 +0100 Subject: [PATCH 0526/2991] move tablet area calculations to functions --- .../Settings/Sections/Input/TabletSettings.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs index a9eeae7cc7..59c7ff04a2 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs @@ -309,9 +309,9 @@ namespace osu.Game.Overlays.Settings.Sections.Input // if lock is applied (or the specified values were out of range) aim to adjust the axis the user was not adjusting to conform. if (sizeChanged == sizeX) - sizeY.Value = (int)Math.Round(areaSize.Value.X / aspectRatio.Value); + sizeY.Value = getHeight(areaSize.Value.X, aspectRatio.Value); else - sizeX.Value = (int)Math.Round(areaSize.Value.Y * aspectRatio.Value); + sizeX.Value = getWidth(areaSize.Value.Y, aspectRatio.Value); } finally { @@ -325,12 +325,12 @@ namespace osu.Game.Overlays.Settings.Sections.Input { aspectLock.Value = false; - int proposedHeight = (int)Math.Round(sizeX.Value / aspectRatio); + int proposedHeight = getHeight(sizeX.Value, aspectRatio); if (proposedHeight < sizeY.MaxValue) sizeY.Value = proposedHeight; else - sizeX.Value = (int)Math.Round(sizeY.Value * aspectRatio); + sizeX.Value = getWidth(sizeY.Value, aspectRatio); updateAspectRatio(); @@ -341,5 +341,9 @@ namespace osu.Game.Overlays.Settings.Sections.Input private void updateAspectRatio() => aspectRatio.Value = currentAspectRatio; private float currentAspectRatio => sizeX.Value / sizeY.Value; + + private static int getHeight(float width, float aspectRatio) => (int)Math.Round(width / aspectRatio); + + private static int getWidth(float height, float aspectRatio) => (int)Math.Round(height * aspectRatio); } } From 1f8824a75495d826d2544dbfd930a29138af9610 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 10 Nov 2022 16:14:40 +0900 Subject: [PATCH 0527/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index b6ddeeb41a..8237a570ff 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9a6866d264..09b1bb7162 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index b2854d7ddd..4264d9220e 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From 6303b88e5666a4d7527bb8ed3cfc0da602913386 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Thu, 10 Nov 2022 14:31:24 +0100 Subject: [PATCH 0528/2991] Fix NRT causing CI failure --- osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs index 612756ba08..ccde8e6ac9 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs @@ -159,7 +159,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default { case ArmedState.Hit: using (BeginAbsoluteSequence(drawableHitObject.HitStateUpdateTime)) - flashBox?.FadeTo(0.9f).FadeOut(300); + flashBox.FadeTo(0.9f).FadeOut(300); break; } } From efc0325bef884e3c12c2a4d5ee1217ad28f36b0e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 10 Nov 2022 23:41:15 +0900 Subject: [PATCH 0529/2991] Fix nullability issue --- osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs index 612756ba08..ccde8e6ac9 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs @@ -159,7 +159,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default { case ArmedState.Hit: using (BeginAbsoluteSequence(drawableHitObject.HitStateUpdateTime)) - flashBox?.FadeTo(0.9f).FadeOut(300); + flashBox.FadeTo(0.9f).FadeOut(300); break; } } From 83a3f1b82e85e981c2117448686bd1c6ad471b67 Mon Sep 17 00:00:00 2001 From: maromalo <54760464+maromalo@users.noreply.github.com> Date: Thu, 10 Nov 2022 14:15:20 -0300 Subject: [PATCH 0530/2991] Add computeRawScore() --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 02512d857d..2b6e40b94e 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -339,16 +339,21 @@ namespace osu.Game.Rulesets.Scoring { default: case ScoringMode.Standardised: - double accuracyScore = accuracyPortion * accuracyRatio; - double comboScore = comboPortion * comboRatio; - return (long)Math.Round((max_score * (accuracyScore + comboScore) + bonusScore) * scoreMultiplier); + return (long)Math.Round(computeRawScore()); case ScoringMode.Classic: // This gives a similar feeling to osu!stable scoring (ScoreV1) while keeping classic scoring as only a constant multiple of standardised scoring. // The invariant is important to ensure that scores don't get re-ordered on leaderboards between the two scoring modes. - double scaledStandardised = ComputeScore(ScoringMode.Standardised, accuracyRatio, comboRatio, bonusScore, totalBasicHitObjects) / max_score; + double scaledStandardised = computeRawScore() / max_score; return (long)Math.Round(Math.Pow(scaledStandardised * Math.Max(1, totalBasicHitObjects), 2) * ClassicScoreMultiplier); } + + double computeRawScore() + { + double accuracyScore = accuracyPortion * accuracyRatio; + double comboScore = comboPortion * comboRatio; + return (max_score * (accuracyScore + comboScore) + bonusScore) * scoreMultiplier; + } } private ScoreRank rankFrom(double acc) From 5b1e39abd5d522e1c4dc6f2486bc43bb6b13f731 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Thu, 10 Nov 2022 22:56:24 +0100 Subject: [PATCH 0531/2991] Fix parsing of `Language` when using default system locale --- osu.Game/Extensions/LanguageExtensions.cs | 25 +++++++++++++++++++ .../Overlays/FirstRunSetup/ScreenWelcome.cs | 10 +++++--- .../Sections/General/LanguageSettings.cs | 18 ++++++------- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/osu.Game/Extensions/LanguageExtensions.cs b/osu.Game/Extensions/LanguageExtensions.cs index b67e7fb6fc..04231c384c 100644 --- a/osu.Game/Extensions/LanguageExtensions.cs +++ b/osu.Game/Extensions/LanguageExtensions.cs @@ -3,6 +3,8 @@ using System; using System.Globalization; +using osu.Framework.Configuration; +using osu.Framework.Localisation; using osu.Game.Localisation; namespace osu.Game.Extensions @@ -29,5 +31,28 @@ namespace osu.Game.Extensions /// Whether the parsing succeeded. public static bool TryParseCultureCode(string cultureCode, out Language language) => Enum.TryParse(cultureCode.Replace("-", "_"), out language); + + /// + /// Parses the that is specified in , + /// or if that is not valid, the language of the current as exposed by . + /// + /// The current . + /// The current of the . + /// The parsed language. + public static Language GetLanguageFor(string frameworkLocale, LocalisationParameters localisationParameters) + { + // the usual case when the user has changed the language + if (TryParseCultureCode(frameworkLocale, out var language)) + return language; + + if (localisationParameters.Store != null) + { + // startup case, locale not explicitly set, or the set language was removed in an update + if (TryParseCultureCode(localisationParameters.Store.EffectiveCulture.Name, out language)) + return language; + } + + return Language.en; + } } } diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs index cb1e96d2f2..992f538e82 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs @@ -63,11 +63,12 @@ namespace osu.Game.Overlays.FirstRunSetup private class LanguageSelectionFlow : FillFlowContainer { private Bindable frameworkLocale = null!; + private IBindable localisationParameters = null!; private ScheduledDelegate? updateSelectedDelegate; [BackgroundDependencyLoader] - private void load(FrameworkConfigManager frameworkConfig) + private void load(FrameworkConfigManager frameworkConfig, LocalisationManager localisation) { Direction = FillDirection.Full; Spacing = new Vector2(5); @@ -80,10 +81,11 @@ namespace osu.Game.Overlays.FirstRunSetup }); frameworkLocale = frameworkConfig.GetBindable(FrameworkSetting.Locale); - frameworkLocale.BindValueChanged(locale => + + localisationParameters = localisation.CurrentParameters.GetBoundCopy(); + localisationParameters.BindValueChanged(p => { - if (!LanguageExtensions.TryParseCultureCode(locale.NewValue, out var language)) - language = Language.en; + var language = LanguageExtensions.GetLanguageFor(frameworkLocale.Value, p.NewValue); // Changing language may cause a short period of blocking the UI thread while the new glyphs are loaded. // Scheduling ensures the button animation plays smoothly after any blocking operation completes. diff --git a/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs index 0f77e6609b..b7e3bd90b0 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Configuration; @@ -16,15 +14,17 @@ namespace osu.Game.Overlays.Settings.Sections.General { public class LanguageSettings : SettingsSubsection { - private SettingsDropdown languageSelection; - private Bindable frameworkLocale; + private SettingsDropdown languageSelection = null!; + private Bindable frameworkLocale = null!; + private IBindable localisationParameters = null!; protected override LocalisableString Header => GeneralSettingsStrings.LanguageHeader; [BackgroundDependencyLoader] - private void load(FrameworkConfigManager frameworkConfig, OsuConfigManager config) + private void load(FrameworkConfigManager frameworkConfig, OsuConfigManager config, LocalisationManager localisation) { frameworkLocale = frameworkConfig.GetBindable(FrameworkSetting.Locale); + localisationParameters = localisation.CurrentParameters.GetBoundCopy(); Children = new Drawable[] { @@ -44,12 +44,8 @@ namespace osu.Game.Overlays.Settings.Sections.General }, }; - frameworkLocale.BindValueChanged(locale => - { - if (!LanguageExtensions.TryParseCultureCode(locale.NewValue, out var language)) - language = Language.en; - languageSelection.Current.Value = language; - }, true); + localisationParameters.BindValueChanged(p + => languageSelection.Current.Value = LanguageExtensions.GetLanguageFor(frameworkLocale.Value, p.NewValue), true); languageSelection.Current.BindValueChanged(val => frameworkLocale.Value = val.NewValue.ToCultureCode()); } From 6ac19615fa2669c53a86d6aee51c19f90e7158dd Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 11 Nov 2022 14:55:41 +0900 Subject: [PATCH 0532/2991] Fix test failure --- osu.Game.Tests/Chat/TestSceneChannelManager.cs | 12 +++++++++++- osu.Game/Online/Chat/Channel.cs | 4 ++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Chat/TestSceneChannelManager.cs b/osu.Game.Tests/Chat/TestSceneChannelManager.cs index e7eb06c795..32fc2604ba 100644 --- a/osu.Game.Tests/Chat/TestSceneChannelManager.cs +++ b/osu.Game.Tests/Chat/TestSceneChannelManager.cs @@ -55,6 +55,14 @@ namespace osu.Game.Tests.Chat case MarkChannelAsReadRequest markRead: handleMarkChannelAsReadRequest(markRead); return true; + + case GetUpdatesRequest updatesRequest: + updatesRequest.TriggerSuccess(new GetUpdatesResponse + { + Messages = sentMessages.ToList(), + Presence = new List() + }); + return true; } return false; @@ -95,6 +103,7 @@ namespace osu.Game.Tests.Chat }); AddStep("post message", () => channelManager.PostMessage("Something interesting")); + AddUntilStep("message postesd", () => !channel.Messages.Any(m => m is LocalMessage)); AddStep("post /help command", () => channelManager.PostCommand("help", channel)); AddStep("post /me command with no action", () => channelManager.PostCommand("me", channel)); @@ -115,7 +124,8 @@ namespace osu.Game.Tests.Chat Content = request.Message.Content, Links = request.Message.Links, Timestamp = request.Message.Timestamp, - Sender = request.Message.Sender + Sender = request.Message.Sender, + Uuid = request.Message.Uuid }; sentMessages.Add(message); diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index 9bfaecc46b..ada9e22027 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -179,6 +179,10 @@ namespace osu.Game.Online.Chat throw new InvalidOperationException("Attempted to add the same message again"); Messages.Add(final); + + if (final.Id > LastMessageId) + LastMessageId = final.Id; + PendingMessageResolved?.Invoke(echo, final); } From 392d4e778eaf3fd4dd3ad433260154bdaff5cbf4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 11 Nov 2022 17:07:37 +0900 Subject: [PATCH 0533/2991] Change default beatmap listing key binding to `Ctrl`+`B` --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index a58c6723ef..ebdc446ec8 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -78,7 +78,7 @@ namespace osu.Game.Input.Bindings new KeyBinding(InputKey.F8, GlobalAction.ToggleChat), new KeyBinding(InputKey.F6, GlobalAction.ToggleNowPlaying), new KeyBinding(InputKey.F9, GlobalAction.ToggleSocial), - new KeyBinding(new[] { InputKey.Control, InputKey.D }, GlobalAction.ToggleBeatmapListing), + new KeyBinding(new[] { InputKey.Control, InputKey.B }, GlobalAction.ToggleBeatmapListing), new KeyBinding(new[] { InputKey.Control, InputKey.O }, GlobalAction.ToggleSettings), new KeyBinding(new[] { InputKey.Control, InputKey.N }, GlobalAction.ToggleNotifications), }; From 0af4bdaf5c3d0acc1b532770adb7a122c303ca48 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 11 Nov 2022 18:29:15 +0900 Subject: [PATCH 0534/2991] Add back removed configuration elements --- osu.Game/Configuration/OsuConfigManager.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 1286a07eeb..3cabd6a21b 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -172,7 +172,9 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.DiscordRichPresence, DiscordRichPresenceMode.Full); - SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f); + SetDefault(OsuSetting.EditorDim, 0.25f, 0f, 0.75f, 0.25f); + SetDefault(OsuSetting.EditorWaveformOpacity, 0.25f, 0f, 1f, 0.25f); + SetDefault(OsuSetting.EditorShowHitMarkers, true); SetDefault(OsuSetting.LastProcessedMetadataId, -1); @@ -294,6 +296,7 @@ namespace osu.Game.Configuration GameplayCursorDuringTouch, DimLevel, BlurLevel, + EditorDim, LightenDuringBreaks, ShowStoryboard, KeyOverlay, @@ -366,6 +369,7 @@ namespace osu.Game.Configuration GameplayDisableWinKey, SeasonalBackgroundMode, EditorWaveformOpacity, + EditorShowHitMarkers, DiscordRichPresence, AutomaticallyDownloadWhenSpectating, ShowOnlineExplicitContent, From 151dd7c62f8c516a11f416883630c9e057785160 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 11 Nov 2022 22:10:27 +0900 Subject: [PATCH 0535/2991] Fix one more reverted change --- osu.Game/Configuration/OsuConfigManager.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 3cabd6a21b..6cbb677a64 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -5,7 +5,6 @@ using System; using System.Diagnostics; -using System.Globalization; using osu.Framework.Bindables; using osu.Framework.Configuration; using osu.Framework.Configuration.Tracking; @@ -116,7 +115,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.MenuParallax, true); // See https://stackoverflow.com/a/63307411 for default sourcing. - SetDefault(OsuSetting.Prefer24HourTime, CultureInfo.CurrentCulture.DateTimeFormat.ShortTimePattern.Contains(@"tt")); + SetDefault(OsuSetting.Prefer24HourTime, !CultureInfoHelper.SystemCulture.DateTimeFormat.ShortTimePattern.Contains(@"tt")); // Gameplay SetDefault(OsuSetting.PositionalHitsoundsLevel, 0.2f, 0, 1); From 173f557376e8c8d14b660b8389ea0769cd93971d Mon Sep 17 00:00:00 2001 From: Samaoo Date: Fri, 11 Nov 2022 17:14:34 +0100 Subject: [PATCH 0536/2991] fix tablet aspect ratio values --- .../Sections/Input/TabletAreaSelection.cs | 22 +++++++++---------- .../Settings/Sections/Input/TabletSettings.cs | 6 ++--- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletAreaSelection.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletAreaSelection.cs index cd6554e52d..3b5190d13b 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletAreaSelection.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletAreaSelection.cs @@ -125,11 +125,11 @@ namespace osu.Game.Overlays.Settings.Sections.Input { usableAreaContainer.ResizeTo(val.NewValue, 100, Easing.OutQuint); - int x = (int)val.NewValue.X; - int y = (int)val.NewValue.Y; + int x = (int)Math.Round(val.NewValue.X); + int y = (int)Math.Round(val.NewValue.Y); int commonDivider = greatestCommonDivider(x, y); - usableAreaText.Text = $"{(float)x / commonDivider}:{(float)y / commonDivider}"; + usableAreaText.Text = $"{x / commonDivider}:{y / commonDivider}"; checkBounds(); }, true); @@ -212,17 +212,17 @@ namespace osu.Game.Overlays.Settings.Sections.Input { base.Update(); - if (!(tablet.Value?.Size is Vector2 size)) - return; + if (tablet.Value?.Size is Vector2 size) + { + float maxDimension = size.LengthFast; - float maxDimension = size.LengthFast; + float fitX = maxDimension / (DrawWidth - Padding.Left - Padding.Right); + float fitY = maxDimension / DrawHeight; - float fitX = maxDimension / (DrawWidth - Padding.Left - Padding.Right); - float fitY = maxDimension / DrawHeight; + float adjust = MathF.Max(fitX, fitY); - float adjust = MathF.Max(fitX, fitY); - - tabletContainer.Scale = new Vector2(1 / adjust); + tabletContainer.Scale = new Vector2(1 / adjust); + } } } } diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs index 59c7ff04a2..8f92bb16f5 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs @@ -325,7 +325,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input { aspectLock.Value = false; - int proposedHeight = getHeight(sizeX.Value, aspectRatio); + float proposedHeight = getHeight(sizeX.Value, aspectRatio); if (proposedHeight < sizeY.MaxValue) sizeY.Value = proposedHeight; @@ -342,8 +342,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input private float currentAspectRatio => sizeX.Value / sizeY.Value; - private static int getHeight(float width, float aspectRatio) => (int)Math.Round(width / aspectRatio); + private static float getHeight(float width, float aspectRatio) => (float)Math.Round(width / aspectRatio); - private static int getWidth(float height, float aspectRatio) => (int)Math.Round(height * aspectRatio); + private static float getWidth(float height, float aspectRatio) => (float)Math.Round(height * aspectRatio); } } From 268011be9e39ca553477e55a283b832117b2d197 Mon Sep 17 00:00:00 2001 From: Samaoo Date: Fri, 11 Nov 2022 17:56:50 +0100 Subject: [PATCH 0537/2991] use MathF --- osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs index 8f92bb16f5..0f96ef3ac7 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs @@ -342,8 +342,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input private float currentAspectRatio => sizeX.Value / sizeY.Value; - private static float getHeight(float width, float aspectRatio) => (float)Math.Round(width / aspectRatio); + private static float getHeight(float width, float aspectRatio) => MathF.Round(width / aspectRatio); - private static float getWidth(float height, float aspectRatio) => (float)Math.Round(height * aspectRatio); + private static float getWidth(float height, float aspectRatio) => MathF.Round(height * aspectRatio); } } From 7ef11cab8b76ea75ec5f1671fa0dbc6f73685361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 12 Nov 2022 02:10:10 +0900 Subject: [PATCH 0538/2991] Adjust taiko argon transformer to new naming --- .../Skinning/Argon/TaikoArgonSkinTransformer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index f0d14f657d..379c675a0f 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -14,14 +14,14 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon { } - public override Drawable? GetDrawableComponent(ISkinComponent component) + public override Drawable? GetDrawableComponent(ISkinComponentLookup component) { switch (component) { - case GameplaySkinComponent resultComponent: + case GameplaySkinComponentLookup resultComponent: return new ArgonJudgementPiece(resultComponent.Component); - case TaikoSkinComponent catchComponent: + case TaikoSkinComponentLookup catchComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. switch (catchComponent.Component) { From 6a4c97b4f119bb91e73eb48c832691665da4fffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 12 Nov 2022 02:20:19 +0900 Subject: [PATCH 0539/2991] Fix code inspection --- osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs index 91f34e1f0e..22f96da61e 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs @@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon EarlyActivationMilliseconds = pre_beat_transition_time; - AddRangeInternal(new Drawable[] + AddRangeInternal(new[] { new Circle { From 8b8147c3212d4475992f48df3ab3498b17c9925c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 12 Nov 2022 03:05:03 +0900 Subject: [PATCH 0540/2991] Rename `{catch -> taiko}Component` --- .../Skinning/Argon/TaikoArgonSkinTransformer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index 379c675a0f..6d1087793d 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -21,9 +21,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case GameplaySkinComponentLookup resultComponent: return new ArgonJudgementPiece(resultComponent.Component); - case TaikoSkinComponentLookup catchComponent: + case TaikoSkinComponentLookup taikoComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. - switch (catchComponent.Component) + switch (taikoComponent.Component) { case TaikoSkinComponents.CentreHit: return new ArgonCentreCirclePiece(); @@ -59,7 +59,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case TaikoSkinComponents.TaikoExplosionGreat: case TaikoSkinComponents.TaikoExplosionMiss: case TaikoSkinComponents.TaikoExplosionOk: - return new ArgonHitExplosion(catchComponent.Component); + return new ArgonHitExplosion(taikoComponent.Component); } break; From b0314c67aa6f21aaae6e9b32be23ceac8b86cafe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 12 Nov 2022 14:16:46 +0900 Subject: [PATCH 0541/2991] Fix failing gameplay bindings test --- .../Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs b/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs index 5bd879de14..c3d7bde68f 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs @@ -56,6 +56,7 @@ namespace osu.Game.Tests.Visual.Navigation PushAndConfirm(() => new PlaySongSelect()); AddUntilStep("wait for selection", () => !Game.Beatmap.IsDefault); + AddUntilStep("wait for carousel load", () => songSelect.BeatmapSetsLoaded); AddStep("enter gameplay", () => InputManager.Key(Key.Enter)); @@ -92,6 +93,8 @@ namespace osu.Game.Tests.Visual.Navigation .AsEnumerable() .First(k => k.RulesetName == "osu" && k.ActionInt == 0); + private Screens.Select.SongSelect songSelect => Game.ScreenStack.CurrentScreen as Screens.Select.SongSelect; + private Player player => Game.ScreenStack.CurrentScreen as Player; private KeyCounter keyCounter => player.ChildrenOfType().First(); From 7a860fb460895486499e8ed897f36d8d30e98c16 Mon Sep 17 00:00:00 2001 From: Samaoo Date: Sat, 12 Nov 2022 08:49:03 +0100 Subject: [PATCH 0542/2991] address reviews --- .../Sections/Input/TabletAreaSelection.cs | 16 ++++++++-------- .../Settings/Sections/Input/TabletSettings.cs | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletAreaSelection.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletAreaSelection.cs index 3b5190d13b..708cd5900a 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletAreaSelection.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletAreaSelection.cs @@ -212,17 +212,17 @@ namespace osu.Game.Overlays.Settings.Sections.Input { base.Update(); - if (tablet.Value?.Size is Vector2 size) - { - float maxDimension = size.LengthFast; + if (!(tablet.Value?.Size is Vector2 size)) + return; - float fitX = maxDimension / (DrawWidth - Padding.Left - Padding.Right); - float fitY = maxDimension / DrawHeight; + float maxDimension = size.LengthFast; - float adjust = MathF.Max(fitX, fitY); + float fitX = maxDimension / (DrawWidth - Padding.Left - Padding.Right); + float fitY = maxDimension / DrawHeight; - tabletContainer.Scale = new Vector2(1 / adjust); - } + float adjust = MathF.Max(fitX, fitY); + + tabletContainer.Scale = new Vector2(1 / adjust); } } } diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs index 0f96ef3ac7..4cafb5c377 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs @@ -342,8 +342,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input private float currentAspectRatio => sizeX.Value / sizeY.Value; - private static float getHeight(float width, float aspectRatio) => MathF.Round(width / aspectRatio); + private static float getHeight(float width, float aspectRatio) => width / aspectRatio; - private static float getWidth(float height, float aspectRatio) => MathF.Round(height * aspectRatio); + private static float getWidth(float height, float aspectRatio) => height * aspectRatio; } } From 4ff17cb4bdb617f7301363380d3424d099d57eb9 Mon Sep 17 00:00:00 2001 From: Samaoo Date: Sat, 12 Nov 2022 08:52:33 +0100 Subject: [PATCH 0543/2991] remove unused using directive --- osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs index 4cafb5c377..21a65862f7 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs @@ -3,7 +3,6 @@ #nullable disable -using System; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; From fa8e38d9d61cc867f9ff37e991693df6b936bb39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Mu=CC=88ller-Ho=CC=88hne?= Date: Sat, 12 Nov 2022 17:05:29 +0900 Subject: [PATCH 0544/2991] Target rounded fragment shader Compatibility with osu-framework change https://github.com/ppy/osu-framework/pull/5512 --- osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs | 2 -- osu.Game/Graphics/Backgrounds/Triangles.cs | 2 +- osu.Game/Graphics/Sprites/LogoAnimation.cs | 1 - osu.Game/Screens/Loader.cs | 4 +--- osu.Game/Screens/Menu/LogoVisualisation.cs | 2 +- 5 files changed, 3 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs index 46c8e7c02a..3bc17c0849 100644 --- a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs @@ -49,7 +49,6 @@ namespace osu.Game.Rulesets.Osu.Skinning private const float max_rotation = 0.25f; public IShader? TextureShader { get; private set; } - public IShader? RoundedTextureShader { get; private set; } protected Texture? Texture { get; set; } @@ -69,7 +68,6 @@ namespace osu.Game.Rulesets.Osu.Skinning [BackgroundDependencyLoader] private void load(ShaderManager shaders) { - RoundedTextureShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); TextureShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE); } diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index 1166a86814..986f5d3ac5 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -103,7 +103,7 @@ namespace osu.Game.Graphics.Backgrounds private void load(IRenderer renderer, ShaderManager shaders) { texture = renderer.WhitePixel; - shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); + shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE); } protected override void LoadComplete() diff --git a/osu.Game/Graphics/Sprites/LogoAnimation.cs b/osu.Game/Graphics/Sprites/LogoAnimation.cs index 7debdc7a37..5233a3d67f 100644 --- a/osu.Game/Graphics/Sprites/LogoAnimation.cs +++ b/osu.Game/Graphics/Sprites/LogoAnimation.cs @@ -17,7 +17,6 @@ namespace osu.Game.Graphics.Sprites private void load(ShaderManager shaders) { TextureShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, @"LogoAnimation"); - RoundedTextureShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, @"LogoAnimation"); // Masking isn't supported for now } private float animationProgress; diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index afba00274c..ac22fdce71 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -125,13 +125,11 @@ namespace osu.Game.Screens [BackgroundDependencyLoader] private void load(ShaderManager manager) { - loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED)); - loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.BLUR)); loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE)); + loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.BLUR)); loadTargets.Add(manager.Load(@"CursorTrail", FragmentShaderDescriptor.TEXTURE)); - loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE_ROUNDED)); loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE)); } diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index c7bda4d8f8..4a20d7cb2b 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -89,7 +89,7 @@ namespace osu.Game.Screens.Menu private void load(IRenderer renderer, ShaderManager shaders) { texture = renderer.WhitePixel; - shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); + shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE); } private readonly float[] temporalAmplitudes = new float[ChannelAmplitudes.AMPLITUDES_SIZE]; From aef25df80844444e517f9bdd9be2bab17dc5a979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 12 Nov 2022 17:06:08 +0900 Subject: [PATCH 0545/2991] Add helper scripts for using local resources --- UseLocalResources.ps1 | 12 ++++++++++++ UseLocalResources.sh | 11 +++++++++++ 2 files changed, 23 insertions(+) create mode 100644 UseLocalResources.ps1 create mode 100755 UseLocalResources.sh diff --git a/UseLocalResources.ps1 b/UseLocalResources.ps1 new file mode 100644 index 0000000000..f9d9df01bb --- /dev/null +++ b/UseLocalResources.ps1 @@ -0,0 +1,12 @@ +$CSPROJ="osu.Game/osu.Game.csproj" +$SLN="osu.sln" + +dotnet remove $CSPROJ package ppy.osu.Game.Resources; +dotnet sln $SLN add ../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj +dotnet add $CSPROJ reference ../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj + +$SLNF=Get-Content "osu.Desktop.slnf" | ConvertFrom-Json +$TMP=New-TemporaryFile +$SLNF.solution.projects += ("../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj") +ConvertTo-Json $SLNF | Out-File $TMP -Encoding UTF8 +Move-Item -Path $TMP -Destination "osu.Desktop.slnf" -Force diff --git a/UseLocalResources.sh b/UseLocalResources.sh new file mode 100755 index 0000000000..6d9d2b6016 --- /dev/null +++ b/UseLocalResources.sh @@ -0,0 +1,11 @@ +CSPROJ="osu.Game/osu.Game.csproj" +SLN="osu.sln" + +dotnet remove $CSPROJ package ppy.osu.Game.Resources; +dotnet sln $SLN add ../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj +dotnet add $CSPROJ reference ../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj + +SLNF="osu.Desktop.slnf" +TMP=$(mktemp) +jq '.solution.projects += ["../osu-resources/osu.Game.Resources/osu.Game.Resources.csproj"]' $SLNF > $TMP +mv -f $TMP $SLNF From 9ef43ebd837e44f8f8cb3c3c5629ec44c7adcb55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Mu=CC=88ller-Ho=CC=88hne?= Date: Sat, 12 Nov 2022 21:24:12 +0900 Subject: [PATCH 0546/2991] Fix compilation after framework-side PR updates --- osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs | 6 ++---- osu.Game/Graphics/Sprites/LogoAnimation.cs | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs index 3bc17c0849..c19ed3fb35 100644 --- a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs @@ -245,18 +245,16 @@ namespace osu.Game.Rulesets.Osu.Skinning texture ??= renderer.WhitePixel; RectangleF textureRect = texture.GetTextureRect(); - var shader = GetAppropriateShader(renderer); - renderer.SetBlend(BlendingParameters.Additive); renderer.PushLocalMatrix(DrawInfo.Matrix); - shader.Bind(); + TextureShader.Bind(); texture.Bind(); for (int i = 0; i < points.Count; i++) drawPointQuad(points[i], textureRect, i + firstVisiblePointIndex); - shader.Unbind(); + TextureShader.Unbind(); renderer.PopLocalMatrix(); } diff --git a/osu.Game/Graphics/Sprites/LogoAnimation.cs b/osu.Game/Graphics/Sprites/LogoAnimation.cs index 5233a3d67f..097de4dfcb 100644 --- a/osu.Game/Graphics/Sprites/LogoAnimation.cs +++ b/osu.Game/Graphics/Sprites/LogoAnimation.cs @@ -57,7 +57,7 @@ namespace osu.Game.Graphics.Sprites protected override void Blit(IRenderer renderer) { - GetAppropriateShader(renderer).GetUniform("progress").UpdateValue(ref progress); + TextureShader.GetUniform("progress").UpdateValue(ref progress); base.Blit(renderer); } From ace4099079889f8b220d8e8514167870dac0cad8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 12 Nov 2022 21:41:10 +0900 Subject: [PATCH 0547/2991] Update ack code after incorrect merge --- osu.Game/Online/Chat/ChannelManager.cs | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 0aa86fb9d1..bb388b7461 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -116,20 +116,7 @@ namespace osu.Game.Online.Chat if (apiState.Value != APIState.Online) return; - scheduledAck?.Cancel(); - - var req = new ChatAckRequest(); - req.Success += _ => scheduleNextRequest(); - req.Failure += _ => scheduleNextRequest(); - api.Queue(req); - - // Todo: Handle silences. - - void scheduleNextRequest() - { - scheduledAck?.Cancel(); - scheduledAck = Scheduler.AddDelayed(performChatAckRequest, 60000); - } + SendAck(); } /// @@ -416,6 +403,7 @@ namespace osu.Game.Online.Chat SinceSilenceId = lastSilenceId }; + req.Failure += _ => scheduleNextRequest(); req.Success += ack => { foreach (var silence in ack.Silences) @@ -424,9 +412,17 @@ namespace osu.Game.Online.Chat channel.RemoveMessagesFromUser(silence.UserId); lastSilenceId = Math.Max(lastSilenceId ?? 0, silence.Id); } + + scheduleNextRequest(); }; api.Queue(req); + + void scheduleNextRequest() + { + scheduledAck?.Cancel(); + scheduledAck = Scheduler.AddDelayed(performChatAckRequest, 60000); + } } /// From 6a3665a6fde45b4f66e977cd79aa5a6670ebd3d8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 12 Nov 2022 22:09:27 +0900 Subject: [PATCH 0548/2991] Remove excess logging on `WebSocketNotificaitonsClient` --- .../Notifications/WebSocket/WebSocketNotificationsClient.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs index 86836099d8..d8d78297e3 100644 --- a/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs +++ b/osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs @@ -72,7 +72,6 @@ namespace osu.Game.Online.Notifications.WebSocket break; } - Logger.Log($"{GetType().ReadableName()} handling event: {message.Event}"); await onMessageReceivedAsync(message); } From bfb939cbd0ae1b1528d23534457a26178cf340d6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 12 Nov 2022 22:24:27 +0900 Subject: [PATCH 0549/2991] Expand on why call needs to be made every 10 minutes --- osu.Game/Online/Chat/ChannelManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index bb388b7461..ebfe44bd66 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -393,7 +393,7 @@ namespace osu.Game.Online.Chat /// /// Sends an acknowledgement request to the API. /// This marks the user as online to receive messages from public channels, while also returning a list of silenced users. - /// It needs to be called at least once every 10 minutes. + /// It needs to be called at least once every 10 minutes to remain visibly marked as online. /// public void SendAck() { From 143c94612872c8ea6c804d51b956f3f6a59e1ce5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 12 Nov 2022 23:02:37 +0900 Subject: [PATCH 0550/2991] Simplify ack re-perform flow --- osu.Game/Online/Chat/ChannelManager.cs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index ebfe44bd66..8f1d2db36c 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -108,15 +108,7 @@ namespace osu.Game.Online.Chat connector.Start(); apiState.BindTo(api.State); - apiState.BindValueChanged(_ => performChatAckRequest(), true); - } - - private void performChatAckRequest() - { - if (apiState.Value != APIState.Online) - return; - - SendAck(); + apiState.BindValueChanged(_ => SendAck(), true); } /// @@ -397,6 +389,9 @@ namespace osu.Game.Online.Chat /// public void SendAck() { + if (apiState.Value != APIState.Online) + return; + var req = new ChatAckRequest { SinceMessageId = lastMessageId, @@ -421,7 +416,7 @@ namespace osu.Game.Online.Chat void scheduleNextRequest() { scheduledAck?.Cancel(); - scheduledAck = Scheduler.AddDelayed(performChatAckRequest, 60000); + scheduledAck = Scheduler.AddDelayed(SendAck, 60000); } } From 22d8a1160e28bae031040fa5376dcfaa0caf219b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 12 Nov 2022 23:32:05 +0900 Subject: [PATCH 0551/2991] Fix last silence ID being updated too often, causing most silences to be missed --- osu.Game/Online/API/Requests/ChatAckRequest.cs | 5 +++-- osu.Game/Online/Chat/ChannelManager.cs | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/osu.Game/Online/API/Requests/ChatAckRequest.cs b/osu.Game/Online/API/Requests/ChatAckRequest.cs index 78f51e21c0..01b0c142dc 100644 --- a/osu.Game/Online/API/Requests/ChatAckRequest.cs +++ b/osu.Game/Online/API/Requests/ChatAckRequest.cs @@ -9,14 +9,15 @@ namespace osu.Game.Online.API.Requests { public class ChatAckRequest : APIRequest { - public long SinceMessageId; + public long? SinceMessageId; public uint? SinceSilenceId; protected override WebRequest CreateWebRequest() { var req = base.CreateWebRequest(); req.Method = HttpMethod.Post; - req.AddParameter(@"since", SinceMessageId.ToString()); + if (SinceMessageId != null) + req.AddParameter(@"since", SinceMessageId.ToString()); if (SinceSilenceId != null) req.AddParameter(@"history_since", SinceSilenceId.Value.ToString()); return req; diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 8f1d2db36c..25a53360f0 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -74,7 +74,7 @@ namespace osu.Game.Online.Chat private bool channelsInitialised; private ScheduledDelegate scheduledAck; - private long lastMessageId; + private long? lastSilenceMessageId; private uint? lastSilenceId; public ChannelManager(IAPIProvider api) @@ -332,7 +332,7 @@ namespace osu.Game.Online.Chat foreach (var group in messages.GroupBy(m => m.ChannelId)) channels.Find(c => c.Id == group.Key)?.AddNewMessages(group.ToArray()); - lastMessageId = messages.LastOrDefault()?.Id ?? lastMessageId; + lastSilenceMessageId ??= messages.LastOrDefault()?.Id; } private void initializeChannels() @@ -394,7 +394,7 @@ namespace osu.Game.Online.Chat var req = new ChatAckRequest { - SinceMessageId = lastMessageId, + SinceMessageId = lastSilenceMessageId, SinceSilenceId = lastSilenceId }; From f343ba611139c98a0424f95c8a07dd0ee4d03b7d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 12 Nov 2022 23:35:21 +0900 Subject: [PATCH 0552/2991] Add xmldoc for chat ack request --- osu.Game/Online/API/Requests/ChatAckRequest.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game/Online/API/Requests/ChatAckRequest.cs b/osu.Game/Online/API/Requests/ChatAckRequest.cs index 01b0c142dc..306b5acc1d 100644 --- a/osu.Game/Online/API/Requests/ChatAckRequest.cs +++ b/osu.Game/Online/API/Requests/ChatAckRequest.cs @@ -7,6 +7,17 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { + /// + /// A request which should be sent occasionally while interested in chat and online state. + /// + /// This will: + /// - Mark the user as "online" (for 10 minutes since the last invocation). + /// - Return any silences since the last invocation (if either or is not null). + /// + /// For silence handling, a should be provided as soon as a message is received by the client. + /// From that point forward, should be preferred after the first + /// arrives in a response from the ack request. Specifying both parameters will prioritise the latter. + /// public class ChatAckRequest : APIRequest { public long? SinceMessageId; From c5cb4e4e7d754a7d076a3d91fac2ae7c841c19dd Mon Sep 17 00:00:00 2001 From: Jai Sharma Date: Sat, 12 Nov 2022 17:48:35 +0000 Subject: [PATCH 0553/2991] Add winner of Triangles mapping competition as a bundled beatmap https://osu.ppy.sh/home/news/2022-10-06-results-triangles --- osu.Game/Beatmaps/Drawables/BundledBeatmapDownloader.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/BundledBeatmapDownloader.cs b/osu.Game/Beatmaps/Drawables/BundledBeatmapDownloader.cs index 80af4108c7..053ac8fc17 100644 --- a/osu.Game/Beatmaps/Drawables/BundledBeatmapDownloader.cs +++ b/osu.Game/Beatmaps/Drawables/BundledBeatmapDownloader.cs @@ -136,7 +136,9 @@ namespace osu.Game.Beatmaps.Drawables private static readonly string[] always_bundled_beatmaps = { // This thing is 40mb, I'm not sure we want it here... - @"1388906 Raphlesia & BilliumMoto - My Love.osz" + @"1388906 Raphlesia & BilliumMoto - My Love.osz", + // Winner of Triangles mapping competition: https://osu.ppy.sh/home/news/2022-10-06-results-triangles + @"1841885 cYsmix - triangles.osz", }; private static readonly string[] bundled_osu = From eae853072298e1251f8a0cfdeecb2cead746fa23 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 13 Nov 2022 12:46:20 +0900 Subject: [PATCH 0554/2991] Fix `SkinnableSprite` lookups broken in lazer-first skins Regressed with removal of local `GetTexture` calls in https://github.com/ppy/osu/commit/e19ba65f9186afab21aec536a636d7d152636dde --- osu.Game/Skinning/ArgonSkin.cs | 13 +++---------- osu.Game/Skinning/LegacySkin.cs | 3 --- osu.Game/Skinning/Skin.cs | 4 ++++ osu.Game/Skinning/TrianglesSkin.cs | 13 +++---------- 4 files changed, 10 insertions(+), 23 deletions(-) diff --git a/osu.Game/Skinning/ArgonSkin.cs b/osu.Game/Skinning/ArgonSkin.cs index a2eb07eba3..6a0c4a23e5 100644 --- a/osu.Game/Skinning/ArgonSkin.cs +++ b/osu.Game/Skinning/ArgonSkin.cs @@ -82,21 +82,14 @@ namespace osu.Game.Skinning public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { + // Temporary until default skin has a valid hit lighting. + if ((lookup as SkinnableSprite.SpriteComponentLookup)?.LookupName == @"lighting") return Drawable.Empty(); + if (base.GetDrawableComponent(lookup) is Drawable c) return c; switch (lookup) { - case SkinnableSprite.SpriteComponentLookup spriteLookup: - switch (spriteLookup.LookupName) - { - // Temporary until default skin has a valid hit lighting. - case @"lighting": - return Drawable.Empty(); - } - - break; - case GlobalSkinComponentLookup globalLookup: switch (globalLookup.Lookup) { diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 98618e3dcd..ea223d172d 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -396,9 +396,6 @@ namespace osu.Game.Skinning } return null; - - case SkinnableSprite.SpriteComponentLookup sprite: - return this.GetAnimation(sprite.LookupName, false, false); } return null; diff --git a/osu.Game/Skinning/Skin.cs b/osu.Game/Skinning/Skin.cs index e222b9017c..25d1dc903c 100644 --- a/osu.Game/Skinning/Skin.cs +++ b/osu.Game/Skinning/Skin.cs @@ -158,6 +158,10 @@ namespace osu.Game.Skinning { switch (lookup) { + // This fallback is important for user skins which use SkinnableSprites. + case SkinnableSprite.SpriteComponentLookup sprite: + return this.GetAnimation(sprite.LookupName, false, false); + case GlobalSkinComponentLookup target: if (!DrawableComponentInfo.TryGetValue(target.Lookup, out var skinnableInfo)) return null; diff --git a/osu.Game/Skinning/TrianglesSkin.cs b/osu.Game/Skinning/TrianglesSkin.cs index 2075cfb6f2..62ef94691b 100644 --- a/osu.Game/Skinning/TrianglesSkin.cs +++ b/osu.Game/Skinning/TrianglesSkin.cs @@ -60,21 +60,14 @@ namespace osu.Game.Skinning public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { + // Temporary until default skin has a valid hit lighting. + if ((lookup as SkinnableSprite.SpriteComponentLookup)?.LookupName == @"lighting") return Drawable.Empty(); + if (base.GetDrawableComponent(lookup) is Drawable c) return c; switch (lookup) { - case SkinnableSprite.SpriteComponentLookup spriteLookup: - switch (spriteLookup.LookupName) - { - // Temporary until default skin has a valid hit lighting. - case @"lighting": - return Drawable.Empty(); - } - - break; - case GlobalSkinComponentLookup target: switch (target.Lookup) { From 887b6832c9435fce99ad7d10095a26f52fcec572 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 13 Nov 2022 16:15:30 +0900 Subject: [PATCH 0555/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 8237a570ff..085b71d131 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 09b1bb7162..8f9fe0f9f7 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 4264d9220e..e8ccc9cb3a 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From 236cc0bdaf10861546efe3b328ac01d63cd546c5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 13 Nov 2022 16:21:28 +0900 Subject: [PATCH 0556/2991] Update resources --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 085b71d131..5f3fb858ee 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -51,7 +51,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8f9fe0f9f7..858cac1dac 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index e8ccc9cb3a..25217b872b 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -61,7 +61,7 @@ - + From 3f8c4a5dfff5c094c2bb4ce6100da4f636a2a037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=E1=BB=93=20Nguy=C3=AAn=20Minh?= Date: Sun, 13 Nov 2022 17:09:43 +0700 Subject: [PATCH 0557/2991] Stack Catch dash/normal touch input vertically --- .../UI/CatchTouchInputMapper.cs | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchTouchInputMapper.cs b/osu.Game.Rulesets.Catch/UI/CatchTouchInputMapper.cs index e6736d6c93..12d695393f 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchTouchInputMapper.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchTouchInputMapper.cs @@ -35,6 +35,8 @@ namespace osu.Game.Rulesets.Catch.UI private void load(CatchInputManager catchInputManager, OsuColour colours) { const float width = 0.15f; + // Ratio between normal move area height and total input height + const float normal_area_height_ratio = 0.45f; keyBindingContainer = catchInputManager.KeyBindingContainer; @@ -54,18 +56,18 @@ namespace osu.Game.Rulesets.Catch.UI Width = width, Children = new Drawable[] { - leftDashBox = new InputArea(TouchCatchAction.DashLeft, trackedActionSources) - { - RelativeSizeAxes = Axes.Both, - Width = 0.5f, - }, leftBox = new InputArea(TouchCatchAction.MoveLeft, trackedActionSources) { RelativeSizeAxes = Axes.Both, - Width = 0.5f, + Height = normal_area_height_ratio, Colour = colours.Gray9, - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + }, + leftDashBox = new InputArea(TouchCatchAction.DashLeft, trackedActionSources) + { + RelativeSizeAxes = Axes.Both, + Height = 1 - normal_area_height_ratio, }, } }, @@ -80,15 +82,15 @@ namespace osu.Game.Rulesets.Catch.UI rightBox = new InputArea(TouchCatchAction.MoveRight, trackedActionSources) { RelativeSizeAxes = Axes.Both, - Width = 0.5f, + Height = normal_area_height_ratio, Colour = colours.Gray9, + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, }, rightDashBox = new InputArea(TouchCatchAction.DashRight, trackedActionSources) { RelativeSizeAxes = Axes.Both, - Width = 0.5f, - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, + Height = 1 - normal_area_height_ratio, }, } }, From 81c9ea98e2119997b22181161974642d826c5f63 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 13 Nov 2022 14:59:17 +0300 Subject: [PATCH 0558/2991] Implement TrianglesV2 component --- .../TestSceneTriangleBorderShader.cs | 59 ++++ .../TestSceneTrianglesBackground.cs | 43 +++ osu.Game/Graphics/Backgrounds/TrianglesV2.cs | 313 ++++++++++++++++++ 3 files changed, 415 insertions(+) create mode 100644 osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs create mode 100644 osu.Game.Tests/Visual/Background/TestSceneTrianglesBackground.cs create mode 100644 osu.Game/Graphics/Backgrounds/TrianglesV2.cs diff --git a/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs b/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs new file mode 100644 index 0000000000..470962088e --- /dev/null +++ b/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs @@ -0,0 +1,59 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable disable + +using osu.Framework.Allocation; +using osu.Framework.Graphics.Shaders; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics; +using osuTK; +using osuTK.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Rendering; + +namespace osu.Game.Tests.Visual.Background +{ + public class TestSceneTriangleBorderShader : OsuTestScene + { + public TestSceneTriangleBorderShader() + { + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.DarkGreen + }, + new TriangleBorder + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(100) + } + }; + } + + private class TriangleBorder : Sprite + { + [BackgroundDependencyLoader] + private void load(ShaderManager shaders, IRenderer renderer) + { + TextureShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, "TriangleBorder"); + Texture = renderer.WhitePixel; + } + + protected override DrawNode CreateDrawNode() => new TriangleBorderDrawNode(this); + + private class TriangleBorderDrawNode : SpriteDrawNode + { + public TriangleBorderDrawNode(TriangleBorder source) + : base(source) + { + } + + protected override bool CanDrawOpaqueInterior => false; + } + } + } +} diff --git a/osu.Game.Tests/Visual/Background/TestSceneTrianglesBackground.cs b/osu.Game.Tests/Visual/Background/TestSceneTrianglesBackground.cs new file mode 100644 index 0000000000..a40d363dbe --- /dev/null +++ b/osu.Game.Tests/Visual/Background/TestSceneTrianglesBackground.cs @@ -0,0 +1,43 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osuTK; +using osuTK.Graphics; +using osu.Game.Graphics.Backgrounds; + +namespace osu.Game.Tests.Visual.Background +{ + public class TestSceneTrianglesBackground : OsuTestScene + { + public TestSceneTrianglesBackground() + { + AddRange(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Gray + }, + new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(200), + Masking = true, + CornerRadius = 40, + Child = new TrianglesV2 + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + ColourTop = Color4.Red, + ColourBottom = Color4.Orange + } + } + }); + } + } +} diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs new file mode 100644 index 0000000000..89ec7d2ad5 --- /dev/null +++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs @@ -0,0 +1,313 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable disable + +using osu.Framework.Utils; +using osuTK; +using System; +using osu.Framework.Graphics.Shaders; +using osu.Framework.Graphics.Textures; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Allocation; +using System.Collections.Generic; +using osu.Framework.Graphics.Rendering; +using osu.Framework.Graphics.Rendering.Vertices; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp; +using osuTK.Graphics; +using osu.Framework.Bindables; +using osu.Framework.Graphics; + +namespace osu.Game.Graphics.Backgrounds +{ + public class TrianglesV2 : Drawable + { + private const float triangle_size = 100; + private const float base_velocity = 50; + private const int texture_height = 128; + + private readonly Bindable colourTop = new Bindable(Color4.White); + private readonly Bindable colourBottom = new Bindable(Color4.Black); + + public Color4 ColourTop + { + get => colourTop.Value; + set => colourTop.Value = value; + } + + public Color4 ColourBottom + { + get => colourBottom.Value; + set => colourBottom.Value = value; + } + + /// + /// Whether we should create new triangles as others expire. + /// + protected virtual bool CreateNewTriangles => true; + + /// + /// The amount of triangles we want compared to the default distribution. + /// + protected virtual float SpawnRatio => 1; + + private float triangleScale = 1; + + /// + /// The relative velocity of the triangles. Default is 1. + /// + public float Velocity = 1; + + private readonly List parts = new List(); + + [Resolved] + private IRenderer renderer { get; set; } + + private Random stableRandom; + private IShader shader; + private Texture texture; + + /// + /// Construct a new triangle visualisation. + /// + /// An optional seed to stabilise random positions / attributes. Note that this does not guarantee stable playback when seeking in time. + public TrianglesV2(int? seed = null) + { + if (seed != null) + stableRandom = new Random(seed.Value); + } + + [BackgroundDependencyLoader] + private void load(ShaderManager shaders) + { + shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, "TriangleBorder"); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + colourTop.BindValueChanged(_ => updateTexture()); + colourBottom.BindValueChanged(_ => updateTexture(), true); + + addTriangles(true); + } + + private void updateTexture() + { + var image = new Image(texture_height, 1); + + texture = renderer.CreateTexture(1, texture_height, true); + + for (int i = 0; i < texture_height; i++) + { + float ratio = (float)i / texture_height; + + image[i, 0] = new Rgba32( + colourBottom.Value.R * ratio + colourTop.Value.R * (1f - ratio), + colourBottom.Value.G * ratio + colourTop.Value.G * (1f - ratio), + colourBottom.Value.B * ratio + colourTop.Value.B * (1f - ratio), + 1f + ); + } + + texture.SetData(new TextureUpload(image)); + Invalidate(Invalidation.DrawNode); + } + + public float TriangleScale + { + get => triangleScale; + set + { + float change = value / triangleScale; + triangleScale = value; + + for (int i = 0; i < parts.Count; i++) + { + TriangleParticle newParticle = parts[i]; + newParticle.Scale *= change; + parts[i] = newParticle; + } + } + } + + protected override void Update() + { + base.Update(); + + Invalidate(Invalidation.DrawNode); + + if (CreateNewTriangles) + addTriangles(false); + + float elapsedSeconds = (float)Time.Elapsed / 1000; + // Since position is relative, the velocity needs to scale inversely with DrawHeight. + // Since we will later multiply by the scale of individual triangles we normalize by + // dividing by triangleScale. + float movedDistance = -elapsedSeconds * Velocity * base_velocity / (DrawHeight * triangleScale); + + for (int i = 0; i < parts.Count; i++) + { + TriangleParticle newParticle = parts[i]; + + // Scale moved distance by the size of the triangle. Smaller triangles should move more slowly. + newParticle.Position.Y += Math.Max(0.5f, parts[i].Scale) * movedDistance; + + parts[i] = newParticle; + + float bottomPos = parts[i].Position.Y + triangle_size * parts[i].Scale * 0.866f / DrawHeight; + if (bottomPos < 0) + parts.RemoveAt(i); + } + } + + /// + /// Clears and re-initialises triangles according to a given seed. + /// + /// An optional seed to stabilise random positions / attributes. Note that this does not guarantee stable playback when seeking in time. + public void Reset(int? seed = null) + { + if (seed != null) + stableRandom = new Random(seed.Value); + + parts.Clear(); + addTriangles(true); + } + + protected int AimCount { get; private set; } + + private void addTriangles(bool randomY) + { + // Limited by the maximum size of QuadVertexBuffer for safety. + const int max_triangles = ushort.MaxValue / (IRenderer.VERTICES_PER_QUAD + 2); + + AimCount = (int)Math.Min(max_triangles, DrawWidth * DrawHeight * 0.002f / (triangleScale * triangleScale) * SpawnRatio); + + for (int i = 0; i < AimCount - parts.Count; i++) + parts.Add(createTriangle(randomY)); + } + + private TriangleParticle createTriangle(bool randomY) + { + TriangleParticle particle = CreateTriangle(); + + particle.Position = new Vector2(nextRandom(), randomY ? nextRandom() : 1); + + return particle; + } + + /// + /// Creates a triangle particle with a random scale. + /// + /// The triangle particle. + protected virtual TriangleParticle CreateTriangle() + { + const float std_dev = 0.16f; + const float mean = 0.5f; + + float u1 = 1 - nextRandom(); //uniform(0,1] random floats + float u2 = 1 - nextRandom(); + float randStdNormal = (float)(Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2)); // random normal(0,1) + float scale = Math.Max(triangleScale * (mean + std_dev * randStdNormal), 0.1f); // random normal(mean,stdDev^2) + + return new TriangleParticle { Scale = scale }; + } + + private float nextRandom() => (float)(stableRandom?.NextDouble() ?? RNG.NextSingle()); + + protected override DrawNode CreateDrawNode() => new TrianglesDrawNode(this); + + private class TrianglesDrawNode : DrawNode + { + protected new TrianglesV2 Source => (TrianglesV2)base.Source; + + private IShader shader; + private Texture texture; + + private readonly List parts = new List(); + private Vector2 size; + + private IVertexBatch vertexBatch; + + public TrianglesDrawNode(TrianglesV2 source) + : base(source) + { + } + + public override void ApplyState() + { + base.ApplyState(); + + shader = Source.shader; + texture = Source.texture; + size = Source.DrawSize; + + parts.Clear(); + parts.AddRange(Source.parts); + } + + public override void Draw(IRenderer renderer) + { + base.Draw(renderer); + + if (Source.AimCount > 0 && (vertexBatch == null || vertexBatch.Size != Source.AimCount)) + { + vertexBatch?.Dispose(); + vertexBatch = renderer.CreateQuadBatch(Source.AimCount, 1); + } + + shader.Bind(); + + foreach (TriangleParticle particle in parts) + { + var offset = triangle_size * new Vector2(particle.Scale * 0.5f, particle.Scale * 0.866f); + + Vector2 topLeft = particle.Position * size + new Vector2(-offset.X, 0f); + Vector2 topRight = particle.Position * size + new Vector2(offset.X, 0); + Vector2 bottomLeft = particle.Position * size + new Vector2(-offset.X, offset.Y); + Vector2 bottomRight = particle.Position * size + new Vector2(offset.X, offset.Y); + + var drawQuad = new Quad( + Vector2Extensions.Transform(topLeft, DrawInfo.Matrix), + Vector2Extensions.Transform(topRight, DrawInfo.Matrix), + Vector2Extensions.Transform(bottomLeft, DrawInfo.Matrix), + Vector2Extensions.Transform(bottomRight, DrawInfo.Matrix) + ); + + var tRect = new Quad( + topLeft.X / size.X, + topLeft.Y / size.Y * texture_height, + (topRight.X - topLeft.X) / size.X, + (bottomRight.Y - topRight.Y) / size.Y * texture_height + ).AABBFloat; + + renderer.DrawQuad(texture, drawQuad, DrawColourInfo.Colour, tRect, vertexBatch.AddAction, textureCoords: tRect); + } + + shader.Unbind(); + } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + vertexBatch?.Dispose(); + } + } + + protected struct TriangleParticle + { + /// + /// The position of the top vertex of the triangle. + /// + public Vector2 Position; + + /// + /// The scale of the triangle. + /// + public float Scale; + } + } +} From 4578a968131a0c0ca68732fa1c0420ddd0c9d2fb Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 13 Nov 2022 08:18:44 -0800 Subject: [PATCH 0559/2991] Fix beatmap card expanded content not blocking clicks from behind --- .../Beatmaps/Drawables/Cards/ExpandedContentScrollContainer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Beatmaps/Drawables/Cards/ExpandedContentScrollContainer.cs b/osu.Game/Beatmaps/Drawables/Cards/ExpandedContentScrollContainer.cs index a80a7998a5..c0ed6ac1a9 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/ExpandedContentScrollContainer.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/ExpandedContentScrollContainer.cs @@ -59,6 +59,8 @@ namespace osu.Game.Beatmaps.Drawables.Cards return base.OnScroll(e); } + protected override bool OnClick(ClickEvent e) => true; + private class ExpandedContentScrollbar : OsuScrollbar { public ExpandedContentScrollbar(Direction scrollDir) From 56fd1f95b150b51ca839e08a4fbf31d8b97d1c9b Mon Sep 17 00:00:00 2001 From: Susko3 Date: Sun, 13 Nov 2022 18:47:28 +0100 Subject: [PATCH 0560/2991] Fix `FallbackSampleStore.GetAsync` fallback logic --- osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs index ad52b4affc..c50f63c3b2 100644 --- a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs +++ b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs @@ -115,7 +115,11 @@ namespace osu.Game.Rulesets.UI public Sample Get(string name) => primary.Get(name) ?? fallback.Get(name); - public Task GetAsync(string name, CancellationToken cancellationToken = default) => primary.GetAsync(name, cancellationToken) ?? fallback.GetAsync(name, cancellationToken); + public async Task GetAsync(string name, CancellationToken cancellationToken = default) + { + return await primary.GetAsync(name, cancellationToken).ConfigureAwait(false) + ?? await fallback.GetAsync(name, cancellationToken).ConfigureAwait(false); + } public Stream GetStream(string name) => primary.GetStream(name) ?? fallback.GetStream(name); From a8c95c39ad0dd19791f025497f27d61fbf77adf6 Mon Sep 17 00:00:00 2001 From: Dario Headley Date: Mon, 14 Nov 2022 16:18:36 +0100 Subject: [PATCH 0561/2991] Exclude sliderticks from the " freeze " --- osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs index bea5d4f5d9..0a1aab9ef1 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFreezeFrame.cs @@ -56,6 +56,8 @@ namespace osu.Game.Rulesets.Osu.Mods { switch (nested) { + //Freezing the SliderTicks doesnt play well with snaking sliders + case SliderTick: //SliderRepeat wont layer correctly if preempt is changed. case SliderRepeat: break; From 576f462f59e9cd6110582a611a01a25ebc71c057 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 Nov 2022 00:53:38 +0900 Subject: [PATCH 0562/2991] Add pooling support to `BarHitErrorMeter` --- .../HUD/HitErrorMeters/BarHitErrorMeter.cs | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index e7b2ce1672..5fca8e2c51 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -11,6 +11,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Pooling; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Configuration; @@ -23,6 +24,7 @@ using osuTK; namespace osu.Game.Screens.Play.HUD.HitErrorMeters { + [Cached] public class BarHitErrorMeter : HitErrorMeter { private const int judgement_line_width = 14; @@ -44,6 +46,8 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters [SettingSource("Label style", "How to show early/late extremities")] public Bindable LabelStyle { get; } = new Bindable(LabelStyles.Icons); + private readonly DrawablePool judgementLinePool = new DrawablePool(50, 100); + private SpriteIcon arrow; private UprightAspectMaintainingContainer labelEarly; private UprightAspectMaintainingContainer labelLate; @@ -88,6 +92,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters Margin = new MarginPadding(2), Children = new Drawable[] { + judgementLinePool, colourBars = new Container { Name = "colour axis", @@ -403,11 +408,12 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters } } - judgementsContainer.Add(new JudgementLine + judgementLinePool.Get(drawableJudgement => { - JudgementLineThickness = { BindTarget = JudgementLineThickness }, - Y = getRelativeJudgementPosition(judgement.TimeOffset), - Colour = GetColourForHitResult(judgement.Type), + drawableJudgement.Y = getRelativeJudgementPosition(judgement.TimeOffset); + drawableJudgement.Colour = GetColourForHitResult(judgement.Type); + + judgementsContainer.Add(drawableJudgement); }); arrow.MoveToY( @@ -417,7 +423,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters private float getRelativeJudgementPosition(double value) => Math.Clamp((float)((value / maxHitWindow) + 1) / 2, 0, 1); - internal class JudgementLine : CompositeDrawable + internal class JudgementLine : PoolableDrawable { public readonly BindableNumber JudgementLineThickness = new BindableFloat(); @@ -437,18 +443,27 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters }; } + [Resolved] + private BarHitErrorMeter barHitErrorMeter { get; set; } + protected override void LoadComplete() { + base.LoadComplete(); + + JudgementLineThickness.BindTo(barHitErrorMeter.JudgementLineThickness); + JudgementLineThickness.BindValueChanged(thickness => Height = thickness.NewValue, true); + } + + protected override void PrepareForUse() + { + base.PrepareForUse(); + const int judgement_fade_in_duration = 100; const int judgement_fade_out_duration = 5000; - base.LoadComplete(); - Alpha = 0; Width = 0; - JudgementLineThickness.BindValueChanged(thickness => Height = thickness.NewValue, true); - this .FadeTo(0.6f, judgement_fade_in_duration, Easing.OutQuint) .ResizeWidthTo(1, judgement_fade_in_duration, Easing.OutQuint) From a86b50d62afd9cd279622f39d31505423ecee6fa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 Nov 2022 01:07:53 +0900 Subject: [PATCH 0563/2991] Apply nullability to `BarHitErrorMeter` --- .../HUD/HitErrorMeters/BarHitErrorMeter.cs | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index 5fca8e2c51..23e9c86adc 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using osu.Framework.Allocation; @@ -27,8 +25,6 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters [Cached] public class BarHitErrorMeter : HitErrorMeter { - private const int judgement_line_width = 14; - [SettingSource("Judgement line thickness", "How thick the individual lines should be.")] public BindableNumber JudgementLineThickness { get; } = new BindableNumber(4) { @@ -46,30 +42,33 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters [SettingSource("Label style", "How to show early/late extremities")] public Bindable LabelStyle { get; } = new Bindable(LabelStyles.Icons); - private readonly DrawablePool judgementLinePool = new DrawablePool(50, 100); + private const int judgement_line_width = 14; - private SpriteIcon arrow; - private UprightAspectMaintainingContainer labelEarly; - private UprightAspectMaintainingContainer labelLate; + private const int max_concurrent_judgements = 50; - private Container colourBarsEarly; - private Container colourBarsLate; - - private Container judgementsContainer; + private const int centre_marker_size = 8; private double maxHitWindow; private double floatingAverage; - private Container colourBars; - private Container arrowContainer; - private (HitResult result, double length)[] hitWindows; + private readonly DrawablePool judgementLinePool = new DrawablePool(50, 100); - private const int max_concurrent_judgements = 50; + private SpriteIcon arrow = null!; + private UprightAspectMaintainingContainer labelEarly = null!; + private UprightAspectMaintainingContainer labelLate = null!; - private Drawable[] centreMarkerDrawables; + private Container colourBarsEarly = null!; + private Container colourBarsLate = null!; - private const int centre_marker_size = 8; + private Container judgementsContainer = null!; + + private Container colourBars = null!; + private Container arrowContainer = null!; + + private (HitResult result, double length)[] hitWindows = null!; + + private Drawable[]? centreMarkerDrawables; public BarHitErrorMeter() { @@ -427,6 +426,9 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters { public readonly BindableNumber JudgementLineThickness = new BindableFloat(); + [Resolved] + private BarHitErrorMeter barHitErrorMeter { get; set; } = null!; + public JudgementLine() { RelativeSizeAxes = Axes.X; @@ -443,9 +445,6 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters }; } - [Resolved] - private BarHitErrorMeter barHitErrorMeter { get; set; } - protected override void LoadComplete() { base.LoadComplete(); From aef6ee23eb871d7c7ae1550b4d451527a623d630 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 14 Nov 2022 01:34:22 +0900 Subject: [PATCH 0564/2991] Apply pooling support to `ColourHitErrorMeter` --- .../HUD/HitErrorMeters/ColourHitErrorMeter.cs | 44 +++++++++++++------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs index dadec7c06b..6bf3ad0b28 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs @@ -3,9 +3,11 @@ using System.Collections.Generic; using System.Linq; +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Pooling; using osu.Framework.Graphics.Shapes; using osu.Game.Configuration; using osu.Game.Rulesets.Judgements; @@ -15,6 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play.HUD.HitErrorMeters { + [Cached] public class ColourHitErrorMeter : HitErrorMeter { private const int animation_duration = 200; @@ -82,7 +85,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters { base.LoadComplete(); - JudgementCount.BindValueChanged(count => + JudgementCount.BindValueChanged(_ => { removeExtraJudgements(); updateMetrics(); @@ -91,11 +94,14 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters JudgementSpacing.BindValueChanged(_ => updateMetrics(), true); } + private readonly DrawablePool judgementLinePool = new DrawablePool(50); + public void Push(Color4 colour) { - Add(new HitErrorShape(colour, drawable_judgement_size) + judgementLinePool.Get(shape => { - Shape = { BindTarget = JudgementShape }, + shape.Colour = colour; + Add(shape); }); removeExtraJudgements(); @@ -116,32 +122,32 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters } } - public class HitErrorShape : Container + public class HitErrorShape : PoolableDrawable { public bool IsRemoved { get; private set; } public readonly Bindable Shape = new Bindable(); - private readonly Color4 colour; + [Resolved] + private ColourHitErrorMeter hitErrorMeter { get; set; } = null!; private Container content = null!; - public HitErrorShape(Color4 colour, int size) + public HitErrorShape() { - this.colour = colour; - Size = new Vector2(size); + Size = new Vector2(drawable_judgement_size); } protected override void LoadComplete() { base.LoadComplete(); - Child = content = new Container + InternalChild = content = new Container { RelativeSizeAxes = Axes.Both, - Colour = colour }; + Shape.BindTo(hitErrorMeter.JudgementShape); Shape.BindValueChanged(shape => { switch (shape.NewValue) @@ -155,17 +161,27 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters break; } }, true); + } - content.FadeInFromZero(animation_duration, Easing.OutQuint); - content.MoveToY(-DrawSize.Y); - content.MoveToY(0, animation_duration, Easing.OutQuint); + protected override void PrepareForUse() + { + base.PrepareForUse(); + + IsRemoved = false; + + this.FadeIn(); + + content.FadeInFromZero(animation_duration, Easing.OutQuint) + .MoveToY(-DrawSize.Y) + .MoveToY(0, animation_duration, Easing.OutQuint); } public void Remove() { IsRemoved = true; - this.FadeOut(animation_duration, Easing.OutQuint).Expire(); + this.FadeOut(animation_duration, Easing.OutQuint) + .Expire(); } } From 59a8603728e280e8cd75e620a89ac7ba4d478bf6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 15 Nov 2022 11:33:19 +0900 Subject: [PATCH 0565/2991] Ensure flowing animation starts correctly from zero --- .../Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs index 6bf3ad0b28..b82afe18a6 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs @@ -169,7 +169,9 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters IsRemoved = false; - this.FadeIn(); + this.FadeIn() + // On pool re-use, start flow animation from (0,0). + .MoveTo(Vector2.Zero); content.FadeInFromZero(animation_duration, Easing.OutQuint) .MoveToY(-DrawSize.Y) From 308ed1abd1353631d98f1c868fd010d0c989b807 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 15 Nov 2022 11:55:33 +0900 Subject: [PATCH 0566/2991] Fix number of judgements shown potentially exceeding upper limit --- .../Visual/Gameplay/TestSceneHitErrorMeter.cs | 5 +---- .../HUD/HitErrorMeters/ColourHitErrorMeter.cs | 17 ++++++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs index 7c668adba5..b90b9b437d 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs @@ -163,10 +163,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for bars to disappear", () => !this.ChildrenOfType().Any()); AddUntilStep("ensure max circles not exceeded", () => - { - return this.ChildrenOfType() - .All(m => m.ChildrenOfType().Count() <= max_displayed_judgements); - }); + this.ChildrenOfType().First().ChildrenOfType().Count(), () => Is.LessThanOrEqualTo(max_displayed_judgements)); AddStep("show displays", () => { diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs index b82afe18a6..86ba85168f 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs @@ -102,9 +102,9 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters { shape.Colour = colour; Add(shape); - }); - removeExtraJudgements(); + removeExtraJudgements(); + }); } private void removeExtraJudgements() @@ -167,17 +167,20 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters { base.PrepareForUse(); - IsRemoved = false; - - this.FadeIn() + this.FadeInFromZero(animation_duration, Easing.OutQuint) // On pool re-use, start flow animation from (0,0). .MoveTo(Vector2.Zero); - content.FadeInFromZero(animation_duration, Easing.OutQuint) - .MoveToY(-DrawSize.Y) + content.MoveToY(-DrawSize.Y) .MoveToY(0, animation_duration, Easing.OutQuint); } + protected override void FreeAfterUse() + { + base.FreeAfterUse(); + IsRemoved = false; + } + public void Remove() { IsRemoved = true; From 489dca79a115060fe76cfa08d5a94b0886eec923 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 15 Nov 2022 12:05:38 +0900 Subject: [PATCH 0567/2991] Remove upper limit for pooling --- osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index 23e9c86adc..c9f1571dfe 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -52,7 +52,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters private double floatingAverage; - private readonly DrawablePool judgementLinePool = new DrawablePool(50, 100); + private readonly DrawablePool judgementLinePool = new DrawablePool(50); private SpriteIcon arrow = null!; private UprightAspectMaintainingContainer labelEarly = null!; From 333165e0528f2f48d427d8cf215efcd01bfb886e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Nov 2022 10:54:37 +0300 Subject: [PATCH 0568/2991] Add test scene for Triangles --- .../TestSceneTrianglesBackground.cs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 osu.Game.Tests/Visual/Background/TestSceneTrianglesBackground.cs diff --git a/osu.Game.Tests/Visual/Background/TestSceneTrianglesBackground.cs b/osu.Game.Tests/Visual/Background/TestSceneTrianglesBackground.cs new file mode 100644 index 0000000000..81a3249efb --- /dev/null +++ b/osu.Game.Tests/Visual/Background/TestSceneTrianglesBackground.cs @@ -0,0 +1,40 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Graphics.Backgrounds; +using osu.Framework.Graphics; +using osuTK.Graphics; +using osu.Framework.Graphics.Shapes; + +namespace osu.Game.Tests.Visual.Background +{ + public class TestSceneTrianglesBackground : OsuTestScene + { + private readonly Triangles triangles; + + public TestSceneTrianglesBackground() + { + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black + }, + triangles = new Triangles + { + RelativeSizeAxes = Axes.Both, + ColourLight = Color4.White, + ColourDark = Color4.Gray + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + AddSliderStep("Triangle scale", 0f, 10f, 1f, s => triangles.TriangleScale = s); + } + } +} From ebff8443340c66acf7fd41deb1feaf7ef1e14080 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Nov 2022 11:06:28 +0300 Subject: [PATCH 0569/2991] Reset triangles on scale change --- osu.Game/Graphics/Backgrounds/Triangles.cs | 34 ++++++++-------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index 986f5d3ac5..b5e77ec638 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -17,6 +17,7 @@ using System.Collections.Generic; using osu.Framework.Graphics.Rendering; using osu.Framework.Graphics.Rendering.Vertices; using osu.Framework.Lists; +using osu.Framework.Bindables; namespace osu.Game.Graphics.Backgrounds { @@ -69,7 +70,13 @@ namespace osu.Game.Graphics.Backgrounds /// protected virtual float SpawnRatio => 1; - private float triangleScale = 1; + private readonly BindableFloat triangleScale = new BindableFloat(1f); + + public float TriangleScale + { + get => triangleScale.Value; + set => triangleScale.Value = value; + } /// /// Whether we should drop-off alpha values of triangles more quickly to improve @@ -109,24 +116,7 @@ namespace osu.Game.Graphics.Backgrounds protected override void LoadComplete() { base.LoadComplete(); - addTriangles(true); - } - - public float TriangleScale - { - get => triangleScale; - set - { - float change = value / triangleScale; - triangleScale = value; - - for (int i = 0; i < parts.Count; i++) - { - TriangleParticle newParticle = parts[i]; - newParticle.Scale *= change; - parts[i] = newParticle; - } - } + triangleScale.BindValueChanged(_ => Reset(), true); } protected override void Update() @@ -147,7 +137,7 @@ namespace osu.Game.Graphics.Backgrounds // Since position is relative, the velocity needs to scale inversely with DrawHeight. // Since we will later multiply by the scale of individual triangles we normalize by // dividing by triangleScale. - float movedDistance = -elapsedSeconds * Velocity * base_velocity / (DrawHeight * triangleScale); + float movedDistance = -elapsedSeconds * Velocity * base_velocity / (DrawHeight * TriangleScale); for (int i = 0; i < parts.Count; i++) { @@ -185,7 +175,7 @@ namespace osu.Game.Graphics.Backgrounds // Limited by the maximum size of QuadVertexBuffer for safety. const int max_triangles = ushort.MaxValue / (IRenderer.VERTICES_PER_QUAD + 2); - AimCount = (int)Math.Min(max_triangles, (DrawWidth * DrawHeight * 0.002f / (triangleScale * triangleScale) * SpawnRatio)); + AimCount = (int)Math.Min(max_triangles, DrawWidth * DrawHeight * 0.002f / (TriangleScale * TriangleScale) * SpawnRatio); for (int i = 0; i < AimCount - parts.Count; i++) parts.Add(createTriangle(randomY)); @@ -214,7 +204,7 @@ namespace osu.Game.Graphics.Backgrounds float u1 = 1 - nextRandom(); //uniform(0,1] random floats float u2 = 1 - nextRandom(); float randStdNormal = (float)(Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2)); // random normal(0,1) - float scale = Math.Max(triangleScale * (mean + std_dev * randStdNormal), 0.1f); // random normal(mean,stdDev^2) + float scale = Math.Max(TriangleScale * (mean + std_dev * randStdNormal), 0.1f); // random normal(mean,stdDev^2) return new TriangleParticle { Scale = scale }; } From c7dc6db124653d628860137d40c7c1c419af9133 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Nov 2022 11:32:05 +0300 Subject: [PATCH 0570/2991] Fix incorrect number of added triangles --- osu.Game/Graphics/Backgrounds/Triangles.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index b5e77ec638..433b264468 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -177,7 +177,9 @@ namespace osu.Game.Graphics.Backgrounds AimCount = (int)Math.Min(max_triangles, DrawWidth * DrawHeight * 0.002f / (TriangleScale * TriangleScale) * SpawnRatio); - for (int i = 0; i < AimCount - parts.Count; i++) + int currentCount = parts.Count; + + for (int i = 0; i < AimCount - currentCount; i++) parts.Add(createTriangle(randomY)); } From f27a5f977d91bc57f40a9f0316f0ec70aae07df5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 15 Nov 2022 11:49:53 +0300 Subject: [PATCH 0571/2991] Improve triangles distribution --- osu.Game/Graphics/Backgrounds/Triangles.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index 433b264468..e2434bb665 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -187,13 +187,27 @@ namespace osu.Game.Graphics.Backgrounds { TriangleParticle particle = CreateTriangle(); - particle.Position = new Vector2(nextRandom(), randomY ? nextRandom() : 1); + particle.Position = getRandomPosition(randomY, particle.Scale); particle.ColourShade = nextRandom(); particle.Colour = CreateTriangleShade(particle.ColourShade); return particle; } + private Vector2 getRandomPosition(bool randomY, float scale) + { + float y = 1; + + if (randomY) + { + // since triangles are drawn from the top - allow them to be positioned a bit above the screen + float maxOffset = triangle_size * scale * 0.866f / DrawHeight; + y = Interpolation.ValueAt(nextRandom(), -maxOffset, 1f, 0f, 1f); + } + + return new Vector2(nextRandom(), y); + } + /// /// Creates a triangle particle with a random scale. /// From 233d45e18508eac8e5544534cdb65f773d02be9c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 15 Nov 2022 18:22:27 +0900 Subject: [PATCH 0572/2991] Fix argon swells incorrectly flashing on every hit --- .../Skinning/Argon/ArgonCirclePiece.cs | 8 ++++++-- osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs | 7 +++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs index 22f96da61e..c22c0e9e79 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Taiko.Objects; using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon @@ -81,12 +82,15 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon updateStateTransforms(drawableHitObject, drawableHitObject.State.Value); } - private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state) + private void updateStateTransforms(DrawableHitObject h, ArmedState state) { + if (h.HitObject is not Hit) + return; + switch (state) { case ArmedState.Hit: - using (BeginAbsoluteSequence(drawableHitObject.HitStateUpdateTime)) + using (BeginAbsoluteSequence(h.HitStateUpdateTime)) { flash.FadeTo(0.9f).FadeOut(500, Easing.OutQuint); } diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs index ccde8e6ac9..7ddc413d98 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs @@ -153,12 +153,15 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default updateStateTransforms(drawableHitObject, drawableHitObject.State.Value); } - private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state) + private void updateStateTransforms(DrawableHitObject h, ArmedState state) { + if (h.HitObject is not Hit) + return; + switch (state) { case ArmedState.Hit: - using (BeginAbsoluteSequence(drawableHitObject.HitStateUpdateTime)) + using (BeginAbsoluteSequence(h.HitStateUpdateTime)) flashBox.FadeTo(0.9f).FadeOut(300); break; } From e8d170e7728ac7427dcb483a7969dfcc8ceeddac Mon Sep 17 00:00:00 2001 From: nanashi-1 Date: Tue, 15 Nov 2022 20:55:55 +0800 Subject: [PATCH 0573/2991] disable certain options when no beatmap is selected --- osu.Game/Screens/Select/PlaySongSelect.cs | 12 +++++++++++- osu.Game/Screens/Select/SongSelect.cs | 22 +++++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 94e4215175..9c590114d5 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -14,6 +14,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Scoring; using osu.Game.Screens.Play; using osu.Game.Screens.Ranking; +using osu.Game.Screens.Select.Options; using osu.Game.Users; using osu.Game.Utils; using osuTK.Input; @@ -33,10 +34,12 @@ namespace osu.Game.Screens.Select private PlayBeatmapDetailArea playBeatmapDetailArea = null!; + protected BeatmapOptionsButton? editOptionButton; + [BackgroundDependencyLoader] private void load(OsuColour colours) { - BeatmapOptions.AddButton(@"Edit", @"beatmap", FontAwesome.Solid.PencilAlt, colours.Yellow, () => Edit()); + editOptionButton = BeatmapOptions.AddButton(@"Edit", @"beatmap", FontAwesome.Solid.PencilAlt, colours.Yellow, () => Edit()); } protected void PresentScore(ScoreInfo score) => @@ -142,5 +145,12 @@ namespace osu.Game.Screens.Select playerLoader = null; } } + + protected override void OnBeatmapOptionsButtonDisabledChanged(bool disabled) + { + base.OnBeatmapOptionsButtonDisabledChanged(disabled); + + if (editOptionButton != null) editOptionButton.Disabled = disabled; + } } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 1add51e725..72645c23be 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -116,6 +116,10 @@ namespace osu.Game.Screens.Select private double audioFeedbackLastPlaybackTime; + protected BeatmapOptionsButton deleteOptionButton; + + protected BeatmapOptionsButton clearOptionButton; + [CanBeNull] private IDisposable modSelectOverlayRegistration; @@ -285,9 +289,9 @@ namespace osu.Game.Screens.Select Footer.AddButton(button, overlay); BeatmapOptions.AddButton(@"Manage", @"collections", FontAwesome.Solid.Book, colours.Green, () => manageCollectionsDialog?.Show()); - BeatmapOptions.AddButton(@"Delete", @"all difficulties", FontAwesome.Solid.Trash, colours.Pink, () => delete(Beatmap.Value.BeatmapSetInfo)); BeatmapOptions.AddButton(@"Remove", @"from unplayed", FontAwesome.Regular.TimesCircle, colours.Purple, null); - BeatmapOptions.AddButton(@"Clear", @"local scores", FontAwesome.Solid.Eraser, colours.Purple, () => clearScores(Beatmap.Value.BeatmapInfo)); + deleteOptionButton = BeatmapOptions.AddButton(@"Delete", @"all difficulties", FontAwesome.Solid.Trash, colours.Pink, () => delete(Beatmap.Value.BeatmapSetInfo)); + clearOptionButton = BeatmapOptions.AddButton(@"Clear", @"local scores", FontAwesome.Solid.Eraser, colours.Purple, () => clearScores(Beatmap.Value.BeatmapInfo)); } sampleChangeDifficulty = audio.Samples.Get(@"SongSelect/select-difficulty"); @@ -412,7 +416,13 @@ namespace osu.Game.Screens.Select private void updateCarouselSelection(ValueChangedEvent e = null) { var beatmap = e?.NewValue ?? Beatmap.Value; - if (beatmap is DummyWorkingBeatmap || !this.IsCurrentScreen()) return; + + if (beatmap is DummyWorkingBeatmap || !this.IsCurrentScreen()) + { + OnBeatmapOptionsButtonDisabledChanged(true); + return; + } + OnBeatmapOptionsButtonDisabledChanged(false); Logger.Log($"Song select working beatmap updated to {beatmap}"); @@ -647,6 +657,12 @@ namespace osu.Game.Screens.Select return false; } + protected virtual void OnBeatmapOptionsButtonDisabledChanged(bool disabled) + { + deleteOptionButton.Disabled = disabled; + clearOptionButton.Disabled = disabled; + } + private void playExitingTransition() { ModSelect.Hide(); From 1186ed3e32acad13312db54a5a18ee0cf56257c0 Mon Sep 17 00:00:00 2001 From: nanashi-1 Date: Tue, 15 Nov 2022 20:56:18 +0800 Subject: [PATCH 0574/2991] add disable --- .../Select/Options/BeatmapOptionsButton.cs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs index 69800c4e86..7d9792d950 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs @@ -31,6 +31,31 @@ namespace osu.Game.Screens.Select.Options private readonly OsuSpriteText secondLine; private readonly Container box; + private readonly float disabledAlpha = 0.5f; + + private bool disabled; + + public bool Disabled + { + get => disabled; + set + { + disabled = value; + + if (disabled) + { + firstLine.Alpha = disabledAlpha; + secondLine.Alpha = disabledAlpha; + iconText.Alpha = disabledAlpha; + return; + } + + firstLine.Alpha = 1; + secondLine.Alpha = 1; + iconText.Alpha = 1; + } + } + public Color4 ButtonColour { get => background.Colour; @@ -57,18 +82,24 @@ namespace osu.Game.Screens.Select.Options protected override bool OnMouseDown(MouseDownEvent e) { + if (disabled) return true; + flash.FadeTo(0.1f, 1000, Easing.OutQuint); return base.OnMouseDown(e); } protected override void OnMouseUp(MouseUpEvent e) { + if (disabled) return; + flash.FadeTo(0, 1000, Easing.OutQuint); base.OnMouseUp(e); } protected override bool OnClick(ClickEvent e) { + if (disabled) return true; + flash.ClearTransforms(); flash.Alpha = 0.9f; flash.FadeOut(800, Easing.OutExpo); From 5973bb1956ae05fc8bb73921feb84acb1d3119b7 Mon Sep 17 00:00:00 2001 From: nanashi-1 Date: Tue, 15 Nov 2022 20:57:31 +0800 Subject: [PATCH 0575/2991] AddButton now returns the button --- osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs index 8785dac0aa..139d9e60b5 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs @@ -66,7 +66,7 @@ namespace osu.Game.Screens.Select.Options /// Colour of the button. /// Icon of the button. /// Binding the button does. - public void AddButton(LocalisableString firstLine, string secondLine, IconUsage icon, Color4 colour, Action action) + public BeatmapOptionsButton AddButton(LocalisableString firstLine, string secondLine, IconUsage icon, Color4 colour, Action action) { var button = new BeatmapOptionsButton { @@ -82,6 +82,8 @@ namespace osu.Game.Screens.Select.Options }; buttonsContainer.Add(button); + + return button; } protected override void PopIn() From 7aec5ca1e8586b2d14e4deac47ceb79ff2a3a574 Mon Sep 17 00:00:00 2001 From: nanashi-1 Date: Tue, 15 Nov 2022 20:57:42 +0800 Subject: [PATCH 0576/2991] visual tests --- .../SongSelect/TestScenePlaySongSelect.cs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 63532fdba8..db49afe79d 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -37,6 +37,7 @@ using osu.Game.Screens.Select; using osu.Game.Screens.Select.Carousel; using osu.Game.Screens.Select.Filter; using osu.Game.Tests.Resources; +using osu.Game.Screens.Select.Options; using osuTK.Input; namespace osu.Game.Tests.Visual.SongSelect @@ -1055,6 +1056,24 @@ namespace osu.Game.Tests.Visual.SongSelect AddUntilStep("mod overlay hidden", () => songSelect!.ModSelect.State.Value == Visibility.Hidden); } + [Test] + public void TestBeatmapOptionsButtonDisable() + { + createSongSelect(); + + addRulesetImportStep(0); + + AddAssert("delete option enabled", () => songSelect!.DeleteOptionButton.Disabled == false); + AddAssert("clear option enabled", () => songSelect!.ClearOptionButton.Disabled == false); + AddAssert("edit option enabled", () => songSelect!.EditOptionButton?.Disabled == false); + + AddStep("delete all beatmaps", () => manager.Delete()); + + AddAssert("delete option disabled", () => songSelect!.DeleteOptionButton.Disabled == true); + AddAssert("clear option disabled", () => songSelect!.ClearOptionButton.Disabled == true); + AddAssert("edit option disabled", () => songSelect!.EditOptionButton?.Disabled == true); + } + private void waitForInitialSelection() { AddUntilStep("wait for initial selection", () => !Beatmap.IsDefault); @@ -1142,6 +1161,12 @@ namespace osu.Game.Tests.Visual.SongSelect public new BeatmapCarousel Carousel => base.Carousel; public new ModSelectOverlay ModSelect => base.ModSelect; + public BeatmapOptionsButton DeleteOptionButton => base.deleteOptionButton; + + public BeatmapOptionsButton ClearOptionButton => base.clearOptionButton; + + public BeatmapOptionsButton? EditOptionButton => base.editOptionButton; + public new void PresentScore(ScoreInfo score) => base.PresentScore(score); protected override bool OnStart() From 52ecd894db8ca4b44758c5a28ac6ccf2d54ee760 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 15 Nov 2022 22:20:08 +0900 Subject: [PATCH 0577/2991] Move equilateral triangle ratio to constant --- osu.Game/Graphics/Backgrounds/Triangles.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index e2434bb665..09d137011c 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -26,6 +26,11 @@ namespace osu.Game.Graphics.Backgrounds private const float triangle_size = 100; private const float base_velocity = 50; + /// + /// sqrt(3) / 2 + /// + private const float equilateral_triangle_ratio = 0.866f; + /// /// How many screen-space pixels are smoothed over. /// Same behavior as Sprite's EdgeSmoothness. @@ -149,7 +154,7 @@ namespace osu.Game.Graphics.Backgrounds parts[i] = newParticle; - float bottomPos = parts[i].Position.Y + triangle_size * parts[i].Scale * 0.866f / DrawHeight; + float bottomPos = parts[i].Position.Y + triangle_size * parts[i].Scale * equilateral_triangle_ratio / DrawHeight; if (bottomPos < 0) parts.RemoveAt(i); } @@ -201,7 +206,7 @@ namespace osu.Game.Graphics.Backgrounds if (randomY) { // since triangles are drawn from the top - allow them to be positioned a bit above the screen - float maxOffset = triangle_size * scale * 0.866f / DrawHeight; + float maxOffset = triangle_size * scale * equilateral_triangle_ratio / DrawHeight; y = Interpolation.ValueAt(nextRandom(), -maxOffset, 1f, 0f, 1f); } @@ -290,7 +295,7 @@ namespace osu.Game.Graphics.Backgrounds foreach (TriangleParticle particle in parts) { - var offset = triangle_size * new Vector2(particle.Scale * 0.5f, particle.Scale * 0.866f); + var offset = triangle_size * new Vector2(particle.Scale * 0.5f, particle.Scale * equilateral_triangle_ratio); var triangle = new Triangle( Vector2Extensions.Transform(particle.Position * size, DrawInfo.Matrix), From 70f50c1319f13a63bcbccc2b2e50d13b4d59d174 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 15 Nov 2022 22:46:20 +0900 Subject: [PATCH 0578/2991] Add test scene covering taiko swell --- .../Skinning/TestSceneDrawableSwell.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableSwell.cs diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableSwell.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableSwell.cs new file mode 100644 index 0000000000..b8c0f6f11e --- /dev/null +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableSwell.cs @@ -0,0 +1,39 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.Objects.Drawables; + +namespace osu.Game.Rulesets.Taiko.Tests.Skinning +{ + [TestFixture] + public class TestSceneDrawableSwell : TaikoSkinnableTestScene + { + [Test] + public void TestHits() + { + AddStep("Centre hit", () => SetContents(_ => new DrawableSwell(createHitAtCurrentTime()) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + })); + } + + private Swell createHitAtCurrentTime() + { + var hit = new Swell + { + StartTime = Time.Current + 3000, + EndTime = Time.Current + 6000, + }; + + hit.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + + return hit; + } + } +} From 9101ad0cbd399f4faa7957792e5efe5d31811932 Mon Sep 17 00:00:00 2001 From: nanashi-1 Date: Wed, 16 Nov 2022 09:42:40 +0800 Subject: [PATCH 0579/2991] fixed naming --- .../Visual/SongSelect/TestScenePlaySongSelect.cs | 6 +++--- osu.Game/Screens/Select/PlaySongSelect.cs | 6 +++--- osu.Game/Screens/Select/SongSelect.cs | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index db49afe79d..1892eaaf3b 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -1161,11 +1161,11 @@ namespace osu.Game.Tests.Visual.SongSelect public new BeatmapCarousel Carousel => base.Carousel; public new ModSelectOverlay ModSelect => base.ModSelect; - public BeatmapOptionsButton DeleteOptionButton => base.deleteOptionButton; + public new BeatmapOptionsButton DeleteOptionButton => base.DeleteOptionButton; - public BeatmapOptionsButton ClearOptionButton => base.clearOptionButton; + public new BeatmapOptionsButton ClearOptionButton => base.ClearOptionButton; - public BeatmapOptionsButton? EditOptionButton => base.editOptionButton; + public new BeatmapOptionsButton? EditOptionButton => base.EditOptionButton; public new void PresentScore(ScoreInfo score) => base.PresentScore(score); diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 9c590114d5..e61c0c4c59 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -34,12 +34,12 @@ namespace osu.Game.Screens.Select private PlayBeatmapDetailArea playBeatmapDetailArea = null!; - protected BeatmapOptionsButton? editOptionButton; + protected BeatmapOptionsButton? EditOptionButton; [BackgroundDependencyLoader] private void load(OsuColour colours) { - editOptionButton = BeatmapOptions.AddButton(@"Edit", @"beatmap", FontAwesome.Solid.PencilAlt, colours.Yellow, () => Edit()); + EditOptionButton = BeatmapOptions.AddButton(@"Edit", @"beatmap", FontAwesome.Solid.PencilAlt, colours.Yellow, () => Edit()); } protected void PresentScore(ScoreInfo score) => @@ -150,7 +150,7 @@ namespace osu.Game.Screens.Select { base.OnBeatmapOptionsButtonDisabledChanged(disabled); - if (editOptionButton != null) editOptionButton.Disabled = disabled; + if (EditOptionButton != null) EditOptionButton.Disabled = disabled; } } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 72645c23be..c91912ec85 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -116,9 +116,9 @@ namespace osu.Game.Screens.Select private double audioFeedbackLastPlaybackTime; - protected BeatmapOptionsButton deleteOptionButton; + protected BeatmapOptionsButton DeleteOptionButton; - protected BeatmapOptionsButton clearOptionButton; + protected BeatmapOptionsButton ClearOptionButton; [CanBeNull] private IDisposable modSelectOverlayRegistration; @@ -290,8 +290,8 @@ namespace osu.Game.Screens.Select BeatmapOptions.AddButton(@"Manage", @"collections", FontAwesome.Solid.Book, colours.Green, () => manageCollectionsDialog?.Show()); BeatmapOptions.AddButton(@"Remove", @"from unplayed", FontAwesome.Regular.TimesCircle, colours.Purple, null); - deleteOptionButton = BeatmapOptions.AddButton(@"Delete", @"all difficulties", FontAwesome.Solid.Trash, colours.Pink, () => delete(Beatmap.Value.BeatmapSetInfo)); - clearOptionButton = BeatmapOptions.AddButton(@"Clear", @"local scores", FontAwesome.Solid.Eraser, colours.Purple, () => clearScores(Beatmap.Value.BeatmapInfo)); + DeleteOptionButton = BeatmapOptions.AddButton(@"Delete", @"all difficulties", FontAwesome.Solid.Trash, colours.Pink, () => delete(Beatmap.Value.BeatmapSetInfo)); + ClearOptionButton = BeatmapOptions.AddButton(@"Clear", @"local scores", FontAwesome.Solid.Eraser, colours.Purple, () => clearScores(Beatmap.Value.BeatmapInfo)); } sampleChangeDifficulty = audio.Samples.Get(@"SongSelect/select-difficulty"); @@ -659,8 +659,8 @@ namespace osu.Game.Screens.Select protected virtual void OnBeatmapOptionsButtonDisabledChanged(bool disabled) { - deleteOptionButton.Disabled = disabled; - clearOptionButton.Disabled = disabled; + DeleteOptionButton.Disabled = disabled; + ClearOptionButton.Disabled = disabled; } private void playExitingTransition() From 46c7451ede328a01cb6465ad144f7545cd524f24 Mon Sep 17 00:00:00 2001 From: nanashi-1 Date: Wed, 16 Nov 2022 09:57:23 +0800 Subject: [PATCH 0580/2991] remove redundant code --- .../Visual/SongSelect/TestScenePlaySongSelect.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 1892eaaf3b..51c4c5e661 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -1063,14 +1063,14 @@ namespace osu.Game.Tests.Visual.SongSelect addRulesetImportStep(0); - AddAssert("delete option enabled", () => songSelect!.DeleteOptionButton.Disabled == false); - AddAssert("clear option enabled", () => songSelect!.ClearOptionButton.Disabled == false); + AddAssert("delete option enabled", () => !songSelect!.DeleteOptionButton.Disabled); + AddAssert("clear option enabled", () => !songSelect!.ClearOptionButton.Disabled); AddAssert("edit option enabled", () => songSelect!.EditOptionButton?.Disabled == false); AddStep("delete all beatmaps", () => manager.Delete()); - AddAssert("delete option disabled", () => songSelect!.DeleteOptionButton.Disabled == true); - AddAssert("clear option disabled", () => songSelect!.ClearOptionButton.Disabled == true); + AddAssert("delete option disabled", () => songSelect!.DeleteOptionButton.Disabled); + AddAssert("clear option disabled", () => songSelect!.ClearOptionButton.Disabled); AddAssert("edit option disabled", () => songSelect!.EditOptionButton?.Disabled == true); } From 1fb8357e93e92cf08d17604f3cbba26a2a8167ff Mon Sep 17 00:00:00 2001 From: nanashi-1 Date: Wed, 16 Nov 2022 09:58:32 +0800 Subject: [PATCH 0581/2991] change `disabledAlpha` from `readonly` to `const` --- osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs index 7d9792d950..1fc5b2bc74 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs @@ -31,7 +31,7 @@ namespace osu.Game.Screens.Select.Options private readonly OsuSpriteText secondLine; private readonly Container box; - private readonly float disabledAlpha = 0.5f; + private const float disabledAlpha = 0.5f; private bool disabled; From 55edd6c9078b0d17a1b68de387f3f4727eb120e7 Mon Sep 17 00:00:00 2001 From: nanashi-1 Date: Wed, 16 Nov 2022 09:58:49 +0800 Subject: [PATCH 0582/2991] add space --- osu.Game/Screens/Select/SongSelect.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index c91912ec85..0341a9bb07 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -422,6 +422,7 @@ namespace osu.Game.Screens.Select OnBeatmapOptionsButtonDisabledChanged(true); return; } + OnBeatmapOptionsButtonDisabledChanged(false); Logger.Log($"Song select working beatmap updated to {beatmap}"); From 5d8d8ffce506d469ca05ea91ccdad4bffb2ff649 Mon Sep 17 00:00:00 2001 From: nanashi-1 Date: Wed, 16 Nov 2022 10:09:51 +0800 Subject: [PATCH 0583/2991] fix naming --- osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs index 1fc5b2bc74..73bc68f6b0 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs @@ -31,7 +31,7 @@ namespace osu.Game.Screens.Select.Options private readonly OsuSpriteText secondLine; private readonly Container box; - private const float disabledAlpha = 0.5f; + private const float disabled_alpha = 0.5f; private bool disabled; @@ -44,9 +44,9 @@ namespace osu.Game.Screens.Select.Options if (disabled) { - firstLine.Alpha = disabledAlpha; - secondLine.Alpha = disabledAlpha; - iconText.Alpha = disabledAlpha; + firstLine.Alpha = disabled_alpha; + secondLine.Alpha = disabled_alpha; + iconText.Alpha = disabled_alpha; return; } From bb762d813150b7d0a89d5e851a719b574f2bae1f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Nov 2022 15:45:26 +0900 Subject: [PATCH 0584/2991] Fix "reset to full area" button not always working correctly --- .../Overlays/Settings/Sections/Input/TabletSettings.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs index 59c7ff04a2..de52a1f938 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs @@ -111,9 +111,10 @@ namespace osu.Game.Overlays.Settings.Sections.Input if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows || RuntimeInfo.OS == RuntimeInfo.Platform.Linux) { t.NewLine(); - var formattedSource = MessageFormatter.FormatText(localisation.GetLocalisedBindableString(TabletSettingsStrings.NoTabletDetectedDescription(RuntimeInfo.OS == RuntimeInfo.Platform.Windows - ? @"https://opentabletdriver.net/Wiki/FAQ/Windows" - : @"https://opentabletdriver.net/Wiki/FAQ/Linux")).Value); + var formattedSource = MessageFormatter.FormatText(localisation.GetLocalisedBindableString(TabletSettingsStrings.NoTabletDetectedDescription( + RuntimeInfo.OS == RuntimeInfo.Platform.Windows + ? @"https://opentabletdriver.net/Wiki/FAQ/Windows" + : @"https://opentabletdriver.net/Wiki/FAQ/Linux")).Value); t.AddLinks(formattedSource.Text, formattedSource.Links); } }), @@ -274,6 +275,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input sizeY.Default = sizeY.MaxValue = tab.Size.Y; areaSize.Default = new Vector2(sizeX.Default, sizeY.Default); + areaOffset.Default = new Vector2(offsetX.Default, offsetY.Default); }), true); } From 45f47cce77358ee53b5478e2508eef2fc6287a3c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Nov 2022 16:13:52 +0900 Subject: [PATCH 0585/2991] Add basic osu!taiko "argon" swell visual --- .../Skinning/Argon/ArgonSwellCirclePiece.cs | 34 +++++++++++++++++++ .../Argon/TaikoArgonSkinTransformer.cs | 3 ++ 2 files changed, 37 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonSwellCirclePiece.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonSwellCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonSwellCirclePiece.cs new file mode 100644 index 0000000000..82a6e34128 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonSwellCirclePiece.cs @@ -0,0 +1,34 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Sprites; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Taiko.Skinning.Argon +{ + public class ArgonSwellCirclePiece : ArgonCirclePiece + { + [BackgroundDependencyLoader] + private void load() + { + AccentColour = ColourInfo.GradientVertical( + new Color4(240, 201, 0, 255), + new Color4(167, 139, 0, 255) + ); + + AddInternal(new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Icon = FontAwesome.Solid.Asterisk, + Size = new Vector2(ICON_SIZE), + Scale = new Vector2(0.8f, 1) + }); + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index 6d1087793d..a5d091a1c8 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -60,6 +60,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon case TaikoSkinComponents.TaikoExplosionMiss: case TaikoSkinComponents.TaikoExplosionOk: return new ArgonHitExplosion(taikoComponent.Component); + + case TaikoSkinComponents.Swell: + return new ArgonSwellCirclePiece(); } break; From ee6fffec5f08bb6d34cae5e7fefb7184eae4132a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Nov 2022 17:54:49 +0900 Subject: [PATCH 0586/2991] Fix combo colour normalisation setting not applying to editor test play --- .../Screens/Edit/GameplayTest/EditorPlayer.cs | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs b/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs index 94975b6b5e..7fc62b3c14 100644 --- a/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs +++ b/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs @@ -1,23 +1,25 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Screens; using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Overlays; using osu.Game.Screens.Play; namespace osu.Game.Screens.Edit.GameplayTest { - public class EditorPlayer : Player + public class EditorPlayer : Player, IGameplaySettings { private readonly Editor editor; private readonly EditorState editorState; [Resolved] - private MusicController musicController { get; set; } + private MusicController musicController { get; set; } = null!; + + private OsuConfigManager config = null!; public EditorPlayer(Editor editor) : base(new PlayerConfiguration { ShowResults = false }) @@ -26,6 +28,14 @@ namespace osu.Game.Screens.Edit.GameplayTest editorState = editor.GetState(); } + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) + { + // needs to be populated before BDL to work correctly. + config = parent.Get(); + + return base.CreateChildDependencies(parent); + } + protected override GameplayClockContainer CreateGameplayClockContainer(WorkingBeatmap beatmap, double gameplayStart) { var masterGameplayClockContainer = new MasterGameplayClockContainer(beatmap, gameplayStart); @@ -74,5 +84,9 @@ namespace osu.Game.Screens.Edit.GameplayTest editor.RestoreState(editorState); return base.OnExiting(e); } + + // Editor overrides but we actually want to use game-wide settings here. + public IBindable ComboColourNormalisationAmount => ((IGameplaySettings)config).ComboColourNormalisationAmount; + public IBindable PositionalHitsoundsLevel => ((IGameplaySettings)config).PositionalHitsoundsLevel; } } From bda32d71bf3f2f9467875a5d0a06574bc713153d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 16 Nov 2022 14:53:55 +0300 Subject: [PATCH 0587/2991] Change test scene name --- .../TestSceneTrianglesV2Background.cs | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs diff --git a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs new file mode 100644 index 0000000000..59922377b0 --- /dev/null +++ b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs @@ -0,0 +1,43 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osuTK; +using osuTK.Graphics; +using osu.Game.Graphics.Backgrounds; + +namespace osu.Game.Tests.Visual.Background +{ + public class TestSceneTrianglesV2Background : OsuTestScene + { + public TestSceneTrianglesV2Background() + { + AddRange(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Gray + }, + new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(200), + Masking = true, + CornerRadius = 40, + Child = new TrianglesV2 + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + ColourTop = Color4.Red, + ColourBottom = Color4.Orange + } + } + }); + } + } +} From 109aa37dd873f5dc56872c13208accc0a490eb93 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 16 Nov 2022 15:02:09 +0300 Subject: [PATCH 0588/2991] Apply fixes from original Triangles --- osu.Game/Graphics/Backgrounds/TrianglesV2.cs | 57 +++++++++++--------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs index 89ec7d2ad5..01e4a39431 100644 --- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs +++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs @@ -27,6 +27,11 @@ namespace osu.Game.Graphics.Backgrounds private const float base_velocity = 50; private const int texture_height = 128; + /// + /// sqrt(3) / 2 + /// + private const float equilateral_triangle_ratio = 0.866f; + private readonly Bindable colourTop = new Bindable(Color4.White); private readonly Bindable colourBottom = new Bindable(Color4.Black); @@ -52,7 +57,13 @@ namespace osu.Game.Graphics.Backgrounds /// protected virtual float SpawnRatio => 1; - private float triangleScale = 1; + private readonly BindableFloat triangleScale = new BindableFloat(1f); + + public float TriangleScale + { + get => triangleScale.Value; + set => triangleScale.Value = value; + } /// /// The relative velocity of the triangles. Default is 1. @@ -91,7 +102,7 @@ namespace osu.Game.Graphics.Backgrounds colourTop.BindValueChanged(_ => updateTexture()); colourBottom.BindValueChanged(_ => updateTexture(), true); - addTriangles(true); + triangleScale.BindValueChanged(_ => Reset(), true); } private void updateTexture() @@ -116,23 +127,6 @@ namespace osu.Game.Graphics.Backgrounds Invalidate(Invalidation.DrawNode); } - public float TriangleScale - { - get => triangleScale; - set - { - float change = value / triangleScale; - triangleScale = value; - - for (int i = 0; i < parts.Count; i++) - { - TriangleParticle newParticle = parts[i]; - newParticle.Scale *= change; - parts[i] = newParticle; - } - } - } - protected override void Update() { base.Update(); @@ -146,7 +140,7 @@ namespace osu.Game.Graphics.Backgrounds // Since position is relative, the velocity needs to scale inversely with DrawHeight. // Since we will later multiply by the scale of individual triangles we normalize by // dividing by triangleScale. - float movedDistance = -elapsedSeconds * Velocity * base_velocity / (DrawHeight * triangleScale); + float movedDistance = -elapsedSeconds * Velocity * base_velocity / (DrawHeight * TriangleScale); for (int i = 0; i < parts.Count; i++) { @@ -157,7 +151,7 @@ namespace osu.Game.Graphics.Backgrounds parts[i] = newParticle; - float bottomPos = parts[i].Position.Y + triangle_size * parts[i].Scale * 0.866f / DrawHeight; + float bottomPos = parts[i].Position.Y + triangle_size * parts[i].Scale * equilateral_triangle_ratio / DrawHeight; if (bottomPos < 0) parts.RemoveAt(i); } @@ -183,9 +177,11 @@ namespace osu.Game.Graphics.Backgrounds // Limited by the maximum size of QuadVertexBuffer for safety. const int max_triangles = ushort.MaxValue / (IRenderer.VERTICES_PER_QUAD + 2); - AimCount = (int)Math.Min(max_triangles, DrawWidth * DrawHeight * 0.002f / (triangleScale * triangleScale) * SpawnRatio); + AimCount = (int)Math.Min(max_triangles, DrawWidth * DrawHeight * 0.002f / (TriangleScale * TriangleScale) * SpawnRatio); - for (int i = 0; i < AimCount - parts.Count; i++) + int currentCount = parts.Count; + + for (int i = 0; i < AimCount - currentCount; i++) parts.Add(createTriangle(randomY)); } @@ -193,7 +189,16 @@ namespace osu.Game.Graphics.Backgrounds { TriangleParticle particle = CreateTriangle(); - particle.Position = new Vector2(nextRandom(), randomY ? nextRandom() : 1); + float y = 1; + + if (randomY) + { + // since triangles are drawn from the top - allow them to be positioned a bit above the screen + float maxOffset = triangle_size * particle.Scale * equilateral_triangle_ratio / DrawHeight; + y = Interpolation.ValueAt(nextRandom(), -maxOffset, 1f, 0f, 1f); + } + + particle.Position = new Vector2(nextRandom(), y); return particle; } @@ -210,7 +215,7 @@ namespace osu.Game.Graphics.Backgrounds float u1 = 1 - nextRandom(); //uniform(0,1] random floats float u2 = 1 - nextRandom(); float randStdNormal = (float)(Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2)); // random normal(0,1) - float scale = Math.Max(triangleScale * (mean + std_dev * randStdNormal), 0.1f); // random normal(mean,stdDev^2) + float scale = Math.Max(TriangleScale * (mean + std_dev * randStdNormal), 0.1f); // random normal(mean,stdDev^2) return new TriangleParticle { Scale = scale }; } @@ -262,7 +267,7 @@ namespace osu.Game.Graphics.Backgrounds foreach (TriangleParticle particle in parts) { - var offset = triangle_size * new Vector2(particle.Scale * 0.5f, particle.Scale * 0.866f); + var offset = triangle_size * new Vector2(particle.Scale * 0.5f, particle.Scale * equilateral_triangle_ratio); Vector2 topLeft = particle.Position * size + new Vector2(-offset.X, 0f); Vector2 topRight = particle.Position * size + new Vector2(offset.X, 0); From cc4f05f3d3ce98a33f3c51a2779d42930f4cc480 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 16 Nov 2022 15:12:57 +0300 Subject: [PATCH 0589/2991] Replace Scale with SpeedMultiplier --- osu.Game/Graphics/Backgrounds/TrianglesV2.cs | 35 +++++++------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs index 01e4a39431..da31c6112b 100644 --- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs +++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs @@ -57,14 +57,6 @@ namespace osu.Game.Graphics.Backgrounds /// protected virtual float SpawnRatio => 1; - private readonly BindableFloat triangleScale = new BindableFloat(1f); - - public float TriangleScale - { - get => triangleScale.Value; - set => triangleScale.Value = value; - } - /// /// The relative velocity of the triangles. Default is 1. /// @@ -102,7 +94,7 @@ namespace osu.Game.Graphics.Backgrounds colourTop.BindValueChanged(_ => updateTexture()); colourBottom.BindValueChanged(_ => updateTexture(), true); - triangleScale.BindValueChanged(_ => Reset(), true); + addTriangles(true); } private void updateTexture() @@ -138,20 +130,17 @@ namespace osu.Game.Graphics.Backgrounds float elapsedSeconds = (float)Time.Elapsed / 1000; // Since position is relative, the velocity needs to scale inversely with DrawHeight. - // Since we will later multiply by the scale of individual triangles we normalize by - // dividing by triangleScale. - float movedDistance = -elapsedSeconds * Velocity * base_velocity / (DrawHeight * TriangleScale); + float movedDistance = -elapsedSeconds * Velocity * base_velocity / DrawHeight; for (int i = 0; i < parts.Count; i++) { TriangleParticle newParticle = parts[i]; - // Scale moved distance by the size of the triangle. Smaller triangles should move more slowly. - newParticle.Position.Y += Math.Max(0.5f, parts[i].Scale) * movedDistance; + newParticle.Position.Y += Math.Max(0.5f, parts[i].SpeedMultiplier) * movedDistance; parts[i] = newParticle; - float bottomPos = parts[i].Position.Y + triangle_size * parts[i].Scale * equilateral_triangle_ratio / DrawHeight; + float bottomPos = parts[i].Position.Y + triangle_size * equilateral_triangle_ratio / DrawHeight; if (bottomPos < 0) parts.RemoveAt(i); } @@ -177,7 +166,7 @@ namespace osu.Game.Graphics.Backgrounds // Limited by the maximum size of QuadVertexBuffer for safety. const int max_triangles = ushort.MaxValue / (IRenderer.VERTICES_PER_QUAD + 2); - AimCount = (int)Math.Min(max_triangles, DrawWidth * DrawHeight * 0.002f / (TriangleScale * TriangleScale) * SpawnRatio); + AimCount = (int)Math.Min(max_triangles, DrawWidth * DrawHeight * 0.001f * SpawnRatio); int currentCount = parts.Count; @@ -194,7 +183,7 @@ namespace osu.Game.Graphics.Backgrounds if (randomY) { // since triangles are drawn from the top - allow them to be positioned a bit above the screen - float maxOffset = triangle_size * particle.Scale * equilateral_triangle_ratio / DrawHeight; + float maxOffset = triangle_size * equilateral_triangle_ratio / DrawHeight; y = Interpolation.ValueAt(nextRandom(), -maxOffset, 1f, 0f, 1f); } @@ -204,7 +193,7 @@ namespace osu.Game.Graphics.Backgrounds } /// - /// Creates a triangle particle with a random scale. + /// Creates a triangle particle with a random speed multiplier. /// /// The triangle particle. protected virtual TriangleParticle CreateTriangle() @@ -215,9 +204,9 @@ namespace osu.Game.Graphics.Backgrounds float u1 = 1 - nextRandom(); //uniform(0,1] random floats float u2 = 1 - nextRandom(); float randStdNormal = (float)(Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2)); // random normal(0,1) - float scale = Math.Max(TriangleScale * (mean + std_dev * randStdNormal), 0.1f); // random normal(mean,stdDev^2) + float speedMultiplier = Math.Max(mean + std_dev * randStdNormal, 0.1f); // random normal(mean,stdDev^2) - return new TriangleParticle { Scale = scale }; + return new TriangleParticle { SpeedMultiplier = speedMultiplier }; } private float nextRandom() => (float)(stableRandom?.NextDouble() ?? RNG.NextSingle()); @@ -267,7 +256,7 @@ namespace osu.Game.Graphics.Backgrounds foreach (TriangleParticle particle in parts) { - var offset = triangle_size * new Vector2(particle.Scale * 0.5f, particle.Scale * equilateral_triangle_ratio); + var offset = triangle_size * new Vector2(0.5f, equilateral_triangle_ratio); Vector2 topLeft = particle.Position * size + new Vector2(-offset.X, 0f); Vector2 topRight = particle.Position * size + new Vector2(offset.X, 0); @@ -310,9 +299,9 @@ namespace osu.Game.Graphics.Backgrounds public Vector2 Position; /// - /// The scale of the triangle. + /// The speed multiplier of the triangle. /// - public float Scale; + public float SpeedMultiplier; } } } From 13cf3fc40c7940b7cbbb2a759eff206bed97349f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 16 Nov 2022 15:17:50 +0300 Subject: [PATCH 0590/2991] Make SpawnRatio public --- .../Background/TestSceneTrianglesV2Background.cs | 13 +++++++++++-- osu.Game/Graphics/Backgrounds/TrianglesV2.cs | 12 +++++++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs index 59922377b0..f6207c46a5 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs @@ -12,6 +12,8 @@ namespace osu.Game.Tests.Visual.Background { public class TestSceneTrianglesV2Background : OsuTestScene { + private readonly TrianglesV2 triangles; + public TestSceneTrianglesV2Background() { AddRange(new Drawable[] @@ -25,10 +27,10 @@ namespace osu.Game.Tests.Visual.Background { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(200), + Size = new Vector2(500), Masking = true, CornerRadius = 40, - Child = new TrianglesV2 + Child = triangles = new TrianglesV2 { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -39,5 +41,12 @@ namespace osu.Game.Tests.Visual.Background } }); } + + protected override void LoadComplete() + { + base.LoadComplete(); + + AddSliderStep("Spawn ratio", 0f, 2f, 1f, s => triangles.SpawnRatio = s); + } } } diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs index da31c6112b..0c4bf59732 100644 --- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs +++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs @@ -52,10 +52,16 @@ namespace osu.Game.Graphics.Backgrounds /// protected virtual bool CreateNewTriangles => true; + private readonly BindableFloat spawnRatio = new BindableFloat(1f); + /// /// The amount of triangles we want compared to the default distribution. /// - protected virtual float SpawnRatio => 1; + public float SpawnRatio + { + get => spawnRatio.Value; + set => spawnRatio.Value = value; + } /// /// The relative velocity of the triangles. Default is 1. @@ -94,7 +100,7 @@ namespace osu.Game.Graphics.Backgrounds colourTop.BindValueChanged(_ => updateTexture()); colourBottom.BindValueChanged(_ => updateTexture(), true); - addTriangles(true); + spawnRatio.BindValueChanged(_ => Reset(), true); } private void updateTexture() @@ -166,7 +172,7 @@ namespace osu.Game.Graphics.Backgrounds // Limited by the maximum size of QuadVertexBuffer for safety. const int max_triangles = ushort.MaxValue / (IRenderer.VERTICES_PER_QUAD + 2); - AimCount = (int)Math.Min(max_triangles, DrawWidth * DrawHeight * 0.001f * SpawnRatio); + AimCount = (int)Math.Min(max_triangles, DrawWidth * DrawHeight * 0.0005f * SpawnRatio); int currentCount = parts.Count; From e1a21e0cf96df3c7deb4b4fbaf8636ef2ad7611d Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 17 Nov 2022 00:01:29 +0900 Subject: [PATCH 0591/2991] create a task to export to avoid block main thread Code quality and remove some #nullable disable --- osu.Game.Tests/Skins/IO/ImportSkinTest.cs | 7 +-- osu.Game/Database/LegacyBeatmapExporter.cs | 7 ++- osu.Game/Database/LegacyExporter.cs | 54 ++++++++++++++++--- osu.Game/Database/LegacyScoreExporter.cs | 11 ++-- osu.Game/Database/LegacyScoreImporter.cs | 2 - osu.Game/Database/LegacySkinExporter.cs | 7 ++- osu.Game/Database/LegacySkinImporter.cs | 2 - osu.Game/Database/RealmAccess.cs | 5 -- .../Online/Leaderboards/LeaderboardScore.cs | 5 +- .../Overlays/Settings/Sections/SkinSection.cs | 9 +++- osu.Game/Screens/Edit/Editor.cs | 5 +- 11 files changed, 78 insertions(+), 36 deletions(-) diff --git a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs index 5c20f46787..7a5f6dbd7c 100644 --- a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs +++ b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs @@ -15,6 +15,7 @@ using osu.Framework.Platform; using osu.Game.Database; using osu.Game.Extensions; using osu.Game.IO; +using osu.Game.Overlays; using osu.Game.Skinning; using SharpCompress.Archives.Zip; @@ -122,7 +123,7 @@ namespace osu.Game.Tests.Skins.IO import1.PerformRead(s => { - new LegacySkinExporter(osu.Dependencies.Get()).ExportModelTo(s, exportStream); + new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get()).ExportModelTo(s, exportStream); }); string exportFilename = import1.GetDisplayString(); @@ -204,7 +205,7 @@ namespace osu.Game.Tests.Skins.IO Assert.IsFalse(s.Protected); Assert.AreEqual(typeof(ArgonSkin), s.CreateInstance(skinManager).GetType()); - new LegacySkinExporter(osu.Dependencies.Get()).ExportModelTo(s, exportStream); + new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get()).ExportModelTo(s, exportStream); Assert.Greater(exportStream.Length, 0); }); @@ -239,7 +240,7 @@ namespace osu.Game.Tests.Skins.IO Assert.IsFalse(s.Protected); Assert.AreEqual(typeof(DefaultLegacySkin), s.CreateInstance(skinManager).GetType()); - new LegacySkinExporter(osu.Dependencies.Get()).ExportModelTo(s, exportStream); + new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get()).ExportModelTo(s, exportStream); Assert.Greater(exportStream.Length, 0); }); diff --git a/osu.Game/Database/LegacyBeatmapExporter.cs b/osu.Game/Database/LegacyBeatmapExporter.cs index d064b9ed58..3e11e898f3 100644 --- a/osu.Game/Database/LegacyBeatmapExporter.cs +++ b/osu.Game/Database/LegacyBeatmapExporter.cs @@ -1,10 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Platform; using osu.Game.Beatmaps; +using osu.Game.Overlays; namespace osu.Game.Database { @@ -12,8 +11,8 @@ namespace osu.Game.Database { protected override string FileExtension => ".osz"; - public LegacyBeatmapExporter(Storage storage) - : base(storage) + public LegacyBeatmapExporter(Storage storage, INotificationOverlay? notificationOverlay) + : base(storage, notificationOverlay) { } } diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 16d7441dde..ed16e4bc80 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -1,11 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.IO; +using System.Threading.Tasks; using osu.Framework.Platform; using osu.Game.Extensions; +using osu.Game.Overlays; +using osu.Game.Overlays.Notifications; using SharpCompress.Archives.Zip; namespace osu.Game.Database @@ -25,10 +26,17 @@ namespace osu.Game.Database private readonly Storage exportStorage; - protected LegacyExporter(Storage storage) + private readonly INotificationOverlay? notificationOverlay; + + protected ProgressNotification Notification = null!; + + private string filename = null!; + + protected LegacyExporter(Storage storage, INotificationOverlay? notificationOverlay) { exportStorage = storage.GetStorageForDirectory(@"exports"); UserFileStorage = storage.GetStorageForDirectory(@"files"); + this.notificationOverlay = notificationOverlay; } /// @@ -37,12 +45,25 @@ namespace osu.Game.Database /// The item to export. public void Export(TModel item) { - string filename = $"{item.GetDisplayString().GetValidFilename()}{FileExtension}"; + filename = $"{item.GetDisplayString().GetValidFilename()}{FileExtension}"; - using (var stream = exportStorage.CreateFileSafely(filename)) - ExportModelTo(item, stream); + Stream stream = exportStorage.CreateFileSafely(filename); - exportStorage.PresentFileExternally(filename); + Notification = new ProgressNotification + { + State = ProgressNotificationState.Active, + Text = "Exporting...", + CompletionText = "Export completed" + }; + Notification.CompletionClickAction += () => exportStorage.PresentFileExternally(filename); + Notification.CancelRequested += () => + { + stream.Dispose(); + return true; + }; + + ExportModelTo(item, stream); + notificationOverlay?.Post(Notification); } /// @@ -57,7 +78,24 @@ namespace osu.Game.Database foreach (var file in model.Files) archive.AddEntry(file.Filename, UserFileStorage.GetStream(file.File.GetStoragePath())); - archive.SaveTo(outputStream); + Task.Factory.StartNew(() => + { + archive.SaveTo(outputStream); + }, Notification.CancellationToken).ContinueWith(t => + { + if (t.IsCompletedSuccessfully) + { + outputStream.Dispose(); + Notification.State = ProgressNotificationState.Completed; + } + else + { + if (Notification.State == ProgressNotificationState.Cancelled) return; + + Notification.State = ProgressNotificationState.Cancelled; + Notification.Text = "Export Failed"; + } + }); } } } diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index 6fa02b957d..1564c7b077 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -1,12 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.IO; using System.Linq; using osu.Framework.Platform; using osu.Game.Extensions; +using osu.Game.Overlays; +using osu.Game.Overlays.Notifications; using osu.Game.Scoring; namespace osu.Game.Database @@ -15,8 +15,8 @@ namespace osu.Game.Database { protected override string FileExtension => ".osr"; - public LegacyScoreExporter(Storage storage) - : base(storage) + public LegacyScoreExporter(Storage storage, INotificationOverlay? notificationOverlay) + : base(storage, notificationOverlay) { } @@ -28,6 +28,9 @@ namespace osu.Game.Database using (var inputStream = UserFileStorage.GetStream(file.File.GetStoragePath())) inputStream.CopyTo(outputStream); + + Notification.State = ProgressNotificationState.Completed; + outputStream.Dispose(); } } } diff --git a/osu.Game/Database/LegacyScoreImporter.cs b/osu.Game/Database/LegacyScoreImporter.cs index f61241141e..131b4ffb0e 100644 --- a/osu.Game/Database/LegacyScoreImporter.cs +++ b/osu.Game/Database/LegacyScoreImporter.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.IO; diff --git a/osu.Game/Database/LegacySkinExporter.cs b/osu.Game/Database/LegacySkinExporter.cs index 1d5364fb8d..a78d69e7b9 100644 --- a/osu.Game/Database/LegacySkinExporter.cs +++ b/osu.Game/Database/LegacySkinExporter.cs @@ -1,9 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Platform; +using osu.Game.Overlays; using osu.Game.Skinning; namespace osu.Game.Database @@ -12,8 +11,8 @@ namespace osu.Game.Database { protected override string FileExtension => ".osk"; - public LegacySkinExporter(Storage storage) - : base(storage) + public LegacySkinExporter(Storage storage, INotificationOverlay? notificationOverlay) + : base(storage, notificationOverlay) { } } diff --git a/osu.Game/Database/LegacySkinImporter.cs b/osu.Game/Database/LegacySkinImporter.cs index 42b2f2e1d8..2f05ccae45 100644 --- a/osu.Game/Database/LegacySkinImporter.cs +++ b/osu.Game/Database/LegacySkinImporter.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Skinning; namespace osu.Game.Database diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs index 1a938c12e5..5a7ead1c59 100644 --- a/osu.Game/Database/RealmAccess.cs +++ b/osu.Game/Database/RealmAccess.cs @@ -173,11 +173,6 @@ namespace osu.Game.Database if (!Filename.EndsWith(realm_extension, StringComparison.Ordinal)) Filename += realm_extension; -#if DEBUG - if (!DebugUtils.IsNUnitRunning) - applyFilenameSchemaSuffix(ref Filename); -#endif - string newerVersionFilename = $"{Filename.Replace(realm_extension, string.Empty)}_newer_version{realm_extension}"; // Attempt to recover a newer database version if available. diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index a7b6bd044d..72f1a94ec8 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -75,6 +75,9 @@ namespace osu.Game.Online.Leaderboards [Resolved] private Storage storage { get; set; } + [Resolved] + private INotificationOverlay notificationOverlay { get; set; } + public ITooltip GetCustomTooltip() => new LeaderboardScoreTooltip(); public virtual ScoreInfo TooltipContent => Score; @@ -427,7 +430,7 @@ namespace osu.Game.Online.Leaderboards if (Score.Files.Count > 0) { - items.Add(new OsuMenuItem("Export", MenuItemType.Standard, () => new LegacyScoreExporter(storage).Export(Score))); + items.Add(new OsuMenuItem("Export", MenuItemType.Standard, () => new LegacyScoreExporter(storage, notificationOverlay).Export(Score))); items.Add(new OsuMenuItem(CommonStrings.ButtonsDelete, MenuItemType.Destructive, () => dialogOverlay?.Push(new LocalScoreDeleteDialog(Score)))); } diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index f602b73065..df6f719b1e 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -141,11 +141,16 @@ namespace osu.Game.Overlays.Settings.Sections [Resolved] private Storage storage { get; set; } + [CanBeNull] + private INotificationOverlay notificationOverlay; + private Bindable currentSkin; [BackgroundDependencyLoader] - private void load() + private void load(INotificationOverlay notificationOverlay) { + this.notificationOverlay = notificationOverlay; + Text = SkinSettingsStrings.ExportSkinButton; Action = export; } @@ -162,7 +167,7 @@ namespace osu.Game.Overlays.Settings.Sections { try { - currentSkin.Value.SkinInfo.PerformRead(s => new LegacySkinExporter(storage).Export(s)); + currentSkin.Value.SkinInfo.PerformRead(s => new LegacySkinExporter(storage, notificationOverlay).Export(s)); } catch (Exception e) { diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index bb390dfbf3..03bdd69f34 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -93,6 +93,9 @@ namespace osu.Game.Screens.Edit [Resolved] private Storage storage { get; set; } + [Resolved] + private INotificationOverlay notificationOverlay { get; set; } + [Resolved(canBeNull: true)] private IDialogOverlay dialogOverlay { get; set; } @@ -938,7 +941,7 @@ namespace osu.Game.Screens.Edit private void exportBeatmap() { Save(); - new LegacyBeatmapExporter(storage).Export(Beatmap.Value.BeatmapSetInfo); + new LegacyBeatmapExporter(storage, notificationOverlay).Export(Beatmap.Value.BeatmapSetInfo); } /// From 7a28a7f2a0d7c337a88d8fad0d4d2b721040fe25 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 17 Nov 2022 01:32:54 +0300 Subject: [PATCH 0592/2991] Move `IGameplaySettings` override to compose screen to keep test mode unaffected --- osu.Game/Configuration/IGameplaySettings.cs | 2 +- osu.Game/Screens/Edit/Compose/ComposeScreen.cs | 13 ++++++++++++- osu.Game/Screens/Edit/Editor.cs | 12 +----------- .../Screens/Edit/GameplayTest/EditorPlayer.cs | 18 +----------------- 4 files changed, 15 insertions(+), 30 deletions(-) diff --git a/osu.Game/Configuration/IGameplaySettings.cs b/osu.Game/Configuration/IGameplaySettings.cs index a35bdd20d0..8d66535017 100644 --- a/osu.Game/Configuration/IGameplaySettings.cs +++ b/osu.Game/Configuration/IGameplaySettings.cs @@ -8,7 +8,7 @@ namespace osu.Game.Configuration { /// /// A settings provider which generally sources from (global user settings) - /// but can allow overriding settings by caching more locally. For instance, in the editor. + /// but can allow overriding settings by caching more locally. For instance, in the editor compose screen. /// /// /// More settings can be moved into this interface as required. diff --git a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs index 3d18b00e75..d3c330c6d7 100644 --- a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs +++ b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Platform; using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Extensions; using osu.Game.IO.Serialization; using osu.Game.Rulesets; @@ -19,7 +20,7 @@ using osu.Game.Screens.Edit.Compose.Components.Timeline; namespace osu.Game.Screens.Edit.Compose { - public class ComposeScreen : EditorScreenWithTimeline + public class ComposeScreen : EditorScreenWithTimeline, IGameplaySettings { [Resolved] private GameHost host { get; set; } @@ -27,6 +28,9 @@ namespace osu.Game.Screens.Edit.Compose [Resolved] private EditorClock clock { get; set; } + [Resolved] + private IGameplaySettings globalGameplaySettings { get; set; } + private Bindable clipboard { get; set; } private HitObjectComposer composer; @@ -157,5 +161,12 @@ namespace osu.Game.Screens.Edit.Compose } #endregion + + // Combo colour normalisation should not be applied in the editor. + // Note this doesn't affect editor test mode. + IBindable IGameplaySettings.ComboColourNormalisationAmount => new Bindable(); + + // Arguable. + IBindable IGameplaySettings.PositionalHitsoundsLevel => globalGameplaySettings.PositionalHitsoundsLevel; } } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index bb390dfbf3..4c44117581 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -58,8 +58,7 @@ namespace osu.Game.Screens.Edit { [Cached(typeof(IBeatSnapProvider))] [Cached] - public class Editor : ScreenWithBeatmapBackground, IKeyBindingHandler, IKeyBindingHandler, IBeatSnapProvider, ISamplePlaybackDisabler, IBeatSyncProvider, - IGameplaySettings + public class Editor : ScreenWithBeatmapBackground, IKeyBindingHandler, IKeyBindingHandler, IBeatSnapProvider, ISamplePlaybackDisabler, IBeatSyncProvider { public override float BackgroundParallaxAmount => 0.1f; @@ -99,9 +98,6 @@ namespace osu.Game.Screens.Edit [Resolved(canBeNull: true)] private INotificationOverlay notifications { get; set; } - [Resolved] - private IGameplaySettings globalGameplaySettings { get; set; } - public readonly Bindable Mode = new Bindable(); public IBindable SamplePlaybackDisabled => samplePlaybackDisabled; @@ -1045,11 +1041,5 @@ namespace osu.Game.Screens.Edit { } } - - // Combo colour normalisation should not be applied in the editor. - IBindable IGameplaySettings.ComboColourNormalisationAmount => new Bindable(); - - // Arguable. - IBindable IGameplaySettings.PositionalHitsoundsLevel => globalGameplaySettings.PositionalHitsoundsLevel; } } diff --git a/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs b/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs index 7fc62b3c14..393ed4ef2e 100644 --- a/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs +++ b/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs @@ -2,16 +2,14 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Screens; using osu.Game.Beatmaps; -using osu.Game.Configuration; using osu.Game.Overlays; using osu.Game.Screens.Play; namespace osu.Game.Screens.Edit.GameplayTest { - public class EditorPlayer : Player, IGameplaySettings + public class EditorPlayer : Player { private readonly Editor editor; private readonly EditorState editorState; @@ -19,8 +17,6 @@ namespace osu.Game.Screens.Edit.GameplayTest [Resolved] private MusicController musicController { get; set; } = null!; - private OsuConfigManager config = null!; - public EditorPlayer(Editor editor) : base(new PlayerConfiguration { ShowResults = false }) { @@ -28,14 +24,6 @@ namespace osu.Game.Screens.Edit.GameplayTest editorState = editor.GetState(); } - protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) - { - // needs to be populated before BDL to work correctly. - config = parent.Get(); - - return base.CreateChildDependencies(parent); - } - protected override GameplayClockContainer CreateGameplayClockContainer(WorkingBeatmap beatmap, double gameplayStart) { var masterGameplayClockContainer = new MasterGameplayClockContainer(beatmap, gameplayStart); @@ -84,9 +72,5 @@ namespace osu.Game.Screens.Edit.GameplayTest editor.RestoreState(editorState); return base.OnExiting(e); } - - // Editor overrides but we actually want to use game-wide settings here. - public IBindable ComboColourNormalisationAmount => ((IGameplaySettings)config).ComboColourNormalisationAmount; - public IBindable PositionalHitsoundsLevel => ((IGameplaySettings)config).PositionalHitsoundsLevel; } } From 0e46614c573cb45a0d08dee817c6f82798b9c9fd Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 17 Nov 2022 03:54:35 +0300 Subject: [PATCH 0593/2991] Revert beatmap option button state changes --- .../SongSelect/TestScenePlaySongSelect.cs | 7 ----- .../Select/Options/BeatmapOptionsButton.cs | 29 ------------------- .../Select/Options/BeatmapOptionsOverlay.cs | 4 +-- osu.Game/Screens/Select/PlaySongSelect.cs | 11 +------ osu.Game/Screens/Select/SongSelect.cs | 22 ++------------ 5 files changed, 4 insertions(+), 69 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 51c4c5e661..614ecca6d2 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -1063,15 +1063,8 @@ namespace osu.Game.Tests.Visual.SongSelect addRulesetImportStep(0); - AddAssert("delete option enabled", () => !songSelect!.DeleteOptionButton.Disabled); - AddAssert("clear option enabled", () => !songSelect!.ClearOptionButton.Disabled); - AddAssert("edit option enabled", () => songSelect!.EditOptionButton?.Disabled == false); - AddStep("delete all beatmaps", () => manager.Delete()); - AddAssert("delete option disabled", () => songSelect!.DeleteOptionButton.Disabled); - AddAssert("clear option disabled", () => songSelect!.ClearOptionButton.Disabled); - AddAssert("edit option disabled", () => songSelect!.EditOptionButton?.Disabled == true); } private void waitForInitialSelection() diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs index 73bc68f6b0..f41ee63a51 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs @@ -33,29 +33,6 @@ namespace osu.Game.Screens.Select.Options private const float disabled_alpha = 0.5f; - private bool disabled; - - public bool Disabled - { - get => disabled; - set - { - disabled = value; - - if (disabled) - { - firstLine.Alpha = disabled_alpha; - secondLine.Alpha = disabled_alpha; - iconText.Alpha = disabled_alpha; - return; - } - - firstLine.Alpha = 1; - secondLine.Alpha = 1; - iconText.Alpha = 1; - } - } - public Color4 ButtonColour { get => background.Colour; @@ -82,24 +59,18 @@ namespace osu.Game.Screens.Select.Options protected override bool OnMouseDown(MouseDownEvent e) { - if (disabled) return true; - flash.FadeTo(0.1f, 1000, Easing.OutQuint); return base.OnMouseDown(e); } protected override void OnMouseUp(MouseUpEvent e) { - if (disabled) return; - flash.FadeTo(0, 1000, Easing.OutQuint); base.OnMouseUp(e); } protected override bool OnClick(ClickEvent e) { - if (disabled) return true; - flash.ClearTransforms(); flash.Alpha = 0.9f; flash.FadeOut(800, Easing.OutExpo); diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs index 139d9e60b5..8785dac0aa 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs @@ -66,7 +66,7 @@ namespace osu.Game.Screens.Select.Options /// Colour of the button. /// Icon of the button. /// Binding the button does. - public BeatmapOptionsButton AddButton(LocalisableString firstLine, string secondLine, IconUsage icon, Color4 colour, Action action) + public void AddButton(LocalisableString firstLine, string secondLine, IconUsage icon, Color4 colour, Action action) { var button = new BeatmapOptionsButton { @@ -82,8 +82,6 @@ namespace osu.Game.Screens.Select.Options }; buttonsContainer.Add(button); - - return button; } protected override void PopIn() diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index e61c0c4c59..8718e8ad07 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -34,12 +34,10 @@ namespace osu.Game.Screens.Select private PlayBeatmapDetailArea playBeatmapDetailArea = null!; - protected BeatmapOptionsButton? EditOptionButton; - [BackgroundDependencyLoader] private void load(OsuColour colours) { - EditOptionButton = BeatmapOptions.AddButton(@"Edit", @"beatmap", FontAwesome.Solid.PencilAlt, colours.Yellow, () => Edit()); + BeatmapOptions.AddButton(@"Edit", @"beatmap", FontAwesome.Solid.PencilAlt, colours.Yellow, () => Edit()); } protected void PresentScore(ScoreInfo score) => @@ -145,12 +143,5 @@ namespace osu.Game.Screens.Select playerLoader = null; } } - - protected override void OnBeatmapOptionsButtonDisabledChanged(bool disabled) - { - base.OnBeatmapOptionsButtonDisabledChanged(disabled); - - if (EditOptionButton != null) EditOptionButton.Disabled = disabled; - } } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 0341a9bb07..062ad17cb1 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -116,10 +116,6 @@ namespace osu.Game.Screens.Select private double audioFeedbackLastPlaybackTime; - protected BeatmapOptionsButton DeleteOptionButton; - - protected BeatmapOptionsButton ClearOptionButton; - [CanBeNull] private IDisposable modSelectOverlayRegistration; @@ -290,8 +286,8 @@ namespace osu.Game.Screens.Select BeatmapOptions.AddButton(@"Manage", @"collections", FontAwesome.Solid.Book, colours.Green, () => manageCollectionsDialog?.Show()); BeatmapOptions.AddButton(@"Remove", @"from unplayed", FontAwesome.Regular.TimesCircle, colours.Purple, null); - DeleteOptionButton = BeatmapOptions.AddButton(@"Delete", @"all difficulties", FontAwesome.Solid.Trash, colours.Pink, () => delete(Beatmap.Value.BeatmapSetInfo)); - ClearOptionButton = BeatmapOptions.AddButton(@"Clear", @"local scores", FontAwesome.Solid.Eraser, colours.Purple, () => clearScores(Beatmap.Value.BeatmapInfo)); + BeatmapOptions.AddButton(@"Delete", @"all difficulties", FontAwesome.Solid.Trash, colours.Pink, () => delete(Beatmap.Value.BeatmapSetInfo)); + BeatmapOptions.AddButton(@"Clear", @"local scores", FontAwesome.Solid.Eraser, colours.Purple, () => clearScores(Beatmap.Value.BeatmapInfo)); } sampleChangeDifficulty = audio.Samples.Get(@"SongSelect/select-difficulty"); @@ -417,14 +413,6 @@ namespace osu.Game.Screens.Select { var beatmap = e?.NewValue ?? Beatmap.Value; - if (beatmap is DummyWorkingBeatmap || !this.IsCurrentScreen()) - { - OnBeatmapOptionsButtonDisabledChanged(true); - return; - } - - OnBeatmapOptionsButtonDisabledChanged(false); - Logger.Log($"Song select working beatmap updated to {beatmap}"); if (!Carousel.SelectBeatmap(beatmap.BeatmapInfo, false)) @@ -658,12 +646,6 @@ namespace osu.Game.Screens.Select return false; } - protected virtual void OnBeatmapOptionsButtonDisabledChanged(bool disabled) - { - DeleteOptionButton.Disabled = disabled; - ClearOptionButton.Disabled = disabled; - } - private void playExitingTransition() { ModSelect.Hide(); From 039ab83a46eefad0a61d7dff787c389eef07f38d Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 17 Nov 2022 03:57:27 +0300 Subject: [PATCH 0594/2991] Disable beatmap options button when none selected --- .../SongSelect/TestScenePlaySongSelect.cs | 12 ++---- .../SongSelect/TestSceneSongSelectFooter.cs | 8 ++++ osu.Game/Screens/Select/Footer.cs | 14 ++++++- osu.Game/Screens/Select/FooterButton.cs | 41 ++++++++++++++++--- osu.Game/Screens/Select/PlaySongSelect.cs | 1 - osu.Game/Screens/Select/SongSelect.cs | 14 ++++++- 6 files changed, 72 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 614ecca6d2..b6b9e8926b 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -37,7 +37,6 @@ using osu.Game.Screens.Select; using osu.Game.Screens.Select.Carousel; using osu.Game.Screens.Select.Filter; using osu.Game.Tests.Resources; -using osu.Game.Screens.Select.Options; using osuTK.Input; namespace osu.Game.Tests.Visual.SongSelect @@ -1057,14 +1056,15 @@ namespace osu.Game.Tests.Visual.SongSelect } [Test] - public void TestBeatmapOptionsButtonDisable() + public void TestBeatmapOptionsDisabled() { createSongSelect(); addRulesetImportStep(0); + AddAssert("options enabled", () => songSelect.ChildrenOfType().Single().Enabled.Value); AddStep("delete all beatmaps", () => manager.Delete()); - + AddAssert("options disabled", () => !songSelect.ChildrenOfType().Single().Enabled.Value); } private void waitForInitialSelection() @@ -1154,12 +1154,6 @@ namespace osu.Game.Tests.Visual.SongSelect public new BeatmapCarousel Carousel => base.Carousel; public new ModSelectOverlay ModSelect => base.ModSelect; - public new BeatmapOptionsButton DeleteOptionButton => base.DeleteOptionButton; - - public new BeatmapOptionsButton ClearOptionButton => base.ClearOptionButton; - - public new BeatmapOptionsButton? EditOptionButton => base.EditOptionButton; - public new void PresentScore(ScoreInfo score) => base.PresentScore(score); protected override bool OnStart() diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooter.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooter.cs index cb78fbfe35..0a88abface 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooter.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooter.cs @@ -3,8 +3,10 @@ #nullable disable +using System.Linq; using NUnit.Framework; using osu.Framework.Graphics; +using osu.Framework.Testing; using osu.Game.Screens.Select; using osuTK; using osuTK.Input; @@ -43,6 +45,12 @@ namespace osu.Game.Tests.Visual.SongSelect InputManager.MoveMouseTo(Vector2.Zero); }); + [Test] + public void TestState() + { + AddRepeatStep("toggle options state", () => this.ChildrenOfType().Last().Enabled.Toggle(), 20); + } + [Test] public void TestFooterRandom() { diff --git a/osu.Game/Screens/Select/Footer.cs b/osu.Game/Screens/Select/Footer.cs index 86fe76c0c6..f9fc2890b0 100644 --- a/osu.Game/Screens/Select/Footer.cs +++ b/osu.Game/Screens/Select/Footer.cs @@ -57,7 +57,18 @@ namespace osu.Game.Screens.Select } } - private void updateModeLight() => modeLight.FadeColour(buttons.FirstOrDefault(b => b.IsHovered)?.SelectedColour ?? Color4.Transparent, TRANSITION_LENGTH, Easing.OutQuint); + private void updateModeLight() + { + var selectedButton = buttons.FirstOrDefault(b => b.Enabled.Value && b.IsHovered); + + if (selectedButton != null) + { + modeLight.FadeIn(TRANSITION_LENGTH, Easing.OutQuint); + modeLight.FadeColour(selectedButton.SelectedColour, TRANSITION_LENGTH, Easing.OutQuint); + } + else + modeLight.FadeOut(TRANSITION_LENGTH, Easing.OutQuint); + } public Footer() { @@ -78,6 +89,7 @@ namespace osu.Game.Screens.Select RelativeSizeAxes = Axes.X, Height = 3, Position = new Vector2(0, -3), + Colour = Color4.Black, }, new FillFlowContainer { diff --git a/osu.Game/Screens/Select/FooterButton.cs b/osu.Game/Screens/Select/FooterButton.cs index 3f8cf2e13a..230cdfc13e 100644 --- a/osu.Game/Screens/Select/FooterButton.cs +++ b/osu.Game/Screens/Select/FooterButton.cs @@ -120,10 +120,18 @@ namespace osu.Game.Screens.Select }; } + protected override void LoadComplete() + { + base.LoadComplete(); + Enabled.BindValueChanged(_ => updateDisplay(), true); + } + public Action Hovered; public Action HoverLost; public GlobalAction? Hotkey; + private bool mouseDown; + protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); @@ -140,32 +148,38 @@ namespace osu.Game.Screens.Select protected override bool OnHover(HoverEvent e) { Hovered?.Invoke(); - light.ScaleTo(new Vector2(1, 2), Footer.TRANSITION_LENGTH, Easing.OutQuint); - light.FadeColour(SelectedColour, Footer.TRANSITION_LENGTH, Easing.OutQuint); + updateDisplay(); return true; } protected override void OnHoverLost(HoverLostEvent e) { HoverLost?.Invoke(); - light.ScaleTo(new Vector2(1, 1), Footer.TRANSITION_LENGTH, Easing.OutQuint); - light.FadeColour(DeselectedColour, Footer.TRANSITION_LENGTH, Easing.OutQuint); + updateDisplay(); } protected override bool OnMouseDown(MouseDownEvent e) { - box.FadeTo(0.3f, Footer.TRANSITION_LENGTH * 2, Easing.OutQuint); + if (!Enabled.Value) + return true; + + mouseDown = true; + updateDisplay(); return base.OnMouseDown(e); } protected override void OnMouseUp(MouseUpEvent e) { - box.FadeOut(Footer.TRANSITION_LENGTH, Easing.OutQuint); + mouseDown = false; + updateDisplay(); base.OnMouseUp(e); } protected override bool OnClick(ClickEvent e) { + if (!Enabled.Value) + return true; + box.ClearTransforms(); box.Alpha = 1; box.FadeOut(Footer.TRANSITION_LENGTH * 3, Easing.OutQuint); @@ -184,5 +198,20 @@ namespace osu.Game.Screens.Select } public virtual void OnReleased(KeyBindingReleaseEvent e) { } + + private void updateDisplay() + { + this.FadeTo(Enabled.Value ? 1 : 0.25f, Footer.TRANSITION_LENGTH, Easing.OutQuint); + + light.ScaleTo(Enabled.Value && IsHovered ? new Vector2(1, 2) : new Vector2(1), Footer.TRANSITION_LENGTH, Easing.OutQuint); + light.FadeColour(Enabled.Value && IsHovered ? SelectedColour : DeselectedColour, Footer.TRANSITION_LENGTH, Easing.OutQuint); + + box.FadeTo(Enabled.Value & mouseDown ? 0.3f : 0f, Footer.TRANSITION_LENGTH * 2, Easing.OutQuint); + + if (Enabled.Value && IsHovered) + Hovered?.Invoke(); + else + HoverLost?.Invoke(); + } } } diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 8718e8ad07..94e4215175 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -14,7 +14,6 @@ using osu.Game.Rulesets.Mods; using osu.Game.Scoring; using osu.Game.Screens.Play; using osu.Game.Screens.Ranking; -using osu.Game.Screens.Select.Options; using osu.Game.Users; using osu.Game.Utils; using osuTK.Input; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 062ad17cb1..6b0ab2b4cb 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -112,6 +112,8 @@ namespace osu.Game.Screens.Select protected BeatmapDetailArea BeatmapDetails { get; private set; } + private FooterButtonOptions beatmapOptionsButton; + private readonly Bindable decoupledRuleset = new Bindable(); private double audioFeedbackLastPlaybackTime; @@ -314,7 +316,7 @@ namespace osu.Game.Screens.Select NextRandom = () => Carousel.SelectNextRandom(), PreviousRandom = Carousel.SelectPreviousRandom }, null), - (new FooterButtonOptions(), BeatmapOptions) + (beatmapOptionsButton = new FooterButtonOptions(), BeatmapOptions) }; protected virtual ModSelectOverlay CreateModSelectOverlay() => new SoloModSelectOverlay(); @@ -738,6 +740,16 @@ namespace osu.Game.Screens.Select beatmapInfoWedge.Beatmap = beatmap; BeatmapDetails.Beatmap = beatmap; + + bool beatmapSelected = beatmap is not DummyWorkingBeatmap; + + if (beatmapSelected) + beatmapOptionsButton.Enabled.Value = true; + else + { + beatmapOptionsButton.Enabled.Value = false; + BeatmapOptions.Hide(); + } } private readonly WeakReference lastTrack = new WeakReference(null); From 55beaf5d931d7964348ae5e8e44839ff2c8cbb3e Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 17 Nov 2022 04:05:15 +0300 Subject: [PATCH 0595/2991] Revert buttons order change --- osu.Game/Screens/Select/SongSelect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 6b0ab2b4cb..57ba751b54 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -287,8 +287,8 @@ namespace osu.Game.Screens.Select Footer.AddButton(button, overlay); BeatmapOptions.AddButton(@"Manage", @"collections", FontAwesome.Solid.Book, colours.Green, () => manageCollectionsDialog?.Show()); - BeatmapOptions.AddButton(@"Remove", @"from unplayed", FontAwesome.Regular.TimesCircle, colours.Purple, null); BeatmapOptions.AddButton(@"Delete", @"all difficulties", FontAwesome.Solid.Trash, colours.Pink, () => delete(Beatmap.Value.BeatmapSetInfo)); + BeatmapOptions.AddButton(@"Remove", @"from unplayed", FontAwesome.Regular.TimesCircle, colours.Purple, null); BeatmapOptions.AddButton(@"Clear", @"local scores", FontAwesome.Solid.Eraser, colours.Purple, () => clearScores(Beatmap.Value.BeatmapInfo)); } From 87b4fee10fc3477c2fd7619270f571e84da7a3cd Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 17 Nov 2022 04:05:21 +0300 Subject: [PATCH 0596/2991] Remove leftover constant --- osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs index f41ee63a51..69800c4e86 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs @@ -31,8 +31,6 @@ namespace osu.Game.Screens.Select.Options private readonly OsuSpriteText secondLine; private readonly Container box; - private const float disabled_alpha = 0.5f; - public Color4 ButtonColour { get => background.Colour; From bfcd9e0f45bf3b8f424073aea7da4e5f150e16ed Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 17 Nov 2022 12:32:35 +0900 Subject: [PATCH 0597/2991] Don't seek to current editor location when location is close to (or before) the first object --- osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs b/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs index 393ed4ef2e..251feecf28 100644 --- a/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs +++ b/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.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.Linq; using osu.Framework.Allocation; using osu.Framework.Screens; using osu.Game.Beatmaps; @@ -27,7 +28,12 @@ namespace osu.Game.Screens.Edit.GameplayTest protected override GameplayClockContainer CreateGameplayClockContainer(WorkingBeatmap beatmap, double gameplayStart) { var masterGameplayClockContainer = new MasterGameplayClockContainer(beatmap, gameplayStart); - masterGameplayClockContainer.Reset(editorState.Time); + + // Only reset the time to the current point if the editor is later than the normal start time (and the first object). + // This allows more sane test playing from the start of the beatmap (ie. correctly adding lead-in time). + if (editorState.Time > gameplayStart && editorState.Time > DrawableRuleset.Objects.FirstOrDefault()?.StartTime) + masterGameplayClockContainer.Reset(editorState.Time); + return masterGameplayClockContainer; } From a4e713a61f7ab1b99cbbcfd28e74a0a971c965e2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 17 Nov 2022 12:36:24 +0900 Subject: [PATCH 0598/2991] When returning to the editor after test play, use the original editor time rather than the point of exit --- osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs b/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs index 393ed4ef2e..e8ba7ad548 100644 --- a/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs +++ b/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs @@ -68,7 +68,6 @@ namespace osu.Game.Screens.Edit.GameplayTest { musicController.Stop(); - editorState.Time = GameplayClockContainer.CurrentTime; editor.RestoreState(editorState); return base.OnExiting(e); } From adab9f0e48d1cc17aa1a8d5f939d76f3881f5905 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 17 Nov 2022 13:34:40 +0900 Subject: [PATCH 0599/2991] Catch and gracefully handle file/directory enumeration failures during stable import Closes https://github.com/ppy/osu/issues/21214. --- osu.Game/Database/LegacyBeatmapImporter.cs | 47 ++++++++++++++++------ 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/osu.Game/Database/LegacyBeatmapImporter.cs b/osu.Game/Database/LegacyBeatmapImporter.cs index 0955461609..c7e6fa2404 100644 --- a/osu.Game/Database/LegacyBeatmapImporter.cs +++ b/osu.Game/Database/LegacyBeatmapImporter.cs @@ -1,11 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - +using System; using System.Collections.Generic; +using System.IO; using System.Linq; using osu.Framework.IO.Stores; +using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.IO; @@ -22,22 +23,42 @@ namespace osu.Game.Database { // make sure the directory exists if (!storage.ExistsDirectory(string.Empty)) - yield break; + return Array.Empty(); - foreach (string directory in storage.GetDirectories(string.Empty)) + List paths = new List(); + + try { - var directoryStorage = storage.GetStorageForDirectory(directory); - - if (!directoryStorage.GetFiles(string.Empty).ExcludeSystemFileNames().Any()) + foreach (string directory in storage.GetDirectories(string.Empty)) { - // if a directory doesn't contain files, attempt looking for beatmaps inside of that directory. - // this is a special behaviour in stable for beatmaps only, see https://github.com/ppy/osu/issues/18615. - foreach (string subDirectory in GetStableImportPaths(directoryStorage)) - yield return subDirectory; + var directoryStorage = storage.GetStorageForDirectory(directory); + + try + { + if (!directoryStorage.GetFiles(string.Empty).ExcludeSystemFileNames().Any()) + { + // if a directory doesn't contain files, attempt looking for beatmaps inside of that directory. + // this is a special behaviour in stable for beatmaps only, see https://github.com/ppy/osu/issues/18615. + foreach (string subDirectory in GetStableImportPaths(directoryStorage)) + paths.Add(subDirectory); + } + else + paths.Add(storage.GetFullPath(directory)); + } + catch (IOException e) + { + // Catch any errors when enumerating files + Logger.Log($"Error when enumerating files in {directoryStorage.GetFullPath(string.Empty)}: {e}"); + } } - else - yield return storage.GetFullPath(directory); } + catch (IOException e) + { + // Catch any errors when enumerating directories + Logger.Log($"Error when enumerating directories in {storage.GetFullPath(string.Empty)}: {e}"); + } + + return paths; } public LegacyBeatmapImporter(IModelImporter importer) From 1050d7da3400ba08ca3a5361b645a53feddd3ccc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 17 Nov 2022 13:36:16 +0900 Subject: [PATCH 0600/2991] Use more generic exception type (issue reported `AggegateException`) --- osu.Game/Database/LegacyBeatmapImporter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Database/LegacyBeatmapImporter.cs b/osu.Game/Database/LegacyBeatmapImporter.cs index c7e6fa2404..887797fe2d 100644 --- a/osu.Game/Database/LegacyBeatmapImporter.cs +++ b/osu.Game/Database/LegacyBeatmapImporter.cs @@ -45,14 +45,14 @@ namespace osu.Game.Database else paths.Add(storage.GetFullPath(directory)); } - catch (IOException e) + catch (Exception e) { // Catch any errors when enumerating files Logger.Log($"Error when enumerating files in {directoryStorage.GetFullPath(string.Empty)}: {e}"); } } } - catch (IOException e) + catch (Exception e) { // Catch any errors when enumerating directories Logger.Log($"Error when enumerating directories in {storage.GetFullPath(string.Empty)}: {e}"); From 5ceb7ecc41c761e2e51c0d1d49534f23cbdc788d Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Thu, 17 Nov 2022 13:56:27 +0900 Subject: [PATCH 0601/2991] Remove unused using --- osu.Game/Database/LegacyBeatmapImporter.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Database/LegacyBeatmapImporter.cs b/osu.Game/Database/LegacyBeatmapImporter.cs index 887797fe2d..20add54949 100644 --- a/osu.Game/Database/LegacyBeatmapImporter.cs +++ b/osu.Game/Database/LegacyBeatmapImporter.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using osu.Framework.IO.Stores; using osu.Framework.Logging; From 12606122e3dd9e10980d548f3c0c3dbd5558e94e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 17 Nov 2022 13:59:07 +0900 Subject: [PATCH 0602/2991] Fix sliders not correctly taking on full available length after changing curve type --- .../Blueprints/Sliders/Components/PathControlPointVisualiser.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index 94655f3cf7..c7e3516d62 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -248,6 +248,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components break; } + slider.Path.ExpectedDistance.Value = null; piece.ControlPoint.Type = type; } From bd2e0dc82b05fb61b1ed4671f0cc3c3ccb02680b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 17 Nov 2022 15:09:41 +0900 Subject: [PATCH 0603/2991] Move "keybindings" keyword to correct section Without this, things like tablet settings would show when searching for bindings, even though these settings have nothing to do with key bindings. --- osu.Game/Overlays/Settings/Sections/Input/BindingSettings.cs | 4 ++++ osu.Game/Overlays/Settings/Sections/InputSection.cs | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Input/BindingSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/BindingSettings.cs index b92746a65a..2f4840a384 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/BindingSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/BindingSettings.cs @@ -3,6 +3,8 @@ #nullable disable +using System.Collections.Generic; +using System.Linq; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Localisation; @@ -13,6 +15,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input { protected override LocalisableString Header => BindingSettingsStrings.ShortcutAndGameplayBindings; + public override IEnumerable FilterTerms => base.FilterTerms.Concat(new LocalisableString[] { "keybindings" }); + public BindingSettings(KeyBindingPanel keyConfig) { Children = new Drawable[] diff --git a/osu.Game/Overlays/Settings/Sections/InputSection.cs b/osu.Game/Overlays/Settings/Sections/InputSection.cs index a8fe3d04be..4d75537f6b 100644 --- a/osu.Game/Overlays/Settings/Sections/InputSection.cs +++ b/osu.Game/Overlays/Settings/Sections/InputSection.cs @@ -3,8 +3,6 @@ #nullable disable -using System.Collections.Generic; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; @@ -22,8 +20,6 @@ namespace osu.Game.Overlays.Settings.Sections public override LocalisableString Header => InputSettingsStrings.InputSectionHeader; - public override IEnumerable FilterTerms => base.FilterTerms.Concat(new LocalisableString[] { "keybindings" }); - public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.Solid.Keyboard From d1b21164006dd08ee56ee1d1e935871e73eab543 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 17 Nov 2022 15:23:20 +0900 Subject: [PATCH 0604/2991] Auto-advance binding for ruleset key bindings --- .../Settings/Sections/Input/KeyBindingRow.cs | 17 ++++++++++++----- .../Sections/Input/KeyBindingsSubsection.cs | 19 ++++++++++++++++++- .../Input/VariantBindingsSubsection.cs | 2 ++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs index c91a6a48d4..12fd6f0746 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs @@ -33,6 +33,11 @@ namespace osu.Game.Overlays.Settings.Sections.Input { public class KeyBindingRow : Container, IFilterable { + /// + /// Invoked when binding of this row finalises with a change being written. + /// + public Action BindingFinalised { get; set; } + private readonly object action; private readonly IEnumerable bindings; @@ -153,7 +158,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input Spacing = new Vector2(5), Children = new Drawable[] { - new CancelButton { Action = finalise }, + new CancelButton { Action = () => finalise(false) }, new ClearButton { Action = clear }, }, }, @@ -240,7 +245,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input } if (bindTarget.IsHovered) - finalise(); + finalise(false); // prevent updating bind target before clear button's action else if (!cancelAndClearButtons.Any(b => b.IsHovered)) updateBindTarget(); @@ -377,10 +382,10 @@ namespace osu.Game.Overlays.Settings.Sections.Input return; bindTarget.UpdateKeyCombination(InputKey.None); - finalise(); + finalise(false); } - private void finalise() + private void finalise(bool changedKey = true) { if (bindTarget != null) { @@ -393,6 +398,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input { // schedule to ensure we don't instantly get focus back on next OnMouseClick (see AcceptFocus impl.) bindTarget = null; + if (changedKey) + BindingFinalised?.Invoke(this); }); } @@ -417,7 +424,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input protected override void OnFocusLost(FocusLostEvent e) { - finalise(); + finalise(false); base.OnFocusLost(e); } diff --git a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs index 628fe08607..a3f378e3c9 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs @@ -19,6 +19,12 @@ namespace osu.Game.Overlays.Settings.Sections.Input { public abstract class KeyBindingsSubsection : SettingsSubsection { + /// + /// After a successful binding, automatically select the next binding row to make quickly + /// binding a large set of keys easier on the user. + /// + protected virtual bool AutoAdvanceTarget => false; + protected IEnumerable Defaults; public RulesetInfo Ruleset { get; protected set; } @@ -49,7 +55,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input Add(new KeyBindingRow(defaultGroup.Key, bindings.Where(b => b.ActionInt.Equals(intKey)).ToList()) { AllowMainMouseButtons = Ruleset != null, - Defaults = defaultGroup.Select(d => d.KeyCombination) + Defaults = defaultGroup.Select(d => d.KeyCombination), + BindingFinalised = bindingCompleted }); } @@ -58,6 +65,16 @@ namespace osu.Game.Overlays.Settings.Sections.Input Action = () => Children.OfType().ForEach(k => k.RestoreDefaults()) }); } + + private void bindingCompleted(KeyBindingRow sender) + { + if (AutoAdvanceTarget) + { + var next = Children.SkipWhile(c => c != sender).Skip(1).FirstOrDefault(); + if (next != null) + GetContainingInputManager().ChangeFocus(next); + } + } } public class ResetButton : DangerousSettingsButton diff --git a/osu.Game/Overlays/Settings/Sections/Input/VariantBindingsSubsection.cs b/osu.Game/Overlays/Settings/Sections/Input/VariantBindingsSubsection.cs index a0f069b3bb..a6f6c28463 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/VariantBindingsSubsection.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/VariantBindingsSubsection.cs @@ -8,6 +8,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input { public class VariantBindingsSubsection : KeyBindingsSubsection { + protected override bool AutoAdvanceTarget => true; + protected override LocalisableString Header { get; } public VariantBindingsSubsection(RulesetInfo ruleset, int variant) From 4773979e52d9a35f284d8da651ed60df8d7c12d5 Mon Sep 17 00:00:00 2001 From: nanashi-1 Date: Thu, 17 Nov 2022 16:15:34 +0800 Subject: [PATCH 0605/2991] add condition --- osu.Game/Screens/Select/SongSelect.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 57ba751b54..5d5019567a 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -414,6 +414,7 @@ namespace osu.Game.Screens.Select private void updateCarouselSelection(ValueChangedEvent e = null) { var beatmap = e?.NewValue ?? Beatmap.Value; + if (beatmap is DummyWorkingBeatmap || !this.IsCurrentScreen()) return; Logger.Log($"Song select working beatmap updated to {beatmap}"); From dea2a6ed8d0465303f8ca4140f57371f91c99fd9 Mon Sep 17 00:00:00 2001 From: Piggey Date: Thu, 17 Nov 2022 12:12:36 +0100 Subject: [PATCH 0606/2991] override `sort()` function in `SoloGameplayLeaderboard` --- .../Screens/Play/HUD/GameplayLeaderboard.cs | 6 +----- .../Play/HUD/SoloGameplayLeaderboard.cs | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs index c8631880ac..2a47964118 100644 --- a/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs @@ -158,7 +158,7 @@ namespace osu.Game.Screens.Play.HUD } } - private void sort() + protected virtual void sort() { if (sorting.IsValid) return; @@ -174,10 +174,6 @@ namespace osu.Game.Screens.Play.HUD orderedByScore[i].ScorePosition = i + 1; } - // change displayed potision to '-' when there are 50 already submitted scores and tracked score is last - if (TrackedScore?.ScorePosition == Flow.Count && Flow.Count == 51) - TrackedScore.ScorePosition = null; - sorting.Validate(); } diff --git a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs index ab3cf2950c..bf9cdc8db7 100644 --- a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics; using osu.Game.Configuration; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; +using osu.Game.Screens.Select; using osu.Game.Users; namespace osu.Game.Screens.Play.HUD @@ -16,6 +17,7 @@ namespace osu.Game.Screens.Play.HUD public class SoloGameplayLeaderboard : GameplayLeaderboard { private const int duration = 100; + private const int max_online_scores = 50; // BAD! private readonly Bindable configVisibility = new Bindable(); private readonly IUser trackingUser; @@ -42,10 +44,15 @@ namespace osu.Game.Screens.Play.HUD this.trackingUser = trackingUser; } + private PlayBeatmapDetailArea.TabType scoresType; + [BackgroundDependencyLoader] private void load(OsuConfigManager config) { config.BindWith(OsuSetting.GameplayLeaderboard, configVisibility); + + // a way to differentiate scores taken from online ranking to local scores + scoresType = config.Get(OsuSetting.BeatmapDetailTab); } protected override void LoadComplete() @@ -93,6 +100,18 @@ namespace osu.Game.Screens.Play.HUD local.DisplayOrder.Value = long.MaxValue; } + protected override void sort() + { + base.sort(); + + if (scoresType != PlayBeatmapDetailArea.TabType.Local) + { + // change displayed potision to '-' when there are 50 already submitted scores and tracked score is last + if (TrackedScore?.ScorePosition == Flow.Count && Flow.Count > max_online_scores) + TrackedScore.ScorePosition = null; + } + } + private void updateVisibility() => this.FadeTo(AlwaysVisible.Value || configVisibility.Value ? 1 : 0, duration); } From a1af663682cce72d49244c194f072a6a1f064fe5 Mon Sep 17 00:00:00 2001 From: Dragon Date: Sun, 13 Nov 2022 20:49:26 +0100 Subject: [PATCH 0607/2991] Implemented previous messages lookup in the ChatTextBox.cs --- osu.Game/Overlays/Chat/ChatTextBox.cs | 57 +++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/osu.Game/Overlays/Chat/ChatTextBox.cs b/osu.Game/Overlays/Chat/ChatTextBox.cs index 887eb96c15..fc4c2ae727 100644 --- a/osu.Game/Overlays/Chat/ChatTextBox.cs +++ b/osu.Game/Overlays/Chat/ChatTextBox.cs @@ -1,14 +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.Collections.Generic; using osu.Framework.Bindables; +using osu.Framework.Input.Events; using osu.Game.Graphics.UserInterface; using osu.Game.Resources.Localisation.Web; +using osuTK.Input; namespace osu.Game.Overlays.Chat { public class ChatTextBox : FocusedTextBox { + private readonly List messageHistory = new List(); + + private int messageIndex = -1; + + private string originalMessage = string.Empty; + public readonly BindableBool ShowSearch = new BindableBool(); public override bool HandleLeftRightArrows => !ShowSearch.Value; @@ -28,11 +37,59 @@ namespace osu.Game.Overlays.Chat }, true); } + protected override bool OnKeyDown(KeyDownEvent e) + { + /* Behavior: + * add when on last element -> last element stays + * subtract when on first element -> sets to original text + * reset indexing when Text is set to Empty + */ + + switch (e.Key) + { + case Key.Up: + if (messageIndex == -1) + originalMessage = Text; + + if (messageIndex == messageHistory.Count - 1) + return true; + + Text = messageHistory[++messageIndex]; + + return true; + + case Key.Down: + if (messageIndex == -1) + return true; + + if (messageIndex == 0) + { + messageIndex = -1; + Text = originalMessage; + return true; + } + + Text = messageHistory[--messageIndex]; + + return true; + } + + bool onKeyDown = base.OnKeyDown(e); + + if (string.IsNullOrEmpty(Text)) + messageIndex = -1; + + return onKeyDown; + } + protected override void Commit() { if (ShowSearch.Value) return; + messageHistory.Insert(0, Text); + messageIndex = -1; + base.Commit(); } } From b9590320b750d64ed532ce0621f54019940c1f4c Mon Sep 17 00:00:00 2001 From: Dragon Date: Sun, 13 Nov 2022 22:34:02 +0100 Subject: [PATCH 0608/2991] Moved implementation to ChatRecentTextBox.cs and derived ChatTextBox.cs and StandAloneChatDisplay.cs from it. --- osu.Game/Online/Chat/StandAloneChatDisplay.cs | 14 ++-- osu.Game/Overlays/Chat/ChatRecentTextBox.cs | 74 +++++++++++++++++++ osu.Game/Overlays/Chat/ChatTextBox.cs | 60 +-------------- 3 files changed, 83 insertions(+), 65 deletions(-) create mode 100644 osu.Game/Overlays/Chat/ChatRecentTextBox.cs diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs index 81db3f0d53..de0387e017 100644 --- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs +++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs @@ -12,7 +12,6 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Graphics; -using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Chat; using osu.Game.Resources.Localisation.Web; using osuTK.Graphics; @@ -120,17 +119,20 @@ namespace osu.Game.Online.Chat AddInternal(drawableChannel); } - public class ChatTextBox : FocusedTextBox + public class ChatTextBox : ChatRecentTextBox { protected override bool OnKeyDown(KeyDownEvent e) { // Chat text boxes are generally used in places where they retain focus, but shouldn't block interaction with other // elements on the same screen. - switch (e.Key) + if (!HoldFocus) { - case Key.Up: - case Key.Down: - return false; + switch (e.Key) + { + case Key.Up: + case Key.Down: + return false; + } } return base.OnKeyDown(e); diff --git a/osu.Game/Overlays/Chat/ChatRecentTextBox.cs b/osu.Game/Overlays/Chat/ChatRecentTextBox.cs new file mode 100644 index 0000000000..87bc3ee48c --- /dev/null +++ b/osu.Game/Overlays/Chat/ChatRecentTextBox.cs @@ -0,0 +1,74 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Framework.Input.Events; +using osu.Game.Graphics.UserInterface; +using osuTK.Input; + +namespace osu.Game.Overlays.Chat +{ + public class ChatRecentTextBox : FocusedTextBox + { + private readonly List messageHistory = new List(); + + private int messageIndex = -1; + + private string originalMessage = string.Empty; + + protected override bool OnKeyDown(KeyDownEvent e) + { + /* Behavior: + * add when on last element -> last element stays + * subtract when on first element -> sets to original text + * reset indexing when Text is set to Empty + */ + + switch (e.Key) + { + case Key.Up: + if (messageIndex == -1) + originalMessage = Text; + + if (messageIndex == messageHistory.Count - 1) + return true; + + Text = messageHistory[++messageIndex]; + + return true; + + case Key.Down: + if (messageIndex == -1) + return true; + + if (messageIndex == 0) + { + messageIndex = -1; + Text = originalMessage; + return true; + } + + Text = messageHistory[--messageIndex]; + + return true; + } + + bool onKeyDown = base.OnKeyDown(e); + + if (string.IsNullOrEmpty(Text)) + messageIndex = -1; + + return onKeyDown; + } + + protected override void Commit() + { + if (!string.IsNullOrEmpty(Text)) + messageHistory.Insert(0, Text); + + messageIndex = -1; + + base.Commit(); + } + } +} diff --git a/osu.Game/Overlays/Chat/ChatTextBox.cs b/osu.Game/Overlays/Chat/ChatTextBox.cs index fc4c2ae727..d3c1a4ad8b 100644 --- a/osu.Game/Overlays/Chat/ChatTextBox.cs +++ b/osu.Game/Overlays/Chat/ChatTextBox.cs @@ -1,23 +1,13 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Collections.Generic; using osu.Framework.Bindables; -using osu.Framework.Input.Events; -using osu.Game.Graphics.UserInterface; using osu.Game.Resources.Localisation.Web; -using osuTK.Input; namespace osu.Game.Overlays.Chat { - public class ChatTextBox : FocusedTextBox + public class ChatTextBox : ChatRecentTextBox { - private readonly List messageHistory = new List(); - - private int messageIndex = -1; - - private string originalMessage = string.Empty; - public readonly BindableBool ShowSearch = new BindableBool(); public override bool HandleLeftRightArrows => !ShowSearch.Value; @@ -37,59 +27,11 @@ namespace osu.Game.Overlays.Chat }, true); } - protected override bool OnKeyDown(KeyDownEvent e) - { - /* Behavior: - * add when on last element -> last element stays - * subtract when on first element -> sets to original text - * reset indexing when Text is set to Empty - */ - - switch (e.Key) - { - case Key.Up: - if (messageIndex == -1) - originalMessage = Text; - - if (messageIndex == messageHistory.Count - 1) - return true; - - Text = messageHistory[++messageIndex]; - - return true; - - case Key.Down: - if (messageIndex == -1) - return true; - - if (messageIndex == 0) - { - messageIndex = -1; - Text = originalMessage; - return true; - } - - Text = messageHistory[--messageIndex]; - - return true; - } - - bool onKeyDown = base.OnKeyDown(e); - - if (string.IsNullOrEmpty(Text)) - messageIndex = -1; - - return onKeyDown; - } - protected override void Commit() { if (ShowSearch.Value) return; - messageHistory.Insert(0, Text); - messageIndex = -1; - base.Commit(); } } From 6d83af01e21228e56753d200e7aee0c94e0b2e67 Mon Sep 17 00:00:00 2001 From: Terochi Date: Tue, 15 Nov 2022 13:06:02 +0100 Subject: [PATCH 0609/2991] Moved and renamed MessageHistoryTextBox.cs for better fit. --- .../UserInterface/MessageHistoryTextBox.cs} | 21 +++++++++++-------- osu.Game/Online/Chat/StandAloneChatDisplay.cs | 3 ++- osu.Game/Overlays/Chat/ChatTextBox.cs | 3 ++- 3 files changed, 16 insertions(+), 11 deletions(-) rename osu.Game/{Overlays/Chat/ChatRecentTextBox.cs => Graphics/UserInterface/MessageHistoryTextBox.cs} (82%) diff --git a/osu.Game/Overlays/Chat/ChatRecentTextBox.cs b/osu.Game/Graphics/UserInterface/MessageHistoryTextBox.cs similarity index 82% rename from osu.Game/Overlays/Chat/ChatRecentTextBox.cs rename to osu.Game/Graphics/UserInterface/MessageHistoryTextBox.cs index 87bc3ee48c..45497e0451 100644 --- a/osu.Game/Overlays/Chat/ChatRecentTextBox.cs +++ b/osu.Game/Graphics/UserInterface/MessageHistoryTextBox.cs @@ -3,12 +3,11 @@ using System.Collections.Generic; using osu.Framework.Input.Events; -using osu.Game.Graphics.UserInterface; using osuTK.Input; -namespace osu.Game.Overlays.Chat +namespace osu.Game.Graphics.UserInterface { - public class ChatRecentTextBox : FocusedTextBox + public class MessageHistoryTextBox : FocusedTextBox { private readonly List messageHistory = new List(); @@ -16,6 +15,15 @@ namespace osu.Game.Overlays.Chat private string originalMessage = string.Empty; + public MessageHistoryTextBox() + { + Current.ValueChanged += text => + { + if (string.IsNullOrEmpty(text.NewValue)) + messageIndex = -1; + }; + } + protected override bool OnKeyDown(KeyDownEvent e) { /* Behavior: @@ -53,12 +61,7 @@ namespace osu.Game.Overlays.Chat return true; } - bool onKeyDown = base.OnKeyDown(e); - - if (string.IsNullOrEmpty(Text)) - messageIndex = -1; - - return onKeyDown; + return base.OnKeyDown(e); } protected override void Commit() diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs index de0387e017..fe279d50a9 100644 --- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs +++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs @@ -12,6 +12,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Chat; using osu.Game.Resources.Localisation.Web; using osuTK.Graphics; @@ -119,7 +120,7 @@ namespace osu.Game.Online.Chat AddInternal(drawableChannel); } - public class ChatTextBox : ChatRecentTextBox + public class ChatTextBox : MessageHistoryTextBox { protected override bool OnKeyDown(KeyDownEvent e) { diff --git a/osu.Game/Overlays/Chat/ChatTextBox.cs b/osu.Game/Overlays/Chat/ChatTextBox.cs index d3c1a4ad8b..26ff4a5b4e 100644 --- a/osu.Game/Overlays/Chat/ChatTextBox.cs +++ b/osu.Game/Overlays/Chat/ChatTextBox.cs @@ -2,11 +2,12 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Bindables; +using osu.Game.Graphics.UserInterface; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Chat { - public class ChatTextBox : ChatRecentTextBox + public class ChatTextBox : MessageHistoryTextBox { public readonly BindableBool ShowSearch = new BindableBool(); From a79af6671eceb918dd598a0c60d997030f57fdcb Mon Sep 17 00:00:00 2001 From: Terochi Date: Tue, 15 Nov 2022 13:07:05 +0100 Subject: [PATCH 0610/2991] Added SetUp for new tests. --- .../Online/TestSceneChatManipulation.cs | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs b/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs new file mode 100644 index 0000000000..6de2584c72 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs @@ -0,0 +1,74 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable disable + +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Overlays.Chat; + +namespace osu.Game.Tests.Visual.Online +{ + [TestFixture] + public class TestSceneChatManipulation : OsuTestScene + { + private ChatTextBox box; + private OsuSpriteText text; + + [SetUp] + public void SetUp() + { + Schedule(() => + { + Children = new Drawable[] + { + box = new ChatTextBox + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + Width = 0.99f, + }, + text = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + Width = 0.99f, + Y = -box.Height, + Font = OsuFont.Default.With(size: 20), + } + }; + box.OnCommit += (_, __) => + { + text.Text = $"{nameof(box.OnCommit)}: {box.Text}"; + box.Text = string.Empty; + box.TakeFocus(); + text.FadeOutFromOne(1000, Easing.InQuint); + }; + }); + } + + [Test] + public void TestReachingLimitOfMessages() + { + } + + [Test] + public void TestStayOnLastIndex() + { + } + + [Test] + public void TestKeepOriginalMessage() + { + } + + [Test] + public void TestResetIndexOnEmpty() + { + } + } +} From 3d4962e1810e3f53e22125cf1012a5c036dade05 Mon Sep 17 00:00:00 2001 From: Terochi Date: Tue, 15 Nov 2022 16:12:24 +0100 Subject: [PATCH 0611/2991] Added functioning tests. --- .../Online/TestSceneChatManipulation.cs | 59 +++++++++++++++++-- ...ageHistoryTextBox.cs => HistoryTextBox.cs} | 32 +++++----- osu.Game/Online/Chat/StandAloneChatDisplay.cs | 2 +- osu.Game/Overlays/Chat/ChatTextBox.cs | 2 +- 4 files changed, 69 insertions(+), 26 deletions(-) rename osu.Game/Graphics/UserInterface/{MessageHistoryTextBox.cs => HistoryTextBox.cs} (62%) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs b/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs index 6de2584c72..4fe0cb685e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs @@ -3,16 +3,18 @@ #nullable disable +using System.Linq; using NUnit.Framework; using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Overlays.Chat; +using osuTK.Input; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneChatManipulation : OsuTestScene + public class TestSceneChatManipulation : OsuManualInputManagerTestScene { private ChatTextBox box; private OsuSpriteText text; @@ -41,6 +43,7 @@ namespace osu.Game.Tests.Visual.Online Font = OsuFont.Default.With(size: 20), } }; + box.OnCommit += (_, __) => { text.Text = $"{nameof(box.OnCommit)}: {box.Text}"; @@ -48,27 +51,71 @@ namespace osu.Game.Tests.Visual.Online box.TakeFocus(); text.FadeOutFromOne(1000, Easing.InQuint); }; - }); - } - [Test] - public void TestReachingLimitOfMessages() - { + box.TakeFocus(); + }); } [Test] public void TestStayOnLastIndex() { + addMessages(2); + AddRepeatStep("Move to last", () => InputManager.Key(Key.Up), 2); + + string lastText = string.Empty; + AddStep("Move up", () => + { + lastText = box.Text; + InputManager.Key(Key.Up); + }); + + AddAssert("Text hasn't changed", () => lastText == box.Text); } [Test] public void TestKeepOriginalMessage() { + addMessages(1); + AddStep("Start writing", () => box.Text = "A random 文, ..."); + + AddStep("Move up", () => InputManager.Key(Key.Up)); + AddStep("Rewrite old message", () => box.Text = "Old Message"); + + AddStep("Move back down", () => InputManager.Key(Key.Down)); + AddAssert("Text back to previous", () => box.Text == "A random 文, ..."); } [Test] public void TestResetIndexOnEmpty() { + addMessages(2); + AddRepeatStep("Move up", () => InputManager.Key(Key.Up), 2); + AddStep("Remove text", () => box.Text = string.Empty); + + AddStep("Move up again", () => InputManager.Key(Key.Up)); + AddAssert("Back to first message", () => box.Text == "Message 2"); + } + + [Test] + public void TestReachingLimitOfMessages() + { + addMessages(100); + AddAssert("List is full of <100-1>", () => + Enumerable.Range(0, 100).Select(number => $"Message {100 - number}").SequenceEqual(box.MessageHistory)); + + addMessages(2); + AddAssert("List is full of <102-3>", () => + Enumerable.Range(0, 100).Select(number => $"Message {102 - number}").SequenceEqual(box.MessageHistory)); + } + + private void addMessages(int count) + { + int iterations = 0; + AddRepeatStep("Add messages", () => + { + box.Text = $"Message {++iterations}"; + InputManager.Key(Key.Enter); + }, count); } } } diff --git a/osu.Game/Graphics/UserInterface/MessageHistoryTextBox.cs b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs similarity index 62% rename from osu.Game/Graphics/UserInterface/MessageHistoryTextBox.cs rename to osu.Game/Graphics/UserInterface/HistoryTextBox.cs index 45497e0451..1b553576d5 100644 --- a/osu.Game/Graphics/UserInterface/MessageHistoryTextBox.cs +++ b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs @@ -7,56 +7,52 @@ using osuTK.Input; namespace osu.Game.Graphics.UserInterface { - public class MessageHistoryTextBox : FocusedTextBox + public class HistoryTextBox : FocusedTextBox { private readonly List messageHistory = new List(); - private int messageIndex = -1; + public IReadOnlyList MessageHistory => messageHistory; + + private int historyIndex = -1; private string originalMessage = string.Empty; - public MessageHistoryTextBox() + public HistoryTextBox() { Current.ValueChanged += text => { if (string.IsNullOrEmpty(text.NewValue)) - messageIndex = -1; + historyIndex = -1; }; } protected override bool OnKeyDown(KeyDownEvent e) { - /* Behavior: - * add when on last element -> last element stays - * subtract when on first element -> sets to original text - * reset indexing when Text is set to Empty - */ - switch (e.Key) { case Key.Up: - if (messageIndex == -1) + if (historyIndex == -1) originalMessage = Text; - if (messageIndex == messageHistory.Count - 1) + if (historyIndex == messageHistory.Count - 1) return true; - Text = messageHistory[++messageIndex]; + Text = messageHistory[++historyIndex]; return true; case Key.Down: - if (messageIndex == -1) + if (historyIndex == -1) return true; - if (messageIndex == 0) + if (historyIndex == 0) { - messageIndex = -1; + historyIndex = -1; Text = originalMessage; return true; } - Text = messageHistory[--messageIndex]; + Text = messageHistory[--historyIndex]; return true; } @@ -69,7 +65,7 @@ namespace osu.Game.Graphics.UserInterface if (!string.IsNullOrEmpty(Text)) messageHistory.Insert(0, Text); - messageIndex = -1; + historyIndex = -1; base.Commit(); } diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs index fe279d50a9..03728b427f 100644 --- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs +++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs @@ -120,7 +120,7 @@ namespace osu.Game.Online.Chat AddInternal(drawableChannel); } - public class ChatTextBox : MessageHistoryTextBox + public class ChatTextBox : HistoryTextBox { protected override bool OnKeyDown(KeyDownEvent e) { diff --git a/osu.Game/Overlays/Chat/ChatTextBox.cs b/osu.Game/Overlays/Chat/ChatTextBox.cs index 26ff4a5b4e..f0bdbce08d 100644 --- a/osu.Game/Overlays/Chat/ChatTextBox.cs +++ b/osu.Game/Overlays/Chat/ChatTextBox.cs @@ -7,7 +7,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Chat { - public class ChatTextBox : MessageHistoryTextBox + public class ChatTextBox : HistoryTextBox { public readonly BindableBool ShowSearch = new BindableBool(); From 44c3e71746b43337ad8cbaab0410e73d8f959d54 Mon Sep 17 00:00:00 2001 From: Terochi Date: Tue, 15 Nov 2022 18:10:43 +0100 Subject: [PATCH 0612/2991] Reversed indexing --- .../Graphics/UserInterface/HistoryTextBox.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs index 1b553576d5..96c0734d63 100644 --- a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs +++ b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs @@ -13,7 +13,7 @@ namespace osu.Game.Graphics.UserInterface public IReadOnlyList MessageHistory => messageHistory; - private int historyIndex = -1; + private int historyIndex; private string originalMessage = string.Empty; @@ -22,7 +22,7 @@ namespace osu.Game.Graphics.UserInterface Current.ValueChanged += text => { if (string.IsNullOrEmpty(text.NewValue)) - historyIndex = -1; + historyIndex = messageHistory.Count; }; } @@ -31,28 +31,28 @@ namespace osu.Game.Graphics.UserInterface switch (e.Key) { case Key.Up: - if (historyIndex == -1) + if (historyIndex == messageHistory.Count) originalMessage = Text; - if (historyIndex == messageHistory.Count - 1) + if (historyIndex == 0) return true; - Text = messageHistory[++historyIndex]; + Text = messageHistory[--historyIndex]; return true; case Key.Down: - if (historyIndex == -1) + if (historyIndex == messageHistory.Count) return true; - if (historyIndex == 0) + if (historyIndex == messageHistory.Count - 1) { - historyIndex = -1; + historyIndex = messageHistory.Count; Text = originalMessage; return true; } - Text = messageHistory[--historyIndex]; + Text = messageHistory[++historyIndex]; return true; } @@ -63,9 +63,9 @@ namespace osu.Game.Graphics.UserInterface protected override void Commit() { if (!string.IsNullOrEmpty(Text)) - messageHistory.Insert(0, Text); + messageHistory.Add(Text); - historyIndex = -1; + historyIndex = messageHistory.Count; base.Commit(); } From 5253f5309e0224ef993786ffb84fd9d7a64f212e Mon Sep 17 00:00:00 2001 From: Terochi Date: Tue, 15 Nov 2022 23:51:57 +0100 Subject: [PATCH 0613/2991] Added more tests for new features --- .../Online/TestSceneChatManipulation.cs | 75 ++++++++++++++++++- .../Graphics/UserInterface/HistoryTextBox.cs | 57 ++++++++++---- 2 files changed, 116 insertions(+), 16 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs b/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs index 4fe0cb685e..efa4cd41b3 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs @@ -8,7 +8,7 @@ using NUnit.Framework; using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Overlays.Chat; +using osu.Game.Graphics.UserInterface; using osuTK.Input; namespace osu.Game.Tests.Visual.Online @@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.Online [TestFixture] public class TestSceneChatManipulation : OsuManualInputManagerTestScene { - private ChatTextBox box; + private HistoryTextBox box; private OsuSpriteText text; [SetUp] @@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual.Online { Children = new Drawable[] { - box = new ChatTextBox + box = new HistoryTextBox(5) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -56,6 +56,75 @@ namespace osu.Game.Tests.Visual.Online }); } + [Test] + public void TestEmptyHistory() + { + const string temp = "Temp message"; + AddStep("Set text", () => box.Text = temp); + + AddStep("Move down", () => InputManager.Key(Key.Down)); + AddAssert("Text is the same", () => box.Text == temp); + + AddStep("Move Up", () => InputManager.Key(Key.Up)); + AddAssert("Text is the same", () => box.Text == temp); + } + + [Test] + public void TestPartialHistory() + { + addMessages(2); + + const string temp = "Temp message"; + AddStep("Set text", () => box.Text = temp); + + AddStep("Move down", () => InputManager.Key(Key.Down)); + AddAssert("Text is the same", () => box.Text == temp); + + AddRepeatStep("Move Up", () => InputManager.Key(Key.Up), 2); + AddAssert("Same as 1st message", () => box.Text == "Message 1"); + + AddStep("Move Up", () => InputManager.Key(Key.Up)); + AddAssert("Text is the same", () => box.Text == "Message 1"); + + AddRepeatStep("Move down", () => InputManager.Key(Key.Down), 2); + AddAssert("Same as temp message", () => box.Text == temp); + + AddStep("Move down", () => InputManager.Key(Key.Down)); + AddAssert("Text is the same", () => box.Text == temp); + } + + [Test] + public void TestFullHistory() + { + addMessages(5); + AddAssert("History saved as <1-5>", () => + Enumerable.Range(1, 5).Select(number => $"Message {number}").SequenceEqual(box.MessageHistory)); + + const string temp = "Temp message"; + AddStep("Set text", () => box.Text = temp); + + AddStep("Move down", () => InputManager.Key(Key.Down)); + AddAssert("Text is the same", () => box.Text == temp); + + addMessages(2); + AddAssert("Overwrote history to <3-7>", () => + Enumerable.Range(3, 5).Select(number => $"Message {number}").SequenceEqual(box.MessageHistory)); + + AddStep("Set text", () => box.Text = temp); + + AddRepeatStep("Move Up", () => InputManager.Key(Key.Up), 5); + AddAssert("Same as 3rd message", () => box.Text == "Message 3"); + + AddStep("Move Up", () => InputManager.Key(Key.Up)); + AddAssert("Text is the same", () => box.Text == "Message 3"); + + AddRepeatStep("Move down", () => InputManager.Key(Key.Down), 4); + AddAssert("Same as previous message", () => box.Text == "Message 7"); + + AddStep("Move down", () => InputManager.Key(Key.Down)); + AddAssert("Same as temp message", () => box.Text == temp); + } + [Test] public void TestStayOnLastIndex() { diff --git a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs index 96c0734d63..c91e5dcb41 100644 --- a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs +++ b/osu.Game/Graphics/UserInterface/HistoryTextBox.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 System.Collections.Generic; using osu.Framework.Input.Events; using osuTK.Input; @@ -9,50 +10,71 @@ namespace osu.Game.Graphics.UserInterface { public class HistoryTextBox : FocusedTextBox { - private readonly List messageHistory = new List(); + private readonly int historyLimit; + + private readonly List messageHistory; public IReadOnlyList MessageHistory => messageHistory; - private int historyIndex; + private int startIndex; private string originalMessage = string.Empty; + private int nullIndex => -1; + private int historyIndex = -1; + private int endIndex => (messageHistory.Count + startIndex - 1) % Math.Max(1, messageHistory.Count); - public HistoryTextBox() + public HistoryTextBox(int historyLimit = 100) { + this.historyLimit = historyLimit; + messageHistory = new List(historyLimit); + Current.ValueChanged += text => { if (string.IsNullOrEmpty(text.NewValue)) - historyIndex = messageHistory.Count; + historyIndex = nullIndex; }; } + public string GetOldMessage(int index) + { + if (index < 0 || index >= messageHistory.Count) + throw new ArgumentOutOfRangeException(); + + return messageHistory[(startIndex + index) % messageHistory.Count]; + } + protected override bool OnKeyDown(KeyDownEvent e) { switch (e.Key) { case Key.Up: - if (historyIndex == messageHistory.Count) + if (historyIndex == nullIndex) + { + historyIndex = endIndex; originalMessage = Text; + } - if (historyIndex == 0) + if (historyIndex == startIndex) return true; - Text = messageHistory[--historyIndex]; + historyIndex = (historyLimit + historyIndex - 1) % historyLimit; + Text = messageHistory[historyIndex]; return true; case Key.Down: - if (historyIndex == messageHistory.Count) + if (historyIndex == nullIndex) return true; - if (historyIndex == messageHistory.Count - 1) + if (historyIndex == endIndex) { - historyIndex = messageHistory.Count; + historyIndex = nullIndex; Text = originalMessage; return true; } - Text = messageHistory[++historyIndex]; + historyIndex = (historyIndex + 1) % historyLimit; + Text = messageHistory[historyIndex]; return true; } @@ -63,9 +85,18 @@ namespace osu.Game.Graphics.UserInterface protected override void Commit() { if (!string.IsNullOrEmpty(Text)) - messageHistory.Add(Text); + { + if (messageHistory.Count == historyLimit) + { + messageHistory[startIndex++] = Text; + } + else + { + messageHistory.Add(Text); + } + } - historyIndex = messageHistory.Count; + historyIndex = nullIndex; base.Commit(); } From 19dc31c7ae6c3b5a2ad6bdd3422e1d60eb5ec8d5 Mon Sep 17 00:00:00 2001 From: Terochi Date: Wed, 16 Nov 2022 13:12:43 +0100 Subject: [PATCH 0614/2991] Changed tests. --- .../Online/TestSceneChatManipulation.cs | 75 +++++++------------ 1 file changed, 29 insertions(+), 46 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs b/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs index efa4cd41b3..3bff321d0d 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs @@ -6,6 +6,7 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Graphics; +using osu.Framework.Input; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; @@ -19,6 +20,8 @@ namespace osu.Game.Tests.Visual.Online private HistoryTextBox box; private OsuSpriteText text; + private int messageCounter; + [SetUp] public void SetUp() { @@ -52,6 +55,8 @@ namespace osu.Game.Tests.Visual.Online text.FadeOutFromOne(1000, Easing.InQuint); }; + messageCounter = 0; + box.TakeFocus(); }); } @@ -97,8 +102,8 @@ namespace osu.Game.Tests.Visual.Online public void TestFullHistory() { addMessages(5); - AddAssert("History saved as <1-5>", () => - Enumerable.Range(1, 5).Select(number => $"Message {number}").SequenceEqual(box.MessageHistory)); + AddAssert("History saved as <5-1>", () => + Enumerable.Range(0, 5).Select(number => $"Message {5 - number}").SequenceEqual(box.MessageHistory)); const string temp = "Temp message"; AddStep("Set text", () => box.Text = temp); @@ -107,8 +112,8 @@ namespace osu.Game.Tests.Visual.Online AddAssert("Text is the same", () => box.Text == temp); addMessages(2); - AddAssert("Overwrote history to <3-7>", () => - Enumerable.Range(3, 5).Select(number => $"Message {number}").SequenceEqual(box.MessageHistory)); + AddAssert("Overrode history to <7-3>", () => + Enumerable.Range(0, 5).Select(number => $"Message {7 - number}").SequenceEqual(box.MessageHistory)); AddStep("Set text", () => box.Text = temp); @@ -126,63 +131,41 @@ namespace osu.Game.Tests.Visual.Online } [Test] - public void TestStayOnLastIndex() + public void TestOverrideFullHistory() { - addMessages(2); - AddRepeatStep("Move to last", () => InputManager.Key(Key.Up), 2); + addMessages(5); + AddAssert("History saved as <5-1>", () => + Enumerable.Range(0, 5).Select(number => $"Message {5 - number}").SequenceEqual(box.MessageHistory)); - string lastText = string.Empty; - AddStep("Move up", () => - { - lastText = box.Text; - InputManager.Key(Key.Up); - }); - - AddAssert("Text hasn't changed", () => lastText == box.Text); + addMessages(6); + AddAssert("Overrode history to <11-7>", () => + Enumerable.Range(0, 5).Select(number => $"Message {11 - number}").SequenceEqual(box.MessageHistory)); } [Test] - public void TestKeepOriginalMessage() - { - addMessages(1); - AddStep("Start writing", () => box.Text = "A random 文, ..."); - - AddStep("Move up", () => InputManager.Key(Key.Up)); - AddStep("Rewrite old message", () => box.Text = "Old Message"); - - AddStep("Move back down", () => InputManager.Key(Key.Down)); - AddAssert("Text back to previous", () => box.Text == "A random 文, ..."); - } - - [Test] - public void TestResetIndexOnEmpty() + public void TestResetIndex() { addMessages(2); - AddRepeatStep("Move up", () => InputManager.Key(Key.Up), 2); + + AddRepeatStep("Move Up", () => InputManager.Key(Key.Up), 2); + AddAssert("Same as 1st message", () => box.Text == "Message 1"); + AddStep("Remove text", () => box.Text = string.Empty); + AddStep("Move Up", () => InputManager.Key(Key.Up)); + AddAssert("Same as previous message", () => box.Text == "Message 2"); - AddStep("Move up again", () => InputManager.Key(Key.Up)); - AddAssert("Back to first message", () => box.Text == "Message 2"); - } - - [Test] - public void TestReachingLimitOfMessages() - { - addMessages(100); - AddAssert("List is full of <100-1>", () => - Enumerable.Range(0, 100).Select(number => $"Message {100 - number}").SequenceEqual(box.MessageHistory)); - - addMessages(2); - AddAssert("List is full of <102-3>", () => - Enumerable.Range(0, 100).Select(number => $"Message {102 - number}").SequenceEqual(box.MessageHistory)); + AddStep("Move Up", () => InputManager.Key(Key.Up)); + AddStep("Select text", () => InputManager.Keys(PlatformAction.SelectAll)); + AddStep("Replace text", () => box.Text = "New text"); + AddStep("Move Up", () => InputManager.Key(Key.Up)); + AddAssert("Same as previous message", () => box.Text == "Message 2"); } private void addMessages(int count) { - int iterations = 0; AddRepeatStep("Add messages", () => { - box.Text = $"Message {++iterations}"; + box.Text = $"Message {++messageCounter}"; InputManager.Key(Key.Enter); }, count); } From 0100c01b82f547ced0d3b040fbba14d88b13847e Mon Sep 17 00:00:00 2001 From: Terochi Date: Wed, 16 Nov 2022 13:16:01 +0100 Subject: [PATCH 0615/2991] Implemented finite limit of stored history. --- .../Graphics/UserInterface/HistoryTextBox.cs | 64 +++++++++++-------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs index c91e5dcb41..6c9df5aca2 100644 --- a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs +++ b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using osu.Framework.Input.Events; using osuTK.Input; @@ -12,16 +13,23 @@ namespace osu.Game.Graphics.UserInterface { private readonly int historyLimit; + private bool everythingSelected; + + public int HistoryLength => messageHistory.Count; + private readonly List messageHistory; - public IReadOnlyList MessageHistory => messageHistory; + public IReadOnlyList MessageHistory => + Enumerable.Range(0, HistoryLength).Select(GetOldMessage).ToList(); + + private string originalMessage = string.Empty; + + private int historyIndex = -1; private int startIndex; - private string originalMessage = string.Empty; - private int nullIndex => -1; - private int historyIndex = -1; - private int endIndex => (messageHistory.Count + startIndex - 1) % Math.Max(1, messageHistory.Count); + private int getNormalizedIndex(int index) => + (HistoryLength + startIndex - index - 1) % HistoryLength; public HistoryTextBox(int historyLimit = 100) { @@ -30,17 +38,27 @@ namespace osu.Game.Graphics.UserInterface Current.ValueChanged += text => { - if (string.IsNullOrEmpty(text.NewValue)) - historyIndex = nullIndex; + if (string.IsNullOrEmpty(text.NewValue) || everythingSelected) + { + historyIndex = -1; + everythingSelected = false; + } }; } + protected override void OnTextSelectionChanged(TextSelectionType selectionType) + { + everythingSelected = SelectedText == Text; + + base.OnTextSelectionChanged(selectionType); + } + public string GetOldMessage(int index) { - if (index < 0 || index >= messageHistory.Count) + if (index < 0 || index >= HistoryLength) throw new ArgumentOutOfRangeException(); - return messageHistory[(startIndex + index) % messageHistory.Count]; + return HistoryLength == 0 ? string.Empty : messageHistory[getNormalizedIndex(index)]; } protected override bool OnKeyDown(KeyDownEvent e) @@ -48,33 +66,28 @@ namespace osu.Game.Graphics.UserInterface switch (e.Key) { case Key.Up: - if (historyIndex == nullIndex) - { - historyIndex = endIndex; - originalMessage = Text; - } - - if (historyIndex == startIndex) + if (historyIndex == HistoryLength - 1) return true; - historyIndex = (historyLimit + historyIndex - 1) % historyLimit; - Text = messageHistory[historyIndex]; + if (historyIndex == -1) + originalMessage = Text; + + Text = messageHistory[getNormalizedIndex(++historyIndex)]; return true; case Key.Down: - if (historyIndex == nullIndex) + if (historyIndex == -1) return true; - if (historyIndex == endIndex) + if (historyIndex == 0) { - historyIndex = nullIndex; + historyIndex = -1; Text = originalMessage; return true; } - historyIndex = (historyIndex + 1) % historyLimit; - Text = messageHistory[historyIndex]; + Text = messageHistory[getNormalizedIndex(--historyIndex)]; return true; } @@ -86,9 +99,10 @@ namespace osu.Game.Graphics.UserInterface { if (!string.IsNullOrEmpty(Text)) { - if (messageHistory.Count == historyLimit) + if (HistoryLength == historyLimit) { messageHistory[startIndex++] = Text; + startIndex %= historyLimit; } else { @@ -96,7 +110,7 @@ namespace osu.Game.Graphics.UserInterface } } - historyIndex = nullIndex; + historyIndex = -1; base.Commit(); } From a9747d367cc9a7321c414622a89777e89f321ca0 Mon Sep 17 00:00:00 2001 From: Dragon Date: Thu, 17 Nov 2022 10:18:17 +0100 Subject: [PATCH 0616/2991] Cleaning up --- .../TestSceneHistoryTextBox.cs} | 23 ++++++------- .../Graphics/UserInterface/HistoryTextBox.cs | 34 +++++++++---------- 2 files changed, 28 insertions(+), 29 deletions(-) rename osu.Game.Tests/Visual/{Online/TestSceneChatManipulation.cs => UserInterface/TestSceneHistoryTextBox.cs} (95%) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs similarity index 95% rename from osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs rename to osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs index 3bff321d0d..f27711f512 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatManipulation.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs @@ -12,16 +12,18 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osuTK.Input; -namespace osu.Game.Tests.Visual.Online +namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneChatManipulation : OsuManualInputManagerTestScene + public class TestSceneHistoryTextBox : OsuManualInputManagerTestScene { - private HistoryTextBox box; - private OsuSpriteText text; + private const string temp = "Temp message"; private int messageCounter; + private HistoryTextBox box; + private OsuSpriteText text; + [SetUp] public void SetUp() { @@ -49,6 +51,9 @@ namespace osu.Game.Tests.Visual.Online box.OnCommit += (_, __) => { + if (string.IsNullOrEmpty(box.Text)) + return; + text.Text = $"{nameof(box.OnCommit)}: {box.Text}"; box.Text = string.Empty; box.TakeFocus(); @@ -64,7 +69,6 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestEmptyHistory() { - const string temp = "Temp message"; AddStep("Set text", () => box.Text = temp); AddStep("Move down", () => InputManager.Key(Key.Down)); @@ -78,8 +82,6 @@ namespace osu.Game.Tests.Visual.Online public void TestPartialHistory() { addMessages(2); - - const string temp = "Temp message"; AddStep("Set text", () => box.Text = temp); AddStep("Move down", () => InputManager.Key(Key.Down)); @@ -102,21 +104,18 @@ namespace osu.Game.Tests.Visual.Online public void TestFullHistory() { addMessages(5); + AddStep("Set text", () => box.Text = temp); AddAssert("History saved as <5-1>", () => Enumerable.Range(0, 5).Select(number => $"Message {5 - number}").SequenceEqual(box.MessageHistory)); - const string temp = "Temp message"; - AddStep("Set text", () => box.Text = temp); - AddStep("Move down", () => InputManager.Key(Key.Down)); AddAssert("Text is the same", () => box.Text == temp); addMessages(2); + AddStep("Set text", () => box.Text = temp); AddAssert("Overrode history to <7-3>", () => Enumerable.Range(0, 5).Select(number => $"Message {7 - number}").SequenceEqual(box.MessageHistory)); - AddStep("Set text", () => box.Text = temp); - AddRepeatStep("Move Up", () => InputManager.Key(Key.Up), 5); AddAssert("Same as 3rd message", () => box.Text == "Message 3"); diff --git a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs index 6c9df5aca2..bebe21da47 100644 --- a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs +++ b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs @@ -12,27 +12,27 @@ namespace osu.Game.Graphics.UserInterface public class HistoryTextBox : FocusedTextBox { private readonly int historyLimit; - - private bool everythingSelected; - - public int HistoryLength => messageHistory.Count; - private readonly List messageHistory; public IReadOnlyList MessageHistory => Enumerable.Range(0, HistoryLength).Select(GetOldMessage).ToList(); - private string originalMessage = string.Empty; - - private int historyIndex = -1; + public int HistoryLength => messageHistory.Count; private int startIndex; + private int selectedIndex = -1; + + private string originalMessage = string.Empty; + private bool everythingSelected; private int getNormalizedIndex(int index) => (HistoryLength + startIndex - index - 1) % HistoryLength; public HistoryTextBox(int historyLimit = 100) { + if (historyLimit <= 0) + throw new ArgumentOutOfRangeException(); + this.historyLimit = historyLimit; messageHistory = new List(historyLimit); @@ -40,7 +40,7 @@ namespace osu.Game.Graphics.UserInterface { if (string.IsNullOrEmpty(text.NewValue) || everythingSelected) { - historyIndex = -1; + selectedIndex = -1; everythingSelected = false; } }; @@ -66,28 +66,28 @@ namespace osu.Game.Graphics.UserInterface switch (e.Key) { case Key.Up: - if (historyIndex == HistoryLength - 1) + if (selectedIndex == HistoryLength - 1) return true; - if (historyIndex == -1) + if (selectedIndex == -1) originalMessage = Text; - Text = messageHistory[getNormalizedIndex(++historyIndex)]; + Text = messageHistory[getNormalizedIndex(++selectedIndex)]; return true; case Key.Down: - if (historyIndex == -1) + if (selectedIndex == -1) return true; - if (historyIndex == 0) + if (selectedIndex == 0) { - historyIndex = -1; + selectedIndex = -1; Text = originalMessage; return true; } - Text = messageHistory[getNormalizedIndex(--historyIndex)]; + Text = messageHistory[getNormalizedIndex(--selectedIndex)]; return true; } @@ -110,7 +110,7 @@ namespace osu.Game.Graphics.UserInterface } } - historyIndex = -1; + selectedIndex = -1; base.Commit(); } From a25c94d567e9bdc4407e9882b0917bd85c6ba2ed Mon Sep 17 00:00:00 2001 From: Dragon Date: Thu, 17 Nov 2022 11:35:13 +0100 Subject: [PATCH 0617/2991] Replacing structure to use LimitedCapacityQueue.cs --- .../UserInterface/TestSceneHistoryTextBox.cs | 11 +-- .../Graphics/UserInterface/HistoryTextBox.cs | 70 +++++++------------ 2 files changed, 31 insertions(+), 50 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs index f27711f512..862777c500 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs @@ -49,7 +49,7 @@ namespace osu.Game.Tests.Visual.UserInterface } }; - box.OnCommit += (_, __) => + box.OnCommit += (_, _) => { if (string.IsNullOrEmpty(box.Text)) return; @@ -70,6 +70,7 @@ namespace osu.Game.Tests.Visual.UserInterface public void TestEmptyHistory() { AddStep("Set text", () => box.Text = temp); + AddAssert("History is empty", () => !box.GetMessageHistory().Any()); AddStep("Move down", () => InputManager.Key(Key.Down)); AddAssert("Text is the same", () => box.Text == temp); @@ -106,7 +107,7 @@ namespace osu.Game.Tests.Visual.UserInterface addMessages(5); AddStep("Set text", () => box.Text = temp); AddAssert("History saved as <5-1>", () => - Enumerable.Range(0, 5).Select(number => $"Message {5 - number}").SequenceEqual(box.MessageHistory)); + Enumerable.Range(0, 5).Select(number => $"Message {5 - number}").SequenceEqual(box.GetMessageHistory())); AddStep("Move down", () => InputManager.Key(Key.Down)); AddAssert("Text is the same", () => box.Text == temp); @@ -114,7 +115,7 @@ namespace osu.Game.Tests.Visual.UserInterface addMessages(2); AddStep("Set text", () => box.Text = temp); AddAssert("Overrode history to <7-3>", () => - Enumerable.Range(0, 5).Select(number => $"Message {7 - number}").SequenceEqual(box.MessageHistory)); + Enumerable.Range(0, 5).Select(number => $"Message {7 - number}").SequenceEqual(box.GetMessageHistory())); AddRepeatStep("Move Up", () => InputManager.Key(Key.Up), 5); AddAssert("Same as 3rd message", () => box.Text == "Message 3"); @@ -134,11 +135,11 @@ namespace osu.Game.Tests.Visual.UserInterface { addMessages(5); AddAssert("History saved as <5-1>", () => - Enumerable.Range(0, 5).Select(number => $"Message {5 - number}").SequenceEqual(box.MessageHistory)); + Enumerable.Range(0, 5).Select(number => $"Message {5 - number}").SequenceEqual(box.GetMessageHistory())); addMessages(6); AddAssert("Overrode history to <11-7>", () => - Enumerable.Range(0, 5).Select(number => $"Message {11 - number}").SequenceEqual(box.MessageHistory)); + Enumerable.Range(0, 5).Select(number => $"Message {11 - number}").SequenceEqual(box.GetMessageHistory())); } [Test] diff --git a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs index bebe21da47..17858ea16d 100644 --- a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs +++ b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs @@ -1,46 +1,44 @@ // 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 osu.Framework.Input.Events; +using osu.Game.Rulesets.Difficulty.Utils; using osuTK.Input; namespace osu.Game.Graphics.UserInterface { public class HistoryTextBox : FocusedTextBox { - private readonly int historyLimit; - private readonly List messageHistory; + private readonly LimitedCapacityQueue messageHistory; - public IReadOnlyList MessageHistory => - Enumerable.Range(0, HistoryLength).Select(GetOldMessage).ToList(); + public IEnumerable GetMessageHistory() + { + if (HistoryCount == 0) + yield break; - public int HistoryLength => messageHistory.Count; + for (int i = HistoryCount - 1; i >= 0; i--) + yield return messageHistory[i]; + } - private int startIndex; - private int selectedIndex = -1; + public int HistoryCount => messageHistory.Count; + + private int selectedIndex; private string originalMessage = string.Empty; private bool everythingSelected; - private int getNormalizedIndex(int index) => - (HistoryLength + startIndex - index - 1) % HistoryLength; + public string GetOldMessage(int index) => messageHistory[HistoryCount - index - 1]; - public HistoryTextBox(int historyLimit = 100) + public HistoryTextBox(int capacity = 100) { - if (historyLimit <= 0) - throw new ArgumentOutOfRangeException(); - - this.historyLimit = historyLimit; - messageHistory = new List(historyLimit); + messageHistory = new LimitedCapacityQueue(capacity); Current.ValueChanged += text => { if (string.IsNullOrEmpty(text.NewValue) || everythingSelected) { - selectedIndex = -1; + selectedIndex = HistoryCount; everythingSelected = false; } }; @@ -53,41 +51,33 @@ namespace osu.Game.Graphics.UserInterface base.OnTextSelectionChanged(selectionType); } - public string GetOldMessage(int index) - { - if (index < 0 || index >= HistoryLength) - throw new ArgumentOutOfRangeException(); - - return HistoryLength == 0 ? string.Empty : messageHistory[getNormalizedIndex(index)]; - } - protected override bool OnKeyDown(KeyDownEvent e) { switch (e.Key) { case Key.Up: - if (selectedIndex == HistoryLength - 1) + if (selectedIndex == 0) return true; - if (selectedIndex == -1) + if (selectedIndex == HistoryCount) originalMessage = Text; - Text = messageHistory[getNormalizedIndex(++selectedIndex)]; + Text = messageHistory[--selectedIndex]; return true; case Key.Down: - if (selectedIndex == -1) + if (selectedIndex == HistoryCount) return true; - if (selectedIndex == 0) + if (selectedIndex == HistoryCount - 1) { - selectedIndex = -1; + selectedIndex = HistoryCount; Text = originalMessage; return true; } - Text = messageHistory[getNormalizedIndex(--selectedIndex)]; + Text = messageHistory[++selectedIndex]; return true; } @@ -98,19 +88,9 @@ namespace osu.Game.Graphics.UserInterface protected override void Commit() { if (!string.IsNullOrEmpty(Text)) - { - if (HistoryLength == historyLimit) - { - messageHistory[startIndex++] = Text; - startIndex %= historyLimit; - } - else - { - messageHistory.Add(Text); - } - } + messageHistory.Enqueue(Text); - selectedIndex = -1; + selectedIndex = HistoryCount; base.Commit(); } From fa00fc5c6d2ee22f393087a921c7b637f1f3823a Mon Sep 17 00:00:00 2001 From: Piggey Date: Thu, 17 Nov 2022 13:27:56 +0100 Subject: [PATCH 0618/2991] change scoresType to be a bindable --- osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs index bf9cdc8db7..39f584efd5 100644 --- a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Play.HUD this.trackingUser = trackingUser; } - private PlayBeatmapDetailArea.TabType scoresType; + private Bindable scoresType = new Bindable(); [BackgroundDependencyLoader] private void load(OsuConfigManager config) @@ -52,7 +52,7 @@ namespace osu.Game.Screens.Play.HUD config.BindWith(OsuSetting.GameplayLeaderboard, configVisibility); // a way to differentiate scores taken from online ranking to local scores - scoresType = config.Get(OsuSetting.BeatmapDetailTab); + scoresType = config.GetBindable(OsuSetting.BeatmapDetailTab); } protected override void LoadComplete() @@ -104,7 +104,7 @@ namespace osu.Game.Screens.Play.HUD { base.sort(); - if (scoresType != PlayBeatmapDetailArea.TabType.Local) + if (scoresType.Value != PlayBeatmapDetailArea.TabType.Local) { // change displayed potision to '-' when there are 50 already submitted scores and tracked score is last if (TrackedScore?.ScorePosition == Flow.Count && Flow.Count > max_online_scores) From 5e4ade3bee2ee0c77e49a00d4ce13a014c72dcb3 Mon Sep 17 00:00:00 2001 From: Piggey Date: Thu, 17 Nov 2022 13:28:04 +0100 Subject: [PATCH 0619/2991] add tests --- .../TestSceneSoloGameplayLeaderboard.cs | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs index 60ed0012ae..edda0ab416 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs @@ -15,6 +15,7 @@ using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; using osu.Game.Screens.Play.HUD; +using osu.Game.Screens.Select; namespace osu.Game.Tests.Visual.Gameplay { @@ -26,6 +27,7 @@ namespace osu.Game.Tests.Visual.Gameplay private readonly BindableList scores = new BindableList(); private readonly Bindable configVisibility = new Bindable(); + private readonly Bindable beatmapTabType = new Bindable(); private SoloGameplayLeaderboard leaderboard = null!; @@ -33,6 +35,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void load(OsuConfigManager config) { config.BindWith(OsuSetting.GameplayLeaderboard, configVisibility); + config.BindWith(OsuSetting.BeatmapDetailTab, beatmapTabType); } [SetUpSteps] @@ -70,6 +73,25 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("toggle expanded", () => leaderboard.Expanded.Value = !leaderboard.Expanded.Value); } + [Test] + public void TestTrackedScorePosition() + { + AddStep("change TabType to global", () => beatmapTabType.Value = PlayBeatmapDetailArea.TabType.Global); + AddUntilStep("tracked player is #50", () => leaderboard.TrackedScore?.ScorePosition! == 50); + + AddStep("change TabType to local", () => beatmapTabType.Value = PlayBeatmapDetailArea.TabType.Local); + AddUntilStep("tracked player is #50", () => leaderboard.TrackedScore?.ScorePosition! == 50); + + AddStep("add one more score", () => scores.Add(new ScoreInfo { User = new APIUser { Username = "New player 1" }, TotalScore = RNG.Next(600000, 1000000) })); + AddUntilStep("tracked player is #51", () => leaderboard.TrackedScore?.ScorePosition! == 51); + + AddStep("change TabType to global", () => beatmapTabType.Value = PlayBeatmapDetailArea.TabType.Global); + AddUntilStep("tracked player is -", () => leaderboard.TrackedScore?.ScorePosition! == null); + + AddStep("change TabType to country", () => beatmapTabType.Value = PlayBeatmapDetailArea.TabType.Country); + AddUntilStep("tracked player is -", () => leaderboard.TrackedScore?.ScorePosition! == null); + } + [Test] public void TestVisibility() { @@ -86,7 +108,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("leaderboard still visible", () => leaderboard.Alpha == 1); } - private static List createSampleScores() + private static List createSampleScores(int numRandScores = 50) { return new[] { @@ -95,7 +117,7 @@ namespace osu.Game.Tests.Visual.Gameplay new ScoreInfo { User = new APIUser { Username = @"spaceman_atlas" }, TotalScore = RNG.Next(500000, 1000000) }, new ScoreInfo { User = new APIUser { Username = @"frenzibyte" }, TotalScore = RNG.Next(500000, 1000000) }, new ScoreInfo { User = new APIUser { Username = @"Susko3" }, TotalScore = RNG.Next(500000, 1000000) }, - }.Concat(Enumerable.Range(0, 50).Select(i => new ScoreInfo { User = new APIUser { Username = $"User {i + 1}" }, TotalScore = 1000000 - i * 10000 })).ToList(); + }.Concat(Enumerable.Range(0, 49 - 5).Select(i => new ScoreInfo { User = new APIUser { Username = $"User {i + 1}" }, TotalScore = 1000000 - i * 10000 })).ToList(); } } } From 20d87fbed4c9bc1079a4da3d94a4eb2ada093ad5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 17 Nov 2022 23:05:34 +0900 Subject: [PATCH 0620/2991] Eagerly dispose of triangles intro textures to avoid holding for full length of game session --- osu.Game/Screens/Menu/IntroTriangles.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index 05a6d25303..4ec877b85a 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -224,8 +224,8 @@ namespace osu.Game.Screens.Menu { rulesetsScale.ScaleTo(0.8f, 1000); rulesets.FadeIn().ScaleTo(1).TransformSpacingTo(new Vector2(200, 0)); - welcomeText.FadeOut(); - triangles.FadeOut(); + welcomeText.FadeOut().Expire(); + triangles.FadeOut().Expire(); } using (BeginDelayedSequence(rulesets_2)) @@ -307,7 +307,7 @@ namespace osu.Game.Screens.Menu } [BackgroundDependencyLoader] - private void load(TextureStore textures) + private void load(LargeTextureStore textures) { InternalChildren = new Drawable[] { From a3e8cc1663be4dab2ebfa9cbd59f0f5adec95da5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 17 Nov 2022 23:41:35 +0900 Subject: [PATCH 0621/2991] Mark beatmap listing placeholder textures as large --- osu.Game/Overlays/BeatmapListingOverlay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index c278c9cb93..b78a432194 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -287,7 +287,7 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(TextureStore textures) + private void load(LargeTextureStore textures) { AddInternal(new FillFlowContainer { @@ -332,7 +332,7 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(TextureStore textures) + private void load(LargeTextureStore textures) { AddInternal(new FillFlowContainer { From 63c185551111aafdcabfc89cd093349ebd420065 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 17 Nov 2022 23:41:49 +0900 Subject: [PATCH 0622/2991] Avoid loading beatmap listing placeholders until required --- osu.Game/Overlays/BeatmapListingOverlay.cs | 43 ++++------------------ 1 file changed, 8 insertions(+), 35 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index b78a432194..5e922973ec 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -41,11 +41,8 @@ namespace osu.Game.Overlays private IBindable apiUser; - private Drawable currentContent; private Container panelTarget; private FillFlowContainer foundContent; - private NotFoundDrawable notFoundContent; - private SupporterRequiredDrawable supporterRequiredContent; private BeatmapListingFilterControl filterControl; public BeatmapListingOverlay() @@ -86,11 +83,6 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.X, Masking = true, Padding = new MarginPadding { Horizontal = 20 }, - Children = new Drawable[] - { - notFoundContent = new NotFoundDrawable(), - supporterRequiredContent = new SupporterRequiredDrawable(), - } } }, }, @@ -107,7 +99,7 @@ namespace osu.Game.Overlays apiUser.BindValueChanged(_ => Schedule(() => { if (api.IsLoggedIn) - addContentToResultsArea(Drawable.Empty()); + replaceResultsAreaContent(Drawable.Empty()); })); } @@ -155,8 +147,9 @@ namespace osu.Game.Overlays if (searchResult.Type == BeatmapListingFilterControl.SearchResultType.SupporterOnlyFilters) { - supporterRequiredContent.UpdateText(searchResult.SupporterOnlyFiltersUsed); - addContentToResultsArea(supporterRequiredContent); + var supporterOnly = new SupporterRequiredDrawable(); + supporterOnly.UpdateText(searchResult.SupporterOnlyFiltersUsed); + replaceResultsAreaContent(supporterOnly); return; } @@ -167,13 +160,13 @@ namespace osu.Game.Overlays //No matches case if (!newCards.Any()) { - addContentToResultsArea(notFoundContent); + replaceResultsAreaContent(new NotFoundDrawable()); return; } var content = createCardContainerFor(newCards); - panelLoadTask = LoadComponentAsync(foundContent = content, addContentToResultsArea, (cancellationToken = new CancellationTokenSource()).Token); + panelLoadTask = LoadComponentAsync(foundContent = content, replaceResultsAreaContent, (cancellationToken = new CancellationTokenSource()).Token); } else { @@ -221,36 +214,16 @@ namespace osu.Game.Overlays return content; } - private void addContentToResultsArea(Drawable content) + private void replaceResultsAreaContent(Drawable content) { Loading.Hide(); lastFetchDisplayedTime = Time.Current; - if (content == currentContent) - return; - - var lastContent = currentContent; - - if (lastContent != null) - { - lastContent.FadeOut(); - if (!isPlaceholderContent(lastContent)) - lastContent.Expire(); - } - - if (!content.IsAlive) - panelTarget.Add(content); + panelTarget.Child = content; content.FadeInFromZero(); - currentContent = content; } - /// - /// Whether is a static placeholder reused multiple times by this overlay. - /// - private bool isPlaceholderContent(Drawable drawable) - => drawable == notFoundContent || drawable == supporterRequiredContent; - private void onCardSizeChanged() { if (foundContent?.IsAlive != true || !foundContent.Any()) From 73e4827d36a57e72a8e26a1ab31882939f19a6a1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 17 Nov 2022 23:55:40 +0900 Subject: [PATCH 0623/2991] Avoid loading overlay headers until first open Also switches them to use non-atlased target as they won't benefit much from atlasing. --- osu.Game/Overlays/OverlayHeaderBackground.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/OverlayHeaderBackground.cs b/osu.Game/Overlays/OverlayHeaderBackground.cs index c47f16272f..540b28d9b2 100644 --- a/osu.Game/Overlays/OverlayHeaderBackground.cs +++ b/osu.Game/Overlays/OverlayHeaderBackground.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays Height = 80; RelativeSizeAxes = Axes.X; Masking = true; - InternalChild = new Background(textureName); + InternalChild = new DelayedLoadWrapper(() => new Background(textureName)); } private class Background : Sprite @@ -36,10 +36,16 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(TextureStore textures) + private void load(LargeTextureStore textures) { Texture = textures.Get(textureName); } + + protected override void LoadComplete() + { + base.LoadComplete(); + this.FadeInFromZero(500, Easing.OutQuint); + } } } } From b37e9c0266088f187329c47b9490eb5e889798fa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 00:01:53 +0900 Subject: [PATCH 0624/2991] Fix news post images never unloading from memory after first display --- .../Overlays/Dashboard/Home/News/FeaturedNewsItemPanel.cs | 7 +------ osu.Game/Overlays/News/NewsCard.cs | 7 ++----- osu.Game/Overlays/News/NewsPostBackground.cs | 7 +++++++ 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/osu.Game/Overlays/Dashboard/Home/News/FeaturedNewsItemPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/FeaturedNewsItemPanel.cs index 8f5c942b6e..1d904526fd 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/FeaturedNewsItemPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/FeaturedNewsItemPanel.cs @@ -119,22 +119,17 @@ namespace osu.Game.Overlays.Dashboard.Home.News [BackgroundDependencyLoader] private void load(GameHost host) { - NewsPostBackground bg; - - Child = new DelayedLoadWrapper(bg = new NewsPostBackground(post.FirstImage) + Child = new DelayedLoadUnloadWrapper(() => new NewsPostBackground(post.FirstImage) { RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fill, Anchor = Anchor.Centre, Origin = Anchor.Centre, - Alpha = 0 }) { RelativeSizeAxes = Axes.Both }; - bg.OnLoadComplete += d => d.FadeIn(250, Easing.In); - TooltipText = "view in browser"; Action = () => host.OpenUrlExternally("https://osu.ppy.sh/home/news/" + post.Slug); diff --git a/osu.Game/Overlays/News/NewsCard.cs b/osu.Game/Overlays/News/NewsCard.cs index eb76522e11..c8e0b0c7ef 100644 --- a/osu.Game/Overlays/News/NewsCard.cs +++ b/osu.Game/Overlays/News/NewsCard.cs @@ -49,7 +49,6 @@ namespace osu.Game.Overlays.News Action = () => host.OpenUrlExternally("https://osu.ppy.sh/home/news/" + post.Slug); } - NewsPostBackground bg; AddRange(new Drawable[] { background = new Box @@ -71,14 +70,14 @@ namespace osu.Game.Overlays.News CornerRadius = 6, Children = new Drawable[] { - new DelayedLoadWrapper(bg = new NewsPostBackground(post.FirstImage) + new DelayedLoadUnloadWrapper(() => new NewsPostBackground(post.FirstImage) { RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fill, Anchor = Anchor.Centre, Origin = Anchor.Centre, Alpha = 0 - }) + }, timeBeforeUnload: 5000) { RelativeSizeAxes = Axes.Both }, @@ -116,8 +115,6 @@ namespace osu.Game.Overlays.News IdleColour = colourProvider.Background4; HoverColour = colourProvider.Background3; - bg.OnLoadComplete += d => d.FadeIn(250, Easing.In); - main.AddParagraph(post.Title, t => t.Font = OsuFont.GetFont(size: 20, weight: FontWeight.SemiBold)); main.AddParagraph(post.Preview, t => t.Font = OsuFont.GetFont(size: 12)); // Should use sans-serif font main.AddParagraph("by ", t => t.Font = OsuFont.GetFont(size: 12)); diff --git a/osu.Game/Overlays/News/NewsPostBackground.cs b/osu.Game/Overlays/News/NewsPostBackground.cs index bddca8f7ec..b77623842c 100644 --- a/osu.Game/Overlays/News/NewsPostBackground.cs +++ b/osu.Game/Overlays/News/NewsPostBackground.cs @@ -4,6 +4,7 @@ #nullable disable using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; @@ -25,6 +26,12 @@ namespace osu.Game.Overlays.News Texture = store.Get(createUrl(sourceUrl)); } + protected override void LoadComplete() + { + base.LoadComplete(); + this.FadeInFromZero(500, Easing.OutQuint); + } + private string createUrl(string source) { if (string.IsNullOrEmpty(source)) From eb8f6626abebab7e24ccb8afe34303c3c87f5a06 Mon Sep 17 00:00:00 2001 From: Piggey Date: Thu, 17 Nov 2022 21:38:09 +0100 Subject: [PATCH 0625/2991] revert changes from `GameplayLeaderboard` tests --- .../Visual/Gameplay/TestSceneGameplayLeaderboard.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs index a385060d62..171ae829a9 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs @@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("add many scores in one go", () => { - for (int i = 0; i < 49; i++) + for (int i = 0; i < 32; i++) createRandomScore(new APIUser { Username = $"Player {i + 1}" }); // Add player at end to force an animation down the whole list. @@ -61,12 +61,6 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for tracked score fully visible", () => leaderboard.ScreenSpaceDrawQuad.Intersects(leaderboard.TrackedScore!.ScreenSpaceDrawQuad)); - AddUntilStep("ensure player is #50", () => leaderboard.CheckPositionByUsername("You", 50)); - - AddStep("add one more player", () => createRandomScore(new APIUser { Username = "Player 50" })); - - AddUntilStep("ensure player is #?", () => leaderboard.CheckPositionByUsername("You", null)); - AddStep("change score to middle", () => playerScore.Value = 1000000); AddWaitStep("wait for movement", 5); AddUntilStep("wait for tracked score fully visible", () => leaderboard.ScreenSpaceDrawQuad.Intersects(leaderboard.TrackedScore!.ScreenSpaceDrawQuad)); From 53769479c772acdfe5aadc324a9a9d7e88e9c097 Mon Sep 17 00:00:00 2001 From: Piggey Date: Thu, 17 Nov 2022 21:42:15 +0100 Subject: [PATCH 0626/2991] oh oops --- .../Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs index edda0ab416..fc1a67e285 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs @@ -108,7 +108,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("leaderboard still visible", () => leaderboard.Alpha == 1); } - private static List createSampleScores(int numRandScores = 50) + private static List createSampleScores() { return new[] { @@ -117,7 +117,7 @@ namespace osu.Game.Tests.Visual.Gameplay new ScoreInfo { User = new APIUser { Username = @"spaceman_atlas" }, TotalScore = RNG.Next(500000, 1000000) }, new ScoreInfo { User = new APIUser { Username = @"frenzibyte" }, TotalScore = RNG.Next(500000, 1000000) }, new ScoreInfo { User = new APIUser { Username = @"Susko3" }, TotalScore = RNG.Next(500000, 1000000) }, - }.Concat(Enumerable.Range(0, 49 - 5).Select(i => new ScoreInfo { User = new APIUser { Username = $"User {i + 1}" }, TotalScore = 1000000 - i * 10000 })).ToList(); + }.Concat(Enumerable.Range(0, 44).Select(i => new ScoreInfo { User = new APIUser { Username = $"User {i + 1}" }, TotalScore = 1000000 - i * 10000 })).ToList(); } } } From eb691266c1e8c9dd71bb44452e9a6871105974d3 Mon Sep 17 00:00:00 2001 From: Piggey Date: Thu, 17 Nov 2022 21:50:39 +0100 Subject: [PATCH 0627/2991] cleanup --- osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs index 39f584efd5..bf83c9a3c6 100644 --- a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs @@ -39,13 +39,13 @@ namespace osu.Game.Screens.Play.HUD /// public readonly Bindable AlwaysVisible = new Bindable(true); + private Bindable scoresType = new Bindable(); + public SoloGameplayLeaderboard(IUser trackingUser) { this.trackingUser = trackingUser; } - private Bindable scoresType = new Bindable(); - [BackgroundDependencyLoader] private void load(OsuConfigManager config) { From 93c2280754d8bb859eb26914e90fa7e5eaf69313 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 10:35:05 +0900 Subject: [PATCH 0628/2991] Fix supporter filters text not being set correctly --- osu.Game/Overlays/BeatmapListingOverlay.cs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index 5e922973ec..2d9583b864 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -147,8 +147,7 @@ namespace osu.Game.Overlays if (searchResult.Type == BeatmapListingFilterControl.SearchResultType.SupporterOnlyFilters) { - var supporterOnly = new SupporterRequiredDrawable(); - supporterOnly.UpdateText(searchResult.SupporterOnlyFiltersUsed); + var supporterOnly = new SupporterRequiredDrawable(searchResult.SupporterOnlyFiltersUsed); replaceResultsAreaContent(supporterOnly); return; } @@ -297,11 +296,15 @@ namespace osu.Game.Overlays { private LinkFlowContainer supporterRequiredText; - public SupporterRequiredDrawable() + private readonly List filtersUsed; + + public SupporterRequiredDrawable(List filtersUsed) { RelativeSizeAxes = Axes.X; Height = 225; Alpha = 0; + + this.filtersUsed = filtersUsed; } [BackgroundDependencyLoader] @@ -333,14 +336,9 @@ namespace osu.Game.Overlays }, } }); - } - - public void UpdateText(List filters) - { - supporterRequiredText.Clear(); supporterRequiredText.AddText( - BeatmapsStrings.ListingSearchSupporterFilterQuoteDefault(string.Join(" and ", filters), "").ToString(), + BeatmapsStrings.ListingSearchSupporterFilterQuoteDefault(string.Join(" and ", filtersUsed), "").ToString(), t => { t.Font = OsuFont.GetFont(size: 16); From b53f9baf6a8d034dd36fd3a2d271205119dbb362 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 11:21:12 +0900 Subject: [PATCH 0629/2991] Fix `NowPlayingOverlay` loading background texture too early (and permanently) --- osu.Game/Overlays/NowPlayingOverlay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index 900b4bebf0..949f1e7b96 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -100,7 +100,7 @@ namespace osu.Game.Overlays }, Children = new[] { - background = new Background(), + background = Empty(), title = new OsuSpriteText { Origin = Anchor.BottomCentre, @@ -413,7 +413,7 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(TextureStore textures) + private void load(LargeTextureStore textures) { sprite.Texture = beatmap?.Background ?? textures.Get(@"Backgrounds/bg4"); } From 82829867db1522a7a255b97fbc8c17a1083a84c7 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 18 Nov 2022 07:07:56 +0300 Subject: [PATCH 0630/2991] Fix beatmap options test failure due to no beatmap being selected --- osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index d58887c090..e500efede3 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -436,6 +436,8 @@ namespace osu.Game.Tests.Visual.Navigation { AddUntilStep("Wait for toolbar to load", () => Game.Toolbar.IsLoaded); + AddStep("import beatmap", () => BeatmapImportHelper.LoadQuickOszIntoOsu(Game).WaitSafely()); + TestPlaySongSelect songSelect = null; PushAndConfirm(() => songSelect = new TestPlaySongSelect()); From a5d22195f2bdd39bb030f2536b93af908070131e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 13:45:46 +0900 Subject: [PATCH 0631/2991] Fix potential incorrect connection state resulting in null reference --- osu.Game/Online/PersistentEndpointClientConnector.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/PersistentEndpointClientConnector.cs b/osu.Game/Online/PersistentEndpointClientConnector.cs index 2c4e127723..be76644745 100644 --- a/osu.Game/Online/PersistentEndpointClientConnector.cs +++ b/osu.Game/Online/PersistentEndpointClientConnector.cs @@ -145,7 +145,9 @@ namespace osu.Game.Online private async Task onConnectionClosed(Exception? ex, CancellationToken cancellationToken) { - isConnected.Value = false; + bool hasBeenCancelled = cancellationToken.IsCancellationRequested; + + await disconnect(true); if (ex != null) await handleErrorAndDelay(ex, cancellationToken).ConfigureAwait(false); @@ -153,7 +155,7 @@ namespace osu.Game.Online Logger.Log($"{ClientName} disconnected", LoggingTarget.Network); // make sure a disconnect wasn't triggered (and this is still the active connection). - if (!cancellationToken.IsCancellationRequested) + if (!hasBeenCancelled) await Task.Run(connect, default).ConfigureAwait(false); } @@ -174,7 +176,9 @@ namespace osu.Game.Online } finally { + isConnected.Value = false; CurrentConnection = null; + if (takeLock) connectionLock.Release(); } From 551192b413ab59053383107a336b9a72a98e9df2 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 18 Nov 2022 13:55:37 +0900 Subject: [PATCH 0632/2991] Refactor a bit for readability --- .../Overlays/Settings/Sections/Input/KeyBindingRow.cs | 10 +++++----- .../Settings/Sections/Input/KeyBindingsSubsection.cs | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs index 12fd6f0746..832aa759d0 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs @@ -34,9 +34,9 @@ namespace osu.Game.Overlays.Settings.Sections.Input public class KeyBindingRow : Container, IFilterable { /// - /// Invoked when binding of this row finalises with a change being written. + /// Invoked when the binding of this row is updated with a change being written. /// - public Action BindingFinalised { get; set; } + public Action BindingUpdated { get; set; } private readonly object action; private readonly IEnumerable bindings; @@ -385,7 +385,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input finalise(false); } - private void finalise(bool changedKey = true) + private void finalise(bool hasChanged = true) { if (bindTarget != null) { @@ -398,8 +398,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input { // schedule to ensure we don't instantly get focus back on next OnMouseClick (see AcceptFocus impl.) bindTarget = null; - if (changedKey) - BindingFinalised?.Invoke(this); + if (hasChanged) + BindingUpdated?.Invoke(this); }); } diff --git a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs index a3f378e3c9..98d569948f 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs @@ -56,7 +56,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input { AllowMainMouseButtons = Ruleset != null, Defaults = defaultGroup.Select(d => d.KeyCombination), - BindingFinalised = bindingCompleted + BindingUpdated = onBindingUpdated }); } @@ -66,7 +66,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input }); } - private void bindingCompleted(KeyBindingRow sender) + private void onBindingUpdated(KeyBindingRow sender) { if (AutoAdvanceTarget) { From e4d134a82057b3d6f05feab5f6251612488a61d5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 14:07:40 +0900 Subject: [PATCH 0633/2991] Reduce time waited on a score submission token from 60 to 30s --- osu.Game/Screens/Play/SubmittingPlayer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/SubmittingPlayer.cs b/osu.Game/Screens/Play/SubmittingPlayer.cs index 345bd5a134..fb296d7988 100644 --- a/osu.Game/Screens/Play/SubmittingPlayer.cs +++ b/osu.Game/Screens/Play/SubmittingPlayer.cs @@ -85,7 +85,7 @@ namespace osu.Game.Screens.Play api.Queue(req); // Generally a timeout would not happen here as APIAccess will timeout first. - if (!tcs.Task.Wait(60000)) + if (!tcs.Task.Wait(30000)) req.TriggerFailure(new InvalidOperationException("Token retrieval timed out (request never run)")); return true; From 964ceddf83360c24ae0cabc4e895e537237bc2c1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 14:21:37 +0900 Subject: [PATCH 0634/2991] Fix API queue only being flushed once while in a failing state --- osu.Game/Online/API/APIAccess.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 8ac2e2d453..65f78e1fd7 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -419,7 +419,7 @@ namespace osu.Game.Online.API failureCount++; log.Add($@"API failure count is now {failureCount}"); - if (failureCount >= 3 && State.Value == APIState.Online) + if (failureCount >= 3) { state.Value = APIState.Failing; flushQueue(); From d47c46d1443be45ad90ca2e70780b21a94aa1080 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 18 Nov 2022 14:16:12 +0900 Subject: [PATCH 0635/2991] Compute raw score in-line Saves on an allocation (though it seems to only be a ValueType so it shouldn't be a big deal) and a tail-call. --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 2b6e40b94e..899d149cbc 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -335,24 +335,21 @@ namespace osu.Game.Rulesets.Scoring [Pure] public long ComputeScore(ScoringMode mode, double accuracyRatio, double comboRatio, long bonusScore, int totalBasicHitObjects) { + double accuracyScore = accuracyPortion * accuracyRatio; + double comboScore = comboPortion * comboRatio; + double rawScore = (max_score * (accuracyScore + comboScore) + bonusScore) * scoreMultiplier; + switch (mode) { default: case ScoringMode.Standardised: - return (long)Math.Round(computeRawScore()); + return (long)Math.Round(rawScore); case ScoringMode.Classic: // This gives a similar feeling to osu!stable scoring (ScoreV1) while keeping classic scoring as only a constant multiple of standardised scoring. // The invariant is important to ensure that scores don't get re-ordered on leaderboards between the two scoring modes. - double scaledStandardised = computeRawScore() / max_score; - return (long)Math.Round(Math.Pow(scaledStandardised * Math.Max(1, totalBasicHitObjects), 2) * ClassicScoreMultiplier); - } - - double computeRawScore() - { - double accuracyScore = accuracyPortion * accuracyRatio; - double comboScore = comboPortion * comboRatio; - return (max_score * (accuracyScore + comboScore) + bonusScore) * scoreMultiplier; + double scaledRawScore = rawScore / max_score; + return (long)Math.Round(Math.Pow(scaledRawScore * Math.Max(1, totalBasicHitObjects), 2) * ClassicScoreMultiplier); } } From 5fc0d45675475d0932c15f566ba5c131d81ab406 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 14:29:10 +0900 Subject: [PATCH 0636/2991] Fix triangle button flash effect looking incorrect --- osu.Game/Graphics/UserInterface/OsuButton.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index 9140815f32..dae5de2d65 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -4,6 +4,7 @@ #nullable disable using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -69,6 +70,8 @@ namespace osu.Game.Graphics.UserInterface protected Box Background; protected SpriteText SpriteText; + private readonly Box flashLayer; + public OsuButton(HoverSampleSet? hoverSounds = HoverSampleSet.Button) { Height = 40; @@ -99,6 +102,14 @@ namespace osu.Game.Graphics.UserInterface Depth = float.MinValue }, SpriteText = CreateText(), + flashLayer = new Box + { + RelativeSizeAxes = Axes.Both, + Blending = BlendingParameters.Additive, + Depth = float.MinValue, + Colour = Color4.White.Opacity(0.5f), + Alpha = 0, + }, } }); @@ -125,7 +136,7 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnClick(ClickEvent e) { if (Enabled.Value) - Background.FlashColour(Color4.White, 800, Easing.OutQuint); + flashLayer.FadeOutFromOne(800, Easing.OutQuint); return base.OnClick(e); } From b0faa009c1d6262a08a5f6bd0b0256b6101cfb7c Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 2 Nov 2022 11:30:29 +0900 Subject: [PATCH 0637/2991] Add some debugging for multiplayer test failures --- .../Online/Multiplayer/MultiplayerClient.cs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/osu.Game/Online/Multiplayer/MultiplayerClient.cs b/osu.Game/Online/Multiplayer/MultiplayerClient.cs index 75334952f0..b39781ebc2 100644 --- a/osu.Game/Online/Multiplayer/MultiplayerClient.cs +++ b/osu.Game/Online/Multiplayer/MultiplayerClient.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; +using Newtonsoft.Json; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Development; @@ -727,13 +728,20 @@ namespace osu.Game.Online.Multiplayer if (Room == null) return; - Debug.Assert(APIRoom != null); + try + { + Debug.Assert(APIRoom != null); - Room.Playlist[Room.Playlist.IndexOf(Room.Playlist.Single(existing => existing.ID == item.ID))] = item; + Room.Playlist[Room.Playlist.IndexOf(Room.Playlist.Single(existing => existing.ID == item.ID))] = item; - int existingIndex = APIRoom.Playlist.IndexOf(APIRoom.Playlist.Single(existing => existing.ID == item.ID)); - APIRoom.Playlist.RemoveAt(existingIndex); - APIRoom.Playlist.Insert(existingIndex, createPlaylistItem(item)); + int existingIndex = APIRoom.Playlist.IndexOf(APIRoom.Playlist.Single(existing => existing.ID == item.ID)); + APIRoom.Playlist.RemoveAt(existingIndex); + APIRoom.Playlist.Insert(existingIndex, createPlaylistItem(item)); + } + catch (Exception ex) + { + throw new AggregateException($"Item: {JsonConvert.SerializeObject(createPlaylistItem(item))}\n\nRoom:{JsonConvert.SerializeObject(APIRoom)}", ex); + } ItemChanged?.Invoke(item); RoomUpdated?.Invoke(); From 45f5849301c2c8b990a179485ac9a1d1fc470bcb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 15:33:13 +0900 Subject: [PATCH 0638/2991] Add more test coverage to `TestSceneKeyBindingPanel` --- .../Settings/TestSceneKeyBindingPanel.cs | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index d7d073e908..99b8be0114 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -40,6 +40,33 @@ namespace osu.Game.Tests.Visual.Settings AddWaitStep("wait for scroll", 5); } + [Test] + public void TestBindingSingleKey() + { + scrollToAndStartBinding("Increase volume"); + AddStep("press k", () => InputManager.Key(Key.K)); + checkBinding("Increase volume", "K"); + } + + [Test] + public void TestBindingSingleModifier() + { + scrollToAndStartBinding("Increase volume"); + AddStep("press shift", () => InputManager.PressKey(Key.ShiftLeft)); + AddStep("release shift", () => InputManager.ReleaseKey(Key.ShiftLeft)); + checkBinding("Increase volume", "LShift"); + } + + [Test] + public void TestBindingSingleKeyWithModifier() + { + scrollToAndStartBinding("Increase volume"); + AddStep("press shift", () => InputManager.PressKey(Key.ShiftLeft)); + AddStep("press k", () => InputManager.Key(Key.K)); + AddStep("release shift", () => InputManager.ReleaseKey(Key.ShiftLeft)); + checkBinding("Increase volume", "LShift-K"); + } + [Test] public void TestBindingMouseWheelToNonGameplay() { @@ -169,7 +196,8 @@ namespace osu.Game.Tests.Visual.Settings AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType>().First().Alpha == 0); - AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.Defaults.ElementAt(0))); + AddAssert("binding cleared", + () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.Defaults.ElementAt(0))); } [Test] @@ -198,7 +226,8 @@ namespace osu.Game.Tests.Visual.Settings AddUntilStep("restore button hidden", () => settingsKeyBindingRow.ChildrenOfType>().First().Alpha == 0); - AddAssert("binding cleared", () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.Defaults.ElementAt(0))); + AddAssert("binding cleared", + () => settingsKeyBindingRow.ChildrenOfType().ElementAt(0).KeyBinding.KeyCombination.Equals(settingsKeyBindingRow.Defaults.ElementAt(0))); } [Test] @@ -256,8 +285,8 @@ namespace osu.Game.Tests.Visual.Settings var firstRow = panel.ChildrenOfType().First(r => r.ChildrenOfType().Any(s => s.Text.ToString() == name)); var firstButton = firstRow.ChildrenOfType().First(); - return firstButton.Text.Text == keyName; - }); + return firstButton.Text.Text.ToString(); + }, () => Is.EqualTo(keyName)); } private void scrollToAndStartBinding(string name) From cb8275ee755d23d109e61d164282bc08bf529cfd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 15:34:26 +0900 Subject: [PATCH 0639/2991] Add failing test coverage to `TestSceneKeyBindingPanel` for multiple non-modifiers being bound --- .../Visual/Settings/TestSceneKeyBindingPanel.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index 99b8be0114..bd54591b9b 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -40,6 +40,16 @@ namespace osu.Game.Tests.Visual.Settings AddWaitStep("wait for scroll", 5); } + [Test] + public void TestBindingTwoNonModifiers() + { + AddStep("press j", () => InputManager.PressKey(Key.J)); + scrollToAndStartBinding("Increase volume"); + AddStep("press k", () => InputManager.Key(Key.K)); + AddStep("release j", () => InputManager.ReleaseKey(Key.J)); + checkBinding("Increase volume", "K"); + } + [Test] public void TestBindingSingleKey() { From e658efbefa9a6452da5b36d894bf6840342ba9f5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 15:20:46 +0900 Subject: [PATCH 0640/2991] Fix being able to bind two non-modifier keys to the same binding --- .../Settings/Sections/Input/KeyBindingRow.cs | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs index c91a6a48d4..6ce8a188e6 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs @@ -226,7 +226,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input } } - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState), KeyCombination.FromMouseButton(e.Button)); return true; } @@ -252,7 +252,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input { if (bindTarget.IsHovered) { - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState, e.ScrollDelta)); + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState, e.ScrollDelta), KeyCombination.FromScrollDelta(e.ScrollDelta).First()); finalise(); return true; } @@ -263,10 +263,10 @@ namespace osu.Game.Overlays.Settings.Sections.Input protected override bool OnKeyDown(KeyDownEvent e) { - if (!HasFocus) + if (!HasFocus || e.Repeat) return false; - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState), KeyCombination.FromKey(e.Key)); if (!isModifier(e.Key)) finalise(); return true; @@ -288,7 +288,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input if (!HasFocus) return false; - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState), KeyCombination.FromJoystickButton(e.Button)); finalise(); return true; @@ -310,7 +310,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input if (!HasFocus) return false; - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState), KeyCombination.FromMidiKey(e.Key)); finalise(); return true; @@ -332,7 +332,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input if (!HasFocus) return false; - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState), KeyCombination.FromTabletAuxiliaryButton(e.Button)); finalise(); return true; @@ -354,7 +354,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input if (!HasFocus) return false; - bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState)); + bindTarget.UpdateKeyCombination(KeyCombination.FromInputState(e.CurrentState), KeyCombination.FromTabletPenButton(e.Button)); finalise(); return true; @@ -563,6 +563,14 @@ namespace osu.Game.Overlays.Settings.Sections.Input } } + /// + /// Update from a key combination, only allowing a single non-modifier key to be specified. + /// + /// A generated from the full input state. + /// The key which triggered this update, and should be used as the binding. + public void UpdateKeyCombination(KeyCombination fullState, InputKey triggerKey) => + UpdateKeyCombination(new KeyCombination(fullState.Keys.Where(KeyCombination.IsModifierKey).Append(triggerKey))); + public void UpdateKeyCombination(KeyCombination newCombination) { if (KeyBinding.RulesetName != null && !RealmKeyBindingStore.CheckValidForGameplay(newCombination)) From 90cd38632391e799b43cf865d1b8fcad1df54cc3 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 18 Nov 2022 09:40:08 +0300 Subject: [PATCH 0641/2991] Fix timeline potentially scrolling at extents while not dragging --- .../Components/Timeline/TimelineHitObjectBlueprint.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index 974e240552..20ef128ee9 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -436,8 +436,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { base.OnDragEnd(e); - OnDragHandled?.Invoke(null); + dragOperation?.Cancel(); + dragOperation = null; + changeHandler?.EndChange(); + OnDragHandled?.Invoke(null); } } From e2aca8dc9073694983188ed10637879f16975b90 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 18 Nov 2022 09:46:50 +0300 Subject: [PATCH 0642/2991] Suppress nullable warning for now --- osu.Game.Tests/Database/LegacyBeatmapImporterTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Database/LegacyBeatmapImporterTest.cs b/osu.Game.Tests/Database/LegacyBeatmapImporterTest.cs index 1df3d336ee..e7fdb52d2f 100644 --- a/osu.Game.Tests/Database/LegacyBeatmapImporterTest.cs +++ b/osu.Game.Tests/Database/LegacyBeatmapImporterTest.cs @@ -65,7 +65,7 @@ namespace osu.Game.Tests.Database private class TestLegacyBeatmapImporter : LegacyBeatmapImporter { public TestLegacyBeatmapImporter() - : base(null) + : base(null!) { } From d17c091d639cbf330d9cd1e535ec267074c6c5b4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 15:47:31 +0900 Subject: [PATCH 0643/2991] Move constant to a better location --- osu.Game/Online/API/Requests/GetScoresRequest.cs | 2 ++ osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index 966e69938c..7d1d26b75d 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -16,6 +16,8 @@ namespace osu.Game.Online.API.Requests { public class GetScoresRequest : APIRequest { + public const int MAX_SCORES_PER_REQUEST = 50; + private readonly IBeatmapInfo beatmapInfo; private readonly BeatmapLeaderboardScope scope; private readonly IRulesetInfo ruleset; diff --git a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs index bf83c9a3c6..243634ee36 100644 --- a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs @@ -7,6 +7,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Configuration; +using osu.Game.Online.API.Requests; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; using osu.Game.Screens.Select; @@ -17,7 +18,6 @@ namespace osu.Game.Screens.Play.HUD public class SoloGameplayLeaderboard : GameplayLeaderboard { private const int duration = 100; - private const int max_online_scores = 50; // BAD! private readonly Bindable configVisibility = new Bindable(); private readonly IUser trackingUser; @@ -107,7 +107,7 @@ namespace osu.Game.Screens.Play.HUD if (scoresType.Value != PlayBeatmapDetailArea.TabType.Local) { // change displayed potision to '-' when there are 50 already submitted scores and tracked score is last - if (TrackedScore?.ScorePosition == Flow.Count && Flow.Count > max_online_scores) + if (TrackedScore?.ScorePosition == Flow.Count && Flow.Count > GetScoresRequest.MAX_SCORES_PER_REQUEST) TrackedScore.ScorePosition = null; } } From e4f522aad1344084857a42659c51a33baea05bc6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 15:47:37 +0900 Subject: [PATCH 0644/2991] Fix inspections / typos --- osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs | 4 ++-- osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs index 2a47964118..7e8c2401dd 100644 --- a/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs @@ -62,7 +62,7 @@ namespace osu.Game.Screens.Play.HUD { base.LoadComplete(); - Scheduler.AddDelayed(sort, 1000, true); + Scheduler.AddDelayed(Sort, 1000, true); } /// @@ -158,7 +158,7 @@ namespace osu.Game.Screens.Play.HUD } } - protected virtual void sort() + protected virtual void Sort() { if (sorting.IsValid) return; diff --git a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs index 243634ee36..0a2f72121d 100644 --- a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs @@ -100,13 +100,13 @@ namespace osu.Game.Screens.Play.HUD local.DisplayOrder.Value = long.MaxValue; } - protected override void sort() + protected override void Sort() { - base.sort(); + base.Sort(); if (scoresType.Value != PlayBeatmapDetailArea.TabType.Local) { - // change displayed potision to '-' when there are 50 already submitted scores and tracked score is last + // change displayed position to '-' when there are 50 already submitted scores and tracked score is last if (TrackedScore?.ScorePosition == Flow.Count && Flow.Count > GetScoresRequest.MAX_SCORES_PER_REQUEST) TrackedScore.ScorePosition = null; } From 20af8217f4d738bbe7a8019ba236e928c4ffe170 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 15:50:41 +0900 Subject: [PATCH 0645/2991] Tidy up bindable flow --- .../Screens/Play/HUD/SoloGameplayLeaderboard.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs index 0a2f72121d..e9e015f96d 100644 --- a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs @@ -20,6 +20,9 @@ namespace osu.Game.Screens.Play.HUD private const int duration = 100; private readonly Bindable configVisibility = new Bindable(); + + private readonly Bindable scoreSource = new Bindable(); + private readonly IUser trackingUser; public readonly IBindableList Scores = new BindableList(); @@ -39,8 +42,6 @@ namespace osu.Game.Screens.Play.HUD /// public readonly Bindable AlwaysVisible = new Bindable(true); - private Bindable scoresType = new Bindable(); - public SoloGameplayLeaderboard(IUser trackingUser) { this.trackingUser = trackingUser; @@ -50,14 +51,13 @@ namespace osu.Game.Screens.Play.HUD private void load(OsuConfigManager config) { config.BindWith(OsuSetting.GameplayLeaderboard, configVisibility); - - // a way to differentiate scores taken from online ranking to local scores - scoresType = config.GetBindable(OsuSetting.BeatmapDetailTab); + config.BindWith(OsuSetting.BeatmapDetailTab, scoreSource); } protected override void LoadComplete() { base.LoadComplete(); + Scores.BindCollectionChanged((_, _) => Scheduler.AddOnce(showScores), true); // Alpha will be updated via `updateVisibility` below. @@ -104,9 +104,9 @@ namespace osu.Game.Screens.Play.HUD { base.Sort(); - if (scoresType.Value != PlayBeatmapDetailArea.TabType.Local) + // change displayed position to '-' when there are 50 already submitted scores and tracked score is last + if (scoreSource.Value != PlayBeatmapDetailArea.TabType.Local) { - // change displayed position to '-' when there are 50 already submitted scores and tracked score is last if (TrackedScore?.ScorePosition == Flow.Count && Flow.Count > GetScoresRequest.MAX_SCORES_PER_REQUEST) TrackedScore.ScorePosition = null; } From aff218dfd528d9900246248a990d2b9312271054 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 15:52:39 +0900 Subject: [PATCH 0646/2991] Redirect through validity function rather than overriding `Sort` --- osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs | 8 +++++--- osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs | 10 +++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs index 7e8c2401dd..47b67fba00 100644 --- a/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs @@ -62,7 +62,7 @@ namespace osu.Game.Screens.Play.HUD { base.LoadComplete(); - Scheduler.AddDelayed(Sort, 1000, true); + Scheduler.AddDelayed(sort, 1000, true); } /// @@ -158,7 +158,7 @@ namespace osu.Game.Screens.Play.HUD } } - protected virtual void Sort() + private void sort() { if (sorting.IsValid) return; @@ -171,12 +171,14 @@ namespace osu.Game.Screens.Play.HUD for (int i = 0; i < Flow.Count; i++) { Flow.SetLayoutPosition(orderedByScore[i], i); - orderedByScore[i].ScorePosition = i + 1; + orderedByScore[i].ScorePosition = CheckValidScorePosition(i + 1) ? i + 1 : null; } sorting.Validate(); } + protected virtual bool CheckValidScorePosition(int i) => true; + private class InputDisabledScrollContainer : OsuScrollContainer { public InputDisabledScrollContainer() diff --git a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs index e9e015f96d..0df3200adb 100644 --- a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs @@ -100,16 +100,16 @@ namespace osu.Game.Screens.Play.HUD local.DisplayOrder.Value = long.MaxValue; } - protected override void Sort() + protected override bool CheckValidScorePosition(int i) { - base.Sort(); - // change displayed position to '-' when there are 50 already submitted scores and tracked score is last if (scoreSource.Value != PlayBeatmapDetailArea.TabType.Local) { - if (TrackedScore?.ScorePosition == Flow.Count && Flow.Count > GetScoresRequest.MAX_SCORES_PER_REQUEST) - TrackedScore.ScorePosition = null; + if (i == Flow.Count && Flow.Count > GetScoresRequest.MAX_SCORES_PER_REQUEST) + return false; } + + return base.CheckValidScorePosition(i); } private void updateVisibility() => From 0a520c979ed9d0cae8dd8c32f83702b41c026283 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 15:59:40 +0900 Subject: [PATCH 0647/2991] Update test to split out per-type tests --- .../TestSceneSoloGameplayLeaderboard.cs | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs index fc1a67e285..d357c52d8a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs @@ -73,23 +73,17 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("toggle expanded", () => leaderboard.Expanded.Value = !leaderboard.Expanded.Value); } - [Test] - public void TestTrackedScorePosition() + [TestCase(PlayBeatmapDetailArea.TabType.Local, 51)] + [TestCase(PlayBeatmapDetailArea.TabType.Global, null)] + [TestCase(PlayBeatmapDetailArea.TabType.Country, null)] + [TestCase(PlayBeatmapDetailArea.TabType.Friends, null)] + public void TestTrackedScorePosition(PlayBeatmapDetailArea.TabType tabType, int? expectedOverflowIndex) { - AddStep("change TabType to global", () => beatmapTabType.Value = PlayBeatmapDetailArea.TabType.Global); - AddUntilStep("tracked player is #50", () => leaderboard.TrackedScore?.ScorePosition! == 50); - - AddStep("change TabType to local", () => beatmapTabType.Value = PlayBeatmapDetailArea.TabType.Local); - AddUntilStep("tracked player is #50", () => leaderboard.TrackedScore?.ScorePosition! == 50); + AddStep($"change TabType to {tabType}", () => beatmapTabType.Value = tabType); + AddUntilStep("tracked player is #50", () => leaderboard.TrackedScore?.ScorePosition, () => Is.EqualTo(50)); AddStep("add one more score", () => scores.Add(new ScoreInfo { User = new APIUser { Username = "New player 1" }, TotalScore = RNG.Next(600000, 1000000) })); - AddUntilStep("tracked player is #51", () => leaderboard.TrackedScore?.ScorePosition! == 51); - - AddStep("change TabType to global", () => beatmapTabType.Value = PlayBeatmapDetailArea.TabType.Global); - AddUntilStep("tracked player is -", () => leaderboard.TrackedScore?.ScorePosition! == null); - - AddStep("change TabType to country", () => beatmapTabType.Value = PlayBeatmapDetailArea.TabType.Country); - AddUntilStep("tracked player is -", () => leaderboard.TrackedScore?.ScorePosition! == null); + AddUntilStep($"tracked player is #{expectedOverflowIndex}", () => leaderboard.TrackedScore?.ScorePosition, () => Is.EqualTo(expectedOverflowIndex)); } [Test] From d59befc9d3a5bd740f1d6a965d58a36cc9ce8d0c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 16:08:27 +0900 Subject: [PATCH 0648/2991] Fix initial visual state of positions before `sort` runs --- osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs b/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs index bbde247c21..0d03d8d090 100644 --- a/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs +++ b/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs @@ -62,17 +62,21 @@ namespace osu.Game.Screens.Play.HUD private int? scorePosition; + private bool scorePositionIsSet; + public int? ScorePosition { get => scorePosition; set { - if (value == scorePosition) + // We always want to run once, as the incoming value may be null and require a visual update to "-". + if (value == scorePosition && scorePositionIsSet) return; scorePosition = value; positionText.Text = scorePosition.HasValue ? $"#{scorePosition.Value.FormatRank()}" : "-"; + scorePositionIsSet = true; updateState(); } From 7c08cff297d3d7c6f31ce52a074397d219a0832b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 16:10:32 +0900 Subject: [PATCH 0649/2991] Make new test more resilient to false passes --- .../Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs index d357c52d8a..7ad4ec2f85 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs @@ -83,7 +83,13 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("tracked player is #50", () => leaderboard.TrackedScore?.ScorePosition, () => Is.EqualTo(50)); AddStep("add one more score", () => scores.Add(new ScoreInfo { User = new APIUser { Username = "New player 1" }, TotalScore = RNG.Next(600000, 1000000) })); - AddUntilStep($"tracked player is #{expectedOverflowIndex}", () => leaderboard.TrackedScore?.ScorePosition, () => Is.EqualTo(expectedOverflowIndex)); + + AddUntilStep("wait for sort", () => leaderboard.ChildrenOfType().First().ScorePosition != null); + + if (expectedOverflowIndex == null) + AddUntilStep($"tracked player has null position", () => leaderboard.TrackedScore?.ScorePosition, () => Is.Null); + else + AddUntilStep($"tracked player is #{expectedOverflowIndex}", () => leaderboard.TrackedScore?.ScorePosition, () => Is.EqualTo(expectedOverflowIndex)); } [Test] From 95908ec023c18d884e6254df3afd60993cb25e10 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 18:13:00 +0900 Subject: [PATCH 0650/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 5f3fb858ee..8212707d44 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 858cac1dac..f81d9d27b4 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 25217b872b..cd70f1c432 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From 06ce8130c2002d9ebd2bfa5ad95b7597e195bbc0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 16 Nov 2022 18:47:58 +0900 Subject: [PATCH 0651/2991] Apply changes in line with framework NRT updates --- osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs | 6 +++--- osu.Game/Collections/CollectionDropdown.cs | 5 +++-- osu.Game/Overlays/ChatOverlay.cs | 6 +++--- osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs | 6 +++--- .../Screens/OnlinePlay/Lounge/LoungeBackgroundScreen.cs | 5 ++--- .../Screens/Play/PlayerSettings/BeatmapOffsetControl.cs | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs index dd0b61cdf5..c5cf09d449 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Taiko.UI public class DrawableTaikoMascot : BeatSyncedContainer { public readonly Bindable State; - public readonly Bindable LastResult; + public readonly Bindable LastResult; private readonly Dictionary animations; @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Taiko.UI Origin = Anchor = Anchor.BottomLeft; State = new Bindable(startingState); - LastResult = new Bindable(); + LastResult = new Bindable(); animations = new Dictionary(); } @@ -63,7 +63,7 @@ namespace osu.Game.Rulesets.Taiko.UI LastResult.BindValueChanged(onNewResult); } - private void onNewResult(ValueChangedEvent resultChangedEvent) + private void onNewResult(ValueChangedEvent resultChangedEvent) { var result = resultChangedEvent.NewValue; if (result == null) diff --git a/osu.Game/Collections/CollectionDropdown.cs b/osu.Game/Collections/CollectionDropdown.cs index 71341f51a4..f203d49900 100644 --- a/osu.Game/Collections/CollectionDropdown.cs +++ b/osu.Game/Collections/CollectionDropdown.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; @@ -100,7 +101,7 @@ namespace osu.Game.Collections private void selectionChanged(ValueChangedEvent filter) { // May be null during .Clear(). - if (filter.NewValue == null) + if (filter.NewValue.IsNull()) return; // Never select the manage collection filter - rollback to the previous filter. @@ -112,7 +113,7 @@ namespace osu.Game.Collections return; } - var newCollection = filter.NewValue?.Collection; + var newCollection = filter.NewValue.Collection; // This dropdown be weird. // We only care about filtering if the actual collection has changed. diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index c491c0c695..e9d28dcf28 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -64,7 +64,7 @@ namespace osu.Game.Overlays private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink); [Cached] - private readonly Bindable currentChannel = new Bindable(); + private readonly Bindable currentChannel = new Bindable(); private readonly IBindableList availableChannels = new BindableList(); private readonly IBindableList joinedChannels = new BindableList(); @@ -293,7 +293,7 @@ namespace osu.Game.Overlays base.OnFocus(e); } - private void currentChannelChanged(ValueChangedEvent channel) + private void currentChannelChanged(ValueChangedEvent channel) { Channel? newChannel = channel.NewValue; @@ -402,7 +402,7 @@ namespace osu.Game.Overlays { List overlayChannels = channelList.Channels.ToList(); - if (overlayChannels.Count < 2) + if (overlayChannels.Count < 2 || currentChannel.Value == null) return; int currentIndex = overlayChannels.IndexOf(currentChannel.Value); diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index 43d68653ad..a34f8f0c1b 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -188,7 +188,7 @@ namespace osu.Game.Overlays.FirstRunSetup public IEnumerable HandledExtensions { get; } = new[] { string.Empty }; - private readonly Bindable currentDirectory = new Bindable(); + private readonly Bindable currentDirectory = new Bindable(); [Resolved(canBeNull: true)] // Can't really be null but required to handle potential of disposal before DI completes. private OsuGameBase? game { get; set; } @@ -206,7 +206,7 @@ namespace osu.Game.Overlays.FirstRunSetup currentDirectory.Value = new DirectoryInfo(fullPath); } - private void onDirectorySelected(ValueChangedEvent directory) + private void onDirectorySelected(ValueChangedEvent directory) { if (directory.NewValue == null) { @@ -247,7 +247,7 @@ namespace osu.Game.Overlays.FirstRunSetup private class DirectoryChooserPopover : OsuPopover { - public DirectoryChooserPopover(Bindable currentDirectory) + public DirectoryChooserPopover(Bindable currentDirectory) { Child = new Container { diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeBackgroundScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeBackgroundScreen.cs index 58ccb24f7a..d2a57f21db 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeBackgroundScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeBackgroundScreen.cs @@ -5,13 +5,12 @@ using osu.Framework.Bindables; using osu.Framework.Screens; using osu.Game.Online.Rooms; using osu.Game.Screens.OnlinePlay.Components; -using PlaylistItem = osu.Game.Online.Rooms.PlaylistItem; namespace osu.Game.Screens.OnlinePlay.Lounge { public class LoungeBackgroundScreen : OnlinePlayBackgroundScreen { - public readonly Bindable SelectedRoom = new Bindable(); + public readonly Bindable SelectedRoom = new Bindable(); private readonly BindableList playlist = new BindableList(); public LoungeBackgroundScreen() @@ -20,7 +19,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge playlist.BindCollectionChanged((_, _) => PlaylistItem = playlist.GetCurrentItem()); } - private void onSelectedRoomChanged(ValueChangedEvent room) + private void onSelectedRoomChanged(ValueChangedEvent room) { if (room.OldValue != null) playlist.UnbindFrom(room.OldValue.Playlist); diff --git a/osu.Game/Screens/Play/PlayerSettings/BeatmapOffsetControl.cs b/osu.Game/Screens/Play/PlayerSettings/BeatmapOffsetControl.cs index 537f4d811a..fc89effe1b 100644 --- a/osu.Game/Screens/Play/PlayerSettings/BeatmapOffsetControl.cs +++ b/osu.Game/Screens/Play/PlayerSettings/BeatmapOffsetControl.cs @@ -27,7 +27,7 @@ namespace osu.Game.Screens.Play.PlayerSettings { public class BeatmapOffsetControl : CompositeDrawable { - public Bindable ReferenceScore { get; } = new Bindable(); + public Bindable ReferenceScore { get; } = new Bindable(); public BindableDouble Current { get; } = new BindableDouble { @@ -176,7 +176,7 @@ namespace osu.Game.Screens.Play.PlayerSettings } } - private void scoreChanged(ValueChangedEvent score) + private void scoreChanged(ValueChangedEvent score) { referenceScoreContainer.Clear(); From 4b29941b4705a38ea26ce4ca617caf75c3be4f1a Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 17 Nov 2022 23:38:24 +0900 Subject: [PATCH 0652/2991] add `LegacyExportManager` --- osu.Game.Tests/Skins/IO/ImportSkinTest.cs | 4 +- osu.Game/Database/LegacyBeatmapExporter.cs | 8 +- osu.Game/Database/LegacyExportManager.cs | 55 +++++++++ osu.Game/Database/LegacyExporter.cs | 102 ---------------- osu.Game/Database/LegacyModelExporter.cs | 113 ++++++++++++++++++ osu.Game/Database/LegacyScoreExporter.cs | 34 +++--- osu.Game/Database/LegacySkinExporter.cs | 8 +- .../Online/Leaderboards/LeaderboardScore.cs | 5 +- osu.Game/OsuGame.cs | 4 + .../Overlays/Settings/Sections/SkinSection.cs | 10 +- osu.Game/Screens/Edit/Editor.cs | 9 +- 11 files changed, 209 insertions(+), 143 deletions(-) create mode 100644 osu.Game/Database/LegacyExportManager.cs delete mode 100644 osu.Game/Database/LegacyExporter.cs create mode 100644 osu.Game/Database/LegacyModelExporter.cs diff --git a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs index 7a5f6dbd7c..ef68b06476 100644 --- a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs +++ b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs @@ -121,9 +121,9 @@ namespace osu.Game.Tests.Skins.IO var import1 = await loadSkinIntoOsu(osu, new ImportTask(createOskWithIni("name 1", "author 1"), "custom.osk")); assertCorrectMetadata(import1, "name 1 [custom]", "author 1", osu); - import1.PerformRead(s => + import1.PerformRead(async s => { - new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get()).ExportModelTo(s, exportStream); + await new LegacyExportManager().ExportAsync(s, exportStream); }); string exportFilename = import1.GetDisplayString(); diff --git a/osu.Game/Database/LegacyBeatmapExporter.cs b/osu.Game/Database/LegacyBeatmapExporter.cs index 3e11e898f3..140ce43fbd 100644 --- a/osu.Game/Database/LegacyBeatmapExporter.cs +++ b/osu.Game/Database/LegacyBeatmapExporter.cs @@ -3,16 +3,16 @@ using osu.Framework.Platform; using osu.Game.Beatmaps; -using osu.Game.Overlays; +using osu.Game.Overlays.Notifications; namespace osu.Game.Database { - public class LegacyBeatmapExporter : LegacyExporter + public class LegacyBeatmapExporter : LegacyModelExporter { protected override string FileExtension => ".osz"; - public LegacyBeatmapExporter(Storage storage, INotificationOverlay? notificationOverlay) - : base(storage, notificationOverlay) + public LegacyBeatmapExporter(Storage storage, RealmAccess realm, ProgressNotification notification) + : base(storage, realm, notification) { } } diff --git a/osu.Game/Database/LegacyExportManager.cs b/osu.Game/Database/LegacyExportManager.cs new file mode 100644 index 0000000000..18cd93ea35 --- /dev/null +++ b/osu.Game/Database/LegacyExportManager.cs @@ -0,0 +1,55 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Threading.Tasks; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Platform; +using osu.Framework.Testing; +using osu.Game.Beatmaps; +using osu.Game.Overlays; +using osu.Game.Overlays.Notifications; +using osu.Game.Scoring; +using osu.Game.Skinning; + +namespace osu.Game.Database +{ + [ExcludeFromDynamicCompile] + public class LegacyExportManager : Component + { + [Resolved] + private RealmAccess realmAccess { get; set; } = null!; + + [Resolved] + private Storage exportStorage { get; set; } = null!; + + [Resolved] + private INotificationOverlay? notifications { get; set; } + + public async Task ExportAsync(IHasGuidPrimaryKey item) + { + var notification = new ProgressNotification + { + State = ProgressNotificationState.Active, + Text = "Exporting...", + CompletionText = "Export completed" + }; + notifications?.Post(notification); + + switch (item) + { + case SkinInfo: + await new LegacySkinExporter(exportStorage, realmAccess, notification).ExportASync(item); + break; + + case ScoreInfo: + await new LegacyScoreExporter(exportStorage, realmAccess, notification).ExportASync(item, false); + break; + + case BeatmapSetInfo: + await new LegacyBeatmapExporter(exportStorage, realmAccess, notification).ExportASync(item); + break; + } + } + } +} diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs deleted file mode 100644 index ed16e4bc80..0000000000 --- a/osu.Game/Database/LegacyExporter.cs +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.IO; -using System.Threading.Tasks; -using osu.Framework.Platform; -using osu.Game.Extensions; -using osu.Game.Overlays; -using osu.Game.Overlays.Notifications; -using SharpCompress.Archives.Zip; - -namespace osu.Game.Database -{ - /// - /// A class which handles exporting legacy user data of a single type from osu-stable. - /// - public abstract class LegacyExporter - where TModel : class, IHasNamedFiles - { - /// - /// The file extension for exports (including the leading '.'). - /// - protected abstract string FileExtension { get; } - - protected readonly Storage UserFileStorage; - - private readonly Storage exportStorage; - - private readonly INotificationOverlay? notificationOverlay; - - protected ProgressNotification Notification = null!; - - private string filename = null!; - - protected LegacyExporter(Storage storage, INotificationOverlay? notificationOverlay) - { - exportStorage = storage.GetStorageForDirectory(@"exports"); - UserFileStorage = storage.GetStorageForDirectory(@"files"); - this.notificationOverlay = notificationOverlay; - } - - /// - /// Exports an item to a legacy (.zip based) package. - /// - /// The item to export. - public void Export(TModel item) - { - filename = $"{item.GetDisplayString().GetValidFilename()}{FileExtension}"; - - Stream stream = exportStorage.CreateFileSafely(filename); - - Notification = new ProgressNotification - { - State = ProgressNotificationState.Active, - Text = "Exporting...", - CompletionText = "Export completed" - }; - Notification.CompletionClickAction += () => exportStorage.PresentFileExternally(filename); - Notification.CancelRequested += () => - { - stream.Dispose(); - return true; - }; - - ExportModelTo(item, stream); - notificationOverlay?.Post(Notification); - } - - /// - /// Exports an item to the given output stream. - /// - /// The item to export. - /// The output stream to export to. - public virtual void ExportModelTo(TModel model, Stream outputStream) - { - using (var archive = ZipArchive.Create()) - { - foreach (var file in model.Files) - archive.AddEntry(file.Filename, UserFileStorage.GetStream(file.File.GetStoragePath())); - - Task.Factory.StartNew(() => - { - archive.SaveTo(outputStream); - }, Notification.CancellationToken).ContinueWith(t => - { - if (t.IsCompletedSuccessfully) - { - outputStream.Dispose(); - Notification.State = ProgressNotificationState.Completed; - } - else - { - if (Notification.State == ProgressNotificationState.Cancelled) return; - - Notification.State = ProgressNotificationState.Cancelled; - Notification.Text = "Export Failed"; - } - }); - } - } - } -} diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs new file mode 100644 index 0000000000..d181226803 --- /dev/null +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -0,0 +1,113 @@ +// 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 System.Threading.Tasks; +using osu.Framework.Platform; +using osu.Game.Extensions; +using osu.Game.Overlays.Notifications; +using Realms; +using SharpCompress.Archives.Zip; + +namespace osu.Game.Database +{ + /// + /// A class which handles exporting legacy user data of a single type from osu-stable. + /// + public abstract class LegacyModelExporter + where TModel : RealmObject + { + /// + /// The file extension for exports (including the leading '.'). + /// + protected abstract string FileExtension { get; } + + protected readonly Storage UserFileStorage; + + private readonly Storage exportStorage; + + private readonly RealmAccess realmAccess; + + private readonly ProgressNotification notification; + + protected ProgressNotification Notification = null!; + + private string filename = null!; + + protected LegacyModelExporter(Storage storage, RealmAccess realm, ProgressNotification notification) + { + exportStorage = storage.GetStorageForDirectory(@"exports"); + UserFileStorage = storage.GetStorageForDirectory(@"files"); + this.notification = notification; + realmAccess = realm; + } + + public async Task ExportASync(IHasGuidPrimaryKey uuid, bool needZipArchive = true) + { + Guid id = uuid.ID; + await Task.Run(() => + { + realmAccess.Run(r => + { + if (r.Find(id) is IHasNamedFiles model) + { + filename = $"{model.GetDisplayString().GetValidFilename()}{FileExtension}"; + } + else + { + return; + } + + using (var outputStream = exportStorage.CreateFileSafely(filename)) + { + if (needZipArchive) + { + using (var archive = ZipArchive.Create()) + { + float i = 0; + + foreach (var file in model.Files) + { + if (notification.CancellationToken.IsCancellationRequested) return; + archive.AddEntry(file.Filename, UserFileStorage.GetStream(file.File.GetStoragePath())); + i++; + notification.Progress = i / model.Files.Count(); + notification.Text = $"Exporting... ({i}/{model.Files.Count()})"; + } + + notification.Text = "Saving Zip Archive..."; + archive.SaveTo(outputStream); + } + } + else + { + var file = model.Files.SingleOrDefault(); + if (file == null) + return; + + using (var inputStream = UserFileStorage.GetStream(file.File.GetStoragePath())) + inputStream.CopyTo(outputStream); + } + } + }); + }).ContinueWith(t => + { + if (t.IsFaulted) + { + notification.State = ProgressNotificationState.Cancelled; + return; + } + + if (notification.CancellationToken.IsCancellationRequested) + { + return; + } + + notification.CompletionText = "Export Complete, Click to open the folder"; + notification.CompletionClickAction += () => exportStorage.PresentFileExternally(filename); + notification.State = ProgressNotificationState.Completed; + }); + } + } +} diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index 1564c7b077..ffbec0530b 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -1,36 +1,32 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.IO; -using System.Linq; using osu.Framework.Platform; -using osu.Game.Extensions; -using osu.Game.Overlays; using osu.Game.Overlays.Notifications; using osu.Game.Scoring; namespace osu.Game.Database { - public class LegacyScoreExporter : LegacyExporter + public class LegacyScoreExporter : LegacyModelExporter { protected override string FileExtension => ".osr"; - public LegacyScoreExporter(Storage storage, INotificationOverlay? notificationOverlay) - : base(storage, notificationOverlay) + public LegacyScoreExporter(Storage storage, RealmAccess realm, ProgressNotification notification) + : base(storage, realm, notification) { } - public override void ExportModelTo(ScoreInfo model, Stream outputStream) - { - var file = model.Files.SingleOrDefault(); - if (file == null) - return; - - using (var inputStream = UserFileStorage.GetStream(file.File.GetStoragePath())) - inputStream.CopyTo(outputStream); - - Notification.State = ProgressNotificationState.Completed; - outputStream.Dispose(); - } + //public override void ExportModelTo(ScoreInfo model, Stream outputStream) + //{ + // var file = model.Files.SingleOrDefault(); + // if (file == null) + // return; + // + // using (var inputStream = UserFileStorage.GetStream(file.File.GetStoragePath())) + // inputStream.CopyTo(outputStream); + // + // Notification.State = ProgressNotificationState.Completed; + // outputStream.Dispose(); + //} } } diff --git a/osu.Game/Database/LegacySkinExporter.cs b/osu.Game/Database/LegacySkinExporter.cs index a78d69e7b9..a35636c248 100644 --- a/osu.Game/Database/LegacySkinExporter.cs +++ b/osu.Game/Database/LegacySkinExporter.cs @@ -2,17 +2,17 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Platform; -using osu.Game.Overlays; +using osu.Game.Overlays.Notifications; using osu.Game.Skinning; namespace osu.Game.Database { - public class LegacySkinExporter : LegacyExporter + public class LegacySkinExporter : LegacyModelExporter { protected override string FileExtension => ".osk"; - public LegacySkinExporter(Storage storage, INotificationOverlay? notificationOverlay) - : base(storage, notificationOverlay) + public LegacySkinExporter(Storage storage, RealmAccess realm, ProgressNotification notification) + : base(storage, realm, notification) { } } diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index 72f1a94ec8..e2f640a44c 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -76,7 +77,7 @@ namespace osu.Game.Online.Leaderboards private Storage storage { get; set; } [Resolved] - private INotificationOverlay notificationOverlay { get; set; } + private LegacyExportManager exporter { get; set; } public ITooltip GetCustomTooltip() => new LeaderboardScoreTooltip(); public virtual ScoreInfo TooltipContent => Score; @@ -430,7 +431,7 @@ namespace osu.Game.Online.Leaderboards if (Score.Files.Count > 0) { - items.Add(new OsuMenuItem("Export", MenuItemType.Standard, () => new LegacyScoreExporter(storage, notificationOverlay).Export(Score))); + items.Add(new OsuMenuItem("Export", MenuItemType.Standard, () => Task.Run(() => exporter.ExportAsync(Score)))); items.Add(new OsuMenuItem(CommonStrings.ButtonsDelete, MenuItemType.Destructive, () => dialogOverlay?.Push(new LocalScoreDeleteDialog(Score)))); } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index a93c187e53..09647f9d1e 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -126,6 +126,9 @@ namespace osu.Game [Cached] private readonly LegacyImportManager legacyImportManager = new LegacyImportManager(); + [Cached] + private readonly LegacyExportManager legacyExportManager = new LegacyExportManager(); + [Cached] private readonly ScreenshotManager screenshotManager = new ScreenshotManager(); @@ -868,6 +871,7 @@ namespace osu.Game }), rightFloatingOverlayContent.Add, true); loadComponentSingleFile(legacyImportManager, Add); + loadComponentSingleFile(legacyExportManager, Add); loadComponentSingleFile(screenshotManager, Add); diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index df6f719b1e..6cd9e591e1 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -141,16 +141,14 @@ namespace osu.Game.Overlays.Settings.Sections [Resolved] private Storage storage { get; set; } - [CanBeNull] - private INotificationOverlay notificationOverlay; + [Resolved] + private LegacyExportManager exporter { get; set; } private Bindable currentSkin; [BackgroundDependencyLoader] - private void load(INotificationOverlay notificationOverlay) + private void load() { - this.notificationOverlay = notificationOverlay; - Text = SkinSettingsStrings.ExportSkinButton; Action = export; } @@ -167,7 +165,7 @@ namespace osu.Game.Overlays.Settings.Sections { try { - currentSkin.Value.SkinInfo.PerformRead(s => new LegacySkinExporter(storage, notificationOverlay).Export(s)); + currentSkin.Value.SkinInfo.PerformRead(s => exporter.ExportAsync(s)); } catch (Exception e) { diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 03bdd69f34..e266239f34 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using JetBrains.Annotations; using osu.Framework; using osu.Framework.Allocation; @@ -93,9 +94,6 @@ namespace osu.Game.Screens.Edit [Resolved] private Storage storage { get; set; } - [Resolved] - private INotificationOverlay notificationOverlay { get; set; } - [Resolved(canBeNull: true)] private IDialogOverlay dialogOverlay { get; set; } @@ -185,6 +183,9 @@ namespace osu.Game.Screens.Edit private Bindable editorBackgroundDim; private Bindable editorHitMarkers; + [Resolved] + private LegacyExportManager exporter { get; set; } + public Editor(EditorLoader loader = null) { this.loader = loader; @@ -941,7 +942,7 @@ namespace osu.Game.Screens.Edit private void exportBeatmap() { Save(); - new LegacyBeatmapExporter(storage, notificationOverlay).Export(Beatmap.Value.BeatmapSetInfo); + Task.Run(() => exporter.ExportAsync(Beatmap.Value.BeatmapSetInfo)); } /// From b86b45b6d25800d3117e2a01862c734cd17a1dbe Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 18 Nov 2022 21:13:21 +0900 Subject: [PATCH 0653/2991] Fix excess string interpolation --- .../Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs index 7ad4ec2f85..881870921c 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs @@ -87,7 +87,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for sort", () => leaderboard.ChildrenOfType().First().ScorePosition != null); if (expectedOverflowIndex == null) - AddUntilStep($"tracked player has null position", () => leaderboard.TrackedScore?.ScorePosition, () => Is.Null); + AddUntilStep("tracked player has null position", () => leaderboard.TrackedScore?.ScorePosition, () => Is.Null); else AddUntilStep($"tracked player is #{expectedOverflowIndex}", () => leaderboard.TrackedScore?.ScorePosition, () => Is.EqualTo(expectedOverflowIndex)); } From 1be8c6bd9c4d48d62fb421d5fda37e332705302e Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 18 Nov 2022 17:19:32 +0300 Subject: [PATCH 0654/2991] Fix "perform from screen" not considering screen load state --- osu.Game/PerformFromMenuRunner.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/PerformFromMenuRunner.cs b/osu.Game/PerformFromMenuRunner.cs index eae13fe5d0..158350b43d 100644 --- a/osu.Game/PerformFromMenuRunner.cs +++ b/osu.Game/PerformFromMenuRunner.cs @@ -89,6 +89,10 @@ namespace osu.Game // check if we are already at a valid target screen. if (validScreens.Any(t => t.IsAssignableFrom(type))) { + if (!((Drawable)current).IsLoaded) + // wait until screen is loaded before invoking action. + return true; + finalAction(current); Cancel(); return true; From 8943819ee70d5e69e7b4c26b712af06067a3b206 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 18 Nov 2022 17:49:03 +0300 Subject: [PATCH 0655/2991] Add test coverage --- .../Navigation/TestScenePerformFromScreen.cs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs b/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs index d1b1ce5c4b..ce0543875b 100644 --- a/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs +++ b/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs @@ -4,6 +4,7 @@ #nullable disable using System.Linq; +using System.Threading; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Extensions; @@ -85,6 +86,19 @@ namespace osu.Game.Tests.Visual.Navigation AddAssert("did perform", () => actionPerformed); } + [Test] + public void TestPerformEnsuresScreenIsLoaded() + { + TestLoadBlockingScreen screen = null; + + AddStep("push blocking screen", () => Game.ScreenStack.Push(screen = new TestLoadBlockingScreen())); + AddStep("perform", () => Game.PerformFromScreen(_ => actionPerformed = true, new[] { typeof(TestLoadBlockingScreen) })); + AddAssert("action not performed", () => !actionPerformed); + + AddStep("allow load", () => screen.LoadEvent.Set()); + AddUntilStep("action performed", () => actionPerformed); + } + [Test] public void TestOverlaysAlwaysClosed() { @@ -270,5 +284,16 @@ namespace osu.Game.Tests.Visual.Navigation return base.OnExiting(e); } } + + public class TestLoadBlockingScreen : OsuScreen + { + public readonly ManualResetEventSlim LoadEvent = new ManualResetEventSlim(); + + [BackgroundDependencyLoader] + private void load() + { + LoadEvent.Wait(10000); + } + } } } From fc4a6cb125c50668765d8b43f5bcf88cb242f28c Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sat, 19 Nov 2022 01:02:35 +0900 Subject: [PATCH 0656/2991] working with test --- osu.Game.Tests/Skins/IO/ImportSkinTest.cs | 31 +++--- osu.Game/Database/LegacyBeatmapExporter.cs | 5 +- osu.Game/Database/LegacyExportManager.cs | 2 +- osu.Game/Database/LegacyModelExporter.cs | 106 +++++++++++---------- osu.Game/Database/LegacyScoreExporter.cs | 52 +++++++--- osu.Game/Database/LegacySkinExporter.cs | 5 +- 6 files changed, 113 insertions(+), 88 deletions(-) diff --git a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs index ef68b06476..0c3c459e87 100644 --- a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs +++ b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs @@ -10,12 +10,11 @@ using System.Runtime.CompilerServices; using System.Threading.Tasks; using NUnit.Framework; using osu.Framework.Allocation; -using osu.Framework.Extensions; using osu.Framework.Platform; using osu.Game.Database; using osu.Game.Extensions; using osu.Game.IO; -using osu.Game.Overlays; +using osu.Game.Overlays.Notifications; using osu.Game.Skinning; using SharpCompress.Archives.Zip; @@ -121,9 +120,9 @@ namespace osu.Game.Tests.Skins.IO var import1 = await loadSkinIntoOsu(osu, new ImportTask(createOskWithIni("name 1", "author 1"), "custom.osk")); assertCorrectMetadata(import1, "name 1 [custom]", "author 1", osu); - import1.PerformRead(async s => + await import1.PerformRead(async s => { - await new LegacyExportManager().ExportAsync(s, exportStream); + await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get(), new ProgressNotification(), exportStream).ExportASync(s); }); string exportFilename = import1.GetDisplayString(); @@ -190,7 +189,7 @@ namespace osu.Game.Tests.Skins.IO }); [Test] - public Task TestExportThenImportDefaultSkin() => runSkinTest(osu => + public Task TestExportThenImportDefaultSkin() => runSkinTest(async osu => { var skinManager = osu.Dependencies.Get(); @@ -200,30 +199,28 @@ namespace osu.Game.Tests.Skins.IO Guid originalSkinId = skinManager.CurrentSkinInfo.Value.ID; - skinManager.CurrentSkinInfo.Value.PerformRead(s => + await skinManager.CurrentSkinInfo.Value.PerformRead(async s => { Assert.IsFalse(s.Protected); Assert.AreEqual(typeof(ArgonSkin), s.CreateInstance(skinManager).GetType()); - new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get()).ExportModelTo(s, exportStream); + await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get(), new ProgressNotification(), exportStream).ExportASync(s); Assert.Greater(exportStream.Length, 0); }); - var imported = skinManager.Import(new ImportTask(exportStream, "exported.osk")); + var imported = await skinManager.Import(new ImportTask(exportStream, "exported.osk")); - imported.GetResultSafely().PerformRead(s => + imported.PerformRead(s => { Assert.IsFalse(s.Protected); Assert.AreNotEqual(originalSkinId, s.ID); Assert.AreEqual(typeof(ArgonSkin), s.CreateInstance(skinManager).GetType()); }); - - return Task.CompletedTask; }); [Test] - public Task TestExportThenImportClassicSkin() => runSkinTest(osu => + public Task TestExportThenImportClassicSkin() => runSkinTest(async osu => { var skinManager = osu.Dependencies.Get(); @@ -235,26 +232,24 @@ namespace osu.Game.Tests.Skins.IO Guid originalSkinId = skinManager.CurrentSkinInfo.Value.ID; - skinManager.CurrentSkinInfo.Value.PerformRead(s => + await skinManager.CurrentSkinInfo.Value.PerformRead(async s => { Assert.IsFalse(s.Protected); Assert.AreEqual(typeof(DefaultLegacySkin), s.CreateInstance(skinManager).GetType()); - new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get()).ExportModelTo(s, exportStream); + await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get(), new ProgressNotification(), exportStream).ExportASync(s); Assert.Greater(exportStream.Length, 0); }); - var imported = skinManager.Import(new ImportTask(exportStream, "exported.osk")); + var imported = await skinManager.Import(new ImportTask(exportStream, "exported.osk")); - imported.GetResultSafely().PerformRead(s => + imported.PerformRead(s => { Assert.IsFalse(s.Protected); Assert.AreNotEqual(originalSkinId, s.ID); Assert.AreEqual(typeof(DefaultLegacySkin), s.CreateInstance(skinManager).GetType()); }); - - return Task.CompletedTask; }); #endregion diff --git a/osu.Game/Database/LegacyBeatmapExporter.cs b/osu.Game/Database/LegacyBeatmapExporter.cs index 140ce43fbd..5505d141ee 100644 --- a/osu.Game/Database/LegacyBeatmapExporter.cs +++ b/osu.Game/Database/LegacyBeatmapExporter.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.IO; using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Overlays.Notifications; @@ -11,8 +12,8 @@ namespace osu.Game.Database { protected override string FileExtension => ".osz"; - public LegacyBeatmapExporter(Storage storage, RealmAccess realm, ProgressNotification notification) - : base(storage, realm, notification) + public LegacyBeatmapExporter(Storage storage, RealmAccess realm, ProgressNotification notification, Stream? stream = null) + : base(storage, realm, notification, stream) { } } diff --git a/osu.Game/Database/LegacyExportManager.cs b/osu.Game/Database/LegacyExportManager.cs index 18cd93ea35..08594ab020 100644 --- a/osu.Game/Database/LegacyExportManager.cs +++ b/osu.Game/Database/LegacyExportManager.cs @@ -43,7 +43,7 @@ namespace osu.Game.Database break; case ScoreInfo: - await new LegacyScoreExporter(exportStorage, realmAccess, notification).ExportASync(item, false); + await new LegacyScoreExporter(exportStorage, realmAccess, notification).ExportASync(item); break; case BeatmapSetInfo: diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index d181226803..a4b0f7ba9d 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.IO; using System.Linq; using System.Threading.Tasks; using osu.Framework.Platform; @@ -25,89 +26,92 @@ namespace osu.Game.Database protected readonly Storage UserFileStorage; - private readonly Storage exportStorage; + protected readonly Storage ExportStorage; - private readonly RealmAccess realmAccess; + protected readonly RealmAccess RealmAccess; - private readonly ProgressNotification notification; + protected readonly ProgressNotification Notification; - protected ProgressNotification Notification = null!; + protected string Filename = null!; - private string filename = null!; + protected Stream? OutputStream; - protected LegacyModelExporter(Storage storage, RealmAccess realm, ProgressNotification notification) + protected bool ShouldDisposeStream; + + protected LegacyModelExporter(Storage storage, RealmAccess realm, ProgressNotification notification, Stream? stream = null) { - exportStorage = storage.GetStorageForDirectory(@"exports"); + ExportStorage = storage.GetStorageForDirectory(@"exports"); UserFileStorage = storage.GetStorageForDirectory(@"files"); - this.notification = notification; - realmAccess = realm; + Notification = notification; + RealmAccess = realm; + OutputStream = stream; + ShouldDisposeStream = false; } - public async Task ExportASync(IHasGuidPrimaryKey uuid, bool needZipArchive = true) + public virtual async Task ExportASync(IHasGuidPrimaryKey uuid) { Guid id = uuid.ID; await Task.Run(() => { - realmAccess.Run(r => + RealmAccess.Run(r => { if (r.Find(id) is IHasNamedFiles model) { - filename = $"{model.GetDisplayString().GetValidFilename()}{FileExtension}"; + Filename = $"{model.GetDisplayString().GetValidFilename()}{FileExtension}"; } else { return; } - using (var outputStream = exportStorage.CreateFileSafely(filename)) + if (OutputStream == null) { - if (needZipArchive) + OutputStream = ExportStorage.CreateFileSafely(Filename); + ShouldDisposeStream = true; + } + + using (var archive = ZipArchive.Create()) + { + float i = 0; + + foreach (var file in model.Files) { - using (var archive = ZipArchive.Create()) - { - float i = 0; + if (Notification.CancellationToken.IsCancellationRequested) return; - foreach (var file in model.Files) - { - if (notification.CancellationToken.IsCancellationRequested) return; - archive.AddEntry(file.Filename, UserFileStorage.GetStream(file.File.GetStoragePath())); - i++; - notification.Progress = i / model.Files.Count(); - notification.Text = $"Exporting... ({i}/{model.Files.Count()})"; - } - - notification.Text = "Saving Zip Archive..."; - archive.SaveTo(outputStream); - } + archive.AddEntry(file.Filename, UserFileStorage.GetStream(file.File.GetStoragePath())); + i++; + Notification.Progress = i / model.Files.Count(); + Notification.Text = $"Exporting... ({i}/{model.Files.Count()})"; } - else - { - var file = model.Files.SingleOrDefault(); - if (file == null) - return; - using (var inputStream = UserFileStorage.GetStream(file.File.GetStoragePath())) - inputStream.CopyTo(outputStream); - } + Notification.Text = "Saving Zip Archive..."; + archive.SaveTo(OutputStream); } }); - }).ContinueWith(t => + }).ContinueWith(OnComplete); + } + + protected void OnComplete(Task t) + { + if (ShouldDisposeStream) { - if (t.IsFaulted) - { - notification.State = ProgressNotificationState.Cancelled; - return; - } + OutputStream?.Dispose(); + } - if (notification.CancellationToken.IsCancellationRequested) - { - return; - } + if (t.IsFaulted) + { + Notification.State = ProgressNotificationState.Cancelled; + return; + } - notification.CompletionText = "Export Complete, Click to open the folder"; - notification.CompletionClickAction += () => exportStorage.PresentFileExternally(filename); - notification.State = ProgressNotificationState.Completed; - }); + if (Notification.CancellationToken.IsCancellationRequested) + { + return; + } + + Notification.CompletionText = "Export Complete, Click to open the folder"; + Notification.CompletionClickAction += () => ExportStorage.PresentFileExternally(Filename); + Notification.State = ProgressNotificationState.Completed; } } } diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index ffbec0530b..3004c02978 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -1,7 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.IO; +using System.Linq; +using System.Threading.Tasks; using osu.Framework.Platform; +using osu.Game.Extensions; using osu.Game.Overlays.Notifications; using osu.Game.Scoring; @@ -11,22 +15,42 @@ namespace osu.Game.Database { protected override string FileExtension => ".osr"; - public LegacyScoreExporter(Storage storage, RealmAccess realm, ProgressNotification notification) - : base(storage, realm, notification) + public LegacyScoreExporter(Storage storage, RealmAccess realm, ProgressNotification notification, Stream? stream = null) + : base(storage, realm, notification, stream) { } - //public override void ExportModelTo(ScoreInfo model, Stream outputStream) - //{ - // var file = model.Files.SingleOrDefault(); - // if (file == null) - // return; - // - // using (var inputStream = UserFileStorage.GetStream(file.File.GetStoragePath())) - // inputStream.CopyTo(outputStream); - // - // Notification.State = ProgressNotificationState.Completed; - // outputStream.Dispose(); - //} + public override async Task ExportASync(IHasGuidPrimaryKey uuid) + { + await Task.Run(() => + { + RealmAccess.Run(r => + { + if (r.Find(uuid.ID) is IHasNamedFiles model) + { + Filename = $"{model.GetDisplayString().GetValidFilename()}{FileExtension}"; + } + else + { + return; + } + + var file = model.Files.SingleOrDefault(); + if (file == null) + return; + + if (Notification.CancellationToken.IsCancellationRequested) return; + + if (OutputStream == null) + { + OutputStream = ExportStorage.CreateFileSafely(Filename); + ShouldDisposeStream = true; + } + + using (var inputStream = UserFileStorage.GetStream(file.File.GetStoragePath())) + inputStream.CopyTo(OutputStream); + }); + }).ContinueWith(OnComplete); + } } } diff --git a/osu.Game/Database/LegacySkinExporter.cs b/osu.Game/Database/LegacySkinExporter.cs index a35636c248..4168763324 100644 --- a/osu.Game/Database/LegacySkinExporter.cs +++ b/osu.Game/Database/LegacySkinExporter.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.IO; using osu.Framework.Platform; using osu.Game.Overlays.Notifications; using osu.Game.Skinning; @@ -11,8 +12,8 @@ namespace osu.Game.Database { protected override string FileExtension => ".osk"; - public LegacySkinExporter(Storage storage, RealmAccess realm, ProgressNotification notification) - : base(storage, realm, notification) + public LegacySkinExporter(Storage storage, RealmAccess realm, ProgressNotification notification, Stream? stream = null) + : base(storage, realm, notification, stream) { } } From 4e457871f3a518b05d6d95e7637c74b7ddc978fb Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sat, 19 Nov 2022 01:03:09 +0900 Subject: [PATCH 0657/2991] impossible null and remove storage --- osu.Game/Online/Leaderboards/LeaderboardScore.cs | 12 ++++-------- osu.Game/Overlays/Settings/Sections/SkinSection.cs | 8 ++------ osu.Game/Screens/Edit/Editor.cs | 8 ++------ 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index e2f640a44c..b374736648 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -18,7 +18,6 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Framework.Localisation; -using osu.Framework.Platform; using osu.Game.Database; using osu.Game.Extensions; using osu.Game.Graphics; @@ -67,16 +66,13 @@ namespace osu.Game.Online.Leaderboards private List statisticsLabels; - [Resolved(CanBeNull = true)] + [Resolved(canBeNull: true)] private IDialogOverlay dialogOverlay { get; set; } - [Resolved(CanBeNull = true)] + [Resolved(canBeNull: true)] private SongSelect songSelect { get; set; } - [Resolved] - private Storage storage { get; set; } - - [Resolved] + [Resolved(canBeNull: true)] private LegacyExportManager exporter { get; set; } public ITooltip GetCustomTooltip() => new LeaderboardScoreTooltip(); @@ -431,7 +427,7 @@ namespace osu.Game.Online.Leaderboards if (Score.Files.Count > 0) { - items.Add(new OsuMenuItem("Export", MenuItemType.Standard, () => Task.Run(() => exporter.ExportAsync(Score)))); + items.Add(new OsuMenuItem("Export", MenuItemType.Standard, () => Task.Run(() => exporter?.ExportAsync(Score)))); items.Add(new OsuMenuItem(CommonStrings.ButtonsDelete, MenuItemType.Destructive, () => dialogOverlay?.Push(new LocalScoreDeleteDialog(Score)))); } diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 6cd9e591e1..e5a26c19fc 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -13,7 +13,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Framework.Logging; -using osu.Framework.Platform; using osu.Game.Database; using osu.Game.Graphics.UserInterface; using osu.Game.Localisation; @@ -138,10 +137,7 @@ namespace osu.Game.Overlays.Settings.Sections [Resolved] private SkinManager skins { get; set; } - [Resolved] - private Storage storage { get; set; } - - [Resolved] + [Resolved(canBeNull: true)] private LegacyExportManager exporter { get; set; } private Bindable currentSkin; @@ -165,7 +161,7 @@ namespace osu.Game.Overlays.Settings.Sections { try { - currentSkin.Value.SkinInfo.PerformRead(s => exporter.ExportAsync(s)); + currentSkin.Value.SkinInfo.PerformRead(s => exporter?.ExportAsync(s)); } catch (Exception e) { diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index e266239f34..77f14f689a 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -21,7 +21,6 @@ using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Framework.Logging; -using osu.Framework.Platform; using osu.Framework.Screens; using osu.Framework.Testing; using osu.Framework.Threading; @@ -91,9 +90,6 @@ namespace osu.Game.Screens.Edit [Resolved] private RulesetStore rulesets { get; set; } - [Resolved] - private Storage storage { get; set; } - [Resolved(canBeNull: true)] private IDialogOverlay dialogOverlay { get; set; } @@ -183,7 +179,7 @@ namespace osu.Game.Screens.Edit private Bindable editorBackgroundDim; private Bindable editorHitMarkers; - [Resolved] + [Resolved(canBeNull: true)] private LegacyExportManager exporter { get; set; } public Editor(EditorLoader loader = null) @@ -942,7 +938,7 @@ namespace osu.Game.Screens.Edit private void exportBeatmap() { Save(); - Task.Run(() => exporter.ExportAsync(Beatmap.Value.BeatmapSetInfo)); + Task.Run(() => exporter?.ExportAsync(Beatmap.Value.BeatmapSetInfo)); } /// From d587f29351f64b1a2bbabf7dd82cbdba2374b2a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 18 Nov 2022 21:02:23 +0100 Subject: [PATCH 0658/2991] Update tests to reflect desired behaviour --- .../Visual/Editing/TestSceneEditorTestGameplay.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs index 981967e413..ee6c322ee3 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs @@ -178,7 +178,7 @@ namespace osu.Game.Tests.Visual.Editing } [Test] - public void TestSharedClockState() + public void TestClockTimeTransferIsOneDirectional() { AddStep("seek to 00:01:00", () => EditorClock.Seek(60_000)); AddStep("click test gameplay button", () => @@ -195,15 +195,15 @@ namespace osu.Game.Tests.Visual.Editing GameplayClockContainer gameplayClockContainer = null; AddStep("fetch gameplay clock", () => gameplayClockContainer = editorPlayer.ChildrenOfType().First()); AddUntilStep("gameplay clock running", () => gameplayClockContainer.IsRunning); + // when the gameplay test is entered, the clock is expected to continue from where it was in the main editor... AddAssert("gameplay time past 00:01:00", () => gameplayClockContainer.CurrentTime >= 60_000); - double timeAtPlayerExit = 0; AddWaitStep("wait some", 5); - AddStep("store time before exit", () => timeAtPlayerExit = gameplayClockContainer.CurrentTime); AddStep("exit player", () => editorPlayer.Exit()); AddUntilStep("current screen is editor", () => Stack.CurrentScreen is Editor); - AddAssert("time is past player exit", () => EditorClock.CurrentTime >= timeAtPlayerExit); + // but when exiting from gameplay test back to editor, the expectation is that the editor time should revert to what it was at the point of initiating the gameplay test. + AddAssert("time reverted to 00:01:00", () => EditorClock.CurrentTime, () => Is.EqualTo(60_000)); } public override void TearDownSteps() From e8ca9f5dc584eccf74370977db246788385535c0 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 19 Nov 2022 00:19:49 +0300 Subject: [PATCH 0659/2991] Rework BarGraph to use Quads --- osu.Game/Graphics/UserInterface/Bar.cs | 12 +- osu.Game/Graphics/UserInterface/BarGraph.cs | 211 +++++++++++++++++--- 2 files changed, 188 insertions(+), 35 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/Bar.cs b/osu.Game/Graphics/UserInterface/Bar.cs index 3c87b166ac..e9a20761b3 100644 --- a/osu.Game/Graphics/UserInterface/Bar.cs +++ b/osu.Game/Graphics/UserInterface/Bar.cs @@ -109,15 +109,11 @@ namespace osu.Game.Graphics.UserInterface } } - [Flags] public enum BarDirection { - LeftToRight = 1, - RightToLeft = 1 << 1, - TopToBottom = 1 << 2, - BottomToTop = 1 << 3, - - Vertical = TopToBottom | BottomToTop, - Horizontal = LeftToRight | RightToLeft, + LeftToRight, + RightToLeft, + TopToBottom, + BottomToTop } } diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index 2e9fd6734f..45eeba11d5 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -5,15 +5,23 @@ using osuTK; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using System.Collections.Generic; using System.Linq; -using osu.Framework.Extensions.EnumExtensions; +using osu.Framework.Graphics.Rendering; +using osu.Framework.Graphics.Shaders; +using osu.Framework.Allocation; +using osu.Framework.Graphics.Textures; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Utils; +using System; namespace osu.Game.Graphics.UserInterface { - public class BarGraph : FillFlowContainer + public class BarGraph : Drawable { + private const int resize_duration = 250; + private const Easing easing = Easing.InOutCubic; + /// /// Manually sets the max value, if null is instead used /// @@ -21,22 +29,21 @@ namespace osu.Game.Graphics.UserInterface private BarDirection direction = BarDirection.BottomToTop; - public new BarDirection Direction + public BarDirection Direction { get => direction; set { - direction = value; - base.Direction = direction.HasFlagFast(BarDirection.Horizontal) ? FillDirection.Vertical : FillDirection.Horizontal; + if (direction == value) + return; - foreach (var bar in Children) - { - bar.Size = direction.HasFlagFast(BarDirection.Horizontal) ? new Vector2(1, 1.0f / Children.Count) : new Vector2(1.0f / Children.Count, 1); - bar.Direction = direction; - } + direction = value; + Invalidate(Invalidation.DrawNode); } } + private IEnumerable bars; + /// /// A list of floats that defines the length of each /// @@ -44,38 +51,188 @@ namespace osu.Game.Graphics.UserInterface { set { - List bars = Children.ToList(); + List newBars = bars?.ToList() ?? new List(); - foreach (var bar in value.Select((length, index) => new { Value = length, Bar = bars.Count > index ? bars[index] : null })) + int newCount = value.Count(); + + float size = newCount; + if (size != 0) + size = 1.0f / size; + + foreach (var bar in value.Select((length, index) => new { Value = length, Bar = newBars.Count > index ? newBars[index] : null })) { float length = MaxValue ?? value.Max(); if (length != 0) - length = bar.Value / length; - - float size = value.Count(); - if (size != 0) - size = 1.0f / size; + length = Math.Max(0f, bar.Value / length); if (bar.Bar != null) { - bar.Bar.Length = length; - bar.Bar.Size = direction.HasFlagFast(BarDirection.Horizontal) ? new Vector2(1, size) : new Vector2(size, 1); + bar.Bar.OldValue = bar.Bar.Value; + + bar.Bar.Value = length; + bar.Bar.ShortSide = size; } else { - Add(new Bar + newBars.Add(new BarDescriptor { - RelativeSizeAxes = Axes.Both, - Size = direction.HasFlagFast(BarDirection.Horizontal) ? new Vector2(1, size) : new Vector2(size, 1), - Length = length, - Direction = Direction, + Value = length, + ShortSide = size }); } } - //I'm using ToList() here because Where() returns an Enumerable which can change it's elements afterwards - RemoveRange(Children.Where((_, index) => index >= value.Count()).ToList(), true); + if (newBars.Count > newCount) + newBars.RemoveRange(newCount, newBars.Count - newCount); + + bars = newBars; + + animationStartTime = Clock.CurrentTime; + animationComplete = false; } } + + private double animationStartTime; + private bool animationComplete; + + private IShader shader = null!; + private Texture texture = null!; + + [BackgroundDependencyLoader] + private void load(IRenderer renderer, ShaderManager shaders) + { + texture = renderer.WhitePixel; + shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE); + } + + protected override void Update() + { + base.Update(); + + if (noBars) + return; + + double currentTime = Clock.CurrentTime; + + if (currentTime < animationStartTime + resize_duration) + { + foreach (var bar in bars) + bar.IntermediateValue = Interpolation.ValueAt(currentTime, bar.OldValue, bar.Value, animationStartTime, animationStartTime + resize_duration, easing); + + Invalidate(Invalidation.DrawNode); + return; + } + else if (!animationComplete) + { + foreach (var bar in bars) + bar.IntermediateValue = bar.Value; + + Invalidate(Invalidation.DrawNode); + + animationComplete = true; + return; + } + } + + private bool noBars => bars?.Any() != true; + + protected override DrawNode CreateDrawNode() => new BarGraphDrawNode(this); + + private class BarGraphDrawNode : DrawNode + { + public new BarGraph Source => (BarGraph)base.Source; + + public BarGraphDrawNode(BarGraph source) + : base(source) + { + } + + private IShader shader = null!; + private Texture texture = null!; + private Vector2 drawSize; + private BarDirection direction; + + private readonly List bars = new List(); + + public override void ApplyState() + { + base.ApplyState(); + + shader = Source.shader; + texture = Source.texture; + drawSize = Source.DrawSize; + direction = Source.direction; + + bars.Clear(); + + if (Source.noBars) + return; + + bars.AddRange(Source.bars); + } + + public override void Draw(IRenderer renderer) + { + base.Draw(renderer); + + if (!bars.Any()) + return; + + shader.Bind(); + + for (int i = 0; i < bars.Count; i++) + { + var bar = bars[i]; + + float barHeight = drawSize.Y * ((direction == BarDirection.TopToBottom || direction == BarDirection.BottomToTop) ? bar.IntermediateValue : bar.ShortSide); + float barWidth = drawSize.X * ((direction == BarDirection.LeftToRight || direction == BarDirection.RightToLeft) ? bar.IntermediateValue : bar.ShortSide); + + Vector2 topLeft; + + switch (direction) + { + default: + case BarDirection.LeftToRight: + topLeft = new Vector2(0, i * barHeight); + break; + + case BarDirection.RightToLeft: + topLeft = new Vector2(drawSize.X - barWidth, i * barHeight); + break; + + case BarDirection.TopToBottom: + topLeft = new Vector2(i * barWidth, 0); + break; + + case BarDirection.BottomToTop: + topLeft = new Vector2(i * barWidth, drawSize.Y - barHeight); + break; + } + + Vector2 topRight = topLeft + new Vector2(barWidth, 0); + Vector2 bottomLeft = topLeft + new Vector2(0, barHeight); + Vector2 bottomRight = bottomLeft + new Vector2(barWidth, 0); + + var drawQuad = new Quad( + Vector2Extensions.Transform(topLeft, DrawInfo.Matrix), + Vector2Extensions.Transform(topRight, DrawInfo.Matrix), + Vector2Extensions.Transform(bottomLeft, DrawInfo.Matrix), + Vector2Extensions.Transform(bottomRight, DrawInfo.Matrix) + ); + + renderer.DrawQuad(texture, drawQuad, DrawColourInfo.Colour); + } + + shader.Unbind(); + } + } + + private class BarDescriptor + { + public float OldValue { get; set; } + public float Value { get; set; } + public float IntermediateValue { get; set; } + public float ShortSide { get; set; } + } } } From 016de2f5a03b34395eb0c71eae5660f42566952c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 19 Nov 2022 05:07:10 +0300 Subject: [PATCH 0660/2991] Fix editor not always playing hitsounds with clock offsets applied --- osu.Game/Screens/Edit/EditorClock.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index 81d82130da..f83874e4a0 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -270,7 +270,7 @@ namespace osu.Game.Screens.Edit { IsSeeking &= Transforms.Any(); - if (track.Value?.IsRunning != true) + if (!IsRunning) { // seeking in the editor can happen while the track isn't running. // in this case we always want to expose ourselves as seeking (to avoid sample playback). From 28867fbbb1750640a30113d576500d0a82502db7 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sat, 19 Nov 2022 12:34:35 +0900 Subject: [PATCH 0661/2991] Add comment --- osu.Game/Database/LegacyExportManager.cs | 18 ++++++++++++++---- osu.Game/Database/LegacyModelExporter.cs | 6 ++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/osu.Game/Database/LegacyExportManager.cs b/osu.Game/Database/LegacyExportManager.cs index 08594ab020..19fca623c5 100644 --- a/osu.Game/Database/LegacyExportManager.cs +++ b/osu.Game/Database/LegacyExportManager.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.IO; using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -14,6 +15,9 @@ using osu.Game.Skinning; namespace osu.Game.Database { + /// + /// A class which centrally manage legacy file exports. + /// [ExcludeFromDynamicCompile] public class LegacyExportManager : Component { @@ -26,7 +30,13 @@ namespace osu.Game.Database [Resolved] private INotificationOverlay? notifications { get; set; } - public async Task ExportAsync(IHasGuidPrimaryKey item) + /// + /// Identify the model type and and automatically assigned to the corresponding exporter. + /// + /// The model should export. + /// The stream if requires a specific output-stream + /// + public async Task ExportAsync(IHasGuidPrimaryKey item, Stream? stream = null) { var notification = new ProgressNotification { @@ -39,15 +49,15 @@ namespace osu.Game.Database switch (item) { case SkinInfo: - await new LegacySkinExporter(exportStorage, realmAccess, notification).ExportASync(item); + await new LegacySkinExporter(exportStorage, realmAccess, notification, stream).ExportASync(item); break; case ScoreInfo: - await new LegacyScoreExporter(exportStorage, realmAccess, notification).ExportASync(item); + await new LegacyScoreExporter(exportStorage, realmAccess, notification, stream).ExportASync(item); break; case BeatmapSetInfo: - await new LegacyBeatmapExporter(exportStorage, realmAccess, notification).ExportASync(item); + await new LegacyBeatmapExporter(exportStorage, realmAccess, notification, stream).ExportASync(item); break; } } diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index a4b0f7ba9d..d734d3341c 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -48,6 +48,12 @@ namespace osu.Game.Database ShouldDisposeStream = false; } + /// + /// Export model to + /// if is null, model will export to default folder. + /// + /// The model which have Guid. + /// public virtual async Task ExportASync(IHasGuidPrimaryKey uuid) { Guid id = uuid.ID; From 290369db47ab44f24b01e5db3cce97f045f57ddf Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 19 Nov 2022 06:40:20 +0300 Subject: [PATCH 0662/2991] Hide scroll speed slider on rulesets which don't support it --- osu.Game/Screens/Edit/Timing/EffectSection.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Screens/Edit/Timing/EffectSection.cs b/osu.Game/Screens/Edit/Timing/EffectSection.cs index f7e59a75f1..9ba3634311 100644 --- a/osu.Game/Screens/Edit/Timing/EffectSection.cs +++ b/osu.Game/Screens/Edit/Timing/EffectSection.cs @@ -8,6 +8,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Screens.Edit.Timing { @@ -41,6 +42,12 @@ namespace osu.Game.Screens.Edit.Timing omitBarLine.Current.BindValueChanged(_ => saveChanges()); scrollSpeedSlider.Current.BindValueChanged(_ => saveChanges()); + // adjusting scroll speed on osu/catch rulesets results in undefined behaviour during legacy beatmap decoding, and generally shouldn't be shown. + // todo: there should be proper way to identify such rulesets, but this should do for now. + var ruleset = Beatmap.BeatmapInfo.Ruleset; + if (ruleset.OnlineID == 0 || ruleset.OnlineID == 2) + scrollSpeedSlider.Hide(); + void saveChanges() { if (!isRebinding) ChangeHandler?.SaveState(); From 2653bd2f997c305d1497d74da66e33be9630cc84 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sat, 19 Nov 2022 12:57:56 +0900 Subject: [PATCH 0663/2991] Make notification cannot cancel when Saving Zip Archive This operation cannot be stopped(if not dispose stream). so make it cannot cancel --- osu.Game/Database/LegacyModelExporter.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index d734d3341c..9fa6f64ee4 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -56,6 +56,9 @@ namespace osu.Game.Database /// public virtual async Task ExportASync(IHasGuidPrimaryKey uuid) { + bool canCancel = true; + Notification.CancelRequested += () => canCancel; + Guid id = uuid.ID; await Task.Run(() => { @@ -91,6 +94,7 @@ namespace osu.Game.Database } Notification.Text = "Saving Zip Archive..."; + canCancel = false; archive.SaveTo(OutputStream); } }); From ca67689a36339a8be554e39d017367873e244017 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 19 Nov 2022 07:44:28 +0300 Subject: [PATCH 0664/2991] Fix intermittent present beatmap test failures --- .../Navigation/TestScenePresentBeatmap.cs | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs index 6469962b08..02b348b439 100644 --- a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs +++ b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs @@ -7,12 +7,14 @@ using System; using System.Linq; using NUnit.Framework; using osu.Framework.Screens; +using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Extensions; using osu.Game.Rulesets; using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Osu; using osu.Game.Screens.Menu; +using osu.Game.Screens.Select; namespace osu.Game.Tests.Visual.Navigation { @@ -55,6 +57,7 @@ namespace osu.Game.Tests.Visual.Navigation presentAndConfirm(firstImport); var secondImport = importBeatmap(3); + confirmBeatmapInSongSelect(secondImport); presentAndConfirm(secondImport); // Test presenting same beatmap more than once @@ -74,6 +77,7 @@ namespace osu.Game.Tests.Visual.Navigation presentAndConfirm(firstImport); var secondImport = importBeatmap(3, new ManiaRuleset().RulesetInfo); + confirmBeatmapInSongSelect(secondImport); presentAndConfirm(secondImport); presentSecondDifficultyAndConfirm(firstImport, 1); @@ -134,13 +138,22 @@ namespace osu.Game.Tests.Visual.Navigation return () => imported; } + private void confirmBeatmapInSongSelect(Func getImport) + { + AddUntilStep("beatmap in song select", () => + { + var songSelect = (Screens.Select.SongSelect)Game.ScreenStack.CurrentScreen; + return songSelect.ChildrenOfType().Single().BeatmapSets.Any(b => b.MatchesOnlineID(getImport())); + }); + } + private void presentAndConfirm(Func getImport) { AddStep("present beatmap", () => Game.PresentBeatmap(getImport())); - AddUntilStep("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect); - AddUntilStep("correct beatmap displayed", () => Game.Beatmap.Value.BeatmapSetInfo.MatchesOnlineID(getImport())); - AddAssert("correct ruleset selected", () => Game.Ruleset.Value.Equals(getImport().Beatmaps.First().Ruleset)); + AddUntilStep("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect songSelect && songSelect.IsLoaded); + AddUntilStep("correct beatmap displayed", () => Game.Beatmap.Value.BeatmapSetInfo.OnlineID, () => Is.EqualTo(getImport().OnlineID)); + AddAssert("correct ruleset selected", () => Game.Ruleset.Value, () => Is.EqualTo(getImport().Beatmaps.First().Ruleset)); } private void presentSecondDifficultyAndConfirm(Func getImport, int importedID) @@ -148,9 +161,9 @@ namespace osu.Game.Tests.Visual.Navigation Predicate pred = b => b.OnlineID == importedID * 2048; AddStep("present difficulty", () => Game.PresentBeatmap(getImport(), pred)); - AddUntilStep("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect); - AddUntilStep("correct beatmap displayed", () => Game.Beatmap.Value.BeatmapInfo.OnlineID == importedID * 2048); - AddAssert("correct ruleset selected", () => Game.Ruleset.Value.Equals(getImport().Beatmaps.First().Ruleset)); + AddUntilStep("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect songSelect && songSelect.IsLoaded); + AddUntilStep("correct beatmap displayed", () => Game.Beatmap.Value.BeatmapInfo.OnlineID, () => Is.EqualTo(importedID * 2048)); + AddAssert("correct ruleset selected", () => Game.Ruleset.Value, () => Is.EqualTo(getImport().Beatmaps.First().Ruleset)); } } } From 11f5fddc1f4a803ac3f737b7c628730d9ee23359 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 19 Nov 2022 09:57:52 +0300 Subject: [PATCH 0665/2991] Remove redundant returns --- osu.Game/Graphics/UserInterface/BarGraph.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index 45eeba11d5..b82911ea56 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -120,7 +120,6 @@ namespace osu.Game.Graphics.UserInterface bar.IntermediateValue = Interpolation.ValueAt(currentTime, bar.OldValue, bar.Value, animationStartTime, animationStartTime + resize_duration, easing); Invalidate(Invalidation.DrawNode); - return; } else if (!animationComplete) { @@ -130,7 +129,6 @@ namespace osu.Game.Graphics.UserInterface Invalidate(Invalidation.DrawNode); animationComplete = true; - return; } } From 9b8f98735cdc642ab7ea5d050bab9f96e77de491 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 19 Nov 2022 10:16:58 +0300 Subject: [PATCH 0666/2991] Use struct for bars description --- osu.Game/Graphics/UserInterface/BarGraph.cs | 55 +++++++++++---------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index b82911ea56..efc5eace0d 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -42,7 +42,7 @@ namespace osu.Game.Graphics.UserInterface } } - private IEnumerable bars; + private readonly List bars = new List(); /// /// A list of floats that defines the length of each @@ -51,30 +51,31 @@ namespace osu.Game.Graphics.UserInterface { set { - List newBars = bars?.ToList() ?? new List(); - int newCount = value.Count(); float size = newCount; if (size != 0) size = 1.0f / size; - foreach (var bar in value.Select((length, index) => new { Value = length, Bar = newBars.Count > index ? newBars[index] : null })) + float maxLength = MaxValue ?? value.Max(); + + foreach (var bar in value.Select((length, index) => new { Value = length, Index = index })) { - float length = MaxValue ?? value.Max(); - if (length != 0) - length = Math.Max(0f, bar.Value / length); + float length = maxLength == 0 ? 0 : Math.Max(0f, bar.Value / maxLength); - if (bar.Bar != null) + if (bar.Index < bars.Count) { - bar.Bar.OldValue = bar.Bar.Value; + BarStruct b = bars[bar.Index]; - bar.Bar.Value = length; - bar.Bar.ShortSide = size; + b.OldValue = b.Value; + b.Value = length; + b.ShortSide = size; + + bars[bar.Index] = b; } else { - newBars.Add(new BarDescriptor + bars.Add(new BarStruct { Value = length, ShortSide = size @@ -82,10 +83,8 @@ namespace osu.Game.Graphics.UserInterface } } - if (newBars.Count > newCount) - newBars.RemoveRange(newCount, newBars.Count - newCount); - - bars = newBars; + if (bars.Count > newCount) + bars.RemoveRange(newCount, bars.Count - newCount); animationStartTime = Clock.CurrentTime; animationComplete = false; @@ -109,22 +108,30 @@ namespace osu.Game.Graphics.UserInterface { base.Update(); - if (noBars) + if (!bars.Any()) return; double currentTime = Clock.CurrentTime; if (currentTime < animationStartTime + resize_duration) { - foreach (var bar in bars) + for (int i = 0; i < bars.Count(); i++) + { + BarStruct bar = bars[i]; bar.IntermediateValue = Interpolation.ValueAt(currentTime, bar.OldValue, bar.Value, animationStartTime, animationStartTime + resize_duration, easing); + bars[i] = bar; + } Invalidate(Invalidation.DrawNode); } else if (!animationComplete) { - foreach (var bar in bars) + for (int i = 0; i < bars.Count(); i++) + { + BarStruct bar = bars[i]; bar.IntermediateValue = bar.Value; + bars[i] = bar; + } Invalidate(Invalidation.DrawNode); @@ -132,8 +139,6 @@ namespace osu.Game.Graphics.UserInterface } } - private bool noBars => bars?.Any() != true; - protected override DrawNode CreateDrawNode() => new BarGraphDrawNode(this); private class BarGraphDrawNode : DrawNode @@ -150,7 +155,7 @@ namespace osu.Game.Graphics.UserInterface private Vector2 drawSize; private BarDirection direction; - private readonly List bars = new List(); + private readonly List bars = new List(); public override void ApplyState() { @@ -162,10 +167,6 @@ namespace osu.Game.Graphics.UserInterface direction = Source.direction; bars.Clear(); - - if (Source.noBars) - return; - bars.AddRange(Source.bars); } @@ -225,7 +226,7 @@ namespace osu.Game.Graphics.UserInterface } } - private class BarDescriptor + private struct BarStruct { public float OldValue { get; set; } public float Value { get; set; } From 05992d3aa8eabf806e2fdcf2074effd819719cf2 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 19 Nov 2022 10:23:37 +0300 Subject: [PATCH 0667/2991] CI fix --- osu.Game/Graphics/UserInterface/BarGraph.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index efc5eace0d..8552c2196c 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -115,7 +115,7 @@ namespace osu.Game.Graphics.UserInterface if (currentTime < animationStartTime + resize_duration) { - for (int i = 0; i < bars.Count(); i++) + for (int i = 0; i < bars.Count; i++) { BarStruct bar = bars[i]; bar.IntermediateValue = Interpolation.ValueAt(currentTime, bar.OldValue, bar.Value, animationStartTime, animationStartTime + resize_duration, easing); @@ -126,7 +126,7 @@ namespace osu.Game.Graphics.UserInterface } else if (!animationComplete) { - for (int i = 0; i < bars.Count(); i++) + for (int i = 0; i < bars.Count; i++) { BarStruct bar = bars[i]; bar.IntermediateValue = bar.Value; From 0239103b6b0f24b6b5d956794be01575d3d1a7ed Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 19 Nov 2022 11:33:14 +0300 Subject: [PATCH 0668/2991] Fix BeatmapOverlay crashing test scene --- osu.Game/Graphics/UserInterface/BarGraph.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index 8552c2196c..56a2a4f579 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -57,7 +57,7 @@ namespace osu.Game.Graphics.UserInterface if (size != 0) size = 1.0f / size; - float maxLength = MaxValue ?? value.Max(); + float maxLength = MaxValue ?? (newCount == 0 ? 0 : value.Max()); foreach (var bar in value.Select((length, index) => new { Value = length, Index = index })) { From 2e3af97892906e02abb53fc7417570ae92c919a3 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 19 Nov 2022 12:13:36 +0300 Subject: [PATCH 0669/2991] Remove unused using --- osu.Game/Screens/Edit/Timing/EffectSection.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Timing/EffectSection.cs b/osu.Game/Screens/Edit/Timing/EffectSection.cs index 9ba3634311..8d12317ee9 100644 --- a/osu.Game/Screens/Edit/Timing/EffectSection.cs +++ b/osu.Game/Screens/Edit/Timing/EffectSection.cs @@ -8,7 +8,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.UserInterfaceV2; -using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Screens.Edit.Timing { From eff6c7be6499aecd6ecf7bfb3faf999334b04d41 Mon Sep 17 00:00:00 2001 From: Terochi Date: Sat, 19 Nov 2022 16:53:35 +0100 Subject: [PATCH 0670/2991] Removed unnecessary methods, changed tests, and moved LimitedCapacityQueue.cs to a more generic namespace. --- .../Difficulty/Skills/Rhythm.cs | 2 +- .../NonVisual/LimitedCapacityQueueTest.cs | 2 +- .../UserInterface/TestSceneHistoryTextBox.cs | 24 ++----------------- .../Graphics/UserInterface/HistoryTextBox.cs | 14 +---------- .../Utils/LimitedCapacityQueue.cs | 2 +- 5 files changed, 6 insertions(+), 38 deletions(-) rename osu.Game/{Rulesets/Difficulty => }/Utils/LimitedCapacityQueue.cs (98%) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Rhythm.cs b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Rhythm.cs index 4a2b97a4cb..ff187a133a 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Rhythm.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Rhythm.cs @@ -6,10 +6,10 @@ using System; using osu.Game.Rulesets.Difficulty.Preprocessing; using osu.Game.Rulesets.Difficulty.Skills; -using osu.Game.Rulesets.Difficulty.Utils; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Taiko.Difficulty.Preprocessing; using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Utils; namespace osu.Game.Rulesets.Taiko.Difficulty.Skills { diff --git a/osu.Game.Tests/NonVisual/LimitedCapacityQueueTest.cs b/osu.Game.Tests/NonVisual/LimitedCapacityQueueTest.cs index 8cd26901c5..8809ce3adc 100644 --- a/osu.Game.Tests/NonVisual/LimitedCapacityQueueTest.cs +++ b/osu.Game.Tests/NonVisual/LimitedCapacityQueueTest.cs @@ -5,7 +5,7 @@ using System; using NUnit.Framework; -using osu.Game.Rulesets.Difficulty.Utils; +using osu.Game.Utils; namespace osu.Game.Tests.NonVisual { diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs index 862777c500..8918e53056 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using System.Linq; using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Input; @@ -21,8 +18,8 @@ namespace osu.Game.Tests.Visual.UserInterface private int messageCounter; - private HistoryTextBox box; - private OsuSpriteText text; + private HistoryTextBox box = null!; + private OsuSpriteText text = null!; [SetUp] public void SetUp() @@ -70,7 +67,6 @@ namespace osu.Game.Tests.Visual.UserInterface public void TestEmptyHistory() { AddStep("Set text", () => box.Text = temp); - AddAssert("History is empty", () => !box.GetMessageHistory().Any()); AddStep("Move down", () => InputManager.Key(Key.Down)); AddAssert("Text is the same", () => box.Text == temp); @@ -106,16 +102,12 @@ namespace osu.Game.Tests.Visual.UserInterface { addMessages(5); AddStep("Set text", () => box.Text = temp); - AddAssert("History saved as <5-1>", () => - Enumerable.Range(0, 5).Select(number => $"Message {5 - number}").SequenceEqual(box.GetMessageHistory())); AddStep("Move down", () => InputManager.Key(Key.Down)); AddAssert("Text is the same", () => box.Text == temp); addMessages(2); AddStep("Set text", () => box.Text = temp); - AddAssert("Overrode history to <7-3>", () => - Enumerable.Range(0, 5).Select(number => $"Message {7 - number}").SequenceEqual(box.GetMessageHistory())); AddRepeatStep("Move Up", () => InputManager.Key(Key.Up), 5); AddAssert("Same as 3rd message", () => box.Text == "Message 3"); @@ -130,18 +122,6 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("Same as temp message", () => box.Text == temp); } - [Test] - public void TestOverrideFullHistory() - { - addMessages(5); - AddAssert("History saved as <5-1>", () => - Enumerable.Range(0, 5).Select(number => $"Message {5 - number}").SequenceEqual(box.GetMessageHistory())); - - addMessages(6); - AddAssert("Overrode history to <11-7>", () => - Enumerable.Range(0, 5).Select(number => $"Message {11 - number}").SequenceEqual(box.GetMessageHistory())); - } - [Test] public void TestResetIndex() { diff --git a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs index 17858ea16d..e9da67e553 100644 --- a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs +++ b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs @@ -1,9 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Collections.Generic; using osu.Framework.Input.Events; -using osu.Game.Rulesets.Difficulty.Utils; +using osu.Game.Utils; using osuTK.Input; namespace osu.Game.Graphics.UserInterface @@ -12,15 +11,6 @@ namespace osu.Game.Graphics.UserInterface { private readonly LimitedCapacityQueue messageHistory; - public IEnumerable GetMessageHistory() - { - if (HistoryCount == 0) - yield break; - - for (int i = HistoryCount - 1; i >= 0; i--) - yield return messageHistory[i]; - } - public int HistoryCount => messageHistory.Count; private int selectedIndex; @@ -28,8 +18,6 @@ namespace osu.Game.Graphics.UserInterface private string originalMessage = string.Empty; private bool everythingSelected; - public string GetOldMessage(int index) => messageHistory[HistoryCount - index - 1]; - public HistoryTextBox(int capacity = 100) { messageHistory = new LimitedCapacityQueue(capacity); diff --git a/osu.Game/Rulesets/Difficulty/Utils/LimitedCapacityQueue.cs b/osu.Game/Utils/LimitedCapacityQueue.cs similarity index 98% rename from osu.Game/Rulesets/Difficulty/Utils/LimitedCapacityQueue.cs rename to osu.Game/Utils/LimitedCapacityQueue.cs index d20eb5e885..86a106a678 100644 --- a/osu.Game/Rulesets/Difficulty/Utils/LimitedCapacityQueue.cs +++ b/osu.Game/Utils/LimitedCapacityQueue.cs @@ -7,7 +7,7 @@ using System; using System.Collections; using System.Collections.Generic; -namespace osu.Game.Rulesets.Difficulty.Utils +namespace osu.Game.Utils { /// /// An indexed queue with limited capacity. From 6f449a583e57230e3af26dd8d40ab6051dc036b9 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 19 Nov 2022 23:27:48 +0300 Subject: [PATCH 0671/2991] Handle empty values as a separate case --- osu.Game.Tests/Visual/Online/TestSceneGraph.cs | 2 ++ osu.Game/Graphics/UserInterface/BarGraph.cs | 13 +++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneGraph.cs b/osu.Game.Tests/Visual/Online/TestSceneGraph.cs index 2f3331b141..8b0536651d 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneGraph.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneGraph.cs @@ -3,6 +3,7 @@ #nullable disable +using System; using System.Linq; using NUnit.Framework; using osu.Framework.Graphics; @@ -32,6 +33,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("values from 1-10", () => graph.Values = Enumerable.Range(1, 10).Select(i => (float)i)); AddStep("values from 1-100", () => graph.Values = Enumerable.Range(1, 100).Select(i => (float)i)); AddStep("reversed values from 1-10", () => graph.Values = Enumerable.Range(1, 10).Reverse().Select(i => (float)i)); + AddStep("empty values", () => graph.Values = Array.Empty()); AddStep("Bottom to top", () => graph.Direction = BarDirection.BottomToTop); AddStep("Top to bottom", () => graph.Direction = BarDirection.TopToBottom); AddStep("Left to right", () => graph.Direction = BarDirection.LeftToRight); diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index 56a2a4f579..c9bffc605e 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -51,13 +51,18 @@ namespace osu.Game.Graphics.UserInterface { set { + if (!value.Any()) + { + bars.Clear(); + Invalidate(Invalidation.DrawNode); + return; + } + int newCount = value.Count(); - float size = newCount; - if (size != 0) - size = 1.0f / size; + float size = 1.0f / newCount; - float maxLength = MaxValue ?? (newCount == 0 ? 0 : value.Max()); + float maxLength = MaxValue ?? value.Max(); foreach (var bar in value.Select((length, index) => new { Value = length, Index = index })) { From f1201454b723cf9f00df4729d0390adecaa0da84 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 19 Nov 2022 23:29:50 +0300 Subject: [PATCH 0672/2991] Use value tuples --- osu.Game/Graphics/UserInterface/BarGraph.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index c9bffc605e..f2352c91da 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -64,7 +64,7 @@ namespace osu.Game.Graphics.UserInterface float maxLength = MaxValue ?? value.Max(); - foreach (var bar in value.Select((length, index) => new { Value = length, Index = index })) + foreach (var bar in value.Select((length, index) => (Value: length, Index: index))) { float length = maxLength == 0 ? 0 : Math.Max(0f, bar.Value / maxLength); From 67ee9f39154dae692caa3c96d8a5b7cfb1fc5643 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 19 Nov 2022 23:34:55 +0300 Subject: [PATCH 0673/2991] Naming adjustments --- osu.Game/Graphics/UserInterface/BarGraph.cs | 40 ++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index f2352c91da..661057cbde 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -42,7 +42,7 @@ namespace osu.Game.Graphics.UserInterface } } - private readonly List bars = new List(); + private readonly List bars = new List(); /// /// A list of floats that defines the length of each @@ -70,20 +70,20 @@ namespace osu.Game.Graphics.UserInterface if (bar.Index < bars.Count) { - BarStruct b = bars[bar.Index]; + BarInfo b = bars[bar.Index]; - b.OldValue = b.Value; - b.Value = length; - b.ShortSide = size; + b.InitialLength = b.FinalLength; + b.FinalLength = length; + b.Breadth = size; bars[bar.Index] = b; } else { - bars.Add(new BarStruct + bars.Add(new BarInfo { - Value = length, - ShortSide = size + FinalLength = length, + Breadth = size }); } } @@ -122,8 +122,8 @@ namespace osu.Game.Graphics.UserInterface { for (int i = 0; i < bars.Count; i++) { - BarStruct bar = bars[i]; - bar.IntermediateValue = Interpolation.ValueAt(currentTime, bar.OldValue, bar.Value, animationStartTime, animationStartTime + resize_duration, easing); + BarInfo bar = bars[i]; + bar.InstantaneousLength = Interpolation.ValueAt(currentTime, bar.InitialLength, bar.FinalLength, animationStartTime, animationStartTime + resize_duration, easing); bars[i] = bar; } @@ -133,8 +133,8 @@ namespace osu.Game.Graphics.UserInterface { for (int i = 0; i < bars.Count; i++) { - BarStruct bar = bars[i]; - bar.IntermediateValue = bar.Value; + BarInfo bar = bars[i]; + bar.InstantaneousLength = bar.FinalLength; bars[i] = bar; } @@ -160,7 +160,7 @@ namespace osu.Game.Graphics.UserInterface private Vector2 drawSize; private BarDirection direction; - private readonly List bars = new List(); + private readonly List bars = new List(); public override void ApplyState() { @@ -188,8 +188,8 @@ namespace osu.Game.Graphics.UserInterface { var bar = bars[i]; - float barHeight = drawSize.Y * ((direction == BarDirection.TopToBottom || direction == BarDirection.BottomToTop) ? bar.IntermediateValue : bar.ShortSide); - float barWidth = drawSize.X * ((direction == BarDirection.LeftToRight || direction == BarDirection.RightToLeft) ? bar.IntermediateValue : bar.ShortSide); + float barHeight = drawSize.Y * ((direction == BarDirection.TopToBottom || direction == BarDirection.BottomToTop) ? bar.InstantaneousLength : bar.Breadth); + float barWidth = drawSize.X * ((direction == BarDirection.LeftToRight || direction == BarDirection.RightToLeft) ? bar.InstantaneousLength : bar.Breadth); Vector2 topLeft; @@ -231,12 +231,12 @@ namespace osu.Game.Graphics.UserInterface } } - private struct BarStruct + private struct BarInfo { - public float OldValue { get; set; } - public float Value { get; set; } - public float IntermediateValue { get; set; } - public float ShortSide { get; set; } + public float InitialLength { get; set; } + public float FinalLength { get; set; } + public float InstantaneousLength { get; set; } + public float Breadth { get; set; } } } } From 6c62cfb8301e5e6f29f64a17ec0323d5a23caca0 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 19 Nov 2022 23:40:02 +0300 Subject: [PATCH 0674/2991] Store barBreadth as a separate float --- osu.Game/Graphics/UserInterface/BarGraph.cs | 22 +++++++++------------ 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index 661057cbde..404b925372 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -43,6 +43,7 @@ namespace osu.Game.Graphics.UserInterface } private readonly List bars = new List(); + private float barBreadth; /// /// A list of floats that defines the length of each @@ -60,7 +61,7 @@ namespace osu.Game.Graphics.UserInterface int newCount = value.Count(); - float size = 1.0f / newCount; + barBreadth = 1.0f / newCount; float maxLength = MaxValue ?? value.Max(); @@ -74,18 +75,12 @@ namespace osu.Game.Graphics.UserInterface b.InitialLength = b.FinalLength; b.FinalLength = length; - b.Breadth = size; bars[bar.Index] = b; + continue; } - else - { - bars.Add(new BarInfo - { - FinalLength = length, - Breadth = size - }); - } + + bars.Add(new BarInfo { FinalLength = length }); } if (bars.Count > newCount) @@ -159,6 +154,7 @@ namespace osu.Game.Graphics.UserInterface private Texture texture = null!; private Vector2 drawSize; private BarDirection direction; + private float barBreadth; private readonly List bars = new List(); @@ -170,6 +166,7 @@ namespace osu.Game.Graphics.UserInterface texture = Source.texture; drawSize = Source.DrawSize; direction = Source.direction; + barBreadth = Source.barBreadth; bars.Clear(); bars.AddRange(Source.bars); @@ -188,8 +185,8 @@ namespace osu.Game.Graphics.UserInterface { var bar = bars[i]; - float barHeight = drawSize.Y * ((direction == BarDirection.TopToBottom || direction == BarDirection.BottomToTop) ? bar.InstantaneousLength : bar.Breadth); - float barWidth = drawSize.X * ((direction == BarDirection.LeftToRight || direction == BarDirection.RightToLeft) ? bar.InstantaneousLength : bar.Breadth); + float barHeight = drawSize.Y * ((direction == BarDirection.TopToBottom || direction == BarDirection.BottomToTop) ? bar.InstantaneousLength : barBreadth); + float barWidth = drawSize.X * ((direction == BarDirection.LeftToRight || direction == BarDirection.RightToLeft) ? bar.InstantaneousLength : barBreadth); Vector2 topLeft; @@ -236,7 +233,6 @@ namespace osu.Game.Graphics.UserInterface public float InitialLength { get; set; } public float FinalLength { get; set; } public float InstantaneousLength { get; set; } - public float Breadth { get; set; } } } } From 2cb966b47cad8127fb828fb440698cb9724a6c97 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 20 Nov 2022 01:20:57 +0300 Subject: [PATCH 0675/2991] Rework BarsInfo struct --- osu.Game/Graphics/UserInterface/BarGraph.cs | 134 ++++++++++++-------- 1 file changed, 83 insertions(+), 51 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index 404b925372..6df0302d1c 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -42,7 +42,8 @@ namespace osu.Game.Graphics.UserInterface } } - private readonly List bars = new List(); + private readonly BarsInfo bars = new BarsInfo(0); + private float barBreadth; /// @@ -71,16 +72,11 @@ namespace osu.Game.Graphics.UserInterface if (bar.Index < bars.Count) { - BarInfo b = bars[bar.Index]; - - b.InitialLength = b.FinalLength; - b.FinalLength = length; - - bars[bar.Index] = b; + bars.UpdateLength(bar.Index, length); continue; } - bars.Add(new BarInfo { FinalLength = length }); + bars.AddBar(length); } if (bars.Count > newCount) @@ -108,31 +104,19 @@ namespace osu.Game.Graphics.UserInterface { base.Update(); - if (!bars.Any()) + if (!bars.Any) return; double currentTime = Clock.CurrentTime; if (currentTime < animationStartTime + resize_duration) { - for (int i = 0; i < bars.Count; i++) - { - BarInfo bar = bars[i]; - bar.InstantaneousLength = Interpolation.ValueAt(currentTime, bar.InitialLength, bar.FinalLength, animationStartTime, animationStartTime + resize_duration, easing); - bars[i] = bar; - } - + bars.Animate(animationStartTime, currentTime); Invalidate(Invalidation.DrawNode); } else if (!animationComplete) { - for (int i = 0; i < bars.Count; i++) - { - BarInfo bar = bars[i]; - bar.InstantaneousLength = bar.FinalLength; - bars[i] = bar; - } - + bars.FinishAnimation(); Invalidate(Invalidation.DrawNode); animationComplete = true; @@ -155,8 +139,7 @@ namespace osu.Game.Graphics.UserInterface private Vector2 drawSize; private BarDirection direction; private float barBreadth; - - private readonly List bars = new List(); + private BarsInfo bars; public override void ApplyState() { @@ -167,26 +150,19 @@ namespace osu.Game.Graphics.UserInterface drawSize = Source.DrawSize; direction = Source.direction; barBreadth = Source.barBreadth; - - bars.Clear(); - bars.AddRange(Source.bars); + bars = Source.bars; } public override void Draw(IRenderer renderer) { base.Draw(renderer); - if (!bars.Any()) - return; - shader.Bind(); for (int i = 0; i < bars.Count; i++) { - var bar = bars[i]; - - float barHeight = drawSize.Y * ((direction == BarDirection.TopToBottom || direction == BarDirection.BottomToTop) ? bar.InstantaneousLength : barBreadth); - float barWidth = drawSize.X * ((direction == BarDirection.LeftToRight || direction == BarDirection.RightToLeft) ? bar.InstantaneousLength : barBreadth); + float barHeight = drawSize.Y * ((direction == BarDirection.TopToBottom || direction == BarDirection.BottomToTop) ? bars.InstantaneousLength(i) : barBreadth); + float barWidth = drawSize.X * ((direction == BarDirection.LeftToRight || direction == BarDirection.RightToLeft) ? bars.InstantaneousLength(i) : barBreadth); Vector2 topLeft; @@ -210,29 +186,85 @@ namespace osu.Game.Graphics.UserInterface break; } - Vector2 topRight = topLeft + new Vector2(barWidth, 0); - Vector2 bottomLeft = topLeft + new Vector2(0, barHeight); - Vector2 bottomRight = bottomLeft + new Vector2(barWidth, 0); - - var drawQuad = new Quad( - Vector2Extensions.Transform(topLeft, DrawInfo.Matrix), - Vector2Extensions.Transform(topRight, DrawInfo.Matrix), - Vector2Extensions.Transform(bottomLeft, DrawInfo.Matrix), - Vector2Extensions.Transform(bottomRight, DrawInfo.Matrix) - ); - - renderer.DrawQuad(texture, drawQuad, DrawColourInfo.Colour); + renderer.DrawQuad( + texture, + new Quad( + Vector2Extensions.Transform(topLeft, DrawInfo.Matrix), + Vector2Extensions.Transform(topLeft + new Vector2(barWidth, 0), DrawInfo.Matrix), + Vector2Extensions.Transform(topLeft + new Vector2(0, barHeight), DrawInfo.Matrix), + Vector2Extensions.Transform(topLeft + new Vector2(barWidth, barHeight), DrawInfo.Matrix) + ), + DrawColourInfo.Colour); } shader.Unbind(); } } - private struct BarInfo + private struct BarsInfo { - public float InitialLength { get; set; } - public float FinalLength { get; set; } - public float InstantaneousLength { get; set; } + private readonly List initialLengths; + private readonly List finalLengths; + private readonly List instantaneousLengths; + + public bool Any => initialLengths.Any(); + + public int Count => initialLengths.Count; + + public BarsInfo(int initialCount) + { + initialLengths = new List(); + finalLengths = new List(); + instantaneousLengths = new List(); + + for (int i = 0; i < initialCount; i++) + { + initialLengths.Add(0); + finalLengths.Add(0); + instantaneousLengths.Add(0); + } + } + + public float InstantaneousLength(int index) => instantaneousLengths[index]; + + public void UpdateLength(int index, float newLength) + { + initialLengths[index] = finalLengths[index]; + finalLengths[index] = newLength; + } + + public void AddBar(float finalLength) + { + initialLengths.Add(0); + finalLengths.Add(finalLength); + instantaneousLengths.Add(0); + } + + public void Clear() + { + initialLengths.Clear(); + finalLengths.Clear(); + instantaneousLengths.Clear(); + } + + public void RemoveRange(int index, int count) + { + initialLengths.RemoveRange(index, count); + finalLengths.RemoveRange(index, count); + instantaneousLengths.RemoveRange(index, count); + } + + public void Animate(double animationStartTime, double currentTime) + { + for (int i = 0; i < Count; i++) + instantaneousLengths[i] = Interpolation.ValueAt(currentTime, initialLengths[i], finalLengths[i], animationStartTime, animationStartTime + resize_duration, easing); + } + + public void FinishAnimation() + { + for (int i = 0; i < Count; i++) + instantaneousLengths[i] = finalLengths[i]; + } } } } From fbfcf49ea6cc7c1639887fc5669da01493ea5d3c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 20 Nov 2022 02:13:54 +0300 Subject: [PATCH 0676/2991] Remove readonly modifier from struct fields --- osu.Game/Graphics/UserInterface/BarGraph.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index 6df0302d1c..4e1d708531 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -203,9 +203,9 @@ namespace osu.Game.Graphics.UserInterface private struct BarsInfo { - private readonly List initialLengths; - private readonly List finalLengths; - private readonly List instantaneousLengths; + private List initialLengths; + private List finalLengths; + private List instantaneousLengths; public bool Any => initialLengths.Any(); From fcb52ee237ad57a57beb949304d85e640f4ac53e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 20 Nov 2022 02:28:07 +0300 Subject: [PATCH 0677/2991] Make BarsInfo a readonly struct --- osu.Game/Graphics/UserInterface/BarGraph.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index 4e1d708531..50c634455b 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -42,7 +42,7 @@ namespace osu.Game.Graphics.UserInterface } } - private readonly BarsInfo bars = new BarsInfo(0); + private BarsInfo bars = new BarsInfo(0); private float barBreadth; @@ -201,11 +201,11 @@ namespace osu.Game.Graphics.UserInterface } } - private struct BarsInfo + private readonly struct BarsInfo { - private List initialLengths; - private List finalLengths; - private List instantaneousLengths; + private readonly List initialLengths; + private readonly List finalLengths; + private readonly List instantaneousLengths; public bool Any => initialLengths.Any(); From 58296bd4f007bcae3bf485583a7bff9cb07046ed Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 20 Nov 2022 04:11:09 +0300 Subject: [PATCH 0678/2991] Introduce `IDrawableScrollingRuleset` for editor consumption --- .../UI/Scrolling/DrawableScrollingRuleset.cs | 4 +++- .../UI/Scrolling/IDrawableScrollingRuleset.cs | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Rulesets/UI/Scrolling/IDrawableScrollingRuleset.cs diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs index 68469d083c..2cb57966e7 100644 --- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.UI.Scrolling /// A type of that supports a . /// s inside this will scroll within the playfield. /// - public abstract class DrawableScrollingRuleset : DrawableRuleset, IKeyBindingHandler + public abstract class DrawableScrollingRuleset : DrawableRuleset, IDrawableScrollingRuleset, IKeyBindingHandler where TObject : HitObject { /// @@ -66,6 +66,8 @@ namespace osu.Game.Rulesets.UI.Scrolling protected virtual ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Sequential; + ScrollVisualisationMethod IDrawableScrollingRuleset.VisualisationMethod => VisualisationMethod; + /// /// Whether the player can change . /// diff --git a/osu.Game/Rulesets/UI/Scrolling/IDrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/IDrawableScrollingRuleset.cs new file mode 100644 index 0000000000..6955ef26e5 --- /dev/null +++ b/osu.Game/Rulesets/UI/Scrolling/IDrawableScrollingRuleset.cs @@ -0,0 +1,16 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable disable +using osu.Game.Configuration; + +namespace osu.Game.Rulesets.UI.Scrolling +{ + /// + /// An interface for scrolling-based s. + /// + public interface IDrawableScrollingRuleset + { + ScrollVisualisationMethod VisualisationMethod { get; } + } +} From 4b0ba86bd0488c3a1b58f3b5fbf51dcf731ad142 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 20 Nov 2022 04:12:50 +0300 Subject: [PATCH 0679/2991] Identify scrolling rulesets using temporary `DrawableRuleset` instances --- osu.Game/Screens/Edit/Timing/EffectSection.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Edit/Timing/EffectSection.cs b/osu.Game/Screens/Edit/Timing/EffectSection.cs index 8d12317ee9..9be663bb26 100644 --- a/osu.Game/Screens/Edit/Timing/EffectSection.cs +++ b/osu.Game/Screens/Edit/Timing/EffectSection.cs @@ -7,7 +7,9 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Configuration; using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Screens.Edit.Timing { @@ -41,10 +43,8 @@ namespace osu.Game.Screens.Edit.Timing omitBarLine.Current.BindValueChanged(_ => saveChanges()); scrollSpeedSlider.Current.BindValueChanged(_ => saveChanges()); - // adjusting scroll speed on osu/catch rulesets results in undefined behaviour during legacy beatmap decoding, and generally shouldn't be shown. - // todo: there should be proper way to identify such rulesets, but this should do for now. - var ruleset = Beatmap.BeatmapInfo.Ruleset; - if (ruleset.OnlineID == 0 || ruleset.OnlineID == 2) + var drawableRuleset = Beatmap.BeatmapInfo.Ruleset.CreateInstance().CreateDrawableRulesetWith(Beatmap.PlayableBeatmap); + if (drawableRuleset is not IDrawableScrollingRuleset scrollingRuleset || scrollingRuleset.VisualisationMethod == ScrollVisualisationMethod.Constant) scrollSpeedSlider.Hide(); void saveChanges() From 36141cb2a4ef2452879cd2932aade19668f8fb35 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 20 Nov 2022 05:14:07 +0300 Subject: [PATCH 0680/2991] Make BarsInfo a class --- osu.Game/Graphics/UserInterface/BarGraph.cs | 64 ++++++++++----------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index 50c634455b..498a480c06 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -42,9 +42,7 @@ namespace osu.Game.Graphics.UserInterface } } - private BarsInfo bars = new BarsInfo(0); - - private float barBreadth; + private readonly BarsInfo bars = new BarsInfo(); /// /// A list of floats that defines the length of each @@ -62,7 +60,7 @@ namespace osu.Game.Graphics.UserInterface int newCount = value.Count(); - barBreadth = 1.0f / newCount; + bars.Breadth = 1.0f / newCount; float maxLength = MaxValue ?? value.Max(); @@ -139,7 +137,8 @@ namespace osu.Game.Graphics.UserInterface private Vector2 drawSize; private BarDirection direction; private float barBreadth; - private BarsInfo bars; + + private readonly List lengths = new List(); public override void ApplyState() { @@ -149,8 +148,10 @@ namespace osu.Game.Graphics.UserInterface texture = Source.texture; drawSize = Source.DrawSize; direction = Source.direction; - barBreadth = Source.barBreadth; - bars = Source.bars; + barBreadth = Source.bars.Breadth; + + lengths.Clear(); + lengths.AddRange(Source.bars.InstantaneousLengths); } public override void Draw(IRenderer renderer) @@ -159,10 +160,10 @@ namespace osu.Game.Graphics.UserInterface shader.Bind(); - for (int i = 0; i < bars.Count; i++) + for (int i = 0; i < lengths.Count; i++) { - float barHeight = drawSize.Y * ((direction == BarDirection.TopToBottom || direction == BarDirection.BottomToTop) ? bars.InstantaneousLength(i) : barBreadth); - float barWidth = drawSize.X * ((direction == BarDirection.LeftToRight || direction == BarDirection.RightToLeft) ? bars.InstantaneousLength(i) : barBreadth); + float barHeight = drawSize.Y * ((direction == BarDirection.TopToBottom || direction == BarDirection.BottomToTop) ? lengths[i] : barBreadth); + float barWidth = drawSize.X * ((direction == BarDirection.LeftToRight || direction == BarDirection.RightToLeft) ? lengths[i] : barBreadth); Vector2 topLeft; @@ -201,31 +202,18 @@ namespace osu.Game.Graphics.UserInterface } } - private readonly struct BarsInfo + private class BarsInfo { - private readonly List initialLengths; - private readonly List finalLengths; - private readonly List instantaneousLengths; + public bool Any => Count > 0; - public bool Any => initialLengths.Any(); + public int Count { get; private set; } - public int Count => initialLengths.Count; + public float Breadth { get; set; } - public BarsInfo(int initialCount) - { - initialLengths = new List(); - finalLengths = new List(); - instantaneousLengths = new List(); + public List InstantaneousLengths { get; } = new List(); - for (int i = 0; i < initialCount; i++) - { - initialLengths.Add(0); - finalLengths.Add(0); - instantaneousLengths.Add(0); - } - } - - public float InstantaneousLength(int index) => instantaneousLengths[index]; + private readonly List initialLengths = new List(); + private readonly List finalLengths = new List(); public void UpdateLength(int index, float newLength) { @@ -237,33 +225,39 @@ namespace osu.Game.Graphics.UserInterface { initialLengths.Add(0); finalLengths.Add(finalLength); - instantaneousLengths.Add(0); + InstantaneousLengths.Add(0); + + Count++; } public void Clear() { initialLengths.Clear(); finalLengths.Clear(); - instantaneousLengths.Clear(); + InstantaneousLengths.Clear(); + + Count = 0; } public void RemoveRange(int index, int count) { initialLengths.RemoveRange(index, count); finalLengths.RemoveRange(index, count); - instantaneousLengths.RemoveRange(index, count); + InstantaneousLengths.RemoveRange(index, count); + + Count -= count; } public void Animate(double animationStartTime, double currentTime) { for (int i = 0; i < Count; i++) - instantaneousLengths[i] = Interpolation.ValueAt(currentTime, initialLengths[i], finalLengths[i], animationStartTime, animationStartTime + resize_duration, easing); + InstantaneousLengths[i] = Interpolation.ValueAt(currentTime, initialLengths[i], finalLengths[i], animationStartTime, animationStartTime + resize_duration, easing); } public void FinishAnimation() { for (int i = 0; i < Count; i++) - instantaneousLengths[i] = finalLengths[i]; + InstantaneousLengths[i] = finalLengths[i]; } } } From b3667821ebfb0b18f5d7a3b0e1cddd156e185f71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 20 Nov 2022 10:07:32 +0100 Subject: [PATCH 0681/2991] Add failing test case --- .../Visual/SongSelect/TestSceneBeatmapCarousel.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index eacaf7f92e..d4d9f89c6a 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -11,6 +11,7 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Configuration; @@ -118,6 +119,15 @@ namespace osu.Game.Tests.Visual.SongSelect } } + [Test] + public void TestDeletion() + { + loadBeatmaps(count: 5, randomDifficulties: true); + + AddStep("remove first set", () => carousel.RemoveBeatmapSet(carousel.Items.Select(item => item.Item).OfType().First().BeatmapSet)); + AddUntilStep("4 beatmap sets visible", () => this.ChildrenOfType().Count(set => set.Alpha > 0) == 4); + } + [Test] public void TestScrollPositionMaintainedOnDelete() { From 7b274083d340fe2571ca22a8339097f9f814f27e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 20 Nov 2022 10:08:34 +0100 Subject: [PATCH 0682/2991] Fix phantom beatmap sets appearing on carousel after delete/update Regressed in c40c70509e1909fab2488120c9e867cb76f66827. As it turns out, `item.Item.Filtered.Value` is not the only condition that should be checked to determine if a carousel item should be hidden or not - `item.Item.State.Value != CarouselItemState.Collapsed` should also be true. This was even available as the `item.Item.Visible` convenience property, which is used in this commit. Failing to check `item.Item.State.Value` led to setting non-zero alpha on collapsed carousel items, leading to phantom beatmap sets appearing, as the alpha was set in the entire carousel's `Update()` method, thus firing every frame. --- 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 2f99f6acca..752a1ede64 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -770,7 +770,7 @@ namespace osu.Game.Screens.Select { updateItem(item); - if (!item.Item.Filtered.Value) + if (item.Item.Visible) { bool isSelected = item.Item.State.Value == CarouselItemState.Selected; From 33b2fe46d950fc125035290b8663ffbfc2858d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 20 Nov 2022 12:29:41 +0100 Subject: [PATCH 0683/2991] Add xmldoc to `HistoryTextBox` --- osu.Game/Graphics/UserInterface/HistoryTextBox.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs index e9da67e553..5d2cd18e9b 100644 --- a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs +++ b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs @@ -7,6 +7,12 @@ using osuTK.Input; namespace osu.Game.Graphics.UserInterface { + /// + /// A which additionally retains a history of text committed, up to a limit + /// (100 by default, specified in constructor). + /// The history of committed text can be navigated using up/down arrows. + /// This resembles the operation of command-line terminals. + /// public class HistoryTextBox : FocusedTextBox { private readonly LimitedCapacityQueue messageHistory; @@ -18,6 +24,13 @@ namespace osu.Game.Graphics.UserInterface private string originalMessage = string.Empty; private bool everythingSelected; + /// + /// Creates a new . + /// + /// + /// The maximum number of committed lines to keep in history. + /// When exceeded, the oldest lines in history will be dropped to make space for new ones. + /// public HistoryTextBox(int capacity = 100) { messageHistory = new LimitedCapacityQueue(capacity); From 793d5b117ec39f0de154d47811d4578d0debc6f1 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 20 Nov 2022 15:20:35 +0300 Subject: [PATCH 0684/2991] Fix timing screen test scene not creating editor beatmap properly --- .../Visual/Editing/TestSceneTimingScreen.cs | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs b/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs index 03c184c27d..e7805bf393 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs @@ -3,14 +3,15 @@ #nullable disable +using System; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Game.Overlays; using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Osu; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Timing; using osu.Game.Screens.Edit.Timing.RowAttributes; @@ -21,10 +22,6 @@ namespace osu.Game.Tests.Visual.Editing [TestFixture] public class TestSceneTimingScreen : EditorClockTestScene { - [Cached(typeof(EditorBeatmap))] - [Cached(typeof(IBeatSnapProvider))] - private readonly EditorBeatmap editorBeatmap; - [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); @@ -32,21 +29,27 @@ namespace osu.Game.Tests.Visual.Editing protected override bool ScrollUsingMouseWheel => false; - public TestSceneTimingScreen() - { - editorBeatmap = new EditorBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)); - } - protected override void LoadComplete() { base.LoadComplete(); - Beatmap.Value = CreateWorkingBeatmap(editorBeatmap.PlayableBeatmap); + Beatmap.Value = CreateWorkingBeatmap(Ruleset.Value); Beatmap.Disabled = true; - Child = timingScreen = new TimingScreen + var editorBeatmap = new EditorBeatmap(Beatmap.Value.GetPlayableBeatmap(Ruleset.Value)); + + Child = new DependencyProvidingContainer { - State = { Value = Visibility.Visible }, + RelativeSizeAxes = Axes.Both, + CachedDependencies = new (Type, object)[] + { + (typeof(EditorBeatmap), editorBeatmap), + (typeof(IBeatSnapProvider), editorBeatmap) + }, + Child = timingScreen = new TimingScreen + { + State = { Value = Visibility.Visible }, + }, }; } From 0f382590e6caa7e58f85ac30840289ea9c4b93f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 20 Nov 2022 15:31:51 +0100 Subject: [PATCH 0685/2991] Remove unnecessary `#nullable disable` --- osu.Game/Rulesets/UI/Scrolling/IDrawableScrollingRuleset.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/Scrolling/IDrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/IDrawableScrollingRuleset.cs index 6955ef26e5..f3a3bb18bd 100644 --- a/osu.Game/Rulesets/UI/Scrolling/IDrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/IDrawableScrollingRuleset.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. -#nullable disable using osu.Game.Configuration; namespace osu.Game.Rulesets.UI.Scrolling From 9040dfbd4ee5b40bff38d5dc8552727a1063d1ae Mon Sep 17 00:00:00 2001 From: RATCM Date: Sun, 20 Nov 2022 17:39:46 +0100 Subject: [PATCH 0686/2991] Match leaderboard filter behaviour to web --- osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index 161d4847bf..5c31d83adb 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -204,10 +204,11 @@ namespace osu.Game.Screens.Select.Leaderboards } else if (filterMods) { - // otherwise find all the scores that have *any* of the currently selected mods (similar to how web applies mod filters) + // otherwise find all the scores that have all of the currently selected mods (similar to how web applies mod filters) // we're creating and using a string list representation of selected mods so that it can be translated into the DB query itself var selectedMods = mods.Value.Select(m => m.Acronym); - scores = scores.Where(s => s.Mods.Any(m => selectedMods.Contains(m.Acronym))); + + scores = scores.Where(s => s.Mods.Select(m => m.Acronym).SequenceEqual(selectedMods)); } scores = scoreManager.OrderByTotalScore(scores.Detach()); From d20a357c0e6b46837d4afe054a6efebbaa480e20 Mon Sep 17 00:00:00 2001 From: RATCM Date: Sun, 20 Nov 2022 19:24:51 +0100 Subject: [PATCH 0687/2991] Fixed ordering bug --- osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index 5c31d83adb..0761a034d8 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -206,9 +206,9 @@ namespace osu.Game.Screens.Select.Leaderboards { // otherwise find all the scores that have all of the currently selected mods (similar to how web applies mod filters) // we're creating and using a string list representation of selected mods so that it can be translated into the DB query itself - var selectedMods = mods.Value.Select(m => m.Acronym); + var selectedMods = mods.Value.Select(m => m.Acronym).ToHashSet(); - scores = scores.Where(s => s.Mods.Select(m => m.Acronym).SequenceEqual(selectedMods)); + scores = scores.Where(s => selectedMods.SetEquals(s.Mods.Select(m => m.Acronym))); } scores = scoreManager.OrderByTotalScore(scores.Detach()); From f5fbb7c8dee5c1114b2f392a49a4f708574231cb Mon Sep 17 00:00:00 2001 From: RATCM Date: Sun, 20 Nov 2022 19:27:40 +0100 Subject: [PATCH 0688/2991] Changed comments --- osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index 0761a034d8..4cc3a30a1e 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -205,7 +205,7 @@ namespace osu.Game.Screens.Select.Leaderboards else if (filterMods) { // otherwise find all the scores that have all of the currently selected mods (similar to how web applies mod filters) - // we're creating and using a string list representation of selected mods so that it can be translated into the DB query itself + // we're creating and using a string HashSet representation of selected mods so that it can be translated into the DB query itself var selectedMods = mods.Value.Select(m => m.Acronym).ToHashSet(); scores = scores.Where(s => selectedMods.SetEquals(s.Mods.Select(m => m.Acronym))); From 18c79dfda3f08552dbdb518a90cd2e68b863de56 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 20 Nov 2022 23:00:13 +0300 Subject: [PATCH 0689/2991] Move all the logic into BarsInfo class --- osu.Game/Graphics/UserInterface/BarGraph.cs | 74 +++++++++------------ 1 file changed, 30 insertions(+), 44 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index 498a480c06..3f356c0225 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -58,27 +58,9 @@ namespace osu.Game.Graphics.UserInterface return; } - int newCount = value.Count(); - - bars.Breadth = 1.0f / newCount; - float maxLength = MaxValue ?? value.Max(); - foreach (var bar in value.Select((length, index) => (Value: length, Index: index))) - { - float length = maxLength == 0 ? 0 : Math.Max(0f, bar.Value / maxLength); - - if (bar.Index < bars.Count) - { - bars.UpdateLength(bar.Index, length); - continue; - } - - bars.AddBar(length); - } - - if (bars.Count > newCount) - bars.RemoveRange(newCount, bars.Count - newCount); + bars.SetLengths(value.Select(v => maxLength == 0 ? 0 : Math.Max(0f, v / maxLength)).ToArray()); animationStartTime = Clock.CurrentTime; animationComplete = false; @@ -208,44 +190,48 @@ namespace osu.Game.Graphics.UserInterface public int Count { get; private set; } - public float Breadth { get; set; } + public float Breadth { get; private set; } public List InstantaneousLengths { get; } = new List(); private readonly List initialLengths = new List(); private readonly List finalLengths = new List(); - public void UpdateLength(int index, float newLength) + public void Clear() => SetLengths(Array.Empty()); + + public void SetLengths(float[] newLengths) { - initialLengths[index] = finalLengths[index]; - finalLengths[index] = newLength; - } + int newCount = newLengths.Length; - public void AddBar(float finalLength) - { - initialLengths.Add(0); - finalLengths.Add(finalLength); - InstantaneousLengths.Add(0); + for (int i = 0; i < newCount; i++) + { + // If we have an old bar at this index - change it's length + if (i < Count) + { + initialLengths[i] = finalLengths[i]; + finalLengths[i] = newLengths[i]; - Count++; - } + continue; + } - public void Clear() - { - initialLengths.Clear(); - finalLengths.Clear(); - InstantaneousLengths.Clear(); + // If exceeded old bars count - add new one + initialLengths.Add(0); + finalLengths.Add(newLengths[i]); + InstantaneousLengths.Add(0); + } - Count = 0; - } + // Remove excessive bars + if (Count > newCount) + { + int barsToRemove = Count - newCount; - public void RemoveRange(int index, int count) - { - initialLengths.RemoveRange(index, count); - finalLengths.RemoveRange(index, count); - InstantaneousLengths.RemoveRange(index, count); + initialLengths.RemoveRange(newCount, barsToRemove); + finalLengths.RemoveRange(newCount, barsToRemove); + InstantaneousLengths.RemoveRange(newCount, barsToRemove); + } - Count -= count; + Count = newCount; + Breadth = Count == 0 ? 0 : (1f / Count); } public void Animate(double animationStartTime, double currentTime) From a431b793b9e5ad4b8d69db3c8a62417c2c340942 Mon Sep 17 00:00:00 2001 From: vegguid <75315940+vegguid@users.noreply.github.com> Date: Sun, 20 Nov 2022 23:18:19 +0100 Subject: [PATCH 0690/2991] Added PreferOriginalMetadataLanguage to FirstRunSetup --- osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs index cb1e96d2f2..907da0429d 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs @@ -18,6 +18,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Localisation; +using osu.Game.Overlays.Settings; using osuTK; namespace osu.Game.Overlays.FirstRunSetup @@ -26,7 +27,7 @@ namespace osu.Game.Overlays.FirstRunSetup public class ScreenWelcome : FirstRunSetupScreen { [BackgroundDependencyLoader] - private void load() + private void load(FrameworkConfigManager frameworkConfig) { Content.Children = new Drawable[] { @@ -52,6 +53,11 @@ namespace osu.Game.Overlays.FirstRunSetup }, } }, + new SettingsCheckbox + { + LabelText = GeneralSettingsStrings.PreferOriginalMetadataLanguage, + Current = frameworkConfig.GetBindable(FrameworkSetting.ShowUnicode) + }, new LanguageSelectionFlow { RelativeSizeAxes = Axes.X, From 815cd56f13fe0bf62e1b9c6783b69d0dbc7f3c95 Mon Sep 17 00:00:00 2001 From: Alden Wu Date: Sun, 20 Nov 2022 16:50:15 -0800 Subject: [PATCH 0691/2991] Add support for nonsquare smoke textures --- .../Skinning/SmokeSegment.cs | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs index c19ed3fb35..66d74ae13e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs @@ -52,11 +52,13 @@ namespace osu.Game.Rulesets.Osu.Skinning protected Texture? Texture { get; set; } - private float radius => Texture?.DisplayWidth * 0.165f ?? 3; + private float height => Texture?.DisplayHeight * 0.165f ?? 3; + + private float width => Texture?.DisplayWidth * 0.165f ?? 3; protected readonly List SmokePoints = new List(); - private float pointInterval => radius * 7f / 8; + private float pointInterval => width * 7f / 8; private double smokeStartTime { get; set; } = double.MinValue; @@ -179,7 +181,8 @@ namespace osu.Game.Rulesets.Osu.Skinning private readonly List points = new List(); private IVertexBatch? quadBatch; - private float radius; + private float width; + private float height; private Vector2 drawSize; private Texture? texture; private int rotationSeed; @@ -202,7 +205,8 @@ namespace osu.Game.Rulesets.Osu.Skinning { base.ApplyState(); - radius = Source.radius; + width = Source.width; + height = Source.height; drawSize = Source.DrawSize; texture = Source.Texture; @@ -334,11 +338,13 @@ namespace osu.Game.Rulesets.Osu.Skinning var dir = PointDirection(point, index); var ortho = dir.PerpendicularLeft; + dir *= scale * width; + ortho *= scale * height; - var localTopLeft = point.Position + (radius * scale * (-ortho - dir)); - var localTopRight = point.Position + (radius * scale * (-ortho + dir)); - var localBotLeft = point.Position + (radius * scale * (ortho - dir)); - var localBotRight = point.Position + (radius * scale * (ortho + dir)); + var localTopLeft = point.Position - ortho - dir; + var localTopRight = point.Position - ortho + dir; + var localBotLeft = point.Position + ortho - dir; + var localBotRight = point.Position + ortho + dir; quadBatch.Add(new TexturedVertex2D { From d0ff5be7e646d54e78f123ed7c763615b012c9c9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Nov 2022 12:15:40 +0900 Subject: [PATCH 0692/2991] Fix `TestSceneTabletSettings` falling off the bottom of the screen --- .../Visual/Settings/TestSceneTabletSettings.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs b/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs index d1d3748c26..84f5ce7627 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics; using osu.Framework.Input.Handlers.Tablet; using osu.Framework.Testing; using osu.Framework.Utils; +using osu.Game.Graphics.Containers; using osu.Game.Overlays; using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings.Sections.Input; @@ -36,12 +37,17 @@ namespace osu.Game.Tests.Visual.Settings Children = new Drawable[] { - settings = new TabletSettings(tabletHandler) + new OsuScrollContainer(Direction.Vertical) { - RelativeSizeAxes = Axes.None, - Width = SettingsPanel.PANEL_WIDTH, - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = settings = new TabletSettings(tabletHandler) + { + RelativeSizeAxes = Axes.None, + Width = SettingsPanel.PANEL_WIDTH, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + } } }; }); From c7ae83768751d64635c287733bc727038616f8f1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Nov 2022 12:45:54 +0900 Subject: [PATCH 0693/2991] Increase maximum aspect ratio for tablet settings to 23:9 / 2.55 --- osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs index f7c372a037..b6efa00cdb 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs @@ -45,9 +45,9 @@ namespace osu.Game.Overlays.Settings.Sections.Input private GameHost host { get; set; } /// - /// Based on ultrawide monitor configurations. + /// Based on ultrawide monitor configurations, plus a bit of lenience for users which are intentionally aiming for higher horizontal velocity. /// - private const float largest_feasible_aspect_ratio = 21f / 9; + private const float largest_feasible_aspect_ratio = 23f / 9; private readonly BindableNumber aspectRatio = new BindableFloat(1) { From fa7b45dfb133dca53206c105c83fbaafeb6810bc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Nov 2022 13:51:49 +0900 Subject: [PATCH 0694/2991] Fix chat day separator not being added on pending message resolution Closes #21316. --- osu.Game/Overlays/Chat/DrawableChannel.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index 544daf7d2c..7f9be1a782 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -134,8 +134,7 @@ namespace osu.Game.Overlays.Chat foreach (var message in displayMessages) { - if (lastMessage == null || lastMessage.Timestamp.ToLocalTime().Date != message.Timestamp.ToLocalTime().Date) - ChatLineFlow.Add(CreateDaySeparator(message.Timestamp)); + addDaySeparatorIfRequired(lastMessage, message); ChatLineFlow.Add(CreateChatLine(message)); lastMessage = message; @@ -183,10 +182,18 @@ namespace osu.Game.Overlays.Chat ChatLineFlow.Remove(found, false); found.Message = updated; + + addDaySeparatorIfRequired(chatLines.LastOrDefault()?.Message, updated); ChatLineFlow.Add(found); } }); + private void addDaySeparatorIfRequired(Message lastMessage, Message message) + { + if (lastMessage == null || lastMessage.Timestamp.ToLocalTime().Date != message.Timestamp.ToLocalTime().Date) + ChatLineFlow.Add(CreateDaySeparator(message.Timestamp)); + } + private void messageRemoved(Message removed) => Schedule(() => { chatLines.FirstOrDefault(c => c.Message == removed)?.FadeColour(Color4.Red, 400).FadeOut(600).Expire(); From e53b4321ffa1eb91524558e15f786a8476b92905 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Nov 2022 14:01:10 +0900 Subject: [PATCH 0695/2991] Ensure two day separators are not added in a row --- osu.Game/Overlays/Chat/DrawableChannel.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index 7f9be1a782..3d2eafd973 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -191,7 +191,15 @@ namespace osu.Game.Overlays.Chat private void addDaySeparatorIfRequired(Message lastMessage, Message message) { if (lastMessage == null || lastMessage.Timestamp.ToLocalTime().Date != message.Timestamp.ToLocalTime().Date) + { + // A day separator is displayed even if no messages are in the channel. + // If there are no messages after it, the simplest way to ensure it is fresh is to remove it + // and add a new one instead. + if (ChatLineFlow.LastOrDefault() is DaySeparator ds) + ChatLineFlow.Remove(ds, true); + ChatLineFlow.Add(CreateDaySeparator(message.Timestamp)); + } } private void messageRemoved(Message removed) => Schedule(() => From 93a189603a3bffd446fa5561a411b08c05ad232d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Nov 2022 14:20:36 +0900 Subject: [PATCH 0696/2991] Hide spinner ticks / bonus from results screen when not applicable to score --- osu.Game/Scoring/ScoreInfo.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index 1b36ae176d..a9ced62c95 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -296,6 +296,13 @@ namespace osu.Game.Scoring break; } + case HitResult.LargeBonus: + case HitResult.SmallBonus: + if (MaximumStatistics.TryGetValue(r.result, out int count) && count > 0) + yield return new HitResultDisplayStatistic(r.result, value, null, r.displayName); + + break; + case HitResult.SmallTickMiss: case HitResult.LargeTickMiss: break; From 40f2da364c1f6753bef8bbf3ae6d976dbbed406f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Nov 2022 14:34:35 +0900 Subject: [PATCH 0697/2991] Limit how far before the first hitobject that barlines can be generated --- osu.Game/Rulesets/Objects/BarLineGenerator.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/BarLineGenerator.cs b/osu.Game/Rulesets/Objects/BarLineGenerator.cs index c2709db747..185088878c 100644 --- a/osu.Game/Rulesets/Objects/BarLineGenerator.cs +++ b/osu.Game/Rulesets/Objects/BarLineGenerator.cs @@ -27,7 +27,10 @@ namespace osu.Game.Rulesets.Objects if (beatmap.HitObjects.Count == 0) return; + HitObject firstObject = beatmap.HitObjects.First(); HitObject lastObject = beatmap.HitObjects.Last(); + + double firstHitTime = firstObject.StartTime; double lastHitTime = 1 + lastObject.GetEndTime(); var timingPoints = beatmap.ControlPointInfo.TimingPoints; @@ -41,10 +44,14 @@ namespace osu.Game.Rulesets.Objects EffectControlPoint currentEffectPoint = beatmap.ControlPointInfo.EffectPointAt(currentTimingPoint.Time); int currentBeat = 0; + // Don't generate barlines before the hit object or t=0 (whichever is earliest). Some beatmaps use very unrealistic values here (although none are ranked). + // I'm not sure we ever want barlines to appear before the first hitobject, but let's keep some degree of compatibility for now. + // Of note, this will still differ from stable if the first timing control point is t<0 and is not near the first hitobject. + double startTime = Math.Max(Math.Min(0, firstHitTime), currentTimingPoint.Time); + // Stop on the next timing point, or if there is no next timing point stop slightly past the last object double endTime = i < timingPoints.Count - 1 ? timingPoints[i + 1].Time : lastHitTime + currentTimingPoint.BeatLength * currentTimingPoint.TimeSignature.Numerator; - double startTime = currentTimingPoint.Time; double barLength = currentTimingPoint.BeatLength * currentTimingPoint.TimeSignature.Numerator; if (currentEffectPoint.OmitFirstBarLine) From 981264b011d95332c2d3ac059bdeae4411e5a34d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Nov 2022 14:51:41 +0900 Subject: [PATCH 0698/2991] Avoid crashing when a system audio device provides a `null` name --- .../Settings/Sections/Audio/AudioDevicesSettings.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs index 7cb9efa1b9..9b53d62272 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs @@ -59,7 +59,11 @@ namespace osu.Game.Overlays.Settings.Sections.Audio // the dropdown. BASS does not give us a simple mechanism to select // specific audio devices in such a case anyways. Such // functionality would require involved OS-specific code. - dropdown.Items = deviceItems.Distinct().ToList(); + dropdown.Items = deviceItems + // Dropdown doesn't like null items. Somehow we are seeing some arrive here (see https://github.com/ppy/osu/issues/21271) + .Where(i => i != null) + .Distinct() + .ToList(); } protected override void Dispose(bool isDisposing) From 9a330c3cdbcf8d275d957216efe43e9bd4e727e8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Nov 2022 14:56:58 +0900 Subject: [PATCH 0699/2991] Apply nullability and clean up conditionals --- .../TestSceneTriangleBorderShader.cs | 2 -- osu.Game/Graphics/Backgrounds/TrianglesV2.cs | 25 ++++++++++--------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs b/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs index 470962088e..41a1d9b42e 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Shapes; diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs index 0c4bf59732..4da227d5d6 100644 --- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs +++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Utils; using osuTK; using System; @@ -71,11 +69,12 @@ namespace osu.Game.Graphics.Backgrounds private readonly List parts = new List(); [Resolved] - private IRenderer renderer { get; set; } + private IRenderer renderer { get; set; } = null!; - private Random stableRandom; - private IShader shader; - private Texture texture; + private Random? stableRandom; + + private IShader shader = null!; + private Texture texture = null!; /// /// Construct a new triangle visualisation. @@ -116,8 +115,7 @@ namespace osu.Game.Graphics.Backgrounds image[i, 0] = new Rgba32( colourBottom.Value.R * ratio + colourTop.Value.R * (1f - ratio), colourBottom.Value.G * ratio + colourTop.Value.G * (1f - ratio), - colourBottom.Value.B * ratio + colourTop.Value.B * (1f - ratio), - 1f + colourBottom.Value.B * ratio + colourTop.Value.B * (1f - ratio) ); } @@ -223,13 +221,13 @@ namespace osu.Game.Graphics.Backgrounds { protected new TrianglesV2 Source => (TrianglesV2)base.Source; - private IShader shader; - private Texture texture; + private IShader shader = null!; + private Texture texture = null!; private readonly List parts = new List(); private Vector2 size; - private IVertexBatch vertexBatch; + private IVertexBatch? vertexBatch; public TrianglesDrawNode(TrianglesV2 source) : base(source) @@ -252,7 +250,10 @@ namespace osu.Game.Graphics.Backgrounds { base.Draw(renderer); - if (Source.AimCount > 0 && (vertexBatch == null || vertexBatch.Size != Source.AimCount)) + if (Source.AimCount == 0) + return; + + if (vertexBatch == null || vertexBatch.Size != Source.AimCount) { vertexBatch?.Dispose(); vertexBatch = renderer.CreateQuadBatch(Source.AimCount, 1); From 5c640d15a0e15edd1749a57da7d6d537797bd4ff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Nov 2022 15:17:54 +0900 Subject: [PATCH 0700/2991] Stop requesting messages as part of initial chat presence --- osu.Game/Online/API/Requests/GetUpdatesRequest.cs | 1 + osu.Game/Online/Notifications/NotificationsClient.cs | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/GetUpdatesRequest.cs b/osu.Game/Online/API/Requests/GetUpdatesRequest.cs index ce2689d262..529c579996 100644 --- a/osu.Game/Online/API/Requests/GetUpdatesRequest.cs +++ b/osu.Game/Online/API/Requests/GetUpdatesRequest.cs @@ -25,6 +25,7 @@ namespace osu.Game.Online.API.Requests var req = base.CreateWebRequest(); if (channel != null) req.AddParameter(@"channel", channel.Id.ToString()); req.AddParameter(@"since", since.ToString()); + req.AddParameter(@"includes[]", "presence"); return req; } diff --git a/osu.Game/Online/Notifications/NotificationsClient.cs b/osu.Game/Online/Notifications/NotificationsClient.cs index 6198707111..5654fa6396 100644 --- a/osu.Game/Online/Notifications/NotificationsClient.cs +++ b/osu.Game/Online/Notifications/NotificationsClient.cs @@ -67,8 +67,11 @@ namespace osu.Game.Online.Notifications protected void HandleChannelParted(Channel channel) => ChannelParted?.Invoke(channel); - protected void HandleMessages(List messages) + protected void HandleMessages(List? messages) { + if (messages == null) + return; + NewMessages?.Invoke(messages); lastMessageId = Math.Max(lastMessageId, messages.LastOrDefault()?.Id ?? 0); } From efd73ea9dac00cc875cd91560df520c0c2797fdb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Nov 2022 15:22:57 +0900 Subject: [PATCH 0701/2991] Rename method to suit better --- osu.Game/Online/Notifications/NotificationsClient.cs | 4 ++-- osu.Game/Tests/PollingNotificationsClient.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/Notifications/NotificationsClient.cs b/osu.Game/Online/Notifications/NotificationsClient.cs index 5654fa6396..5762e0e588 100644 --- a/osu.Game/Online/Notifications/NotificationsClient.cs +++ b/osu.Game/Online/Notifications/NotificationsClient.cs @@ -33,11 +33,11 @@ namespace osu.Game.Online.Notifications public override Task ConnectAsync(CancellationToken cancellationToken) { - API.Queue(CreateFetchMessagesRequest(0)); + API.Queue(CreateInitialFetchRequest(0)); return Task.CompletedTask; } - protected APIRequest CreateFetchMessagesRequest(long? lastMessageId = null) + protected APIRequest CreateInitialFetchRequest(long? lastMessageId = null) { var fetchReq = new GetUpdatesRequest(lastMessageId ?? this.lastMessageId); diff --git a/osu.Game/Tests/PollingNotificationsClient.cs b/osu.Game/Tests/PollingNotificationsClient.cs index c1f032a647..571a7a1ed1 100644 --- a/osu.Game/Tests/PollingNotificationsClient.cs +++ b/osu.Game/Tests/PollingNotificationsClient.cs @@ -24,7 +24,7 @@ namespace osu.Game.Tests { while (!cancellationToken.IsCancellationRequested) { - await API.PerformAsync(CreateFetchMessagesRequest()); + await API.PerformAsync(CreateInitialFetchRequest()); await Task.Delay(1000, cancellationToken); } }, cancellationToken); From 462a213ffc616a3c92569776d66d28d7f569a311 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Nov 2022 15:23:04 +0900 Subject: [PATCH 0702/2991] Add TODO note about handling initial silences --- osu.Game/Online/API/Requests/GetUpdatesResponse.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Online/API/Requests/GetUpdatesResponse.cs b/osu.Game/Online/API/Requests/GetUpdatesResponse.cs index 61f6a8664d..7e030ce922 100644 --- a/osu.Game/Online/API/Requests/GetUpdatesResponse.cs +++ b/osu.Game/Online/API/Requests/GetUpdatesResponse.cs @@ -16,5 +16,7 @@ namespace osu.Game.Online.API.Requests [JsonProperty] public List Messages; + + // TODO: Handle Silences here (will need to add to includes[] in the request). } } From 3da21e596af9f376bc54eb8259bd8e0fc533d90f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Nov 2022 16:06:36 +0900 Subject: [PATCH 0703/2991] Add support for storyboards with incorrect path specifications (`\\` instead of `\`) Closes https://github.com/ppy/osu/issues/21204. --- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 6991500df5..a4e15f790a 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -147,7 +147,11 @@ namespace osu.Game.Beatmaps.Formats ); } - protected string CleanFilename(string path) => path.Trim('"').ToStandardisedPath(); + protected string CleanFilename(string path) => path + // User error which is supported by stable (https://github.com/ppy/osu/issues/21204) + .Replace(@"\\", @"\") + .Trim('"') + .ToStandardisedPath(); public enum Section { From 14a4de36f4cbd269f40b982930c9aedd8dbbba59 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 21 Nov 2022 10:20:35 +0300 Subject: [PATCH 0704/2991] Expose thickness property --- .../TestSceneTriangleBorderShader.cs | 41 ++++++++++++++++++- .../TestSceneTrianglesV2Background.cs | 1 + osu.Game/Graphics/Backgrounds/TrianglesV2.cs | 18 ++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs b/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs index 41a1d9b42e..64512bc651 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs @@ -14,6 +14,8 @@ namespace osu.Game.Tests.Visual.Background { public class TestSceneTriangleBorderShader : OsuTestScene { + private readonly TriangleBorder border; + public TestSceneTriangleBorderShader() { Children = new Drawable[] @@ -23,7 +25,7 @@ namespace osu.Game.Tests.Visual.Background RelativeSizeAxes = Axes.Both, Colour = Color4.DarkGreen }, - new TriangleBorder + border = new TriangleBorder { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -32,8 +34,27 @@ namespace osu.Game.Tests.Visual.Background }; } + protected override void LoadComplete() + { + base.LoadComplete(); + + AddSliderStep("Thickness", 0f, 1f, 0.02f, t => border.Thickness = t); + } + private class TriangleBorder : Sprite { + private float thickness = 0.02f; + + public float Thickness + { + get => thickness; + set + { + thickness = value; + Invalidate(Invalidation.DrawNode); + } + } + [BackgroundDependencyLoader] private void load(ShaderManager shaders, IRenderer renderer) { @@ -45,11 +66,29 @@ namespace osu.Game.Tests.Visual.Background private class TriangleBorderDrawNode : SpriteDrawNode { + public new TriangleBorder Source => (TriangleBorder)base.Source; + public TriangleBorderDrawNode(TriangleBorder source) : base(source) { } + private float thickness; + + public override void ApplyState() + { + base.ApplyState(); + + thickness = Source.thickness; + } + + public override void Draw(IRenderer renderer) + { + TextureShader.GetUniform("thickness").UpdateValue(ref thickness); + + base.Draw(renderer); + } + protected override bool CanDrawOpaqueInterior => false; } } diff --git a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs index f6207c46a5..e8abc573cd 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs @@ -47,6 +47,7 @@ namespace osu.Game.Tests.Visual.Background base.LoadComplete(); AddSliderStep("Spawn ratio", 0f, 2f, 1f, s => triangles.SpawnRatio = s); + AddSliderStep("Thickness", 0f, 1f, 0.02f, t => triangles.Thickness = t); } } } diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs index 4da227d5d6..ca920bdd66 100644 --- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs +++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs @@ -45,6 +45,21 @@ namespace osu.Game.Graphics.Backgrounds set => colourBottom.Value = value; } + private float thickness = 0.02f; + + public float Thickness + { + get => thickness; + set + { + if (thickness == value) + return; + + thickness = value; + // No need for invalidation since it's happening in Update() + } + } + /// /// Whether we should create new triangles as others expire. /// @@ -226,6 +241,7 @@ namespace osu.Game.Graphics.Backgrounds private readonly List parts = new List(); private Vector2 size; + private float thickness; private IVertexBatch? vertexBatch; @@ -241,6 +257,7 @@ namespace osu.Game.Graphics.Backgrounds shader = Source.shader; texture = Source.texture; size = Source.DrawSize; + thickness = Source.thickness; parts.Clear(); parts.AddRange(Source.parts); @@ -260,6 +277,7 @@ namespace osu.Game.Graphics.Backgrounds } shader.Bind(); + shader.GetUniform("thickness").UpdateValue(ref thickness); foreach (TriangleParticle particle in parts) { From ec8532951c7547fc3d30943debf081962f52b170 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 21 Nov 2022 10:32:19 +0300 Subject: [PATCH 0705/2991] Make Thickness property auto --- osu.Game/Graphics/Backgrounds/TrianglesV2.cs | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs index ca920bdd66..5fc32ff704 100644 --- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs +++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs @@ -45,20 +45,7 @@ namespace osu.Game.Graphics.Backgrounds set => colourBottom.Value = value; } - private float thickness = 0.02f; - - public float Thickness - { - get => thickness; - set - { - if (thickness == value) - return; - - thickness = value; - // No need for invalidation since it's happening in Update() - } - } + public float Thickness { get; set; } = 0.02f; // No need for invalidation since it's happening in Update() /// /// Whether we should create new triangles as others expire. @@ -257,7 +244,7 @@ namespace osu.Game.Graphics.Backgrounds shader = Source.shader; texture = Source.texture; size = Source.DrawSize; - thickness = Source.thickness; + thickness = Source.Thickness; parts.Clear(); parts.AddRange(Source.parts); From 60ef88844c31459dfa94a5ffdb1fdf41530f2c96 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Mon, 21 Nov 2022 17:09:56 +0900 Subject: [PATCH 0706/2991] Recover accidentally deleted codes --- osu.Game/Database/RealmAccess.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs index 5a7ead1c59..1a938c12e5 100644 --- a/osu.Game/Database/RealmAccess.cs +++ b/osu.Game/Database/RealmAccess.cs @@ -173,6 +173,11 @@ namespace osu.Game.Database if (!Filename.EndsWith(realm_extension, StringComparison.Ordinal)) Filename += realm_extension; +#if DEBUG + if (!DebugUtils.IsNUnitRunning) + applyFilenameSchemaSuffix(ref Filename); +#endif + string newerVersionFilename = $"{Filename.Replace(realm_extension, string.Empty)}_newer_version{realm_extension}"; // Attempt to recover a newer database version if available. From 8f942f130b82b6ec5c37018a4d67d745eb160a28 Mon Sep 17 00:00:00 2001 From: Terochi Date: Mon, 21 Nov 2022 09:32:44 +0100 Subject: [PATCH 0707/2991] Variant 1: edit changes history, empty text resets index --- .../UserInterface/TestSceneHistoryTextBox.cs | 59 ++++--------------- .../Graphics/UserInterface/HistoryTextBox.cs | 18 ++---- osu.Game/Utils/LimitedCapacityQueue.cs | 7 +++ 3 files changed, 24 insertions(+), 60 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs index 8918e53056..6ead7bc168 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs @@ -3,7 +3,6 @@ using NUnit.Framework; using osu.Framework.Graphics; -using osu.Framework.Input; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; @@ -64,62 +63,32 @@ namespace osu.Game.Tests.Visual.UserInterface } [Test] - public void TestEmptyHistory() + public void TestChangedHistory() { + addMessages(2); AddStep("Set text", () => box.Text = temp); + AddStep("Move up", () => InputManager.Key(Key.Up)); + AddStep("Change text", () => box.Text = "New message"); AddStep("Move down", () => InputManager.Key(Key.Down)); - AddAssert("Text is the same", () => box.Text == temp); - - AddStep("Move Up", () => InputManager.Key(Key.Up)); - AddAssert("Text is the same", () => box.Text == temp); + AddStep("Move up", () => InputManager.Key(Key.Up)); + AddAssert("Changes kept", () => box.Text == "New message"); } [Test] - public void TestPartialHistory() + public void TestInputOnEdge() { addMessages(2); AddStep("Set text", () => box.Text = temp); AddStep("Move down", () => InputManager.Key(Key.Down)); - AddAssert("Text is the same", () => box.Text == temp); + AddAssert("Text unchanged", () => box.Text == temp); - AddRepeatStep("Move Up", () => InputManager.Key(Key.Up), 2); + AddRepeatStep("Move up", () => InputManager.Key(Key.Up), 2); AddAssert("Same as 1st message", () => box.Text == "Message 1"); - AddStep("Move Up", () => InputManager.Key(Key.Up)); - AddAssert("Text is the same", () => box.Text == "Message 1"); - - AddRepeatStep("Move down", () => InputManager.Key(Key.Down), 2); - AddAssert("Same as temp message", () => box.Text == temp); - - AddStep("Move down", () => InputManager.Key(Key.Down)); - AddAssert("Text is the same", () => box.Text == temp); - } - - [Test] - public void TestFullHistory() - { - addMessages(5); - AddStep("Set text", () => box.Text = temp); - - AddStep("Move down", () => InputManager.Key(Key.Down)); - AddAssert("Text is the same", () => box.Text == temp); - - addMessages(2); - AddStep("Set text", () => box.Text = temp); - - AddRepeatStep("Move Up", () => InputManager.Key(Key.Up), 5); - AddAssert("Same as 3rd message", () => box.Text == "Message 3"); - - AddStep("Move Up", () => InputManager.Key(Key.Up)); - AddAssert("Text is the same", () => box.Text == "Message 3"); - - AddRepeatStep("Move down", () => InputManager.Key(Key.Down), 4); - AddAssert("Same as previous message", () => box.Text == "Message 7"); - - AddStep("Move down", () => InputManager.Key(Key.Down)); - AddAssert("Same as temp message", () => box.Text == temp); + AddStep("Move up", () => InputManager.Key(Key.Up)); + AddAssert("Text unchanged", () => box.Text == "Message 1"); } [Test] @@ -133,12 +102,6 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("Remove text", () => box.Text = string.Empty); AddStep("Move Up", () => InputManager.Key(Key.Up)); AddAssert("Same as previous message", () => box.Text == "Message 2"); - - AddStep("Move Up", () => InputManager.Key(Key.Up)); - AddStep("Select text", () => InputManager.Keys(PlatformAction.SelectAll)); - AddStep("Replace text", () => box.Text = "New text"); - AddStep("Move Up", () => InputManager.Key(Key.Up)); - AddAssert("Same as previous message", () => box.Text == "Message 2"); } private void addMessages(int count) diff --git a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs index 5d2cd18e9b..b0ca5beb66 100644 --- a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs +++ b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs @@ -22,7 +22,6 @@ namespace osu.Game.Graphics.UserInterface private int selectedIndex; private string originalMessage = string.Empty; - private bool everythingSelected; /// /// Creates a new . @@ -37,21 +36,11 @@ namespace osu.Game.Graphics.UserInterface Current.ValueChanged += text => { - if (string.IsNullOrEmpty(text.NewValue) || everythingSelected) - { + if (string.IsNullOrEmpty(text.NewValue)) selectedIndex = HistoryCount; - everythingSelected = false; - } }; } - protected override void OnTextSelectionChanged(TextSelectionType selectionType) - { - everythingSelected = SelectedText == Text; - - base.OnTextSelectionChanged(selectionType); - } - protected override bool OnKeyDown(KeyDownEvent e) { switch (e.Key) @@ -62,6 +51,8 @@ namespace osu.Game.Graphics.UserInterface if (selectedIndex == HistoryCount) originalMessage = Text; + else if (!string.IsNullOrEmpty(Text)) + messageHistory[selectedIndex] = Text; Text = messageHistory[--selectedIndex]; @@ -71,6 +62,9 @@ namespace osu.Game.Graphics.UserInterface if (selectedIndex == HistoryCount) return true; + if (!string.IsNullOrEmpty(Text)) + messageHistory[selectedIndex] = Text; + if (selectedIndex == HistoryCount - 1) { selectedIndex = HistoryCount; diff --git a/osu.Game/Utils/LimitedCapacityQueue.cs b/osu.Game/Utils/LimitedCapacityQueue.cs index 86a106a678..8f3b36a059 100644 --- a/osu.Game/Utils/LimitedCapacityQueue.cs +++ b/osu.Game/Utils/LimitedCapacityQueue.cs @@ -103,6 +103,13 @@ namespace osu.Game.Utils return array[(start + index) % capacity]; } + set + { + if (index < 0 || index >= Count) + throw new ArgumentOutOfRangeException(nameof(index)); + + array[(start + index) % capacity] = value; + } } /// From 672e1cd45bfc1ad6d495ad833d02c7ae7a9e7b40 Mon Sep 17 00:00:00 2001 From: Terochi Date: Mon, 21 Nov 2022 09:38:33 +0100 Subject: [PATCH 0708/2991] Variant 2: edit changes history, cannot reset index (similar to stable) --- .../Visual/UserInterface/TestSceneHistoryTextBox.cs | 2 +- osu.Game/Graphics/UserInterface/HistoryTextBox.cs | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs index 6ead7bc168..e0f734fce0 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs @@ -101,7 +101,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("Remove text", () => box.Text = string.Empty); AddStep("Move Up", () => InputManager.Key(Key.Up)); - AddAssert("Same as previous message", () => box.Text == "Message 2"); + AddAssert("Text unchanged", () => box.Text == string.Empty); } private void addMessages(int count) diff --git a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs index b0ca5beb66..6791812b98 100644 --- a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs +++ b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs @@ -33,12 +33,6 @@ namespace osu.Game.Graphics.UserInterface public HistoryTextBox(int capacity = 100) { messageHistory = new LimitedCapacityQueue(capacity); - - Current.ValueChanged += text => - { - if (string.IsNullOrEmpty(text.NewValue)) - selectedIndex = HistoryCount; - }; } protected override bool OnKeyDown(KeyDownEvent e) From ed53168267485ba0ca2bdc97057fd43566770cd4 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Mon, 21 Nov 2022 17:42:11 +0900 Subject: [PATCH 0709/2991] typo fix --- osu.Game.Tests/Skins/IO/ImportSkinTest.cs | 6 +++--- osu.Game/Database/LegacyExportManager.cs | 4 ++-- osu.Game/Database/LegacyModelExporter.cs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs index 0c3c459e87..c4dde59e3f 100644 --- a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs +++ b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs @@ -122,7 +122,7 @@ namespace osu.Game.Tests.Skins.IO await import1.PerformRead(async s => { - await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get(), new ProgressNotification(), exportStream).ExportASync(s); + await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get(), new ProgressNotification(), exportStream).ExportAsync(s); }); string exportFilename = import1.GetDisplayString(); @@ -204,7 +204,7 @@ namespace osu.Game.Tests.Skins.IO Assert.IsFalse(s.Protected); Assert.AreEqual(typeof(ArgonSkin), s.CreateInstance(skinManager).GetType()); - await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get(), new ProgressNotification(), exportStream).ExportASync(s); + await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get(), new ProgressNotification(), exportStream).ExportAsync(s); Assert.Greater(exportStream.Length, 0); }); @@ -237,7 +237,7 @@ namespace osu.Game.Tests.Skins.IO Assert.IsFalse(s.Protected); Assert.AreEqual(typeof(DefaultLegacySkin), s.CreateInstance(skinManager).GetType()); - await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get(), new ProgressNotification(), exportStream).ExportASync(s); + await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get(), new ProgressNotification(), exportStream).ExportAsync(s); Assert.Greater(exportStream.Length, 0); }); diff --git a/osu.Game/Database/LegacyExportManager.cs b/osu.Game/Database/LegacyExportManager.cs index 19fca623c5..a694a0705e 100644 --- a/osu.Game/Database/LegacyExportManager.cs +++ b/osu.Game/Database/LegacyExportManager.cs @@ -49,7 +49,7 @@ namespace osu.Game.Database switch (item) { case SkinInfo: - await new LegacySkinExporter(exportStorage, realmAccess, notification, stream).ExportASync(item); + await new LegacySkinExporter(exportStorage, realmAccess, notification, stream).ExportAsync(item); break; case ScoreInfo: @@ -57,7 +57,7 @@ namespace osu.Game.Database break; case BeatmapSetInfo: - await new LegacyBeatmapExporter(exportStorage, realmAccess, notification, stream).ExportASync(item); + await new LegacyBeatmapExporter(exportStorage, realmAccess, notification, stream).ExportAsync(item); break; } } diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 9fa6f64ee4..01ebbdcaff 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -54,11 +54,11 @@ namespace osu.Game.Database /// /// The model which have Guid. /// - public virtual async Task ExportASync(IHasGuidPrimaryKey uuid) { bool canCancel = true; Notification.CancelRequested += () => canCancel; + public virtual async Task ExportAsync(IHasGuidPrimaryKey uuid) Guid id = uuid.ID; await Task.Run(() => { From 58288275a6f38291a283840ec12e6009f8479332 Mon Sep 17 00:00:00 2001 From: Terochi Date: Mon, 21 Nov 2022 09:43:36 +0100 Subject: [PATCH 0710/2991] Variant 3: cannot change history, cannot reset index (the "default") --- .../Visual/UserInterface/TestSceneHistoryTextBox.cs | 2 +- osu.Game/Graphics/UserInterface/HistoryTextBox.cs | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs index e0f734fce0..414c1276e1 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs @@ -72,7 +72,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("Change text", () => box.Text = "New message"); AddStep("Move down", () => InputManager.Key(Key.Down)); AddStep("Move up", () => InputManager.Key(Key.Up)); - AddAssert("Changes kept", () => box.Text == "New message"); + AddAssert("Changes lost", () => box.Text == "Message 2"); } [Test] diff --git a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs index 6791812b98..290457564b 100644 --- a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs +++ b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs @@ -45,8 +45,6 @@ namespace osu.Game.Graphics.UserInterface if (selectedIndex == HistoryCount) originalMessage = Text; - else if (!string.IsNullOrEmpty(Text)) - messageHistory[selectedIndex] = Text; Text = messageHistory[--selectedIndex]; @@ -56,9 +54,6 @@ namespace osu.Game.Graphics.UserInterface if (selectedIndex == HistoryCount) return true; - if (!string.IsNullOrEmpty(Text)) - messageHistory[selectedIndex] = Text; - if (selectedIndex == HistoryCount - 1) { selectedIndex = HistoryCount; From 7dc7729ac2464c9967c1deff87056d1721897626 Mon Sep 17 00:00:00 2001 From: Terochi Date: Mon, 21 Nov 2022 10:11:26 +0100 Subject: [PATCH 0711/2991] Variant 4: cannot change history, empty text/everything selected resets index (current with bug fix) --- .../UserInterface/TestSceneHistoryTextBox.cs | 9 +++++- .../Graphics/UserInterface/HistoryTextBox.cs | 28 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs index 414c1276e1..29f1e29b55 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs @@ -3,6 +3,7 @@ using NUnit.Framework; using osu.Framework.Graphics; +using osu.Framework.Input; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; @@ -101,7 +102,13 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("Remove text", () => box.Text = string.Empty); AddStep("Move Up", () => InputManager.Key(Key.Up)); - AddAssert("Text unchanged", () => box.Text == string.Empty); + AddAssert("Same as previous message", () => box.Text == "Message 2"); + + AddStep("Move Up", () => InputManager.Key(Key.Up)); + AddStep("Select text", () => InputManager.Keys(PlatformAction.SelectAll)); + AddStep("Replace text", () => box.Text = "New text"); + AddStep("Move Up", () => InputManager.Key(Key.Up)); + AddAssert("Same as previous message", () => box.Text == "Message 2"); } private void addMessages(int count) diff --git a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs index 290457564b..f2b975226c 100644 --- a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs +++ b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs @@ -22,6 +22,7 @@ namespace osu.Game.Graphics.UserInterface private int selectedIndex; private string originalMessage = string.Empty; + private bool everythingSelected; /// /// Creates a new . @@ -33,6 +34,29 @@ namespace osu.Game.Graphics.UserInterface public HistoryTextBox(int capacity = 100) { messageHistory = new LimitedCapacityQueue(capacity); + + Current.ValueChanged += text => + { + if (string.IsNullOrEmpty(text.NewValue) || everythingSelected) + { + selectedIndex = HistoryCount; + everythingSelected = false; + } + }; + } + + protected override void OnTextDeselected() + { + base.OnTextDeselected(); + + everythingSelected = false; + } + + protected override void OnTextSelectionChanged(TextSelectionType selectionType) + { + base.OnTextSelectionChanged(selectionType); + + everythingSelected = SelectedText == Text; } protected override bool OnKeyDown(KeyDownEvent e) @@ -43,6 +67,8 @@ namespace osu.Game.Graphics.UserInterface if (selectedIndex == 0) return true; + everythingSelected = false; + if (selectedIndex == HistoryCount) originalMessage = Text; @@ -54,6 +80,8 @@ namespace osu.Game.Graphics.UserInterface if (selectedIndex == HistoryCount) return true; + everythingSelected = false; + if (selectedIndex == HistoryCount - 1) { selectedIndex = HistoryCount; From d81ef541bc8ff8f49119b4491a6842277c60983c Mon Sep 17 00:00:00 2001 From: Terochi Date: Mon, 21 Nov 2022 10:17:28 +0100 Subject: [PATCH 0712/2991] Variant 5: cannot change history, edit resets index --- .../UserInterface/TestSceneHistoryTextBox.cs | 9 +------- .../Graphics/UserInterface/HistoryTextBox.cs | 22 +------------------ 2 files changed, 2 insertions(+), 29 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs index 29f1e29b55..78b1bdb18c 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs @@ -3,7 +3,6 @@ using NUnit.Framework; using osu.Framework.Graphics; -using osu.Framework.Input; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; @@ -100,13 +99,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddRepeatStep("Move Up", () => InputManager.Key(Key.Up), 2); AddAssert("Same as 1st message", () => box.Text == "Message 1"); - AddStep("Remove text", () => box.Text = string.Empty); - AddStep("Move Up", () => InputManager.Key(Key.Up)); - AddAssert("Same as previous message", () => box.Text == "Message 2"); - - AddStep("Move Up", () => InputManager.Key(Key.Up)); - AddStep("Select text", () => InputManager.Keys(PlatformAction.SelectAll)); - AddStep("Replace text", () => box.Text = "New text"); + AddStep("Change text", () => box.Text = "New message"); AddStep("Move Up", () => InputManager.Key(Key.Up)); AddAssert("Same as previous message", () => box.Text == "Message 2"); } diff --git a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs index f2b975226c..0958e1832e 100644 --- a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs +++ b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs @@ -22,7 +22,6 @@ namespace osu.Game.Graphics.UserInterface private int selectedIndex; private string originalMessage = string.Empty; - private bool everythingSelected; /// /// Creates a new . @@ -37,28 +36,13 @@ namespace osu.Game.Graphics.UserInterface Current.ValueChanged += text => { - if (string.IsNullOrEmpty(text.NewValue) || everythingSelected) + if (selectedIndex != HistoryCount && text.NewValue != messageHistory[selectedIndex]) { selectedIndex = HistoryCount; - everythingSelected = false; } }; } - protected override void OnTextDeselected() - { - base.OnTextDeselected(); - - everythingSelected = false; - } - - protected override void OnTextSelectionChanged(TextSelectionType selectionType) - { - base.OnTextSelectionChanged(selectionType); - - everythingSelected = SelectedText == Text; - } - protected override bool OnKeyDown(KeyDownEvent e) { switch (e.Key) @@ -67,8 +51,6 @@ namespace osu.Game.Graphics.UserInterface if (selectedIndex == 0) return true; - everythingSelected = false; - if (selectedIndex == HistoryCount) originalMessage = Text; @@ -80,8 +62,6 @@ namespace osu.Game.Graphics.UserInterface if (selectedIndex == HistoryCount) return true; - everythingSelected = false; - if (selectedIndex == HistoryCount - 1) { selectedIndex = HistoryCount; From b404b87f6830824d104362dc33a1cc640547912b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 Nov 2022 18:26:53 +0900 Subject: [PATCH 0713/2991] Realign white line on argon hold note ends to match hit target --- .../Skinning/Argon/ArgonHoldNoteTailPiece.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs index e1068c6cd8..00cd37b6cf 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs @@ -38,6 +38,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon }, new Container { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, RelativeSizeAxes = Axes.Both, Height = 0.82f, Masking = true, @@ -54,6 +56,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon { RelativeSizeAxes = Axes.X, Height = ArgonNotePiece.CORNER_RADIUS * 2, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, }, }; } From e37d30a3733871eb39622d6f5ea95d6cfe22a5a6 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Mon, 21 Nov 2022 18:58:01 +0900 Subject: [PATCH 0714/2991] refactor based on reviews removed LegacyExportManager Separated the method of CreateZip method and the default export method --- osu.Game.Tests/Skins/IO/ImportSkinTest.cs | 7 +- osu.Game/Database/LegacyBeatmapExporter.cs | 11 +- osu.Game/Database/LegacyExportManager.cs | 65 --------- osu.Game/Database/LegacyModelExporter.cs | 128 +++++++++--------- osu.Game/Database/LegacyScoreExporter.cs | 33 ++--- osu.Game/Database/LegacySkinExporter.cs | 11 +- .../Online/Leaderboards/LeaderboardScore.cs | 13 +- osu.Game/OsuGame.cs | 4 - .../Overlays/Settings/Sections/SkinSection.cs | 13 +- osu.Game/Screens/Edit/Editor.cs | 12 +- 10 files changed, 113 insertions(+), 184 deletions(-) delete mode 100644 osu.Game/Database/LegacyExportManager.cs diff --git a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs index c4dde59e3f..703c63b91a 100644 --- a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs +++ b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs @@ -14,7 +14,6 @@ using osu.Framework.Platform; using osu.Game.Database; using osu.Game.Extensions; using osu.Game.IO; -using osu.Game.Overlays.Notifications; using osu.Game.Skinning; using SharpCompress.Archives.Zip; @@ -122,7 +121,7 @@ namespace osu.Game.Tests.Skins.IO await import1.PerformRead(async s => { - await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get(), new ProgressNotification(), exportStream).ExportAsync(s); + await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get()).ExportToStreamAsync(s, exportStream); }); string exportFilename = import1.GetDisplayString(); @@ -204,7 +203,7 @@ namespace osu.Game.Tests.Skins.IO Assert.IsFalse(s.Protected); Assert.AreEqual(typeof(ArgonSkin), s.CreateInstance(skinManager).GetType()); - await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get(), new ProgressNotification(), exportStream).ExportAsync(s); + await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get()).ExportToStreamAsync(s, exportStream); Assert.Greater(exportStream.Length, 0); }); @@ -237,7 +236,7 @@ namespace osu.Game.Tests.Skins.IO Assert.IsFalse(s.Protected); Assert.AreEqual(typeof(DefaultLegacySkin), s.CreateInstance(skinManager).GetType()); - await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get(), new ProgressNotification(), exportStream).ExportAsync(s); + await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get()).ExportToStreamAsync(s, exportStream); Assert.Greater(exportStream.Length, 0); }); diff --git a/osu.Game/Database/LegacyBeatmapExporter.cs b/osu.Game/Database/LegacyBeatmapExporter.cs index 5505d141ee..22bccbcda6 100644 --- a/osu.Game/Database/LegacyBeatmapExporter.cs +++ b/osu.Game/Database/LegacyBeatmapExporter.cs @@ -1,20 +1,19 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.IO; using osu.Framework.Platform; using osu.Game.Beatmaps; -using osu.Game.Overlays.Notifications; +using osu.Game.Overlays; namespace osu.Game.Database { public class LegacyBeatmapExporter : LegacyModelExporter { - protected override string FileExtension => ".osz"; - - public LegacyBeatmapExporter(Storage storage, RealmAccess realm, ProgressNotification notification, Stream? stream = null) - : base(storage, realm, notification, stream) + public LegacyBeatmapExporter(Storage storage, RealmAccess realm, INotificationOverlay? notifications = null) + : base(storage, realm, notifications) { } + + protected override string FileExtension => ".osz"; } } diff --git a/osu.Game/Database/LegacyExportManager.cs b/osu.Game/Database/LegacyExportManager.cs deleted file mode 100644 index a694a0705e..0000000000 --- a/osu.Game/Database/LegacyExportManager.cs +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.IO; -using System.Threading.Tasks; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Platform; -using osu.Framework.Testing; -using osu.Game.Beatmaps; -using osu.Game.Overlays; -using osu.Game.Overlays.Notifications; -using osu.Game.Scoring; -using osu.Game.Skinning; - -namespace osu.Game.Database -{ - /// - /// A class which centrally manage legacy file exports. - /// - [ExcludeFromDynamicCompile] - public class LegacyExportManager : Component - { - [Resolved] - private RealmAccess realmAccess { get; set; } = null!; - - [Resolved] - private Storage exportStorage { get; set; } = null!; - - [Resolved] - private INotificationOverlay? notifications { get; set; } - - /// - /// Identify the model type and and automatically assigned to the corresponding exporter. - /// - /// The model should export. - /// The stream if requires a specific output-stream - /// - public async Task ExportAsync(IHasGuidPrimaryKey item, Stream? stream = null) - { - var notification = new ProgressNotification - { - State = ProgressNotificationState.Active, - Text = "Exporting...", - CompletionText = "Export completed" - }; - notifications?.Post(notification); - - switch (item) - { - case SkinInfo: - await new LegacySkinExporter(exportStorage, realmAccess, notification, stream).ExportAsync(item); - break; - - case ScoreInfo: - await new LegacyScoreExporter(exportStorage, realmAccess, notification, stream).ExportASync(item); - break; - - case BeatmapSetInfo: - await new LegacyBeatmapExporter(exportStorage, realmAccess, notification, stream).ExportAsync(item); - break; - } - } - } -} diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 01ebbdcaff..83167e7319 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -5,8 +5,10 @@ using System; using System.IO; using System.Linq; using System.Threading.Tasks; +using osu.Framework.Graphics; using osu.Framework.Platform; using osu.Game.Extensions; +using osu.Game.Overlays; using osu.Game.Overlays.Notifications; using Realms; using SharpCompress.Archives.Zip; @@ -16,112 +18,106 @@ namespace osu.Game.Database /// /// A class which handles exporting legacy user data of a single type from osu-stable. /// - public abstract class LegacyModelExporter - where TModel : RealmObject + public abstract class LegacyModelExporter : Component + where TModel : RealmObject, IHasNamedFiles, IHasGuidPrimaryKey { /// /// The file extension for exports (including the leading '.'). /// protected abstract string FileExtension { get; } - protected readonly Storage UserFileStorage; + protected Storage UserFileStorage; + protected Storage ExportStorage; - protected readonly Storage ExportStorage; + protected RealmAccess RealmAccess; - protected readonly RealmAccess RealmAccess; - - protected readonly ProgressNotification Notification; + private readonly ProgressNotification notification; protected string Filename = null!; - protected Stream? OutputStream; + private bool canCancel = true; - protected bool ShouldDisposeStream; - - protected LegacyModelExporter(Storage storage, RealmAccess realm, ProgressNotification notification, Stream? stream = null) + protected LegacyModelExporter(Storage storage, RealmAccess realm, INotificationOverlay? notifications = null) { ExportStorage = storage.GetStorageForDirectory(@"exports"); UserFileStorage = storage.GetStorageForDirectory(@"files"); - Notification = notification; RealmAccess = realm; - OutputStream = stream; - ShouldDisposeStream = false; + + notification = new ProgressNotification + { + State = ProgressNotificationState.Active, + Text = "Exporting...", + CompletionText = "Export completed" + }; + notification.CancelRequested += () => canCancel; + + notifications?.Post(notification); } - /// - /// Export model to - /// if is null, model will export to default folder. - /// - /// The model which have Guid. - /// + public async Task ExportAsync(RealmObject item) { - bool canCancel = true; - Notification.CancelRequested += () => canCancel; + if (item is TModel model) + { + Filename = $"{model.GetDisplayString().GetValidFilename()}{FileExtension}"; - public virtual async Task ExportAsync(IHasGuidPrimaryKey uuid) + using (var stream = ExportStorage.CreateFileSafely(Filename)) + { + await ExportToStreamAsync(model, stream); + } + } + } + + public virtual async Task ExportToStreamAsync(TModel uuid, Stream stream) + { Guid id = uuid.ID; await Task.Run(() => { RealmAccess.Run(r => { - if (r.Find(id) is IHasNamedFiles model) - { - Filename = $"{model.GetDisplayString().GetValidFilename()}{FileExtension}"; - } - else - { - return; - } - - if (OutputStream == null) - { - OutputStream = ExportStorage.CreateFileSafely(Filename); - ShouldDisposeStream = true; - } - - using (var archive = ZipArchive.Create()) - { - float i = 0; - - foreach (var file in model.Files) - { - if (Notification.CancellationToken.IsCancellationRequested) return; - - archive.AddEntry(file.Filename, UserFileStorage.GetStream(file.File.GetStoragePath())); - i++; - Notification.Progress = i / model.Files.Count(); - Notification.Text = $"Exporting... ({i}/{model.Files.Count()})"; - } - - Notification.Text = "Saving Zip Archive..."; - canCancel = false; - archive.SaveTo(OutputStream); - } + TModel model = r.Find(id); + createZipArchive(model, stream); }); }).ContinueWith(OnComplete); } + private void createZipArchive(TModel model, Stream outputStream) + { + using (var archive = ZipArchive.Create()) + { + float i = 0; + + foreach (var file in model.Files) + { + if (notification.CancellationToken.IsCancellationRequested) return; + + archive.AddEntry(file.Filename, UserFileStorage.GetStream(file.File.GetStoragePath())); + i++; + notification.Progress = i / model.Files.Count(); + notification.Text = $"Exporting... ({i}/{model.Files.Count()})"; + } + + notification.Text = "Saving Zip Archive..."; + canCancel = false; + archive.SaveTo(outputStream); + } + } + protected void OnComplete(Task t) { - if (ShouldDisposeStream) - { - OutputStream?.Dispose(); - } - if (t.IsFaulted) { - Notification.State = ProgressNotificationState.Cancelled; + notification.State = ProgressNotificationState.Cancelled; return; } - if (Notification.CancellationToken.IsCancellationRequested) + if (notification.CancellationToken.IsCancellationRequested) { return; } - Notification.CompletionText = "Export Complete, Click to open the folder"; - Notification.CompletionClickAction += () => ExportStorage.PresentFileExternally(Filename); - Notification.State = ProgressNotificationState.Completed; + notification.CompletionText = "Export Complete, Click to open the folder"; + notification.CompletionClickAction += () => ExportStorage.PresentFileExternally(Filename); + notification.State = ProgressNotificationState.Completed; } } } diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index 3004c02978..e00bc2a0ca 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -6,49 +6,36 @@ using System.Linq; using System.Threading.Tasks; using osu.Framework.Platform; using osu.Game.Extensions; -using osu.Game.Overlays.Notifications; +using osu.Game.Overlays; using osu.Game.Scoring; namespace osu.Game.Database { public class LegacyScoreExporter : LegacyModelExporter { - protected override string FileExtension => ".osr"; - - public LegacyScoreExporter(Storage storage, RealmAccess realm, ProgressNotification notification, Stream? stream = null) - : base(storage, realm, notification, stream) + public LegacyScoreExporter(Storage storage, RealmAccess realm, INotificationOverlay? notifications = null) + : base(storage, realm, notifications) { } - public override async Task ExportASync(IHasGuidPrimaryKey uuid) + protected override string FileExtension => ".osr"; + + public override async Task ExportToStreamAsync(ScoreInfo uuid, Stream stream) { await Task.Run(() => { RealmAccess.Run(r => { - if (r.Find(uuid.ID) is IHasNamedFiles model) - { - Filename = $"{model.GetDisplayString().GetValidFilename()}{FileExtension}"; - } - else - { - return; - } + ScoreInfo model = r.Find(uuid.ID); + + Filename = $"{model.GetDisplayString().GetValidFilename()}{FileExtension}"; var file = model.Files.SingleOrDefault(); if (file == null) return; - if (Notification.CancellationToken.IsCancellationRequested) return; - - if (OutputStream == null) - { - OutputStream = ExportStorage.CreateFileSafely(Filename); - ShouldDisposeStream = true; - } - using (var inputStream = UserFileStorage.GetStream(file.File.GetStoragePath())) - inputStream.CopyTo(OutputStream); + inputStream.CopyTo(stream); }); }).ContinueWith(OnComplete); } diff --git a/osu.Game/Database/LegacySkinExporter.cs b/osu.Game/Database/LegacySkinExporter.cs index 4168763324..6e65963f29 100644 --- a/osu.Game/Database/LegacySkinExporter.cs +++ b/osu.Game/Database/LegacySkinExporter.cs @@ -1,20 +1,19 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.IO; using osu.Framework.Platform; -using osu.Game.Overlays.Notifications; +using osu.Game.Overlays; using osu.Game.Skinning; namespace osu.Game.Database { public class LegacySkinExporter : LegacyModelExporter { - protected override string FileExtension => ".osk"; - - public LegacySkinExporter(Storage storage, RealmAccess realm, ProgressNotification notification, Stream? stream = null) - : base(storage, realm, notification, stream) + public LegacySkinExporter(Storage storage, RealmAccess realm, INotificationOverlay? notifications = null) + : base(storage, realm, notifications) { } + + protected override string FileExtension => ".osk"; } } diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index b374736648..0a9f2a81bd 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -34,6 +34,7 @@ using osuTK.Graphics; using osu.Game.Online.API; using osu.Game.Resources.Localisation.Web; using osu.Game.Utils; +using osu.Framework.Platform; namespace osu.Game.Online.Leaderboards { @@ -72,8 +73,14 @@ namespace osu.Game.Online.Leaderboards [Resolved(canBeNull: true)] private SongSelect songSelect { get; set; } - [Resolved(canBeNull: true)] - private LegacyExportManager exporter { get; set; } + [Resolved] + private Storage storage { get; set; } + + [Resolved] + private RealmAccess realm { get; set; } + + [Resolved] + private INotificationOverlay notifications { get; set; } public ITooltip GetCustomTooltip() => new LeaderboardScoreTooltip(); public virtual ScoreInfo TooltipContent => Score; @@ -427,7 +434,7 @@ namespace osu.Game.Online.Leaderboards if (Score.Files.Count > 0) { - items.Add(new OsuMenuItem("Export", MenuItemType.Standard, () => Task.Run(() => exporter?.ExportAsync(Score)))); + items.Add(new OsuMenuItem("Export", MenuItemType.Standard, () => Task.Run(() => new LegacyScoreExporter(storage, realm, notifications).ExportAsync(Score)))); items.Add(new OsuMenuItem(CommonStrings.ButtonsDelete, MenuItemType.Destructive, () => dialogOverlay?.Push(new LocalScoreDeleteDialog(Score)))); } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 09647f9d1e..a93c187e53 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -126,9 +126,6 @@ namespace osu.Game [Cached] private readonly LegacyImportManager legacyImportManager = new LegacyImportManager(); - [Cached] - private readonly LegacyExportManager legacyExportManager = new LegacyExportManager(); - [Cached] private readonly ScreenshotManager screenshotManager = new ScreenshotManager(); @@ -871,7 +868,6 @@ namespace osu.Game }), rightFloatingOverlayContent.Add, true); loadComponentSingleFile(legacyImportManager, Add); - loadComponentSingleFile(legacyExportManager, Add); loadComponentSingleFile(screenshotManager, Add); diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index e5a26c19fc..46e760283d 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -13,6 +13,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Framework.Logging; +using osu.Framework.Platform; using osu.Game.Database; using osu.Game.Graphics.UserInterface; using osu.Game.Localisation; @@ -137,8 +138,14 @@ namespace osu.Game.Overlays.Settings.Sections [Resolved] private SkinManager skins { get; set; } - [Resolved(canBeNull: true)] - private LegacyExportManager exporter { get; set; } + [Resolved] + private Storage storage { get; set; } + + [Resolved] + private RealmAccess realm { get; set; } + + [Resolved] + private INotificationOverlay notifications { get; set; } private Bindable currentSkin; @@ -161,7 +168,7 @@ namespace osu.Game.Overlays.Settings.Sections { try { - currentSkin.Value.SkinInfo.PerformRead(s => exporter?.ExportAsync(s)); + currentSkin.Value.SkinInfo.PerformRead(s => new LegacySkinExporter(storage, realm, notifications).ExportAsync(s)); } catch (Exception e) { diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 77f14f689a..e53c550a1a 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -21,6 +21,7 @@ using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Framework.Logging; +using osu.Framework.Platform; using osu.Framework.Screens; using osu.Framework.Testing; using osu.Framework.Threading; @@ -90,6 +91,12 @@ namespace osu.Game.Screens.Edit [Resolved] private RulesetStore rulesets { get; set; } + [Resolved] + private Storage storage { get; set; } + + [Resolved] + private RealmAccess realm { get; set; } + [Resolved(canBeNull: true)] private IDialogOverlay dialogOverlay { get; set; } @@ -179,9 +186,6 @@ namespace osu.Game.Screens.Edit private Bindable editorBackgroundDim; private Bindable editorHitMarkers; - [Resolved(canBeNull: true)] - private LegacyExportManager exporter { get; set; } - public Editor(EditorLoader loader = null) { this.loader = loader; @@ -938,7 +942,7 @@ namespace osu.Game.Screens.Edit private void exportBeatmap() { Save(); - Task.Run(() => exporter?.ExportAsync(Beatmap.Value.BeatmapSetInfo)); + Task.Run(() => new LegacyBeatmapExporter(storage, realm, notifications).ExportAsync(Beatmap.Value.BeatmapSetInfo)); } /// From 9c6421a462d67e30d9bf9d4b2cdf9171765ae97e Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Mon, 21 Nov 2022 19:00:10 +0900 Subject: [PATCH 0715/2991] log the error --- osu.Game/Database/LegacyModelExporter.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 83167e7319..9769a6d42a 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using osu.Framework.Graphics; +using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Extensions; using osu.Game.Overlays; @@ -107,6 +108,8 @@ namespace osu.Game.Database if (t.IsFaulted) { notification.State = ProgressNotificationState.Cancelled; + Logger.Error(t.Exception, "An error occurred while exporting"); + return; } From 564f136945c0f3fef744014c5762f44145e325ae Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Mon, 21 Nov 2022 19:04:05 +0900 Subject: [PATCH 0716/2991] add xmldoc --- osu.Game/Database/LegacyModelExporter.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 9769a6d42a..47068a8d2b 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -55,6 +55,11 @@ namespace osu.Game.Database notifications?.Post(notification); } + /// + /// Export the model to default folder. + /// + /// The model should export. + /// public async Task ExportAsync(RealmObject item) { if (item is TModel model) @@ -68,6 +73,12 @@ namespace osu.Game.Database } } + /// + /// Export te model corresponding to uuid to given stream. + /// + /// The medel which have . + /// The stream to export. + /// public virtual async Task ExportToStreamAsync(TModel uuid, Stream stream) { Guid id = uuid.ID; From 162f0bb95e1c525ce926935fafbcf98f3a76bdac Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Mon, 21 Nov 2022 19:05:26 +0900 Subject: [PATCH 0717/2991] filename can be private --- osu.Game/Database/LegacyModelExporter.cs | 8 ++++---- osu.Game/Database/LegacyScoreExporter.cs | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 47068a8d2b..3780f2b9cc 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -34,7 +34,7 @@ namespace osu.Game.Database private readonly ProgressNotification notification; - protected string Filename = null!; + private string filename = ""; private bool canCancel = true; @@ -64,9 +64,9 @@ namespace osu.Game.Database { if (item is TModel model) { - Filename = $"{model.GetDisplayString().GetValidFilename()}{FileExtension}"; + filename = $"{model.GetDisplayString().GetValidFilename()}{FileExtension}"; - using (var stream = ExportStorage.CreateFileSafely(Filename)) + using (var stream = ExportStorage.CreateFileSafely(filename)) { await ExportToStreamAsync(model, stream); } @@ -130,7 +130,7 @@ namespace osu.Game.Database } notification.CompletionText = "Export Complete, Click to open the folder"; - notification.CompletionClickAction += () => ExportStorage.PresentFileExternally(Filename); + notification.CompletionClickAction += () => ExportStorage.PresentFileExternally(filename); notification.State = ProgressNotificationState.Completed; } } diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index e00bc2a0ca..ae0fbf8d19 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -28,8 +28,6 @@ namespace osu.Game.Database { ScoreInfo model = r.Find(uuid.ID); - Filename = $"{model.GetDisplayString().GetValidFilename()}{FileExtension}"; - var file = model.Files.SingleOrDefault(); if (file == null) return; From c509c5be40a449b872053e129358dd747b7e72f1 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Mon, 21 Nov 2022 19:45:30 +0900 Subject: [PATCH 0718/2991] impossible null --- osu.Game/Online/Leaderboards/LeaderboardScore.cs | 2 +- osu.Game/Overlays/Settings/Sections/SkinSection.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index 0a9f2a81bd..27c3e0ce47 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -79,7 +79,7 @@ namespace osu.Game.Online.Leaderboards [Resolved] private RealmAccess realm { get; set; } - [Resolved] + [Resolved(canBeNull: true)] private INotificationOverlay notifications { get; set; } public ITooltip GetCustomTooltip() => new LeaderboardScoreTooltip(); diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 46e760283d..eb51c18e31 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -144,7 +144,7 @@ namespace osu.Game.Overlays.Settings.Sections [Resolved] private RealmAccess realm { get; set; } - [Resolved] + [Resolved(canBeNull: true)] private INotificationOverlay notifications { get; set; } private Bindable currentSkin; From ff5cb116f03ef2850b5d5dd68533da5bb5a1b059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 21 Nov 2022 19:27:06 +0100 Subject: [PATCH 0719/2991] Fix weird scroll container sizing --- osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs b/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs index 84f5ce7627..5e75bd7bc1 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs @@ -39,8 +39,7 @@ namespace osu.Game.Tests.Visual.Settings { new OsuScrollContainer(Direction.Vertical) { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.Both, Child = settings = new TabletSettings(tabletHandler) { RelativeSizeAxes = Axes.None, From 735cac3104f4ba43eaa9fbdb0d909f506dfe58ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 21 Nov 2022 20:56:38 +0100 Subject: [PATCH 0720/2991] Rewrite rank graph test to use more modern style --- .../Visual/Online/TestSceneRankGraph.cs | 87 ++++++++++++------- 1 file changed, 58 insertions(+), 29 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs b/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs index 1b1a5c7c6a..304c710b10 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs @@ -1,13 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Testing; using osu.Game.Graphics; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; @@ -23,33 +22,14 @@ namespace osu.Game.Tests.Visual.Online [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink); - public TestSceneRankGraph() + private RankGraph graph = null!; + + private const int history_length = 89; + + [SetUpSteps] + public void SetUpSteps() { - RankGraph graph; - - int[] data = new int[89]; - int[] dataWithZeros = new int[89]; - int[] smallData = new int[89]; - int[] edgyData = new int[89]; - - for (int i = 0; i < 89; i++) - data[i] = dataWithZeros[i] = (i + 1) * 1000; - - for (int i = 20; i < 60; i++) - dataWithZeros[i] = 0; - - for (int i = 79; i < 89; i++) - smallData[i] = 100000 - i * 1000; - - bool edge = true; - - for (int i = 0; i < 20; i++) - { - edgyData[i] = 100000 + (edge ? 1000 : -1000) * (i + 1); - edge = !edge; - } - - Add(new Container + AddStep("create graph", () => Child = new Container { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -67,8 +47,14 @@ namespace osu.Game.Tests.Visual.Online } } }); + } + [Test] + public void TestNullUser() => AddStep("null user", () => graph.Statistics.Value = null); + + [Test] + public void TestRankOnly() => AddStep("rank only", () => { graph.Statistics.Value = new UserStatistics @@ -78,6 +64,14 @@ namespace osu.Game.Tests.Visual.Online }; }); + [Test] + public void TestWithRankHistory() + { + int[] data = new int[history_length]; + + for (int i = 0; i < history_length; i++) + data[i] = (i + 1) * 1000; + AddStep("with rank history", () => { graph.Statistics.Value = new UserStatistics @@ -86,10 +80,22 @@ namespace osu.Game.Tests.Visual.Online PP = 12345, RankHistory = new APIRankHistory { - Data = data, + Data = data } }; }); + } + + [Test] + public void TestRanksWithZeroValues() + { + int[] dataWithZeros = new int[history_length]; + + for (int i = 0; i < history_length; i++) + { + if (i < 20 || i >= 60) + dataWithZeros[i] = (i + 1) * 1000; + } AddStep("with zero values", () => { @@ -103,6 +109,15 @@ namespace osu.Game.Tests.Visual.Online } }; }); + } + + [Test] + public void TestSmallAmountOfData() + { + int[] smallData = new int[history_length]; + + for (int i = history_length - 10; i < history_length; i++) + smallData[i] = 100000 - i * 1000; AddStep("small amount of data", () => { @@ -116,6 +131,20 @@ namespace osu.Game.Tests.Visual.Online } }; }); + } + + [Test] + public void TestHistoryWithEdges() + { + int[] edgyData = new int[89]; + + bool edge = true; + + for (int i = 0; i < 20; i++) + { + edgyData[i] = 100000 + (edge ? 1000 : -1000) * (i + 1); + edge = !edge; + } AddStep("graph with edges", () => { From 1777a6013619b021c078224ff02c86aad21014ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 21 Nov 2022 20:58:52 +0100 Subject: [PATCH 0721/2991] Add failing assertions --- .../Visual/Online/TestSceneRankGraph.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs b/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs index 304c710b10..ce4d11800b 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankGraph.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.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -8,6 +9,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Testing; using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; using osu.Game.Overlays.Profile.Header.Components; @@ -50,11 +52,15 @@ namespace osu.Game.Tests.Visual.Online } [Test] - public void TestNullUser() => + public void TestNullUser() + { AddStep("null user", () => graph.Statistics.Value = null); + AddAssert("line graph hidden", () => this.ChildrenOfType().All(graph => graph.Alpha == 0)); + } [Test] - public void TestRankOnly() => + public void TestRankOnly() + { AddStep("rank only", () => { graph.Statistics.Value = new UserStatistics @@ -63,6 +69,8 @@ namespace osu.Game.Tests.Visual.Online PP = 12345, }; }); + AddAssert("line graph hidden", () => this.ChildrenOfType().All(graph => graph.Alpha == 0)); + } [Test] public void TestWithRankHistory() @@ -84,6 +92,7 @@ namespace osu.Game.Tests.Visual.Online } }; }); + AddAssert("line graph shown", () => this.ChildrenOfType().All(graph => graph.Alpha == 1)); } [Test] @@ -109,6 +118,7 @@ namespace osu.Game.Tests.Visual.Online } }; }); + AddAssert("line graph shown", () => this.ChildrenOfType().All(graph => graph.Alpha == 1)); } [Test] @@ -131,6 +141,7 @@ namespace osu.Game.Tests.Visual.Online } }; }); + AddAssert("line graph shown", () => this.ChildrenOfType().All(graph => graph.Alpha == 1)); } [Test] @@ -158,6 +169,7 @@ namespace osu.Game.Tests.Visual.Online } }; }); + AddAssert("line graph shown", () => this.ChildrenOfType().All(graph => graph.Alpha == 1)); } } } From 41039340cfcaf81dee840f56812a1f0f6974fa96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 21 Nov 2022 21:00:06 +0100 Subject: [PATCH 0722/2991] Fix rank graphs not showing in test due to unset `IsRanked` --- osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs b/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs index ce4d11800b..d05f1f02f7 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs @@ -65,6 +65,7 @@ namespace osu.Game.Tests.Visual.Online { graph.Statistics.Value = new UserStatistics { + IsRanked = true, GlobalRank = 123456, PP = 12345, }; @@ -84,6 +85,7 @@ namespace osu.Game.Tests.Visual.Online { graph.Statistics.Value = new UserStatistics { + IsRanked = true, GlobalRank = 89000, PP = 12345, RankHistory = new APIRankHistory @@ -110,6 +112,7 @@ namespace osu.Game.Tests.Visual.Online { graph.Statistics.Value = new UserStatistics { + IsRanked = true, GlobalRank = 89000, PP = 12345, RankHistory = new APIRankHistory @@ -133,6 +136,7 @@ namespace osu.Game.Tests.Visual.Online { graph.Statistics.Value = new UserStatistics { + IsRanked = true, GlobalRank = 12000, PP = 12345, RankHistory = new APIRankHistory @@ -161,6 +165,7 @@ namespace osu.Game.Tests.Visual.Online { graph.Statistics.Value = new UserStatistics { + IsRanked = true, GlobalRank = 12000, PP = 12345, RankHistory = new APIRankHistory From 4084a2b0669509433826e2676711c000a3be2b9a Mon Sep 17 00:00:00 2001 From: Alden Wu Date: Mon, 21 Nov 2022 18:57:59 -0800 Subject: [PATCH 0723/2991] Highlight `ChatLine` username on hover --- osu.Game/Overlays/Chat/ChatLine.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index a991103fac..af5fa89ca1 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -23,6 +23,7 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; using osuTK; using osuTK.Graphics; +using osu.Framework.Input.Events; namespace osu.Game.Overlays.Chat { @@ -291,6 +292,20 @@ namespace osu.Game.Overlays.Chat return items.ToArray(); } } + + protected override bool OnHover(HoverEvent e) + { + this.FadeColour(new Color4(1.4f, 1.4f, 1.4f, 1), 150, Easing.OutQuint); + + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + + this.FadeColour(Color4.White, 250, Easing.OutQuint); + } } private static readonly Color4[] username_colours = From 1632df1f4db4a9aea047548f3ad6205ebdfd4eda Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Nov 2022 14:51:17 +0900 Subject: [PATCH 0724/2991] Update `DifficultyBindable` to match new bindable spec --- osu.Game/Rulesets/Mods/DifficultyBindable.cs | 21 ++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/osu.Game/Rulesets/Mods/DifficultyBindable.cs b/osu.Game/Rulesets/Mods/DifficultyBindable.cs index 34e9fe40a3..2b3ba1dd13 100644 --- a/osu.Game/Rulesets/Mods/DifficultyBindable.cs +++ b/osu.Game/Rulesets/Mods/DifficultyBindable.cs @@ -99,22 +99,31 @@ namespace osu.Game.Rulesets.Mods CurrentNumber.MaxValue = ExtendedLimits.Value && extendedMaxValue != null ? extendedMaxValue.Value : maxValue; } + public override void CopyTo(Bindable them) + { + if (!(them is DifficultyBindable otherDifficultyBindable)) + throw new InvalidOperationException($"Cannot copy to a non-{nameof(DifficultyBindable)}."); + + base.CopyTo(them); + + otherDifficultyBindable.ReadCurrentFromDifficulty = ReadCurrentFromDifficulty; + + // the following max value copies are only safe as long as these values are effectively constants. + otherDifficultyBindable.MaxValue = maxValue; + otherDifficultyBindable.ExtendedMaxValue = extendedMaxValue; + } + public override void BindTo(Bindable them) { if (!(them is DifficultyBindable otherDifficultyBindable)) throw new InvalidOperationException($"Cannot bind to a non-{nameof(DifficultyBindable)}."); - ReadCurrentFromDifficulty = otherDifficultyBindable.ReadCurrentFromDifficulty; - - // the following max value copies are only safe as long as these values are effectively constants. - MaxValue = otherDifficultyBindable.maxValue; - ExtendedMaxValue = otherDifficultyBindable.extendedMaxValue; + base.BindTo(them); ExtendedLimits.BindTarget = otherDifficultyBindable.ExtendedLimits; // the actual values need to be copied after the max value constraints. CurrentNumber.BindTarget = otherDifficultyBindable.CurrentNumber; - base.BindTo(them); } public override void UnbindFrom(IUnbindable them) From 57723107dd313833902032268921f779346f5472 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Nov 2022 16:15:32 +0900 Subject: [PATCH 0725/2991] Fix osu!mania hold notes occasionally getting in a visually incorrect hit state To correctly end a mania hold note, `endHold()` needs to be called. This was not happening in a very specific scenario: - The hold note's head is not hit - The user pressed the column's key within the hold note's tail's window, but does so to hit the next object (a note in proximity to the hold note's tail). - The hit policy forces a miss on the hold note, but `endHold()` is not called - `CheckForResult` is not called after this point due to `Judged` being `true`. Closes #21311. --- .../Objects/Drawables/DrawableHoldNote.cs | 14 ++++++++++++-- .../Objects/Drawables/DrawableManiaHitObject.cs | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index c68eec610c..86d4ad0a36 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -262,14 +262,24 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables tick.MissForcefully(); } - ApplyResult(r => r.Type = Tail.IsHit ? r.Judgement.MaxResult : r.Judgement.MinResult); - endHold(); + if (Tail.IsHit) + ApplyResult(r => r.Type = r.Judgement.MaxResult); + else + MissForcefully(); } if (Tail.Judged && !Tail.IsHit) HoldBrokenTime = Time.Current; } + public override void MissForcefully() + { + base.MissForcefully(); + + // Important that this is always called when a result is applied. + endHold(); + } + public bool OnPressed(KeyBindingPressEvent e) { if (AllJudged) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index 73dc937a00..51f8ab1cf8 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// /// Causes this to get missed, disregarding all conditions in implementations of . /// - public void MissForcefully() => ApplyResult(r => r.Type = r.Judgement.MinResult); + public virtual void MissForcefully() => ApplyResult(r => r.Type = r.Judgement.MinResult); } public abstract class DrawableManiaHitObject : DrawableManiaHitObject From c1b193149c67b061c7c5597b953f5e5b0aa487de Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Nov 2022 17:09:10 +0900 Subject: [PATCH 0726/2991] Add test coverage of input near end of hold note with nearby subsequent note Covers the scenarios mentioned in #21371. Turns out this seems mostly okay already, so there are no fixes applied here. --- .../TestSceneHoldNoteInput.cs | 165 +++++++++++++++++- 1 file changed, 160 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs index 0296303867..0cba2076be 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs @@ -23,6 +23,15 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Mania.Tests { + /// + /// Diagrams in this class are represented as: + /// - : time + /// O : note + /// [ ] : hold note + /// + /// x : button press + /// o : button release + /// public class TestSceneHoldNoteInput : RateAdjustedBeatmapTestScene { private const double time_before_head = 250; @@ -223,6 +232,149 @@ namespace osu.Game.Rulesets.Mania.Tests assertTailJudgement(HitResult.Meh); } + /// + /// -----[ ]-O------------- + /// xo o + /// + [Test] + public void TestPressAndReleaseJustBeforeTailWithNearbyNoteAndCloseByHead() + { + Note note; + + const int duration = 50; + + var beatmap = new Beatmap + { + HitObjects = + { + // hold note is very short, to make the head still in range + new HoldNote + { + StartTime = time_head, + Duration = duration, + Column = 0, + }, + { + // Next note within tail lenience + note = new Note + { + StartTime = time_head + duration + 10 + } + } + }, + BeatmapInfo = + { + Difficulty = new BeatmapDifficulty { SliderTickRate = 4 }, + Ruleset = new ManiaRuleset().RulesetInfo + }, + }; + + performTest(new List + { + new ManiaReplayFrame(time_head + duration, ManiaAction.Key1), + new ManiaReplayFrame(time_head + duration + 10), + }, beatmap); + + assertHeadJudgement(HitResult.Good); + assertTailJudgement(HitResult.Perfect); + + assertHitObjectJudgement(note, HitResult.Miss); + } + + /// + /// -----[ ]--O-- + /// xo o + /// + [Test] + public void TestPressAndReleaseJustBeforeTailWithNearbyNote() + { + Note note; + + var beatmap = new Beatmap + { + HitObjects = + { + new HoldNote + { + StartTime = time_head, + Duration = time_tail - time_head, + Column = 0, + }, + { + // Next note within tail lenience + note = new Note + { + StartTime = time_tail + 50 + } + } + }, + BeatmapInfo = + { + Difficulty = new BeatmapDifficulty { SliderTickRate = 4 }, + Ruleset = new ManiaRuleset().RulesetInfo + }, + }; + + performTest(new List + { + new ManiaReplayFrame(time_tail - 10, ManiaAction.Key1), + new ManiaReplayFrame(time_tail), + }, beatmap); + + assertHeadJudgement(HitResult.Miss); + assertTickJudgement(HitResult.LargeTickMiss); + assertTailJudgement(HitResult.Miss); + + assertHitObjectJudgement(note, HitResult.Good); + } + + /// + /// -----[ ]--O-- + /// xo o + /// + [Test] + public void TestPressAndReleaseJustAfterTailWithNearbyNote() + { + Note note; + + var beatmap = new Beatmap + { + HitObjects = + { + new HoldNote + { + StartTime = time_head, + Duration = time_tail - time_head, + Column = 0, + }, + { + // Next note within tail lenience + note = new Note + { + StartTime = time_tail + 50 + } + } + }, + BeatmapInfo = + { + Difficulty = new BeatmapDifficulty { SliderTickRate = 4 }, + Ruleset = new ManiaRuleset().RulesetInfo + }, + }; + + performTest(new List + { + new ManiaReplayFrame(time_tail + 10, ManiaAction.Key1), + new ManiaReplayFrame(time_tail + 20), + }, beatmap); + + assertHeadJudgement(HitResult.Miss); + assertTickJudgement(HitResult.LargeTickMiss); + assertTailJudgement(HitResult.Miss); + + assertHitObjectJudgement(note, HitResult.Great); + } + /// /// -----[ ]----- /// xo o @@ -351,20 +503,23 @@ namespace osu.Game.Rulesets.Mania.Tests .All(j => j.Type.IsHit())); } + private void assertHitObjectJudgement(HitObject hitObject, HitResult result) + => AddAssert($"object judged as {result}", () => judgementResults.First(j => j.HitObject == hitObject).Type, () => Is.EqualTo(result)); + private void assertHeadJudgement(HitResult result) - => AddAssert($"head judged as {result}", () => judgementResults.First(j => j.HitObject is Note).Type == result); + => AddAssert($"head judged as {result}", () => judgementResults.First(j => j.HitObject is Note).Type, () => Is.EqualTo(result)); private void assertTailJudgement(HitResult result) - => AddAssert($"tail judged as {result}", () => judgementResults.Single(j => j.HitObject is TailNote).Type == result); + => AddAssert($"tail judged as {result}", () => judgementResults.Single(j => j.HitObject is TailNote).Type, () => Is.EqualTo(result)); private void assertNoteJudgement(HitResult result) - => AddAssert($"hold note judged as {result}", () => judgementResults.Single(j => j.HitObject is HoldNote).Type == result); + => AddAssert($"hold note judged as {result}", () => judgementResults.Single(j => j.HitObject is HoldNote).Type, () => Is.EqualTo(result)); private void assertTickJudgement(HitResult result) - => AddAssert($"any tick judged as {result}", () => judgementResults.Where(j => j.HitObject is HoldNoteTick).Any(j => j.Type == result)); + => AddAssert($"any tick judged as {result}", () => judgementResults.Where(j => j.HitObject is HoldNoteTick).Select(j => j.Type), () => Does.Contain(result)); private void assertLastTickJudgement(HitResult result) - => AddAssert($"last tick judged as {result}", () => judgementResults.Last(j => j.HitObject is HoldNoteTick).Type == result); + => AddAssert($"last tick judged as {result}", () => judgementResults.Last(j => j.HitObject is HoldNoteTick).Type, () => Is.EqualTo(result)); private ScoreAccessibleReplayPlayer currentPlayer; From a2b505f4c09f94854a5ef3f6dedc831ad6452a3c Mon Sep 17 00:00:00 2001 From: Alden Wu Date: Tue, 22 Nov 2022 00:31:22 -0800 Subject: [PATCH 0727/2991] Use a direct `Lighten` instead of >1f Color4 values --- osu.Game/Overlays/Chat/ChatLine.cs | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index af5fa89ca1..bfbffabd2b 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -61,6 +61,8 @@ namespace osu.Game.Overlays.Chat private OsuSpriteText username = null!; + private Drawable usernameColouredDrawable = null!; + private Container? highlight; private readonly Bindable prefer24HourTime = new Bindable(); @@ -89,6 +91,10 @@ namespace osu.Game.Overlays.Chat ? Color4Extensions.FromHex(message.Sender.Colour) : username_colours[message.Sender.Id % username_colours.Length]; + // this can be either the username sprite text or a container + // around it depending on which branch is taken in createUsername() + var usernameDrawable = createUsername(); + InternalChild = new GridContainer { RelativeSizeAxes = Axes.X, @@ -113,13 +119,13 @@ namespace osu.Game.Overlays.Chat Colour = colourProvider?.Background1 ?? Colour4.White, AlwaysPresent = true, }, - new MessageSender(message.Sender) + new MessageSender(message.Sender, usernameColouredDrawable) { Width = UsernameWidth, AutoSizeAxes = Axes.Y, Origin = Anchor.TopRight, Anchor = Anchor.TopRight, - Child = createUsername(), + Child = usernameDrawable, Margin = new MarginPadding { Horizontal = Spacing }, }, ContentFlow = new LinkFlowContainer(t => @@ -198,7 +204,6 @@ namespace osu.Game.Overlays.Chat username = new OsuSpriteText { Shadow = false, - Colour = senderHasColour ? colours.ChatBlue : usernameColour, Truncate = true, EllipsisString = "…", Font = OsuFont.GetFont(size: TextSize, weight: FontWeight.Bold, italics: true), @@ -208,7 +213,13 @@ namespace osu.Game.Overlays.Chat }; if (!senderHasColour) + { + usernameColouredDrawable = username; + usernameColouredDrawable.Colour = usernameColour; return username; + } + + username.Colour = colours.ChatBlue; // Background effect return new Container @@ -233,7 +244,7 @@ namespace osu.Game.Overlays.Chat CornerRadius = 4, Children = new Drawable[] { - new Box + usernameColouredDrawable = new Box { RelativeSizeAxes = Axes.Both, Colour = usernameColour, @@ -252,15 +263,19 @@ namespace osu.Game.Overlays.Chat private class MessageSender : OsuClickableContainer, IHasContextMenu { private readonly APIUser sender; + private readonly Drawable colouredDrawable; + private readonly Color4 defaultColour; private Action startChatAction = null!; [Resolved] private IAPIProvider api { get; set; } = null!; - public MessageSender(APIUser sender) + public MessageSender(APIUser sender, Drawable colouredDrawable) { this.sender = sender; + this.colouredDrawable = colouredDrawable; + defaultColour = colouredDrawable.Colour; } [BackgroundDependencyLoader] @@ -295,7 +310,7 @@ namespace osu.Game.Overlays.Chat protected override bool OnHover(HoverEvent e) { - this.FadeColour(new Color4(1.4f, 1.4f, 1.4f, 1), 150, Easing.OutQuint); + colouredDrawable.FadeColour(defaultColour.Lighten(0.4f), 150, Easing.OutQuint); return base.OnHover(e); } @@ -304,7 +319,7 @@ namespace osu.Game.Overlays.Chat { base.OnHoverLost(e); - this.FadeColour(Color4.White, 250, Easing.OutQuint); + colouredDrawable.FadeColour(defaultColour, 250, Easing.OutQuint); } } From de163b2bb55752d48b405a5fd3ed3f2f6104b172 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 22 Nov 2022 19:48:55 +0900 Subject: [PATCH 0728/2991] Change song select to only allow volume adjusting if alt is held while scrolling --- osu.Game/Screens/Select/SongSelect.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 5d5019567a..18ea0f69a2 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -304,6 +304,16 @@ namespace osu.Game.Screens.Select modSelectOverlayRegistration = OverlayManager?.RegisterBlockingOverlay(ModSelect); } + protected override bool OnScroll(ScrollEvent e) + { + // Match stable behaviour of only alt-scroll adjusting volume. + // Supporting scroll adjust without a modifier key just feels bad, since there are so many scrollable elements on the screen. + if (!e.CurrentState.Keyboard.AltPressed) + return true; + + return base.OnScroll(e); + } + /// /// Creates the buttons to be displayed in the footer. /// From 76bb529cfa750daf08d15f61f32e034b49ecbd83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 21 Nov 2022 20:30:42 +0100 Subject: [PATCH 0729/2991] Add test for local echo adding day separator --- .../Visual/Online/TestSceneDrawableChannel.cs | 87 +++++++++++++++++++ osu.Game/Online/Chat/StandAloneChatDisplay.cs | 4 +- osu.Game/Overlays/Chat/DaySeparator.cs | 8 +- 3 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneDrawableChannel.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneDrawableChannel.cs b/osu.Game.Tests/Visual/Online/TestSceneDrawableChannel.cs new file mode 100644 index 0000000000..dc1e00ee8f --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneDrawableChannel.cs @@ -0,0 +1,87 @@ +// 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 NUnit.Framework; +using osu.Framework.Graphics; +using osu.Framework.Testing; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Chat; +using osu.Game.Overlays.Chat; + +namespace osu.Game.Tests.Visual.Online +{ + [TestFixture] + public class TestSceneDrawableChannel : OsuTestScene + { + private Channel channel = null!; + private DrawableChannel drawableChannel = null!; + + [SetUpSteps] + public void SetUpSteps() + { + AddStep("create channel", () => channel = new Channel + { + Id = 1, + Name = "Test channel" + }); + AddStep("create drawable channel", () => Child = drawableChannel = new DrawableChannel(channel) + { + RelativeSizeAxes = Axes.Both + }); + } + + [Test] + public void TestDaySeparators() + { + var localUser = new APIUser + { + Id = 3, + Username = "LocalUser" + }; + string uuid = Guid.NewGuid().ToString(); + AddStep("add local echo message", () => channel.AddLocalEcho(new LocalEchoMessage + { + Sender = localUser, + Content = "Hi there all!", + Timestamp = new DateTimeOffset(2022, 11, 21, 20, 11, 13, TimeSpan.Zero), + Uuid = uuid + })); + AddUntilStep("one day separator present", () => drawableChannel.ChildrenOfType().Count() == 1); + + AddStep("add two prior messages to channel", () => channel.AddNewMessages( + new Message(1) + { + Sender = new APIUser + { + Id = 1, + Username = "TestUser" + }, + Content = "This is a message", + Timestamp = new DateTimeOffset(2021, 10, 10, 13, 33, 23, TimeSpan.Zero), + }, + new Message(2) + { + Sender = new APIUser + { + Id = 2, + Username = "TestUser2" + }, + Content = "This is another message", + Timestamp = new DateTimeOffset(2021, 10, 11, 13, 33, 23, TimeSpan.Zero) + })); + AddUntilStep("three day separators present", () => drawableChannel.ChildrenOfType().Count() == 3); + + AddStep("resolve pending message", () => channel.ReplaceMessage(channel.Messages.OfType().Single(), new Message(3) + { + Sender = localUser, + Content = "Hi there all!", + Timestamp = new DateTimeOffset(2022, 11, 22, 20, 11, 16, TimeSpan.Zero), + Uuid = uuid + })); + AddUntilStep("three day separators present", () => drawableChannel.ChildrenOfType().Count() == 3); + AddAssert("last day separator is from correct day", () => drawableChannel.ChildrenOfType().Last().Date.Date == new DateTime(2022, 11, 22)); + } + } +} diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs index 81db3f0d53..e45a14136d 100644 --- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs +++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs @@ -174,8 +174,8 @@ namespace osu.Game.Online.Chat protected override float Spacing => 5; protected override float DateAlign => 125; - public StandAloneDaySeparator(DateTimeOffset time) - : base(time) + public StandAloneDaySeparator(DateTimeOffset date) + : base(date) { } diff --git a/osu.Game/Overlays/Chat/DaySeparator.cs b/osu.Game/Overlays/Chat/DaySeparator.cs index be0b53785c..d68f325738 100644 --- a/osu.Game/Overlays/Chat/DaySeparator.cs +++ b/osu.Game/Overlays/Chat/DaySeparator.cs @@ -22,14 +22,14 @@ namespace osu.Game.Overlays.Chat protected virtual float Spacing => 15; - private readonly DateTimeOffset time; + public readonly DateTimeOffset Date; [Resolved(CanBeNull = true)] private OverlayColourProvider? colourProvider { get; set; } - public DaySeparator(DateTimeOffset time) + public DaySeparator(DateTimeOffset date) { - this.time = time; + Date = date; Height = 40; } @@ -80,7 +80,7 @@ namespace osu.Game.Overlays.Chat { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - Text = time.ToLocalTime().ToLocalisableString(@"dd MMMM yyyy").ToUpper(), + Text = Date.ToLocalTime().ToLocalisableString(@"dd MMMM yyyy").ToUpper(), Font = OsuFont.Torus.With(size: TextSize, weight: FontWeight.SemiBold), Colour = colourProvider?.Content1 ?? Colour4.White, }, From 5343f6922cbfdae09fb87654e2aa1d198a71c270 Mon Sep 17 00:00:00 2001 From: Joppe27 Date: Tue, 22 Nov 2022 17:22:00 +0100 Subject: [PATCH 0730/2991] Add legacy circle piece animations based on combo --- .../Skinning/Legacy/LegacyCirclePiece.cs | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs index 6b2576a564..2a260b8cb3 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs @@ -2,13 +2,16 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; +using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Screens.Play; using osu.Game.Skinning; using osuTK; using osuTK.Graphics; @@ -18,6 +21,13 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy public class LegacyCirclePiece : CompositeDrawable, IHasAccentColour { private Drawable backgroundLayer = null!; + private Drawable? foregroundLayer; + + private Bindable currentCombo { get; } = new BindableInt(); + + private int animationFrame; + private int multiplier; + private double beatLength; // required for editor blueprints (not sure why these circle pieces are zero size). public override Quad ScreenSpaceDrawQuad => backgroundLayer.ScreenSpaceDrawQuad; @@ -27,6 +37,12 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy RelativeSizeAxes = Axes.Both; } + [Resolved] + private GameplayState? gameplayState { get; set; } + + [Resolved] + private IBeatSyncProvider? beatSyncProvider { get; set; } + [BackgroundDependencyLoader] private void load(ISkinSource skin, DrawableHitObject drawableHitObject) { @@ -45,7 +61,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy // backgroundLayer is guaranteed to exist due to the pre-check in TaikoLegacySkinTransformer. AddInternal(backgroundLayer = new LegacyKiaiFlashingDrawable(() => getDrawableFor("circle"))); - var foregroundLayer = getDrawableFor("circleoverlay"); + foregroundLayer = getDrawableFor("circleoverlay"); if (foregroundLayer != null) AddInternal(foregroundLayer); @@ -58,6 +74,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy c.Anchor = Anchor.Centre; c.Origin = Anchor.Centre; } + + if (gameplayState != null) + currentCombo.BindTo(gameplayState.ScoreProcessor.Combo); } protected override void LoadComplete() @@ -74,6 +93,29 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy // This ensures they are scaled relative to each other but also match the expected DrawableHit size. foreach (var c in InternalChildren) c.Scale = new Vector2(DrawHeight / 128); + + if (currentCombo.Value >= 150) + { + multiplier = 2; + } + else if (currentCombo.Value >= 50) + { + multiplier = 1; + } + else + { + (foregroundLayer as IFramedAnimation)?.GotoFrame(0); + return; + } + + if (beatSyncProvider?.ControlPoints != null) + { + beatLength = beatSyncProvider.ControlPoints.TimingPointAt(LifetimeStart).BeatLength; + + animationFrame = Time.Current % ((beatLength * 2) / multiplier) >= beatLength / multiplier ? 0 : 1; + + (foregroundLayer as IFramedAnimation)?.GotoFrame(animationFrame); + } } private Color4 accentColour; From db34fa99b1adc5a1d422da1b93e129fdcda31dbd Mon Sep 17 00:00:00 2001 From: Joppe27 Date: Tue, 22 Nov 2022 17:22:34 +0100 Subject: [PATCH 0731/2991] Add tests and clean up inefficient code --- .../Skinning/TestSceneDrawableDrumRoll.cs | 25 ++++++++- .../Skinning/TestSceneDrawableDrumRollKiai.cs | 30 ---------- .../Skinning/TestSceneDrawableHit.cs | 55 +++++++++++++++++++ .../Skinning/TestSceneDrawableHitKiai.cs | 30 ---------- 4 files changed, 79 insertions(+), 61 deletions(-) delete mode 100644 osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRollKiai.cs delete mode 100644 osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHitKiai.cs diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRoll.cs index e42dc254ac..7a3439d8eb 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRoll.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning }; [Test] - public void DrumrollTest() + public void TestDrumroll() { AddStep("Drum roll", () => SetContents(_ => { @@ -57,6 +57,14 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning })); } + [Test] + public void TestDrumrollKiai() + { + AddStep("Create beatmap", createBeatmap); + + TestDrumroll(); + } + private DrumRoll createDrumRollAtCurrentTime(bool strong = false) { var drumroll = new DrumRoll @@ -73,5 +81,20 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning return drumroll; } + + private void createBeatmap() + { + var controlPointInfo = new ControlPointInfo(); + + controlPointInfo.Add(0, new TimingControlPoint { BeatLength = 500 }); + controlPointInfo.Add(0, new EffectControlPoint { KiaiMode = true }); + + Beatmap.Value = CreateWorkingBeatmap(new Beatmap + { + ControlPointInfo = controlPointInfo + }); + + Beatmap.Value.Track.Start(); + } } } diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRollKiai.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRollKiai.cs deleted file mode 100644 index 53977150e7..0000000000 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRollKiai.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using NUnit.Framework; -using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Beatmaps; - -namespace osu.Game.Rulesets.Taiko.Tests.Skinning -{ - [TestFixture] - public class TestSceneDrawableDrumRollKiai : TestSceneDrawableDrumRoll - { - [SetUp] - public void SetUp() => Schedule(() => - { - var controlPointInfo = new ControlPointInfo(); - - controlPointInfo.Add(0, new TimingControlPoint { BeatLength = 500 }); - controlPointInfo.Add(0, new EffectControlPoint { KiaiMode = true }); - - Beatmap.Value = CreateWorkingBeatmap(new Beatmap - { - ControlPointInfo = controlPointInfo - }); - - // track needs to be playing for BeatSyncedContainer to work. - Beatmap.Value.Track.Start(); - }); - } -} diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs index eb2b6c1d74..3902a3123b 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs @@ -4,17 +4,23 @@ #nullable disable using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Objects.Drawables; +using osu.Game.Screens.Play; +using osu.Game.Tests.Gameplay; namespace osu.Game.Rulesets.Taiko.Tests.Skinning { [TestFixture] public class TestSceneDrawableHit : TaikoSkinnableTestScene { + [Cached] + private GameplayState gameplayState = TestGameplayState.Create(new TaikoRuleset()); + [Test] public void TestHits() { @@ -43,6 +49,38 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning })); } + [Test] + public void TestHitKiai() + { + AddStep("Create beatmap", () => createBeatmap(true)); + + TestHits(); + } + + [Test] + public void TestHitAnimationSlow() + { + AddStep("Create beatmap", () => createBeatmap(false)); + + AddStep("Reset combo", () => gameplayState.ScoreProcessor.Combo.Value = 0); + + AddRepeatStep("Increase combo", () => gameplayState.ScoreProcessor.Combo.Value++, 50); + + TestHits(); + } + + [Test] + public void TestHitAnimationFast() + { + AddStep("Create beatmap", () => createBeatmap(false)); + + AddStep("Reset combo", () => gameplayState.ScoreProcessor.Combo.Value = 0); + + AddRepeatStep("Increase combo", () => gameplayState.ScoreProcessor.Combo.Value++, 150); + + TestHits(); + } + private Hit createHitAtCurrentTime(bool strong = false, bool rim = false) { var hit = new Hit @@ -56,5 +94,22 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning return hit; } + + private void createBeatmap(bool includeKiai) + { + var controlPointInfo = new ControlPointInfo(); + + controlPointInfo.Add(0, new TimingControlPoint { BeatLength = 500 }); + + if (includeKiai) + controlPointInfo.Add(0, new EffectControlPoint { KiaiMode = true }); + + Beatmap.Value = CreateWorkingBeatmap(new Beatmap + { + ControlPointInfo = controlPointInfo + }); + + Beatmap.Value.Track.Start(); + } } } diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHitKiai.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHitKiai.cs deleted file mode 100644 index fac0530749..0000000000 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHitKiai.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using NUnit.Framework; -using osu.Game.Beatmaps; -using osu.Game.Beatmaps.ControlPoints; - -namespace osu.Game.Rulesets.Taiko.Tests.Skinning -{ - [TestFixture] - public class TestSceneDrawableHitKiai : TestSceneDrawableHit - { - [SetUp] - public void SetUp() => Schedule(() => - { - var controlPointInfo = new ControlPointInfo(); - - controlPointInfo.Add(0, new TimingControlPoint { BeatLength = 500 }); - controlPointInfo.Add(0, new EffectControlPoint { KiaiMode = true }); - - Beatmap.Value = CreateWorkingBeatmap(new Beatmap - { - ControlPointInfo = controlPointInfo - }); - - // track needs to be playing for BeatSyncedContainer to work. - Beatmap.Value.Track.Start(); - }); - } -} From 39934bccd6f78d7d328b1b7b9901147304a9c08b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 22 Nov 2022 19:47:41 +0100 Subject: [PATCH 0732/2991] Add back removed test coverage --- .../UserInterface/TestSceneHistoryTextBox.cs | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs index 78b1bdb18c..8ed5dd43cc 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs @@ -62,6 +62,68 @@ namespace osu.Game.Tests.Visual.UserInterface }); } + [Test] + public void TestEmptyHistory() + { + AddStep("Set text", () => box.Text = temp); + + AddStep("Move down", () => InputManager.Key(Key.Down)); + AddAssert("Text is unchanged", () => box.Text == temp); + + AddStep("Move up", () => InputManager.Key(Key.Up)); + AddAssert("Text is unchanged", () => box.Text == temp); + } + + [Test] + public void TestPartialHistory() + { + addMessages(3); + AddStep("Set text", () => box.Text = temp); + + AddStep("Move down", () => InputManager.Key(Key.Down)); + AddAssert("Text is unchanged", () => box.Text == temp); + + AddRepeatStep("Move up", () => InputManager.Key(Key.Up), 3); + AddAssert("Same as 1st message", () => box.Text == "Message 1"); + + AddStep("Move up", () => InputManager.Key(Key.Up)); + AddAssert("Same as 1st message", () => box.Text == "Message 1"); + + AddStep("Move down", () => InputManager.Key(Key.Down)); + AddAssert("Same as 2nd message", () => box.Text == "Message 2"); + + AddRepeatStep("Move down", () => InputManager.Key(Key.Down), 2); + AddAssert("Temporary message restored", () => box.Text == temp); + + AddStep("Move down", () => InputManager.Key(Key.Down)); + AddAssert("Text is unchanged", () => box.Text == temp); + } + + [Test] + public void TestFullHistory() + { + addMessages(7); + AddStep("Set text", () => box.Text = temp); + + AddStep("Move down", () => InputManager.Key(Key.Down)); + AddAssert("Text is unchanged", () => box.Text == temp); + + AddRepeatStep("Move up", () => InputManager.Key(Key.Up), 5); + AddAssert("Same as 3rd message", () => box.Text == "Message 3"); + + AddStep("Move up", () => InputManager.Key(Key.Up)); + AddAssert("Same as 3rd message", () => box.Text == "Message 3"); + + AddRepeatStep("Move down", () => InputManager.Key(Key.Down), 4); + AddAssert("Same as 7th message", () => box.Text == "Message 7"); + + AddStep("Move down", () => InputManager.Key(Key.Down)); + AddAssert("Temporary message restored", () => box.Text == temp); + + AddStep("Move down", () => InputManager.Key(Key.Down)); + AddAssert("Text is unchanged", () => box.Text == temp); + } + [Test] public void TestChangedHistory() { From 8dbc38e17a83e3737c17b0faa72dc047a5fd95f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 22 Nov 2022 20:14:22 +0100 Subject: [PATCH 0733/2991] Remove unused setter --- osu.Game/Utils/LimitedCapacityQueue.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/osu.Game/Utils/LimitedCapacityQueue.cs b/osu.Game/Utils/LimitedCapacityQueue.cs index 8f3b36a059..86a106a678 100644 --- a/osu.Game/Utils/LimitedCapacityQueue.cs +++ b/osu.Game/Utils/LimitedCapacityQueue.cs @@ -103,13 +103,6 @@ namespace osu.Game.Utils return array[(start + index) % capacity]; } - set - { - if (index < 0 || index >= Count) - throw new ArgumentOutOfRangeException(nameof(index)); - - array[(start + index) % capacity] = value; - } } /// From 5a5b0ed4ef67ded0211486baf887ac251645b931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 22 Nov 2022 20:28:41 +0100 Subject: [PATCH 0734/2991] Restructure tests not to call each other Bit weird to have tests call other tests. Private helper methods is better, if unavoidable. --- .../Skinning/TestSceneDrawableDrumRoll.cs | 18 ++--- .../Skinning/TestSceneDrawableHit.cs | 68 +++++++++---------- 2 files changed, 40 insertions(+), 46 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRoll.cs index 7a3439d8eb..25cb3f7886 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRoll.cs @@ -26,8 +26,10 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning }; [Test] - public void TestDrumroll() + public void TestDrumroll([Values] bool withKiai) { + AddStep("set up beatmap", () => setUpBeatmap(withKiai)); + AddStep("Drum roll", () => SetContents(_ => { var hoc = new ScrollingHitObjectContainer(); @@ -57,14 +59,6 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning })); } - [Test] - public void TestDrumrollKiai() - { - AddStep("Create beatmap", createBeatmap); - - TestDrumroll(); - } - private DrumRoll createDrumRollAtCurrentTime(bool strong = false) { var drumroll = new DrumRoll @@ -82,12 +76,14 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning return drumroll; } - private void createBeatmap() + private void setUpBeatmap(bool withKiai) { var controlPointInfo = new ControlPointInfo(); controlPointInfo.Add(0, new TimingControlPoint { BeatLength = 500 }); - controlPointInfo.Add(0, new EffectControlPoint { KiaiMode = true }); + + if (withKiai) + controlPointInfo.Add(0, new EffectControlPoint { KiaiMode = true }); Beatmap.Value = CreateWorkingBeatmap(new Beatmap { diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs index 3902a3123b..b13255b31c 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs @@ -22,7 +22,37 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning private GameplayState gameplayState = TestGameplayState.Create(new TaikoRuleset()); [Test] - public void TestHits() + public void TestHits([Values] bool withKiai) + { + AddStep("Create beatmap", () => setUpBeatmap(withKiai)); + addHitSteps(); + } + + [Test] + public void TestHitAnimationSlow() + { + AddStep("Create beatmap", () => setUpBeatmap(false)); + + AddStep("Reset combo", () => gameplayState.ScoreProcessor.Combo.Value = 0); + + AddRepeatStep("Increase combo", () => gameplayState.ScoreProcessor.Combo.Value++, 50); + + addHitSteps(); + } + + [Test] + public void TestHitAnimationFast() + { + AddStep("Create beatmap", () => setUpBeatmap(false)); + + AddStep("Reset combo", () => gameplayState.ScoreProcessor.Combo.Value = 0); + + AddRepeatStep("Increase combo", () => gameplayState.ScoreProcessor.Combo.Value++, 150); + + addHitSteps(); + } + + private void addHitSteps() { AddStep("Centre hit", () => SetContents(_ => new DrawableHit(createHitAtCurrentTime()) { @@ -49,38 +79,6 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning })); } - [Test] - public void TestHitKiai() - { - AddStep("Create beatmap", () => createBeatmap(true)); - - TestHits(); - } - - [Test] - public void TestHitAnimationSlow() - { - AddStep("Create beatmap", () => createBeatmap(false)); - - AddStep("Reset combo", () => gameplayState.ScoreProcessor.Combo.Value = 0); - - AddRepeatStep("Increase combo", () => gameplayState.ScoreProcessor.Combo.Value++, 50); - - TestHits(); - } - - [Test] - public void TestHitAnimationFast() - { - AddStep("Create beatmap", () => createBeatmap(false)); - - AddStep("Reset combo", () => gameplayState.ScoreProcessor.Combo.Value = 0); - - AddRepeatStep("Increase combo", () => gameplayState.ScoreProcessor.Combo.Value++, 150); - - TestHits(); - } - private Hit createHitAtCurrentTime(bool strong = false, bool rim = false) { var hit = new Hit @@ -95,13 +93,13 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning return hit; } - private void createBeatmap(bool includeKiai) + private void setUpBeatmap(bool withKiai) { var controlPointInfo = new ControlPointInfo(); controlPointInfo.Add(0, new TimingControlPoint { BeatLength = 500 }); - if (includeKiai) + if (withKiai) controlPointInfo.Add(0, new EffectControlPoint { KiaiMode = true }); Beatmap.Value = CreateWorkingBeatmap(new Beatmap From 8ac0a759f01b92c665d6108fc1271e5f70590475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 22 Nov 2022 20:30:27 +0100 Subject: [PATCH 0735/2991] Set combo immediately rather than via repeat steps Doesn't help anyone to be waiting literal minutes for combo to hit 50 or 150 in a test scene supposed to quickly visually demonstrate a component. Doesn't help for CI runtime, either. --- .../Skinning/TestSceneDrawableHit.cs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs index b13255b31c..65a59be89b 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs @@ -33,10 +33,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning { AddStep("Create beatmap", () => setUpBeatmap(false)); - AddStep("Reset combo", () => gameplayState.ScoreProcessor.Combo.Value = 0); - - AddRepeatStep("Increase combo", () => gameplayState.ScoreProcessor.Combo.Value++, 50); - + AddStep("Set 50 combo", () => gameplayState.ScoreProcessor.Combo.Value = 50); addHitSteps(); } @@ -45,10 +42,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning { AddStep("Create beatmap", () => setUpBeatmap(false)); - AddStep("Reset combo", () => gameplayState.ScoreProcessor.Combo.Value = 0); - - AddRepeatStep("Increase combo", () => gameplayState.ScoreProcessor.Combo.Value++, 150); - + AddStep("Set 150 combo", () => gameplayState.ScoreProcessor.Combo.Value = 150); addHitSteps(); } From 38f2a27f537e12d9deef306e327715983afecb33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 22 Nov 2022 20:34:43 +0100 Subject: [PATCH 0736/2991] Split animation logic to its own method Also add a guard, to bypass all of it if the foreground layer is not in fact animatable. --- .../Skinning/Legacy/LegacyCirclePiece.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs index 2a260b8cb3..c8dc29f444 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs @@ -26,7 +26,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy private Bindable currentCombo { get; } = new BindableInt(); private int animationFrame; - private int multiplier; private double beatLength; // required for editor blueprints (not sure why these circle pieces are zero size). @@ -94,6 +93,14 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy foreach (var c in InternalChildren) c.Scale = new Vector2(DrawHeight / 128); + if (foregroundLayer is IFramedAnimation animatableForegroundLayer) + animateForegroundLayer(animatableForegroundLayer); + } + + private void animateForegroundLayer(IFramedAnimation animatableForegroundLayer) + { + int multiplier; + if (currentCombo.Value >= 150) { multiplier = 2; @@ -104,7 +111,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy } else { - (foregroundLayer as IFramedAnimation)?.GotoFrame(0); + animatableForegroundLayer.GotoFrame(0); return; } @@ -114,7 +121,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy animationFrame = Time.Current % ((beatLength * 2) / multiplier) >= beatLength / multiplier ? 0 : 1; - (foregroundLayer as IFramedAnimation)?.GotoFrame(animationFrame); + animatableForegroundLayer.GotoFrame(animationFrame); } } From ce7af0df637b3098c8e5eca1d9d137bc5fe2ed94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 22 Nov 2022 20:39:22 +0100 Subject: [PATCH 0737/2991] Always use current timing point for circle piece animation Using `LifetimeStart` seemed arbitrary and wrong not only in a compatibility-with-stable sense, but also in a general sanity sense (why would each object potentially be using a different timing point to animate?) --- osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs index c8dc29f444..03d89d269b 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs @@ -117,7 +117,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy if (beatSyncProvider?.ControlPoints != null) { - beatLength = beatSyncProvider.ControlPoints.TimingPointAt(LifetimeStart).BeatLength; + beatLength = beatSyncProvider.ControlPoints.TimingPointAt(Time.Current).BeatLength; animationFrame = Time.Current % ((beatLength * 2) / multiplier) >= beatLength / multiplier ? 0 : 1; From 675e32df5761cd81c7365aa7aaac7116bcd6da9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 22 Nov 2022 20:43:22 +0100 Subject: [PATCH 0738/2991] Add test steps for testing combo reset to 0 --- osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs index 65a59be89b..adfd27c5d6 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs @@ -35,6 +35,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning AddStep("Set 50 combo", () => gameplayState.ScoreProcessor.Combo.Value = 50); addHitSteps(); + AddStep("Reset combo", () => gameplayState.ScoreProcessor.Combo.Value = 0); } [Test] @@ -44,6 +45,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning AddStep("Set 150 combo", () => gameplayState.ScoreProcessor.Combo.Value = 150); addHitSteps(); + AddStep("Reset combo", () => gameplayState.ScoreProcessor.Combo.Value = 0); } private void addHitSteps() From 6e9d163c7240eba2964e4043229fa5f7bdcacf0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 22 Nov 2022 20:56:07 +0100 Subject: [PATCH 0739/2991] Specify `canBeNull: true` in `[Resolved]` for now --- osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs index 03d89d269b..a5867ff51c 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs @@ -36,10 +36,10 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy RelativeSizeAxes = Axes.Both; } - [Resolved] + [Resolved(canBeNull: true)] private GameplayState? gameplayState { get; set; } - [Resolved] + [Resolved(canBeNull: true)] private IBeatSyncProvider? beatSyncProvider { get; set; } [BackgroundDependencyLoader] From d146f86511ac3b34e995c586ad6889cc2c2ef194 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Nov 2022 15:39:56 +0900 Subject: [PATCH 0740/2991] Fix crash when hitting 'T' to tap timing while no timing point is selected --- osu.Game/Screens/Edit/Timing/TapButton.cs | 3 +++ osu.Game/Screens/Edit/Timing/TapTimingControl.cs | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/osu.Game/Screens/Edit/Timing/TapButton.cs b/osu.Game/Screens/Edit/Timing/TapButton.cs index 151c3cea2e..2944eea4fe 100644 --- a/osu.Game/Screens/Edit/Timing/TapButton.cs +++ b/osu.Game/Screens/Edit/Timing/TapButton.cs @@ -295,6 +295,9 @@ namespace osu.Game.Screens.Edit.Timing private void handleTap() { + if (selectedGroup?.Value == null) + return; + tapTimings.Add(Clock.CurrentTime); if (tapTimings.Count > initial_taps_to_ignore + max_taps_to_consider) diff --git a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs index abc73851e4..daa3168746 100644 --- a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs +++ b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs @@ -183,12 +183,18 @@ namespace osu.Game.Screens.Edit.Timing private void start() { + if (selectedGroup.Value == null) + return; + editorClock.Seek(selectedGroup.Value.Time); editorClock.Start(); } private void reset() { + if (selectedGroup.Value == null) + return; + editorClock.Stop(); editorClock.Seek(selectedGroup.Value.Time); } From 9b9b8a597773e9a4dfab256422c268056ad6878d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Nov 2022 15:59:31 +0900 Subject: [PATCH 0741/2991] Add ability to seek between control points in editor using down/up arrows Matches stable. Addresses #21376. --- .../Visual/Editing/TestSceneEditorSeeking.cs | 21 +++++++++++++++++++ osu.Game/Screens/Edit/Editor.cs | 18 ++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorSeeking.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorSeeking.cs index 924396ce03..14679ae01d 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorSeeking.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorSeeking.cs @@ -25,6 +25,7 @@ namespace osu.Game.Tests.Visual.Editing beatmap.ControlPointInfo.Clear(); beatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 }); beatmap.ControlPointInfo.Add(2000, new TimingControlPoint { BeatLength = 500 }); + beatmap.ControlPointInfo.Add(20000, new TimingControlPoint { BeatLength = 500 }); return beatmap; } @@ -116,6 +117,26 @@ namespace osu.Game.Tests.Visual.Editing pressAndCheckTime(Key.Right, 3000); } + [Test] + public void TestSeekBetweenControlPoints() + { + AddStep("seek to 0", () => EditorClock.Seek(0)); + AddAssert("time is 0", () => EditorClock.CurrentTime == 0); + + // already at first control point, noop + pressAndCheckTime(Key.Down, 0); + + pressAndCheckTime(Key.Up, 2000); + + pressAndCheckTime(Key.Up, 20000); + // at last control point, noop + pressAndCheckTime(Key.Up, 20000); + + pressAndCheckTime(Key.Down, 2000); + pressAndCheckTime(Key.Down, 0); + pressAndCheckTime(Key.Down, 0); + } + private void pressAndCheckTime(Key key, double expectedTime) { AddStep($"press {key}", () => InputManager.Key(key)); diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 4c44117581..7c0e021ff9 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -499,6 +499,14 @@ namespace osu.Game.Screens.Edit seek(e, 1); return true; + case Key.Down: + seekControlPoint(-1); + return true; + + case Key.Up: + seekControlPoint(1); + return true; + // Track traversal keys. // Matching osu-stable implementations. case Key.Z: @@ -892,6 +900,16 @@ namespace osu.Game.Screens.Edit } } + private void seekControlPoint(int direction) + { + var found = direction < 1 + ? editorBeatmap.ControlPointInfo.AllControlPoints.LastOrDefault(p => p.Time < clock.CurrentTime) + : editorBeatmap.ControlPointInfo.AllControlPoints.FirstOrDefault(p => p.Time > clock.CurrentTime); + + if (found != null) + clock.Seek(found.Time); + } + private void seek(UIEvent e, int direction) { double amount = e.ShiftPressed ? 4 : 1; From b89689a34a4dd719c18b73b29180463170f5a7e3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Nov 2022 16:31:50 +0900 Subject: [PATCH 0742/2991] Rename class and reword settings text/tooltips to avoid clashing with other naming --- ...nfoDrawable.cs => BeatmapAttributeText.cs} | 83 +++++++++---------- osu.Game/Skinning/Components/TextElement.cs | 2 +- 2 files changed, 42 insertions(+), 43 deletions(-) rename osu.Game/Skinning/Components/{BeatmapInfoDrawable.cs => BeatmapAttributeText.cs} (57%) diff --git a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs b/osu.Game/Skinning/Components/BeatmapAttributeText.cs similarity index 57% rename from osu.Game/Skinning/Components/BeatmapInfoDrawable.cs rename to osu.Game/Skinning/Components/BeatmapAttributeText.cs index 379bdec333..6520130e75 100644 --- a/osu.Game/Skinning/Components/BeatmapInfoDrawable.cs +++ b/osu.Game/Skinning/Components/BeatmapAttributeText.cs @@ -22,47 +22,46 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Skinning.Components { [UsedImplicitly] - public class BeatmapInfoDrawable : Container, ISkinnableDrawable + public class BeatmapAttributeText : Container, ISkinnableDrawable { - private const BeatmapInfo default_beatmap_info = BeatmapInfo.StarRating; public bool UsesFixedAnchor { get; set; } - [SettingSource("Tracked Beatmap Info/Label", "Which part of the BeatmapInformation should be displayed.")] - public Bindable Type { get; } = new Bindable(default_beatmap_info); + [SettingSource("Attribute", "The attribute to be displayed.")] + public Bindable Attribute { get; } = new Bindable(BeatmapAttribute.StarRating); - [SettingSource("Template", "Bypass the restriction of 1 Info per element. Format is '{'+Type+'}' to substitue values. e.g. '{Song}' ")] + [SettingSource("Template", "Supports {Label} and {Value}, but also including arbitrary attributes like {StarRating} (see attribute list for supported values).")] public Bindable Template { get; set; } = new Bindable("{Label}: {Value}"); [Resolved] private IBindable beatmap { get; set; } = null!; - private readonly Dictionary valueDictionary = new Dictionary(); - private static readonly ImmutableDictionary label_dictionary; + private readonly Dictionary valueDictionary = new Dictionary(); + private static readonly ImmutableDictionary label_dictionary; private readonly OsuSpriteText text; - static BeatmapInfoDrawable() + static BeatmapAttributeText() { - label_dictionary = new Dictionary + label_dictionary = new Dictionary { - [BeatmapInfo.CircleSize] = BeatmapsetsStrings.ShowStatsCs, - [BeatmapInfo.Accuracy] = BeatmapsetsStrings.ShowStatsAccuracy, - [BeatmapInfo.HPDrain] = BeatmapsetsStrings.ShowStatsDrain, - [BeatmapInfo.ApproachRate] = BeatmapsetsStrings.ShowStatsAr, - [BeatmapInfo.StarRating] = BeatmapsetsStrings.ShowStatsStars, - [BeatmapInfo.Song] = EditorSetupStrings.Title, - [BeatmapInfo.Artist] = EditorSetupStrings.Artist, - [BeatmapInfo.Difficulty] = EditorSetupStrings.DifficultyHeader, + [BeatmapAttribute.CircleSize] = BeatmapsetsStrings.ShowStatsCs, + [BeatmapAttribute.Accuracy] = BeatmapsetsStrings.ShowStatsAccuracy, + [BeatmapAttribute.HPDrain] = BeatmapsetsStrings.ShowStatsDrain, + [BeatmapAttribute.ApproachRate] = BeatmapsetsStrings.ShowStatsAr, + [BeatmapAttribute.StarRating] = BeatmapsetsStrings.ShowStatsStars, + [BeatmapAttribute.Song] = EditorSetupStrings.Title, + [BeatmapAttribute.Artist] = EditorSetupStrings.Artist, + [BeatmapAttribute.Difficulty] = EditorSetupStrings.DifficultyHeader, //todo: is there a good alternative, to NotificationsOptionsMapping? - [BeatmapInfo.Mapper] = AccountsStrings.NotificationsOptionsMapping, - [BeatmapInfo.Length] = ArtistStrings.TracklistLength, - [BeatmapInfo.Status] = BeatmapDiscussionsStrings.IndexFormBeatmapsetStatusDefault, - [BeatmapInfo.BPM] = BeatmapsetsStrings.ShowStatsBpm, - [BeatmapInfo.None] = BeatmapInfo.None.ToString() + [BeatmapAttribute.Mapper] = AccountsStrings.NotificationsOptionsMapping, + [BeatmapAttribute.Length] = ArtistStrings.TracklistLength, + [BeatmapAttribute.Status] = BeatmapDiscussionsStrings.IndexFormBeatmapsetStatusDefault, + [BeatmapAttribute.BPM] = BeatmapsetsStrings.ShowStatsBpm, + [BeatmapAttribute.None] = BeatmapAttribute.None.ToString() }.ToImmutableDictionary(); } - public BeatmapInfoDrawable() + public BeatmapAttributeText() { AutoSizeAxes = Axes.Both; InternalChildren = new Drawable[] @@ -76,7 +75,7 @@ namespace osu.Game.Skinning.Components } }; - foreach (var type in Enum.GetValues(typeof(BeatmapInfo)).Cast()) + foreach (var type in Enum.GetValues(typeof(BeatmapAttribute)).Cast()) { valueDictionary[type] = type.ToString(); } @@ -85,7 +84,7 @@ namespace osu.Game.Skinning.Components protected override void LoadComplete() { base.LoadComplete(); - Type.BindValueChanged(_ => updateLabel()); + Attribute.BindValueChanged(_ => updateLabel()); Template.BindValueChanged(f => updateLabel(), true); beatmap.BindValueChanged(b => { @@ -96,10 +95,10 @@ namespace osu.Game.Skinning.Components private void updateLabel() { - string newText = Template.Value.Replace("{Label}", label_dictionary[Type.Value].ToString()) - .Replace("{Value}", valueDictionary[Type.Value].ToString()); + string newText = Template.Value.Replace("{Label}", label_dictionary[Attribute.Value].ToString()) + .Replace("{Value}", valueDictionary[Attribute.Value].ToString()); - foreach (var type in Enum.GetValues(typeof(BeatmapInfo)).Cast()) + foreach (var type in Enum.GetValues(typeof(BeatmapAttribute)).Cast()) { newText = newText.Replace("{" + type + "}", valueDictionary[type].ToString()); } @@ -111,34 +110,34 @@ namespace osu.Game.Skinning.Components { //update cs double cs = workingBeatmap.BeatmapInfo.Difficulty.CircleSize; - valueDictionary[BeatmapInfo.CircleSize] = cs.ToString("F2"); + valueDictionary[BeatmapAttribute.CircleSize] = cs.ToString("F2"); //update HP double hp = workingBeatmap.BeatmapInfo.Difficulty.DrainRate; - valueDictionary[BeatmapInfo.HPDrain] = hp.ToString("F2"); + valueDictionary[BeatmapAttribute.HPDrain] = hp.ToString("F2"); //update od double od = workingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty; - valueDictionary[BeatmapInfo.Accuracy] = od.ToString("F2"); + valueDictionary[BeatmapAttribute.Accuracy] = od.ToString("F2"); //update ar double ar = workingBeatmap.BeatmapInfo.Difficulty.ApproachRate; - valueDictionary[BeatmapInfo.ApproachRate] = ar.ToString("F2"); + valueDictionary[BeatmapAttribute.ApproachRate] = ar.ToString("F2"); //update sr double sr = workingBeatmap.BeatmapInfo.StarRating; - valueDictionary[BeatmapInfo.StarRating] = sr.ToString("F2"); + valueDictionary[BeatmapAttribute.StarRating] = sr.ToString("F2"); //update song title - valueDictionary[BeatmapInfo.Song] = workingBeatmap.BeatmapInfo.Metadata.Title; + valueDictionary[BeatmapAttribute.Song] = workingBeatmap.BeatmapInfo.Metadata.Title; //update artist - valueDictionary[BeatmapInfo.Artist] = workingBeatmap.BeatmapInfo.Metadata.Artist; + valueDictionary[BeatmapAttribute.Artist] = workingBeatmap.BeatmapInfo.Metadata.Artist; //update difficulty name - valueDictionary[BeatmapInfo.Difficulty] = workingBeatmap.BeatmapInfo.DifficultyName; + valueDictionary[BeatmapAttribute.Difficulty] = workingBeatmap.BeatmapInfo.DifficultyName; //update mapper - valueDictionary[BeatmapInfo.Mapper] = workingBeatmap.BeatmapInfo.Metadata.Author.Username; + valueDictionary[BeatmapAttribute.Mapper] = workingBeatmap.BeatmapInfo.Metadata.Author.Username; //update Length - valueDictionary[BeatmapInfo.Length] = TimeSpan.FromMilliseconds(workingBeatmap.BeatmapInfo.Length).ToFormattedDuration(); + valueDictionary[BeatmapAttribute.Length] = TimeSpan.FromMilliseconds(workingBeatmap.BeatmapInfo.Length).ToFormattedDuration(); //update Status - valueDictionary[BeatmapInfo.Status] = GetBetmapStatus(workingBeatmap.BeatmapInfo.Status); + valueDictionary[BeatmapAttribute.Status] = GetBetmapStatus(workingBeatmap.BeatmapInfo.Status); //update BPM - valueDictionary[BeatmapInfo.BPM] = workingBeatmap.BeatmapInfo.BPM.ToString("F2"); - valueDictionary[BeatmapInfo.None] = string.Empty; + valueDictionary[BeatmapAttribute.BPM] = workingBeatmap.BeatmapInfo.BPM.ToString("F2"); + valueDictionary[BeatmapAttribute.None] = string.Empty; } public static LocalisableString GetBetmapStatus(BeatmapOnlineStatus status) @@ -178,7 +177,7 @@ namespace osu.Game.Skinning.Components } } - public enum BeatmapInfo + public enum BeatmapAttribute { CircleSize, HPDrain, diff --git a/osu.Game/Skinning/Components/TextElement.cs b/osu.Game/Skinning/Components/TextElement.cs index da09aa76b2..1e618a7f82 100644 --- a/osu.Game/Skinning/Components/TextElement.cs +++ b/osu.Game/Skinning/Components/TextElement.cs @@ -16,7 +16,7 @@ namespace osu.Game.Skinning.Components { public bool UsesFixedAnchor { get; set; } - [SettingSource("Displayed Text", "What text should be displayed")] + [SettingSource("Text", "The text to be displayed.")] public Bindable Text { get; } = new Bindable("Circles!"); public TextElement() From 27473262af2757a9142922c46221700c585fc6b5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Nov 2022 16:39:13 +0900 Subject: [PATCH 0743/2991] Rename attributes in enum to match better with user expectations --- .../Components/BeatmapAttributeText.cs | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/osu.Game/Skinning/Components/BeatmapAttributeText.cs b/osu.Game/Skinning/Components/BeatmapAttributeText.cs index 6520130e75..a3b0ed7168 100644 --- a/osu.Game/Skinning/Components/BeatmapAttributeText.cs +++ b/osu.Game/Skinning/Components/BeatmapAttributeText.cs @@ -8,6 +8,8 @@ using System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions; +using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Localisation; @@ -18,6 +20,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Localisation; using osu.Game.Resources.Localisation.Web; +using osu.Game.Screens.Select.Filter; namespace osu.Game.Skinning.Components { @@ -36,6 +39,7 @@ namespace osu.Game.Skinning.Components private IBindable beatmap { get; set; } = null!; private readonly Dictionary valueDictionary = new Dictionary(); + private static readonly ImmutableDictionary label_dictionary; private readonly OsuSpriteText text; @@ -49,15 +53,13 @@ namespace osu.Game.Skinning.Components [BeatmapAttribute.HPDrain] = BeatmapsetsStrings.ShowStatsDrain, [BeatmapAttribute.ApproachRate] = BeatmapsetsStrings.ShowStatsAr, [BeatmapAttribute.StarRating] = BeatmapsetsStrings.ShowStatsStars, - [BeatmapAttribute.Song] = EditorSetupStrings.Title, + [BeatmapAttribute.Title] = EditorSetupStrings.Title, [BeatmapAttribute.Artist] = EditorSetupStrings.Artist, - [BeatmapAttribute.Difficulty] = EditorSetupStrings.DifficultyHeader, - //todo: is there a good alternative, to NotificationsOptionsMapping? - [BeatmapAttribute.Mapper] = AccountsStrings.NotificationsOptionsMapping, - [BeatmapAttribute.Length] = ArtistStrings.TracklistLength, - [BeatmapAttribute.Status] = BeatmapDiscussionsStrings.IndexFormBeatmapsetStatusDefault, + [BeatmapAttribute.DifficultyName] = EditorSetupStrings.DifficultyHeader, + [BeatmapAttribute.Creator] = EditorSetupStrings.Creator, + [BeatmapAttribute.Length] = ArtistStrings.TracklistLength.ToTitle(), + [BeatmapAttribute.RankedStatus] = BeatmapDiscussionsStrings.IndexFormBeatmapsetStatusDefault, [BeatmapAttribute.BPM] = BeatmapsetsStrings.ShowStatsBpm, - [BeatmapAttribute.None] = BeatmapAttribute.None.ToString() }.ToImmutableDictionary(); } @@ -124,20 +126,19 @@ namespace osu.Game.Skinning.Components double sr = workingBeatmap.BeatmapInfo.StarRating; valueDictionary[BeatmapAttribute.StarRating] = sr.ToString("F2"); //update song title - valueDictionary[BeatmapAttribute.Song] = workingBeatmap.BeatmapInfo.Metadata.Title; + valueDictionary[BeatmapAttribute.Title] = workingBeatmap.BeatmapInfo.Metadata.Title; //update artist valueDictionary[BeatmapAttribute.Artist] = workingBeatmap.BeatmapInfo.Metadata.Artist; //update difficulty name - valueDictionary[BeatmapAttribute.Difficulty] = workingBeatmap.BeatmapInfo.DifficultyName; + valueDictionary[BeatmapAttribute.DifficultyName] = workingBeatmap.BeatmapInfo.DifficultyName; //update mapper - valueDictionary[BeatmapAttribute.Mapper] = workingBeatmap.BeatmapInfo.Metadata.Author.Username; + valueDictionary[BeatmapAttribute.Creator] = workingBeatmap.BeatmapInfo.Metadata.Author.Username; //update Length valueDictionary[BeatmapAttribute.Length] = TimeSpan.FromMilliseconds(workingBeatmap.BeatmapInfo.Length).ToFormattedDuration(); //update Status - valueDictionary[BeatmapAttribute.Status] = GetBetmapStatus(workingBeatmap.BeatmapInfo.Status); + valueDictionary[BeatmapAttribute.RankedStatus] = GetBetmapStatus(workingBeatmap.BeatmapInfo.Status); //update BPM valueDictionary[BeatmapAttribute.BPM] = workingBeatmap.BeatmapInfo.BPM.ToString("F2"); - valueDictionary[BeatmapAttribute.None] = string.Empty; } public static LocalisableString GetBetmapStatus(BeatmapOnlineStatus status) @@ -184,13 +185,12 @@ namespace osu.Game.Skinning.Components Accuracy, ApproachRate, StarRating, - Song, + Title, Artist, - Difficulty, - Mapper, + DifficultyName, + Creator, Length, - Status, + RankedStatus, BPM, - None, } } From a8af83e62a0709d32f30215f044443f2fe07fc67 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Nov 2022 16:49:39 +0900 Subject: [PATCH 0744/2991] Move label initialisation out of ctor --- .../Components/BeatmapAttributeText.cs | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/osu.Game/Skinning/Components/BeatmapAttributeText.cs b/osu.Game/Skinning/Components/BeatmapAttributeText.cs index a3b0ed7168..1d6661d26e 100644 --- a/osu.Game/Skinning/Components/BeatmapAttributeText.cs +++ b/osu.Game/Skinning/Components/BeatmapAttributeText.cs @@ -20,7 +20,6 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Localisation; using osu.Game.Resources.Localisation.Web; -using osu.Game.Screens.Select.Filter; namespace osu.Game.Skinning.Components { @@ -40,29 +39,24 @@ namespace osu.Game.Skinning.Components private readonly Dictionary valueDictionary = new Dictionary(); - private static readonly ImmutableDictionary label_dictionary; + private static readonly ImmutableDictionary label_dictionary = new Dictionary + { + [BeatmapAttribute.CircleSize] = BeatmapsetsStrings.ShowStatsCs, + [BeatmapAttribute.Accuracy] = BeatmapsetsStrings.ShowStatsAccuracy, + [BeatmapAttribute.HPDrain] = BeatmapsetsStrings.ShowStatsDrain, + [BeatmapAttribute.ApproachRate] = BeatmapsetsStrings.ShowStatsAr, + [BeatmapAttribute.StarRating] = BeatmapsetsStrings.ShowStatsStars, + [BeatmapAttribute.Title] = EditorSetupStrings.Title, + [BeatmapAttribute.Artist] = EditorSetupStrings.Artist, + [BeatmapAttribute.DifficultyName] = EditorSetupStrings.DifficultyHeader, + [BeatmapAttribute.Creator] = EditorSetupStrings.Creator, + [BeatmapAttribute.Length] = ArtistStrings.TracklistLength.ToTitle(), + [BeatmapAttribute.RankedStatus] = BeatmapDiscussionsStrings.IndexFormBeatmapsetStatusDefault, + [BeatmapAttribute.BPM] = BeatmapsetsStrings.ShowStatsBpm, + }.ToImmutableDictionary(); private readonly OsuSpriteText text; - static BeatmapAttributeText() - { - label_dictionary = new Dictionary - { - [BeatmapAttribute.CircleSize] = BeatmapsetsStrings.ShowStatsCs, - [BeatmapAttribute.Accuracy] = BeatmapsetsStrings.ShowStatsAccuracy, - [BeatmapAttribute.HPDrain] = BeatmapsetsStrings.ShowStatsDrain, - [BeatmapAttribute.ApproachRate] = BeatmapsetsStrings.ShowStatsAr, - [BeatmapAttribute.StarRating] = BeatmapsetsStrings.ShowStatsStars, - [BeatmapAttribute.Title] = EditorSetupStrings.Title, - [BeatmapAttribute.Artist] = EditorSetupStrings.Artist, - [BeatmapAttribute.DifficultyName] = EditorSetupStrings.DifficultyHeader, - [BeatmapAttribute.Creator] = EditorSetupStrings.Creator, - [BeatmapAttribute.Length] = ArtistStrings.TracklistLength.ToTitle(), - [BeatmapAttribute.RankedStatus] = BeatmapDiscussionsStrings.IndexFormBeatmapsetStatusDefault, - [BeatmapAttribute.BPM] = BeatmapsetsStrings.ShowStatsBpm, - }.ToImmutableDictionary(); - } - public BeatmapAttributeText() { AutoSizeAxes = Axes.Both; From 0f034606fd68b4106bd0deeaae75b962fb617489 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Nov 2022 16:49:51 +0900 Subject: [PATCH 0745/2991] Use `LocalisableDescription` from `BeatmapOnlineStatus` enum instead of locally defined --- .../Components/BeatmapAttributeText.cs | 38 +------------------ 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/osu.Game/Skinning/Components/BeatmapAttributeText.cs b/osu.Game/Skinning/Components/BeatmapAttributeText.cs index 1d6661d26e..5cb78864f7 100644 --- a/osu.Game/Skinning/Components/BeatmapAttributeText.cs +++ b/osu.Game/Skinning/Components/BeatmapAttributeText.cs @@ -130,46 +130,10 @@ namespace osu.Game.Skinning.Components //update Length valueDictionary[BeatmapAttribute.Length] = TimeSpan.FromMilliseconds(workingBeatmap.BeatmapInfo.Length).ToFormattedDuration(); //update Status - valueDictionary[BeatmapAttribute.RankedStatus] = GetBetmapStatus(workingBeatmap.BeatmapInfo.Status); + valueDictionary[BeatmapAttribute.RankedStatus] = workingBeatmap.BeatmapInfo.Status.GetLocalisableDescription(); //update BPM valueDictionary[BeatmapAttribute.BPM] = workingBeatmap.BeatmapInfo.BPM.ToString("F2"); } - - public static LocalisableString GetBetmapStatus(BeatmapOnlineStatus status) - { - switch (status) - { - case BeatmapOnlineStatus.Approved: - return BeatmapsetsStrings.ShowStatusApproved; - - case BeatmapOnlineStatus.Graveyard: - return BeatmapsetsStrings.ShowStatusGraveyard; - - case BeatmapOnlineStatus.Loved: - return BeatmapsetsStrings.ShowStatusLoved; - - case BeatmapOnlineStatus.None: - return "None"; - - case BeatmapOnlineStatus.Pending: - return BeatmapsetsStrings.ShowStatusPending; - - case BeatmapOnlineStatus.Qualified: - return BeatmapsetsStrings.ShowStatusQualified; - - case BeatmapOnlineStatus.Ranked: - return BeatmapsetsStrings.ShowStatusRanked; - - case BeatmapOnlineStatus.LocallyModified: - return SongSelectStrings.LocallyModified; - - case BeatmapOnlineStatus.WIP: - return BeatmapsetsStrings.ShowStatusWip; - - default: - return @"null"; - } - } } public enum BeatmapAttribute From 0749a7bb0777691b35f438311ce1e7c3acf3a973 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Nov 2022 16:53:36 +0900 Subject: [PATCH 0746/2991] Simplify attribute assignment --- .../Components/BeatmapAttributeText.cs | 29 ++++--------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/osu.Game/Skinning/Components/BeatmapAttributeText.cs b/osu.Game/Skinning/Components/BeatmapAttributeText.cs index 5cb78864f7..498ea1d268 100644 --- a/osu.Game/Skinning/Components/BeatmapAttributeText.cs +++ b/osu.Game/Skinning/Components/BeatmapAttributeText.cs @@ -104,35 +104,18 @@ namespace osu.Game.Skinning.Components public void UpdateBeatmapContent(WorkingBeatmap workingBeatmap) { - //update cs - double cs = workingBeatmap.BeatmapInfo.Difficulty.CircleSize; - valueDictionary[BeatmapAttribute.CircleSize] = cs.ToString("F2"); - //update HP - double hp = workingBeatmap.BeatmapInfo.Difficulty.DrainRate; - valueDictionary[BeatmapAttribute.HPDrain] = hp.ToString("F2"); - //update od - double od = workingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty; - valueDictionary[BeatmapAttribute.Accuracy] = od.ToString("F2"); - //update ar - double ar = workingBeatmap.BeatmapInfo.Difficulty.ApproachRate; - valueDictionary[BeatmapAttribute.ApproachRate] = ar.ToString("F2"); - //update sr - double sr = workingBeatmap.BeatmapInfo.StarRating; - valueDictionary[BeatmapAttribute.StarRating] = sr.ToString("F2"); - //update song title valueDictionary[BeatmapAttribute.Title] = workingBeatmap.BeatmapInfo.Metadata.Title; - //update artist valueDictionary[BeatmapAttribute.Artist] = workingBeatmap.BeatmapInfo.Metadata.Artist; - //update difficulty name valueDictionary[BeatmapAttribute.DifficultyName] = workingBeatmap.BeatmapInfo.DifficultyName; - //update mapper valueDictionary[BeatmapAttribute.Creator] = workingBeatmap.BeatmapInfo.Metadata.Author.Username; - //update Length valueDictionary[BeatmapAttribute.Length] = TimeSpan.FromMilliseconds(workingBeatmap.BeatmapInfo.Length).ToFormattedDuration(); - //update Status valueDictionary[BeatmapAttribute.RankedStatus] = workingBeatmap.BeatmapInfo.Status.GetLocalisableDescription(); - //update BPM - valueDictionary[BeatmapAttribute.BPM] = workingBeatmap.BeatmapInfo.BPM.ToString("F2"); + valueDictionary[BeatmapAttribute.BPM] = workingBeatmap.BeatmapInfo.BPM.ToString(@"F2"); + valueDictionary[BeatmapAttribute.CircleSize] = ((double)workingBeatmap.BeatmapInfo.Difficulty.CircleSize).ToString(@"F2"); + valueDictionary[BeatmapAttribute.HPDrain] = ((double)workingBeatmap.BeatmapInfo.Difficulty.DrainRate).ToString(@"F2"); + valueDictionary[BeatmapAttribute.Accuracy] = ((double)workingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty).ToString(@"F2"); + valueDictionary[BeatmapAttribute.ApproachRate] = ((double)workingBeatmap.BeatmapInfo.Difficulty.ApproachRate).ToString(@"F2"); + valueDictionary[BeatmapAttribute.StarRating] = workingBeatmap.BeatmapInfo.StarRating.ToString(@"F2"); } } From 774f70e380ab129f4472a73494e1397e556b0238 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Nov 2022 16:56:40 +0900 Subject: [PATCH 0747/2991] Simplify class structure --- .../Components/BeatmapAttributeText.cs | 40 +++++++++---------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/osu.Game/Skinning/Components/BeatmapAttributeText.cs b/osu.Game/Skinning/Components/BeatmapAttributeText.cs index 498ea1d268..572b4ba818 100644 --- a/osu.Game/Skinning/Components/BeatmapAttributeText.cs +++ b/osu.Game/Skinning/Components/BeatmapAttributeText.cs @@ -60,49 +60,32 @@ namespace osu.Game.Skinning.Components public BeatmapAttributeText() { AutoSizeAxes = Axes.Both; + InternalChildren = new Drawable[] { text = new OsuSpriteText { - Text = "BeatInfoDrawable", Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Font = OsuFont.Default.With(size: 40) } }; - - foreach (var type in Enum.GetValues(typeof(BeatmapAttribute)).Cast()) - { - valueDictionary[type] = type.ToString(); - } } protected override void LoadComplete() { base.LoadComplete(); + Attribute.BindValueChanged(_ => updateLabel()); - Template.BindValueChanged(f => updateLabel(), true); + Template.BindValueChanged(_ => updateLabel()); beatmap.BindValueChanged(b => { - UpdateBeatmapContent(b.NewValue); + updateBeatmapContent(b.NewValue); updateLabel(); }, true); } - private void updateLabel() - { - string newText = Template.Value.Replace("{Label}", label_dictionary[Attribute.Value].ToString()) - .Replace("{Value}", valueDictionary[Attribute.Value].ToString()); - - foreach (var type in Enum.GetValues(typeof(BeatmapAttribute)).Cast()) - { - newText = newText.Replace("{" + type + "}", valueDictionary[type].ToString()); - } - - text.Text = newText; - } - - public void UpdateBeatmapContent(WorkingBeatmap workingBeatmap) + private void updateBeatmapContent(WorkingBeatmap workingBeatmap) { valueDictionary[BeatmapAttribute.Title] = workingBeatmap.BeatmapInfo.Metadata.Title; valueDictionary[BeatmapAttribute.Artist] = workingBeatmap.BeatmapInfo.Metadata.Artist; @@ -117,6 +100,19 @@ namespace osu.Game.Skinning.Components valueDictionary[BeatmapAttribute.ApproachRate] = ((double)workingBeatmap.BeatmapInfo.Difficulty.ApproachRate).ToString(@"F2"); valueDictionary[BeatmapAttribute.StarRating] = workingBeatmap.BeatmapInfo.StarRating.ToString(@"F2"); } + + private void updateLabel() + { + string newText = Template.Value.Replace("{Label}", label_dictionary[Attribute.Value].ToString()) + .Replace("{Value}", valueDictionary[Attribute.Value].ToString()); + + foreach (var type in Enum.GetValues(typeof(BeatmapAttribute)).Cast()) + { + newText = newText.Replace("{" + type + "}", valueDictionary[type].ToString()); + } + + text.Text = newText; + } } public enum BeatmapAttribute From a6bba1967ebfa392a27e2c77f4f0e4e68aac353f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Nov 2022 17:06:22 +0900 Subject: [PATCH 0748/2991] Update serialisation test to match new comopnent naming --- .../Archives/modified-default-20221102.osk | Bin 1534 -> 1599 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/osu.Game.Tests/Resources/Archives/modified-default-20221102.osk b/osu.Game.Tests/Resources/Archives/modified-default-20221102.osk index 3ec328db4e8212e2cb709865362b24f83951b93e..c1333acd13185826f4516eccf92f6d6d2e24cb8a 100644 GIT binary patch literal 1599 zcmWIWW@Zs#U|`^2$nGc)?YJIvbt{k;!UPgwU?|Sc%+t%v%e>pam(S5rp!Iic*Tsns z{)H?Gei;(7NFq&7dbjbWax?RJz7HqvVN%k%*!@oB{`ASkdDF844}3asA%o*q<;}x> zMuqE-a7=Q9Ftyj^XG=3j=%kV4kr1`we2WdC?W-Z$=X>o@7xxcT1BKAM-*l|!M zCuDkQtlz4W&+OxB5tz+^=dFGg6cF&q z`;2esrl5dR`g)-u7c?|a`JC}S@2Pt&1Z=74Gy|2P}=+8&6z!W&g?1KD=?$mLCK2CfYmEzD+8*dXMK!&cbbub;Q=25gBZ}! zzKNN69-%JI`MCx8d8v6N#bDRJo$ly=+d$;_`@bTA=MNTjOkU$*>u@S8bGBIEgC+}! z?_0MP`xqr3 z(fq@?w z{lWQp>A|TvsmUeact08(n|;VYr1pDwO6@zRTVGB$@@w6eJ2vA?p8g}}wdH0r)RuZW z3jY5clxwclY-ld2$p2l%@_CWpyEW|>&gHbMsfcbUZPr<-RWtud!}4r37GZ6hX_bns z9BV&t2+dVL8t{6Ot`@Ih&X(R=>Sk4~L57-aEb`NOkBMFn3vsjsGqZ`LW`W`=;U=f$H{l&EfbuG28E+4RM_}%t6^3{@u zE57zWF!8mRvq?zii}S0X?T2qIh-)v=xa2eK*_QhZ{;JU%qYiUQKXGl`l`I`mcc<2S zN7FXO3%4v*zLJZ&RCw&irj}W$X75dt>`yNG_HUYVURSrfgW=a2p&eV2uWfyv_)2L0 z1!LoaTaVi=T#1){KgqseU+AS{J8s>L2+M3MVbe%WJ>?i1Df=~E{fqu(p;`JeErI0` zix{k*t*=gh=Ca{Ed!9tay^|Yc9)4(g{7Et@?t_cG&;4Gt{^~6npYlJwI(r`&PmD|= z47dwUU}Ql+BZz_(qv*QO%Ot2C28PDlP+jm63SBFD$$-#00hnO0mlNn_peHYc8U4%{ Vi7mjJl?|kT1qeR@X>(Q(4*+f4o~Hl+ literal 1534 zcmWIWW@Zs#U|`^2NN-6B{k=AO?o1$WGgyRyp*TA;PcJhsQ}v7?Uz3A?!^L?i?+t<+ zla2&jio6+_nX1E<*3i4#IPE6y!yGZWliC~`|LOn#{Vzl`#=R|W?&X`O80LDVbQ(Nn znX#yx+1rz4%;f*Sr?uTAxyVI%L+HDUVhxY@BW5nr?WLKLEw~Gv4vZmjIpK z1H`;Q403*EURu6hR&jpb>Ss@b0s=mHpYaXd6clhuUoSMIBhX97>-_odz@Q5TMg~Tg zLN1&*>wnVcw2$w_kV}l(<$7MeIw$p+UUHm0eeSgW`DU+*XQI}d?VI+U#a$tj}*2ki&Obn>bd;h|Bkv}5?LpU=713%Dt z!TEXV!Kpc^$t7S1?wuH$eaJwf^*!r<=WE_87slTzdvNqxt--MwXLd<{RJs<_k*Cm#O61*4n}CKI$QjBky+}4dvo?E9ALgL{iCd#pKZ5a%i#m^JlemmzSzU* zn>F{6i?6z5Vu9M*ZOpwIWqwccDz*t;iaE+#Ikm*syV5-8LP%rPg6fEEm$eUxY&q?i zExc6g`}RX8+cqt23Cb|jk1YMX+$reB>uR>0mVcZD|1z*|e9!){Fs)Yq$l-;;t{+)_ zD=a=GtCuWJe#_;4FMsKl&*IxI>0MR3X!LFROBL6>XIi$rUD$G}r*YRNznnSYH{PDv z&xjiK)eZ7#FMwfR1`K#HVA%U6X6AW>x;W?O7Ubup=9LtKqu}lI*zDT|B5m)v|MII{ zUpK-2QNN?!ttHXNB#gax&A!Ba)Yj7_Ra54qPU4&W;d!#tkD6<1mc2-8c3j_gU-?VH zo5i<38z27}YAcg&a6dQU!$C=n*h&6t7>rH}I%G}a+@^eaHs{O(lcpZ(3Edcw9O}jV z!s>Uy^`DF@c1}|EnwNK7^7aFvM3sdmCt6;oJazi;hx^U5SBy_QraAH4v8r8WV*agk zcT1IP*qvJw#jB1ipVF46{C3S%C>i4mS7sdL-U)uL=KT!B_ z)h7=BUU#+~ArS^MotNz}*>(JyrqrY>aUbn3+u0UquI1j?-rhSYp?rP}qcQ94nrYsq zj^8HhvXm6gSzzb+cj5D`yOyU&{H&{B5%fxWrMmC=@%GT~OMWMQ`ELLD-^VkF+3Q$E z$}TWYvrzM#p?18aC Ghz9_U=60t5 From e69ed67335ab9824b238e4f0953be2d9c0b46ea9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Nov 2022 18:09:47 +0900 Subject: [PATCH 0749/2991] Add test of barline generation with negative start time control point --- .../TestSceneBarLineGeneration.cs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneBarLineGeneration.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneBarLineGeneration.cs index 095fddc33f..bd52af7615 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneBarLineGeneration.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneBarLineGeneration.cs @@ -83,5 +83,41 @@ namespace osu.Game.Rulesets.Taiko.Tests AddAssert("first barline ommited", () => barlines.All(b => b.StartTime != start_time)); AddAssert("second barline generated", () => barlines.Any(b => b.StartTime == start_time + (beat_length * time_signature_numerator))); } + + [Test] + public void TestNegativeStartTimeTimingPoint() + { + const double beat_length = 250; + + const int time_signature_numerator = 4; + + var beatmap = new Beatmap + { + HitObjects = + { + new Hit + { + Type = HitType.Centre, + StartTime = 1000 + } + }, + BeatmapInfo = + { + Difficulty = new BeatmapDifficulty { SliderTickRate = 4 }, + Ruleset = new TaikoRuleset().RulesetInfo + }, + }; + + beatmap.ControlPointInfo.Add(-100, new TimingControlPoint + { + BeatLength = beat_length, + TimeSignature = new TimeSignature(time_signature_numerator) + }); + + var barlines = new BarLineGenerator(beatmap).BarLines; + + AddAssert("bar line generated at t=900", () => barlines.Any(line => line.StartTime == 900)); + AddAssert("bar line generated at t=1900", () => barlines.Any(line => line.StartTime == 1900)); + } } } From f9d952220fcee1e1aadc588cbec85ce179461e55 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Nov 2022 18:12:03 +0900 Subject: [PATCH 0750/2991] Fix barlines being misaligned if generation start time is clamped --- osu.Game/Rulesets/Objects/BarLineGenerator.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/BarLineGenerator.cs b/osu.Game/Rulesets/Objects/BarLineGenerator.cs index 185088878c..5c76c43f20 100644 --- a/osu.Game/Rulesets/Objects/BarLineGenerator.cs +++ b/osu.Game/Rulesets/Objects/BarLineGenerator.cs @@ -47,13 +47,28 @@ namespace osu.Game.Rulesets.Objects // Don't generate barlines before the hit object or t=0 (whichever is earliest). Some beatmaps use very unrealistic values here (although none are ranked). // I'm not sure we ever want barlines to appear before the first hitobject, but let's keep some degree of compatibility for now. // Of note, this will still differ from stable if the first timing control point is t<0 and is not near the first hitobject. - double startTime = Math.Max(Math.Min(0, firstHitTime), currentTimingPoint.Time); + double generationStartTime = Math.Min(0, firstHitTime); // Stop on the next timing point, or if there is no next timing point stop slightly past the last object double endTime = i < timingPoints.Count - 1 ? timingPoints[i + 1].Time : lastHitTime + currentTimingPoint.BeatLength * currentTimingPoint.TimeSignature.Numerator; double barLength = currentTimingPoint.BeatLength * currentTimingPoint.TimeSignature.Numerator; + double startTime; + + if (currentTimingPoint.Time > generationStartTime) + { + startTime = currentTimingPoint.Time; + } + else + { + // If the timing point starts before the minimum allowable time for bar lines, + // we still need to compute a start time for generation that is actually properly aligned with the timing point. + int barCount = (int)Math.Ceiling((generationStartTime - currentTimingPoint.Time) / barLength); + + startTime = currentTimingPoint.Time + barCount * barLength; + } + if (currentEffectPoint.OmitFirstBarLine) { startTime += barLength; From 5467097387b97f0dbf2ae9defb7234368977e5c2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 23 Nov 2022 18:49:51 +0900 Subject: [PATCH 0751/2991] Fix adjacent day separators potentially being left behind after pending message resolution --- osu.Game/Overlays/Chat/DrawableChannel.cs | 36 ++++++++++++++--------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index 3d2eafd973..65876fd7c5 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -141,27 +141,15 @@ namespace osu.Game.Overlays.Chat } var staleMessages = chatLines.Where(c => c.LifetimeEnd == double.MaxValue).ToArray(); + int count = staleMessages.Length - Channel.MAX_HISTORY; if (count > 0) { - void expireAndAdjustScroll(Drawable d) - { - scroll.OffsetScrollPosition(-d.DrawHeight); - d.Expire(); - } - for (int i = 0; i < count; i++) expireAndAdjustScroll(staleMessages[i]); - // remove all adjacent day separators after stale message removal - for (int i = 0; i < ChatLineFlow.Count - 1; i++) - { - if (!(ChatLineFlow[i] is DaySeparator)) break; - if (!(ChatLineFlow[i + 1] is DaySeparator)) break; - - expireAndAdjustScroll(ChatLineFlow[i]); - } + removeAdjacentDaySeparators(); } // due to the scroll adjusts from old messages removal above, a scroll-to-end must be enforced, @@ -199,9 +187,29 @@ namespace osu.Game.Overlays.Chat ChatLineFlow.Remove(ds, true); ChatLineFlow.Add(CreateDaySeparator(message.Timestamp)); + + removeAdjacentDaySeparators(); } } + private void removeAdjacentDaySeparators() + { + // remove all adjacent day separators after stale message removal + for (int i = 0; i < ChatLineFlow.Count - 1; i++) + { + if (!(ChatLineFlow[i] is DaySeparator)) break; + if (!(ChatLineFlow[i + 1] is DaySeparator)) break; + + expireAndAdjustScroll(ChatLineFlow[i]); + } + } + + private void expireAndAdjustScroll(Drawable d) + { + scroll.OffsetScrollPosition(-d.DrawHeight); + d.Expire(); + } + private void messageRemoved(Message removed) => Schedule(() => { chatLines.FirstOrDefault(c => c.Message == removed)?.FadeColour(Color4.Red, 400).FadeOut(600).Expire(); From 2204af04e485cbd2af81f51d8846684a36a17477 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 23 Nov 2022 16:12:13 +0300 Subject: [PATCH 0752/2991] Improve test scene to better show colour gradient --- .../TestSceneTrianglesV2Background.cs | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs index e8abc573cd..0c3a21d510 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs @@ -27,16 +27,24 @@ namespace osu.Game.Tests.Visual.Background { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(500), + Size = new Vector2(500, 100), Masking = true, CornerRadius = 40, - Child = triangles = new TrianglesV2 + Children = new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - ColourTop = Color4.Red, - ColourBottom = Color4.Orange + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Red + }, + triangles = new TrianglesV2 + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + ColourTop = Color4.White, + ColourBottom = Color4.Red + } } } }); From 06449b62f1517ab9f77e3a0c8050af8c0065ee5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 23 Nov 2022 16:03:54 +0100 Subject: [PATCH 0753/2991] Add test coverage for crash scenario --- .../Visual/Editing/TestSceneTapTimingControl.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTapTimingControl.cs b/osu.Game.Tests/Visual/Editing/TestSceneTapTimingControl.cs index 10e1206b53..f2bfffda06 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneTapTimingControl.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneTapTimingControl.cs @@ -18,6 +18,7 @@ using osu.Game.Overlays; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Timing; using osuTK; +using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { @@ -125,6 +126,13 @@ namespace osu.Game.Tests.Visual.Editing AddUntilStep("wait for track stopped", () => !EditorClock.IsRunning); } + [Test] + public void TestNoCrashOnTapWhenNoGroupSelected() + { + AddStep("unset selected group", () => selectedGroup.Value = null); + AddStep("press T to tap", () => InputManager.Key(Key.T)); + } + protected override void Dispose(bool isDisposing) { Beatmap.Disabled = false; From cf5f5a4de310147523f2a41ff5621149758b07e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 23 Nov 2022 17:19:58 +0100 Subject: [PATCH 0754/2991] Extend tap timing control test coverage in no point selected case --- .../Editing/TestSceneTapTimingControl.cs | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTapTimingControl.cs b/osu.Game.Tests/Visual/Editing/TestSceneTapTimingControl.cs index f2bfffda06..6ed63515e9 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneTapTimingControl.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneTapTimingControl.cs @@ -127,10 +127,38 @@ namespace osu.Game.Tests.Visual.Editing } [Test] - public void TestNoCrashOnTapWhenNoGroupSelected() + public void TestNoCrashesWhenNoGroupSelected() { AddStep("unset selected group", () => selectedGroup.Value = null); AddStep("press T to tap", () => InputManager.Key(Key.T)); + + AddStep("click tap button", () => + { + control.ChildrenOfType() + .Last() + .TriggerClick(); + }); + + AddStep("click reset button", () => + { + control.ChildrenOfType() + .First() + .TriggerClick(); + }); + + AddStep("adjust offset", () => + { + var adjustOffsetButton = control.ChildrenOfType().First(); + InputManager.MoveMouseTo(adjustOffsetButton); + InputManager.Click(MouseButton.Left); + }); + + AddStep("adjust BPM", () => + { + var adjustBPMButton = control.ChildrenOfType().Last(); + InputManager.MoveMouseTo(adjustBPMButton); + InputManager.Click(MouseButton.Left); + }); } protected override void Dispose(bool isDisposing) From 30f9cc46a7618031088f98fc2d2444279f9e6dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 23 Nov 2022 17:22:40 +0100 Subject: [PATCH 0755/2991] Protect offset and bpm adjustments from null selection too --- osu.Game/Screens/Edit/Timing/TapTimingControl.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs index daa3168746..3b26e335d9 100644 --- a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs +++ b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs @@ -201,6 +201,9 @@ namespace osu.Game.Screens.Edit.Timing private void adjustOffset(double adjust) { + if (selectedGroup.Value == null) + return; + bool wasAtStart = editorClock.CurrentTimeAccurate == selectedGroup.Value.Time; // VERY TEMPORARY @@ -222,7 +225,7 @@ namespace osu.Game.Screens.Edit.Timing private void adjustBpm(double adjust) { - var timing = selectedGroup.Value.ControlPoints.OfType().FirstOrDefault(); + var timing = selectedGroup.Value?.ControlPoints.OfType().FirstOrDefault(); if (timing == null) return; From 3acf15c7b8945e01081d86eeeeb2033bfcec9000 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Nov 2022 01:26:49 +0900 Subject: [PATCH 0756/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 8212707d44..06121fa9fa 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f81d9d27b4..b6dc691359 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index cd70f1c432..c7200b9620 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From 4b44f31b5edd98f43e57ed81bb94f5c16c87b9a1 Mon Sep 17 00:00:00 2001 From: C0D3 M4513R <28912031+C0D3-M4513R@users.noreply.github.com> Date: Wed, 23 Nov 2022 21:02:43 +0100 Subject: [PATCH 0757/2991] Use LocaliseableStings in `BeatmapAttributeText` --- .../Components/BeatmapAttributeText.cs | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/osu.Game/Skinning/Components/BeatmapAttributeText.cs b/osu.Game/Skinning/Components/BeatmapAttributeText.cs index 572b4ba818..ec84831fb4 100644 --- a/osu.Game/Skinning/Components/BeatmapAttributeText.cs +++ b/osu.Game/Skinning/Components/BeatmapAttributeText.cs @@ -93,25 +93,34 @@ namespace osu.Game.Skinning.Components valueDictionary[BeatmapAttribute.Creator] = workingBeatmap.BeatmapInfo.Metadata.Author.Username; valueDictionary[BeatmapAttribute.Length] = TimeSpan.FromMilliseconds(workingBeatmap.BeatmapInfo.Length).ToFormattedDuration(); valueDictionary[BeatmapAttribute.RankedStatus] = workingBeatmap.BeatmapInfo.Status.GetLocalisableDescription(); - valueDictionary[BeatmapAttribute.BPM] = workingBeatmap.BeatmapInfo.BPM.ToString(@"F2"); - valueDictionary[BeatmapAttribute.CircleSize] = ((double)workingBeatmap.BeatmapInfo.Difficulty.CircleSize).ToString(@"F2"); - valueDictionary[BeatmapAttribute.HPDrain] = ((double)workingBeatmap.BeatmapInfo.Difficulty.DrainRate).ToString(@"F2"); - valueDictionary[BeatmapAttribute.Accuracy] = ((double)workingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty).ToString(@"F2"); - valueDictionary[BeatmapAttribute.ApproachRate] = ((double)workingBeatmap.BeatmapInfo.Difficulty.ApproachRate).ToString(@"F2"); - valueDictionary[BeatmapAttribute.StarRating] = workingBeatmap.BeatmapInfo.StarRating.ToString(@"F2"); + valueDictionary[BeatmapAttribute.BPM] = workingBeatmap.BeatmapInfo.BPM.ToLocalisableString(@"F2"); + valueDictionary[BeatmapAttribute.CircleSize] = ((double)workingBeatmap.BeatmapInfo.Difficulty.CircleSize).ToLocalisableString(@"F2"); + valueDictionary[BeatmapAttribute.HPDrain] = ((double)workingBeatmap.BeatmapInfo.Difficulty.DrainRate).ToLocalisableString(@"F2"); + valueDictionary[BeatmapAttribute.Accuracy] = ((double)workingBeatmap.BeatmapInfo.Difficulty.OverallDifficulty).ToLocalisableString(@"F2"); + valueDictionary[BeatmapAttribute.ApproachRate] = ((double)workingBeatmap.BeatmapInfo.Difficulty.ApproachRate).ToLocalisableString(@"F2"); + valueDictionary[BeatmapAttribute.StarRating] = workingBeatmap.BeatmapInfo.StarRating.ToLocalisableString(@"F2"); } private void updateLabel() { - string newText = Template.Value.Replace("{Label}", label_dictionary[Attribute.Value].ToString()) - .Replace("{Value}", valueDictionary[Attribute.Value].ToString()); + string numberedTemplate = Template.Value + .Replace("{", "{{") + .Replace("}", "}}") + .Replace(@"{{Label}}", "{0}") + .Replace(@"{{Value}}", $"{{{1 + (int)Attribute.Value}}}"); + + object?[] args = valueDictionary.OrderBy(pair => pair.Key) + .Select(pair => pair.Value) + .Prepend(label_dictionary[Attribute.Value]) + .Cast() + .ToArray(); foreach (var type in Enum.GetValues(typeof(BeatmapAttribute)).Cast()) { - newText = newText.Replace("{" + type + "}", valueDictionary[type].ToString()); + numberedTemplate = numberedTemplate.Replace($"{{{{{type}}}}}", $"{{{1 + (int)type}}}"); } - text.Text = newText; + text.Text = LocalisableString.Format(numberedTemplate, args); } } From 37f725bfa242982350f40326db6399a7835a936c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Nov 2022 13:55:58 +0900 Subject: [PATCH 0758/2991] Reverse directionality of up/down traversal keys to match scroll --- .../Visual/Editing/TestSceneEditorSeeking.cs | 18 +++++++++--------- osu.Game/Screens/Edit/Editor.cs | 5 +++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorSeeking.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorSeeking.cs index 14679ae01d..8ef84fb094 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorSeeking.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorSeeking.cs @@ -124,17 +124,17 @@ namespace osu.Game.Tests.Visual.Editing AddAssert("time is 0", () => EditorClock.CurrentTime == 0); // already at first control point, noop - pressAndCheckTime(Key.Down, 0); - - pressAndCheckTime(Key.Up, 2000); - - pressAndCheckTime(Key.Up, 20000); - // at last control point, noop - pressAndCheckTime(Key.Up, 20000); + pressAndCheckTime(Key.Up, 0); pressAndCheckTime(Key.Down, 2000); - pressAndCheckTime(Key.Down, 0); - pressAndCheckTime(Key.Down, 0); + + pressAndCheckTime(Key.Down, 20000); + // at last control point, noop + pressAndCheckTime(Key.Down, 20000); + + pressAndCheckTime(Key.Up, 2000); + pressAndCheckTime(Key.Up, 0); + pressAndCheckTime(Key.Up, 0); } private void pressAndCheckTime(Key key, double expectedTime) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 7c0e021ff9..e40910e5c6 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -499,11 +499,12 @@ namespace osu.Game.Screens.Edit seek(e, 1); return true; - case Key.Down: + // Of those, these two keys are reversed from stable because it feels more natural (and matches mouse wheel scroll directionality). + case Key.Up: seekControlPoint(-1); return true; - case Key.Up: + case Key.Down: seekControlPoint(1); return true; From a2438428a23639a9100f21e3723849325ae136c1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Nov 2022 13:57:43 +0900 Subject: [PATCH 0759/2991] Move base call to end --- osu.Game/Rulesets/Mods/DifficultyBindable.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Mods/DifficultyBindable.cs b/osu.Game/Rulesets/Mods/DifficultyBindable.cs index 2b3ba1dd13..cca72cf3ac 100644 --- a/osu.Game/Rulesets/Mods/DifficultyBindable.cs +++ b/osu.Game/Rulesets/Mods/DifficultyBindable.cs @@ -118,12 +118,12 @@ namespace osu.Game.Rulesets.Mods if (!(them is DifficultyBindable otherDifficultyBindable)) throw new InvalidOperationException($"Cannot bind to a non-{nameof(DifficultyBindable)}."); - base.BindTo(them); - ExtendedLimits.BindTarget = otherDifficultyBindable.ExtendedLimits; // the actual values need to be copied after the max value constraints. CurrentNumber.BindTarget = otherDifficultyBindable.CurrentNumber; + + base.BindTo(them); } public override void UnbindFrom(IUnbindable them) From 2e277ef40a3b51b8e935863f3ceea5bc4694597c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Nov 2022 15:18:49 +0900 Subject: [PATCH 0760/2991] Update resources --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 5f3fb858ee..647c7b179c 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -51,7 +51,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 858cac1dac..5c4b5642b5 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 25217b872b..19f4248055 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -61,7 +61,7 @@ - + From 40f706155f56603f86f8c1bbfc194330d0a83f29 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Nov 2022 15:04:54 +0900 Subject: [PATCH 0761/2991] Update `RoundedButton` to have new triangles design --- .../UserInterface/TestSceneRoundedButton.cs | 2 +- osu.Game/Graphics/UserInterface/OsuButton.cs | 7 ++- .../Graphics/UserInterfaceV2/RoundedButton.cs | 61 +++++++++++++++++-- osu.Game/Overlays/Settings/SettingsButton.cs | 11 ---- 4 files changed, 63 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneRoundedButton.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneRoundedButton.cs index 2587960275..178a68b599 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneRoundedButton.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneRoundedButton.cs @@ -37,7 +37,7 @@ namespace osu.Game.Tests.Visual.UserInterface }, new SettingsButton { - Text = "Test button", + Text = "Test settings button", Anchor = Anchor.Centre, Origin = Anchor.Centre, Enabled = { BindTarget = enabled }, diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index dae5de2d65..6f1312652b 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -37,7 +37,7 @@ namespace osu.Game.Graphics.UserInterface /// /// Sets a custom background colour to this button, replacing the provided default. /// - public Color4 BackgroundColour + public virtual Color4 BackgroundColour { get => backgroundColour ?? defaultBackgroundColour; set @@ -90,6 +90,7 @@ namespace osu.Game.Graphics.UserInterface Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, + Depth = float.MaxValue, }, Hover = new Box { @@ -141,13 +142,15 @@ namespace osu.Game.Graphics.UserInterface return base.OnClick(e); } + protected virtual float HoverLayerFinalAlpha => 0.1f; + protected override bool OnHover(HoverEvent e) { if (Enabled.Value) { Hover.FadeTo(0.2f, 40, Easing.OutQuint) .Then() - .FadeTo(0.1f, 800, Easing.OutQuint); + .FadeTo(HoverLayerFinalAlpha, 800, Easing.OutQuint); } return base.OnHover(e); diff --git a/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs b/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs index 4477633da1..3d970284ec 100644 --- a/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs +++ b/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs @@ -1,19 +1,28 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Input.Events; using osu.Framework.Localisation; +using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays; +using osuTK.Graphics; namespace osu.Game.Graphics.UserInterfaceV2 { public class RoundedButton : OsuButton, IFilterable { + private TrianglesV2? triangles; + + protected override float HoverLayerFinalAlpha => 0; + + private Color4 triangleGradientSecondColour = Color4.Transparent; + public override float Height { get => base.Height; @@ -26,19 +35,63 @@ namespace osu.Game.Graphics.UserInterfaceV2 } } + public override Color4 BackgroundColour + { + get => base.BackgroundColour; + set + { + base.BackgroundColour = value; + triangleGradientSecondColour = BackgroundColour.Lighten(0.2f); + updateColours(); + } + } + [BackgroundDependencyLoader(true)] - private void load(OsuColour colours) + private void load(OverlayColourProvider? overlayColourProvider, OsuColour colours) { // According to flyte, buttons are supposed to have explicit colours for now. // Not sure this is the correct direction, but we haven't decided on an `OverlayColourProvider` stand-in yet. // This is a better default. See `SettingsButton` for an override which uses `OverlayColourProvider`. - DefaultBackgroundColour = colours.Blue3; + DefaultBackgroundColour = overlayColourProvider?.Colour3 ?? colours.Blue3; + triangleGradientSecondColour = overlayColourProvider?.Colour1 ?? colours.Blue3.Lighten(0.2f); } protected override void LoadComplete() { base.LoadComplete(); + updateCornerRadius(); + + Add(triangles = new TrianglesV2 + { + Thickness = 0.02f, + SpawnRatio = 0.6f, + RelativeSizeAxes = Axes.Both, + Depth = float.MaxValue, + }); + + updateColours(); + } + + private void updateColours() + { + if (triangles == null) + return; + + triangles.ColourTop = triangleGradientSecondColour; + triangles.ColourBottom = BackgroundColour; + } + + protected override bool OnHover(HoverEvent e) + { + Background.FadeColour(triangleGradientSecondColour, 300, Easing.OutQuint); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + Background.FadeColour(BackgroundColour, 300, Easing.OutQuint); + base.OnHoverLost(e); } private void updateCornerRadius() => Content.CornerRadius = DrawHeight / 2; diff --git a/osu.Game/Overlays/Settings/SettingsButton.cs b/osu.Game/Overlays/Settings/SettingsButton.cs index 5f2a416f58..10aea92b22 100644 --- a/osu.Game/Overlays/Settings/SettingsButton.cs +++ b/osu.Game/Overlays/Settings/SettingsButton.cs @@ -1,16 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Cursor; using osu.Framework.Localisation; -using osu.Game.Graphics; using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Overlays.Settings @@ -23,12 +18,6 @@ namespace osu.Game.Overlays.Settings Padding = new MarginPadding { Left = SettingsPanel.CONTENT_MARGINS, Right = SettingsPanel.CONTENT_MARGINS }; } - [BackgroundDependencyLoader(true)] - private void load([CanBeNull] OverlayColourProvider overlayColourProvider, OsuColour colours) - { - DefaultBackgroundColour = overlayColourProvider?.Highlight1 ?? colours.Blue3; - } - public LocalisableString TooltipText { get; set; } public override IEnumerable FilterTerms From 4fbca4037c45b67e192396903ffc8a448ff09ef9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Nov 2022 15:08:03 +0900 Subject: [PATCH 0762/2991] Update existing triangle buttons to use `RoundedButton` --- .../Graphics/UserInterface/TriangleButton.cs | 32 ++----------------- 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/TriangleButton.cs b/osu.Game/Graphics/UserInterface/TriangleButton.cs index 60d1824e5a..891c8f779f 100644 --- a/osu.Game/Graphics/UserInterface/TriangleButton.cs +++ b/osu.Game/Graphics/UserInterface/TriangleButton.cs @@ -1,42 +1,14 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using System.Collections.Generic; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Localisation; -using osu.Game.Graphics.Backgrounds; +using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Graphics.UserInterface { /// /// A button with moving triangles in the background. /// - public class TriangleButton : OsuButton, IFilterable + public class TriangleButton : RoundedButton { - protected Triangles Triangles { get; private set; } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - Add(Triangles = new Triangles - { - RelativeSizeAxes = Axes.Both, - ColourDark = colours.BlueDarker, - ColourLight = colours.Blue, - }); - } - - public virtual IEnumerable FilterTerms => new[] { Text }; - - public bool MatchingFilter - { - set => this.FadeTo(value ? 1 : 0); - } - - public bool FilteringActive { get; set; } } } From bea2acc60ef93f5bed5896a83e8ccb8250d7aafc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Nov 2022 15:18:26 +0900 Subject: [PATCH 0763/2991] Remove local specifications of triangle colouring --- .../UserInterface/DangerousTriangleButton.cs | 2 -- .../Overlays/BeatmapSet/Buttons/HeaderButton.cs | 5 ----- .../Match/Components/CreateRoomButton.cs | 1 - .../Match/Components/PurpleTriangleButton.cs | 2 -- .../Match/MultiplayerMatchSettingsOverlay.cs | 2 -- .../Multiplayer/Match/MultiplayerReadyButton.cs | 7 ------- .../Multiplayer/Match/MultiplayerSpectateButton.cs | 14 ++------------ .../OnlinePlay/Playlists/PlaylistsReadyButton.cs | 2 -- .../Playlists/PlaylistsRoomSettingsOverlay.cs | 2 -- 9 files changed, 2 insertions(+), 35 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/DangerousTriangleButton.cs b/osu.Game/Graphics/UserInterface/DangerousTriangleButton.cs index 1414979531..3c78cbb634 100644 --- a/osu.Game/Graphics/UserInterface/DangerousTriangleButton.cs +++ b/osu.Game/Graphics/UserInterface/DangerousTriangleButton.cs @@ -13,8 +13,6 @@ namespace osu.Game.Graphics.UserInterface private void load(OsuColour colours) { BackgroundColour = colours.PinkDark; - Triangles.ColourDark = colours.PinkDarker; - Triangles.ColourLight = colours.Pink; } } } diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs index 25d11bd6d7..d6bf3464da 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -22,9 +20,6 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons private void load() { BackgroundColour = Color4Extensions.FromHex(@"094c5f"); - Triangles.ColourLight = Color4Extensions.FromHex(@"0f7c9b"); - Triangles.ColourDark = Color4Extensions.FromHex(@"094c5f"); - Triangles.TriangleScale = 1.5f; } } } diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/CreateRoomButton.cs b/osu.Game/Screens/OnlinePlay/Match/Components/CreateRoomButton.cs index 3d0c181d9d..20e4b78eb4 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/CreateRoomButton.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/CreateRoomButton.cs @@ -16,7 +16,6 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components private void load() { SpriteText.Font = SpriteText.Font.With(size: 14); - Triangles.TriangleScale = 1.5f; } public bool OnPressed(KeyBindingPressEvent e) diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/PurpleTriangleButton.cs b/osu.Game/Screens/OnlinePlay/Match/Components/PurpleTriangleButton.cs index 5c751f238f..c6df53c368 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/PurpleTriangleButton.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/PurpleTriangleButton.cs @@ -15,8 +15,6 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components private void load() { BackgroundColour = Color4Extensions.FromHex(@"593790"); - Triangles.ColourLight = Color4Extensions.FromHex(@"7247b6"); - Triangles.ColourDark = Color4Extensions.FromHex(@"593790"); } } } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs index bbdfed0a00..17c361a420 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs @@ -475,8 +475,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match private void load(OsuColour colours) { BackgroundColour = colours.Yellow; - Triangles.ColourLight = colours.YellowLight; - Triangles.ColourDark = colours.YellowDark; } } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerReadyButton.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerReadyButton.cs index b4ff34cbc2..5f2ae82f55 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerReadyButton.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerReadyButton.cs @@ -12,7 +12,6 @@ using osu.Framework.Audio.Sample; using osu.Framework.Localisation; using osu.Framework.Threading; using osu.Game.Graphics; -using osu.Game.Graphics.Backgrounds; using osu.Game.Online.Multiplayer; using osu.Game.Screens.OnlinePlay.Components; @@ -20,8 +19,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match { public class MultiplayerReadyButton : ReadyButton { - public new Triangles Triangles => base.Triangles; - [Resolved] private MultiplayerClient multiplayerClient { get; set; } @@ -212,15 +209,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match void setYellow() { BackgroundColour = colours.YellowDark; - Triangles.ColourDark = colours.YellowDark; - Triangles.ColourLight = colours.Yellow; } void setGreen() { BackgroundColour = colours.Green; - Triangles.ColourDark = colours.Green; - Triangles.ColourLight = colours.GreenLight; } } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerSpectateButton.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerSpectateButton.cs index b55a7d0731..51f11341cc 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerSpectateButton.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerSpectateButton.cs @@ -7,7 +7,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Graphics; -using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osuTK; @@ -24,11 +23,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match private IBindable operationInProgress; - private readonly ButtonWithTrianglesExposed button; + private readonly TriangleButton button; public MultiplayerSpectateButton() { - InternalChild = button = new ButtonWithTrianglesExposed + InternalChild = button = new TriangleButton { RelativeSizeAxes = Axes.Both, Size = Vector2.One, @@ -67,15 +66,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match default: button.Text = "Spectate"; button.BackgroundColour = colours.BlueDark; - button.Triangles.ColourDark = colours.BlueDarker; - button.Triangles.ColourLight = colours.Blue; break; case MultiplayerUserState.Spectating: button.Text = "Stop spectating"; button.BackgroundColour = colours.Gray4; - button.Triangles.ColourDark = colours.Gray5; - button.Triangles.ColourLight = colours.Gray6; break; } @@ -83,10 +78,5 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match && Client.Room.State != MultiplayerRoomState.Closed && !operationInProgress.Value; } - - private class ButtonWithTrianglesExposed : TriangleButton - { - public new Triangles Triangles => base.Triangles; - } } } diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs index b8ab514721..79933e606e 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs @@ -38,8 +38,6 @@ namespace osu.Game.Screens.OnlinePlay.Playlists private void load(OsuColour colours) { BackgroundColour = colours.Green; - Triangles.ColourDark = colours.Green; - Triangles.ColourLight = colours.GreenLight; } private bool hasRemainingAttempts = true; diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs index cd52981528..3c57ea5a3b 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs @@ -425,8 +425,6 @@ namespace osu.Game.Screens.OnlinePlay.Playlists private void load(OsuColour colours) { BackgroundColour = colours.Yellow; - Triangles.ColourLight = colours.YellowLight; - Triangles.ColourDark = colours.YellowDark; } } From 53b03df93d60da4b8d0c395ff997ca265f51ba59 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Nov 2022 16:26:57 +0900 Subject: [PATCH 0764/2991] Combine `TriangleButton` and `RoundedButton` classes --- .../TestScenePlaylistsMatchSettingsOverlay.cs | 3 ++- .../Visual/UserInterface/TestSceneLoadingLayer.cs | 5 +++-- .../Visual/UserInterface/TestSceneOsuPopover.cs | 8 ++++---- .../TestSceneScreenBreadcrumbControl.cs | 3 ++- .../Screens/Setup/ActionableInfo.cs | 2 +- .../Screens/Setup/StablePathSelectScreen.cs | 4 ++-- .../Screens/Setup/TournamentSwitcher.cs | 3 ++- ...TriangleButton.cs => DangerousRoundedButton.cs} | 3 ++- osu.Game/Graphics/UserInterface/TriangleButton.cs | 14 -------------- .../Overlays/BeatmapSet/Buttons/HeaderButton.cs | 4 ++-- .../Overlays/Dashboard/CurrentlyPlayingDisplay.cs | 2 +- .../Settings/Sections/Input/KeyBindingRow.cs | 5 +++-- .../Sections/Maintenance/DirectorySelectScreen.cs | 5 ++--- osu.Game/Screens/Import/FileImportScreen.cs | 5 ++--- .../Components/MatchBeatmapDetailArea.cs | 4 ++-- .../Screens/OnlinePlay/Components/ReadyButton.cs | 4 ++-- .../OnlinePlay/Lounge/DrawableLoungeRoom.cs | 4 ++-- .../Match/Components/CreateRoomButton.cs | 2 +- ...pleTriangleButton.cs => PurpleRoundedButton.cs} | 6 ++---- .../Screens/OnlinePlay/Match/DrawableMatchRoom.cs | 2 +- osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs | 2 +- .../Match/MultiplayerMatchSettingsOverlay.cs | 7 ++++--- .../Multiplayer/Match/MultiplayerSpectateButton.cs | 6 +++--- .../Multiplayer/MultiplayerMatchSubScreen.cs | 2 +- .../Playlists/PlaylistsRoomSettingsOverlay.cs | 9 +++++---- osu.Game/Screens/Play/SoloSpectator.cs | 6 +++--- .../Tests/Visual/OsuManualInputManagerTestScene.cs | 10 +++++----- 27 files changed, 60 insertions(+), 70 deletions(-) rename osu.Game/Graphics/UserInterface/{DangerousTriangleButton.cs => DangerousRoundedButton.cs} (80%) delete mode 100644 osu.Game/Graphics/UserInterface/TriangleButton.cs rename osu.Game/Screens/OnlinePlay/Match/Components/{PurpleTriangleButton.cs => PurpleRoundedButton.cs} (80%) diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs index c71bdb3a06..811135435c 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Online.Rooms; using osu.Game.Screens.OnlinePlay; using osu.Game.Screens.OnlinePlay.Playlists; @@ -148,7 +149,7 @@ namespace osu.Game.Tests.Visual.Playlists private class TestRoomSettings : PlaylistsRoomSettingsOverlay { - public TriangleButton ApplyButton => ((MatchSettings)Settings).ApplyButton; + public RoundedButton ApplyButton => ((MatchSettings)Settings).ApplyButton; public OsuTextBox NameField => ((MatchSettings)Settings).NameField; public OsuDropdown DurationField => ((MatchSettings)Settings).DurationField; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLoadingLayer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLoadingLayer.cs index 2fc6405b88..9afb93236e 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneLoadingLayer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLoadingLayer.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Utils; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; using osuTK; using osuTK.Graphics; @@ -49,8 +50,8 @@ namespace osu.Game.Tests.Visual.UserInterface Children = new Drawable[] { new OsuSpriteText { Text = "Sample content" }, - new TriangleButton { Text = "can't puush me", Width = 200, }, - new TriangleButton { Text = "puush me", Width = 200, Action = () => { } }, + new RoundedButton { Text = "can't puush me", Width = 200, }, + new RoundedButton { Text = "puush me", Width = 200, Action = () => { } }, } }, overlay = new TestLoadingLayer(true), diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuPopover.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuPopover.cs index 6cc89a6df8..e286578f56 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuPopover.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuPopover.cs @@ -33,7 +33,7 @@ namespace osu.Game.Tests.Visual.UserInterface Text = @"No OverlayColourProvider", Font = OsuFont.Default.With(size: 40) }, - new TriangleButtonWithPopover() + new RoundedButtonWithPopover() } }; @@ -50,15 +50,15 @@ namespace osu.Game.Tests.Visual.UserInterface Text = @"With OverlayColourProvider (orange)", Font = OsuFont.Default.With(size: 40) }, - new TriangleButtonWithPopover() + new RoundedButtonWithPopover() } } }; } - private class TriangleButtonWithPopover : TriangleButton, IHasPopover + private class RoundedButtonWithPopover : RoundedButton, IHasPopover { - public TriangleButtonWithPopover() + public RoundedButtonWithPopover() { Width = 100; Height = 30; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneScreenBreadcrumbControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneScreenBreadcrumbControl.cs index b3ee0af78b..7cfcc9de1f 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneScreenBreadcrumbControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneScreenBreadcrumbControl.cs @@ -11,6 +11,7 @@ using osu.Framework.Screens; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Screens; using osuTK; @@ -109,7 +110,7 @@ namespace osu.Game.Tests.Visual.UserInterface Origin = Anchor.TopCentre, Text = Title, }, - new TriangleButton + new RoundedButton { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, diff --git a/osu.Game.Tournament/Screens/Setup/ActionableInfo.cs b/osu.Game.Tournament/Screens/Setup/ActionableInfo.cs index a9ac21284e..1172c26ffa 100644 --- a/osu.Game.Tournament/Screens/Setup/ActionableInfo.cs +++ b/osu.Game.Tournament/Screens/Setup/ActionableInfo.cs @@ -61,7 +61,7 @@ namespace osu.Game.Tournament.Screens.Setup Spacing = new Vector2(10, 0), Children = new Drawable[] { - Button = new TriangleButton + Button = new RoundedButton { Size = new Vector2(100, 40), Action = () => Action?.Invoke() diff --git a/osu.Game.Tournament/Screens/Setup/StablePathSelectScreen.cs b/osu.Game.Tournament/Screens/Setup/StablePathSelectScreen.cs index fac488fcf5..32ac75178e 100644 --- a/osu.Game.Tournament/Screens/Setup/StablePathSelectScreen.cs +++ b/osu.Game.Tournament/Screens/Setup/StablePathSelectScreen.cs @@ -93,7 +93,7 @@ namespace osu.Game.Tournament.Screens.Setup Spacing = new Vector2(20), Children = new Drawable[] { - new TriangleButton + new RoundedButton { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -101,7 +101,7 @@ namespace osu.Game.Tournament.Screens.Setup Text = "Select stable path", Action = ChangePath }, - new TriangleButton + new RoundedButton { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Tournament/Screens/Setup/TournamentSwitcher.cs b/osu.Game.Tournament/Screens/Setup/TournamentSwitcher.cs index 447d6f44ce..1a1c90e96a 100644 --- a/osu.Game.Tournament/Screens/Setup/TournamentSwitcher.cs +++ b/osu.Game.Tournament/Screens/Setup/TournamentSwitcher.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Tournament.IO; namespace osu.Game.Tournament.Screens.Setup @@ -37,7 +38,7 @@ namespace osu.Game.Tournament.Screens.Setup { var drawable = base.CreateComponent(); - FlowContainer.Insert(-1, folderButton = new TriangleButton + FlowContainer.Insert(-1, folderButton = new RoundedButton { Text = "Open folder", Width = 100 diff --git a/osu.Game/Graphics/UserInterface/DangerousTriangleButton.cs b/osu.Game/Graphics/UserInterface/DangerousRoundedButton.cs similarity index 80% rename from osu.Game/Graphics/UserInterface/DangerousTriangleButton.cs rename to osu.Game/Graphics/UserInterface/DangerousRoundedButton.cs index 3c78cbb634..265ac01253 100644 --- a/osu.Game/Graphics/UserInterface/DangerousTriangleButton.cs +++ b/osu.Game/Graphics/UserInterface/DangerousRoundedButton.cs @@ -4,10 +4,11 @@ #nullable disable using osu.Framework.Allocation; +using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Graphics.UserInterface { - public class DangerousTriangleButton : TriangleButton + public class DangerousRoundedButton : RoundedButton { [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game/Graphics/UserInterface/TriangleButton.cs b/osu.Game/Graphics/UserInterface/TriangleButton.cs deleted file mode 100644 index 891c8f779f..0000000000 --- a/osu.Game/Graphics/UserInterface/TriangleButton.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Game.Graphics.UserInterfaceV2; - -namespace osu.Game.Graphics.UserInterface -{ - /// - /// A button with moving triangles in the background. - /// - public class TriangleButton : RoundedButton - { - } -} diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs index d6bf3464da..3b22ff594c 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs @@ -4,11 +4,11 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; -using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Overlays.BeatmapSet.Buttons { - public class HeaderButton : TriangleButton + public class HeaderButton : RoundedButton { public HeaderButton() { diff --git a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs index aae4932c22..571393f617 100644 --- a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs +++ b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs @@ -203,7 +203,7 @@ namespace osu.Game.Overlays.Dashboard Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, }, - new PurpleTriangleButton + new PurpleRoundedButton { RelativeSizeAxes = Axes.X, Text = "Spectate", diff --git a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs index 25ab8cfad2..386fee9d55 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs @@ -22,6 +22,7 @@ using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Input; using osu.Game.Input.Bindings; using osu.Game.Resources.Localisation.Web; @@ -446,7 +447,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input isDefault.Value = bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults); } - private class CancelButton : TriangleButton + private class CancelButton : RoundedButton { public CancelButton() { @@ -455,7 +456,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input } } - public class ClearButton : DangerousTriangleButton + public class ClearButton : DangerousRoundedButton { public ClearButton() { diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/DirectorySelectScreen.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/DirectorySelectScreen.cs index 1c9a758c6f..539600c7ca 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/DirectorySelectScreen.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/DirectorySelectScreen.cs @@ -13,7 +13,6 @@ using osuTK; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; -using osu.Game.Graphics.UserInterface; using osu.Framework.Screens; using osu.Game.Graphics.Containers; using osu.Game.Localisation; @@ -22,7 +21,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { public abstract class DirectorySelectScreen : OsuScreen { - private TriangleButton selectionButton; + private RoundedButton selectionButton; private OsuDirectorySelector directorySelector; @@ -101,7 +100,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance }, new Drawable[] { - selectionButton = new TriangleButton + selectionButton = new RoundedButton { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Screens/Import/FileImportScreen.cs b/osu.Game/Screens/Import/FileImportScreen.cs index e3d8de2dfd..e63fb95fc0 100644 --- a/osu.Game/Screens/Import/FileImportScreen.cs +++ b/osu.Game/Screens/Import/FileImportScreen.cs @@ -14,7 +14,6 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Screens; using osu.Game.Graphics; using osu.Game.Graphics.Containers; -using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; using osuTK; @@ -28,7 +27,7 @@ namespace osu.Game.Screens.Import private Container contentContainer; private TextFlowContainer currentFileText; - private TriangleButton importButton; + private RoundedButton importButton; private const float duration = 300; private const float button_height = 50; @@ -100,7 +99,7 @@ namespace osu.Game.Screens.Import } }, }, - importButton = new TriangleButton + importButton = new RoundedButton { Text = "Import", Anchor = Anchor.BottomCentre, diff --git a/osu.Game/Screens/OnlinePlay/Components/MatchBeatmapDetailArea.cs b/osu.Game/Screens/OnlinePlay/Components/MatchBeatmapDetailArea.cs index 9a48769405..6d477be568 100644 --- a/osu.Game/Screens/OnlinePlay/Components/MatchBeatmapDetailArea.cs +++ b/osu.Game/Screens/OnlinePlay/Components/MatchBeatmapDetailArea.cs @@ -9,7 +9,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Online.Rooms; using osu.Game.Screens.OnlinePlay.Playlists; using osu.Game.Screens.Select; @@ -54,7 +54,7 @@ namespace osu.Game.Screens.OnlinePlay.Components }, new Drawable[] { - new TriangleButton + new RoundedButton { Text = "Add new playlist entry", RelativeSizeAxes = Axes.Both, diff --git a/osu.Game/Screens/OnlinePlay/Components/ReadyButton.cs b/osu.Game/Screens/OnlinePlay/Components/ReadyButton.cs index 0871fc9a72..ae0f8cb3e4 100644 --- a/osu.Game/Screens/OnlinePlay/Components/ReadyButton.cs +++ b/osu.Game/Screens/OnlinePlay/Components/ReadyButton.cs @@ -7,13 +7,13 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Cursor; using osu.Framework.Localisation; -using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Online; using osu.Game.Online.Rooms; namespace osu.Game.Screens.OnlinePlay.Components { - public abstract class ReadyButton : TriangleButton, IHasTooltip + public abstract class ReadyButton : RoundedButton, IHasTooltip { public new readonly BindableBool Enabled = new BindableBool(); diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index 8a2aeb9e5e..c53324288d 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -197,7 +197,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge } private OsuPasswordTextBox passwordTextBox; - private TriangleButton joinButton; + private RoundedButton joinButton; private OsuSpriteText errorText; private Sample sampleJoinFail; @@ -226,7 +226,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge Width = 200, PlaceholderText = "password", }, - joinButton = new TriangleButton + joinButton = new RoundedButton { Width = 80, Text = "Join Room", diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/CreateRoomButton.cs b/osu.Game/Screens/OnlinePlay/Match/Components/CreateRoomButton.cs index 20e4b78eb4..4f42540146 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/CreateRoomButton.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/CreateRoomButton.cs @@ -10,7 +10,7 @@ using osu.Framework.Input.Events; namespace osu.Game.Screens.OnlinePlay.Match.Components { - public abstract class CreateRoomButton : PurpleTriangleButton, IKeyBindingHandler + public abstract class CreateRoomButton : PurpleRoundedButton, IKeyBindingHandler { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/PurpleTriangleButton.cs b/osu.Game/Screens/OnlinePlay/Match/Components/PurpleRoundedButton.cs similarity index 80% rename from osu.Game/Screens/OnlinePlay/Match/Components/PurpleTriangleButton.cs rename to osu.Game/Screens/OnlinePlay/Match/Components/PurpleRoundedButton.cs index c6df53c368..869806d21f 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/PurpleTriangleButton.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/PurpleRoundedButton.cs @@ -1,15 +1,13 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; -using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Screens.OnlinePlay.Match.Components { - public class PurpleTriangleButton : TriangleButton + public class PurpleRoundedButton : RoundedButton { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs b/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs index 7c444b9bbd..7b0b0bdaa4 100644 --- a/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs @@ -48,7 +48,7 @@ namespace osu.Game.Screens.OnlinePlay.Match { if (allowEdit) { - ButtonsContainer.Add(editButton = new PurpleTriangleButton + ButtonsContainer.Add(editButton = new PurpleRoundedButton { RelativeSizeAxes = Axes.Y, Size = new Vector2(100, 1), diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index 00c819e5e4..a4ef0297cf 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -517,7 +517,7 @@ namespace osu.Game.Screens.OnlinePlay.Match /// The room to change the settings of. protected abstract RoomSettingsOverlay CreateRoomSettingsOverlay(Room room); - public class UserModSelectButton : PurpleTriangleButton, IKeyBindingHandler + public class UserModSelectButton : PurpleRoundedButton, IKeyBindingHandler { public bool OnPressed(KeyBindingPressEvent e) { diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs index 17c361a420..6e0c81ab21 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs @@ -16,6 +16,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Online.Multiplayer; using osu.Game.Online.Rooms; using osu.Game.Overlays; @@ -64,7 +65,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match public OsuEnumDropdown QueueModeDropdown = null!; public OsuTextBox PasswordTextBox = null!; public OsuCheckbox AutoSkipCheckbox = null!; - public TriangleButton ApplyButton = null!; + public RoundedButton ApplyButton = null!; public OsuSpriteText ErrorText = null!; @@ -274,7 +275,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match RelativeSizeAxes = Axes.X, Height = DrawableRoomPlaylistItem.HEIGHT }, - new PurpleTriangleButton + new PurpleRoundedButton { RelativeSizeAxes = Axes.X, Height = 40, @@ -460,7 +461,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match }); } - public class CreateOrUpdateButton : TriangleButton + public class CreateOrUpdateButton : RoundedButton { [Resolved(typeof(Room), nameof(Room.RoomID))] private Bindable roomId { get; set; } = null!; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerSpectateButton.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerSpectateButton.cs index 51f11341cc..89b3e980e6 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerSpectateButton.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerSpectateButton.cs @@ -7,7 +7,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Graphics; -using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Online.Multiplayer; using osuTK; @@ -23,11 +23,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match private IBindable operationInProgress; - private readonly TriangleButton button; + private readonly RoundedButton button; public MultiplayerSpectateButton() { - InternalChild = button = new TriangleButton + InternalChild = button = new RoundedButton { RelativeSizeAxes = Axes.Both, Size = Vector2.One, diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index db752f2b42..969b8e61d3 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -430,7 +430,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer modSettingChangeTracker?.Dispose(); } - public class AddItemButton : PurpleTriangleButton + public class AddItemButton : PurpleRoundedButton { } } diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs index 3c57ea5a3b..e4fcf0cbac 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs @@ -16,6 +16,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Rooms; @@ -58,7 +59,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists public OsuTextBox NameField = null!, MaxParticipantsField = null!, MaxAttemptsField = null!; public OsuDropdown DurationField = null!; public RoomAvailabilityPicker AvailabilityPicker = null!; - public TriangleButton ApplyButton = null!; + public RoundedButton ApplyButton = null!; public bool IsLoading => loadingLayer.State.Value == Visibility.Visible; @@ -68,7 +69,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists private DrawableRoomPlaylist playlist = null!; private OsuSpriteText playlistLength = null!; - private PurpleTriangleButton editPlaylistButton = null!; + private PurpleRoundedButton editPlaylistButton = null!; [Resolved] private IRoomManager? manager { get; set; } @@ -222,7 +223,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists }, new Drawable[] { - editPlaylistButton = new PurpleTriangleButton + editPlaylistButton = new PurpleRoundedButton { RelativeSizeAxes = Axes.X, Height = 40, @@ -414,7 +415,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists } } - public class CreateRoomButton : TriangleButton + public class CreateRoomButton : RoundedButton { public CreateRoomButton() { diff --git a/osu.Game/Screens/Play/SoloSpectator.cs b/osu.Game/Screens/Play/SoloSpectator.cs index 9ef05c3a05..2f1c86e639 100644 --- a/osu.Game/Screens/Play/SoloSpectator.cs +++ b/osu.Game/Screens/Play/SoloSpectator.cs @@ -18,7 +18,7 @@ using osu.Game.Beatmaps.Drawables.Cards; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; @@ -54,7 +54,7 @@ namespace osu.Game.Screens.Play private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); private Container beatmapPanelContainer; - private TriangleButton watchButton; + private RoundedButton watchButton; private SettingsCheckbox automaticDownload; /// @@ -147,7 +147,7 @@ namespace osu.Game.Screens.Play Anchor = Anchor.Centre, Origin = Anchor.Centre, }, - watchButton = new PurpleTriangleButton + watchButton = new PurpleRoundedButton { Text = "Start Watching", Width = 250, diff --git a/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs b/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs index e56c546bac..3c569038b4 100644 --- a/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs +++ b/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs @@ -12,7 +12,7 @@ using osu.Framework.Testing; using osu.Framework.Testing.Input; using osu.Game.Graphics.Cursor; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Input.Bindings; using osuTK; using osuTK.Graphics; @@ -27,8 +27,8 @@ namespace osu.Game.Tests.Visual protected readonly ManualInputManager InputManager; - private readonly TriangleButton buttonTest; - private readonly TriangleButton buttonLocal; + private readonly RoundedButton buttonTest; + private readonly RoundedButton buttonLocal; /// /// Whether to create a nested container to handle s that result from local (manual) test input. @@ -110,13 +110,13 @@ namespace osu.Game.Tests.Visual Children = new Drawable[] { - buttonLocal = new TriangleButton + buttonLocal = new RoundedButton { Text = "local", Size = new Vector2(50, 30), Action = returnUserInput }, - buttonTest = new TriangleButton + buttonTest = new RoundedButton { Text = "test", Size = new Vector2(50, 30), From 6ad432b311a457d90bebf0fe55304fde76c8d005 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 24 Nov 2022 16:33:01 +0900 Subject: [PATCH 0765/2991] Use `RoundedButton` in more places --- osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs | 13 +++++++++---- .../Multiplayer/Match/MultiplayerCountdownButton.cs | 4 ++-- .../Match/MultiplayerMatchSettingsOverlay.cs | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs b/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs index 3d970284ec..4de4a14042 100644 --- a/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs +++ b/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -21,7 +22,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 protected override float HoverLayerFinalAlpha => 0; - private Color4 triangleGradientSecondColour = Color4.Transparent; + private Color4? triangleGradientSecondColour; public override float Height { @@ -53,7 +54,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 // Not sure this is the correct direction, but we haven't decided on an `OverlayColourProvider` stand-in yet. // This is a better default. See `SettingsButton` for an override which uses `OverlayColourProvider`. DefaultBackgroundColour = overlayColourProvider?.Colour3 ?? colours.Blue3; - triangleGradientSecondColour = overlayColourProvider?.Colour1 ?? colours.Blue3.Lighten(0.2f); + triangleGradientSecondColour ??= overlayColourProvider?.Colour1 ?? colours.Blue3.Lighten(0.2f); } protected override void LoadComplete() @@ -78,13 +79,17 @@ namespace osu.Game.Graphics.UserInterfaceV2 if (triangles == null) return; - triangles.ColourTop = triangleGradientSecondColour; + Debug.Assert(triangleGradientSecondColour != null); + + triangles.ColourTop = triangleGradientSecondColour.Value; triangles.ColourBottom = BackgroundColour; } protected override bool OnHover(HoverEvent e) { - Background.FadeColour(triangleGradientSecondColour, 300, Easing.OutQuint); + Debug.Assert(triangleGradientSecondColour != null); + + Background.FadeColour(triangleGradientSecondColour.Value, 300, Easing.OutQuint); return base.OnHover(e); } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerCountdownButton.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerCountdownButton.cs index cd94b47d9e..c28e6d36e9 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerCountdownButton.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerCountdownButton.cs @@ -109,7 +109,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match foreach (var duration in available_delays) { - flow.Add(new OsuButton + flow.Add(new RoundedButton { RelativeSizeAxes = Axes.X, Text = $"Start match in {duration.Humanize()}", @@ -124,7 +124,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match if (multiplayerClient.Room?.ActiveCountdowns.Any(c => c is MatchStartCountdown) == true && multiplayerClient.IsHost) { - flow.Add(new OsuButton + flow.Add(new RoundedButton { RelativeSizeAxes = Axes.X, Text = "Stop countdown", diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs index 6e0c81ab21..7c4b71b920 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs @@ -275,7 +275,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match RelativeSizeAxes = Axes.X, Height = DrawableRoomPlaylistItem.HEIGHT }, - new PurpleRoundedButton + new RoundedButton { RelativeSizeAxes = Axes.X, Height = 40, From 7b620392fe6430e8d8c948ef097839da219860ed Mon Sep 17 00:00:00 2001 From: Derrick Timmermans Date: Thu, 24 Nov 2022 13:13:45 +0100 Subject: [PATCH 0766/2991] Provide DrawableRulesetDependencies from HitObjectComposer --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 520fcb0290..d19ab2239e 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -79,7 +79,7 @@ namespace osu.Game.Rulesets.Edit } protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) => - dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); + dependencies = new DrawableRulesetDependencies(Ruleset, base.CreateChildDependencies(parent)); [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) From f6e229c24dd1e730a88807b8edcb3b38997f68ca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Nov 2022 01:15:11 +0900 Subject: [PATCH 0767/2991] "Fix" mod copy failure --- osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModMuted.cs | 4 ++-- osu.Game/Rulesets/Mods/ModMuted.cs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModMuted.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModMuted.cs index 68669d1a53..d7d24c99ee 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModMuted.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModMuted.cs @@ -45,8 +45,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods InverseMuting = { Value = false }, })); - AddAssert("mute combo count = 0", () => muted.MuteComboCount.Value == 0); - AddAssert("inverse muting = false", () => muted.InverseMuting.Value == false); + AddAssert("mute combo count copied", () => muted.MuteComboCount.Value, () => Is.EqualTo(0)); + AddAssert("inverse muting copied", () => muted.InverseMuting.Value, () => Is.False); } } } diff --git a/osu.Game/Rulesets/Mods/ModMuted.cs b/osu.Game/Rulesets/Mods/ModMuted.cs index 05ecd37000..27a777bff7 100644 --- a/osu.Game/Rulesets/Mods/ModMuted.cs +++ b/osu.Game/Rulesets/Mods/ModMuted.cs @@ -35,6 +35,9 @@ namespace osu.Game.Rulesets.Mods private readonly BindableNumber currentCombo = new BindableInt(); + [SettingSource("Start muted", "Increase volume as combo builds.")] + public BindableBool InverseMuting { get; } = new BindableBool(); + [SettingSource("Enable metronome", "Add a metronome beat to help you keep track of the rhythm.")] public BindableBool EnableMetronome { get; } = new BindableBool(true); @@ -45,9 +48,6 @@ namespace osu.Game.Rulesets.Mods MaxValue = 500, }; - [SettingSource("Start muted", "Increase volume as combo builds.")] - public BindableBool InverseMuting { get; } = new BindableBool(); - [SettingSource("Mute hit sounds", "Hit sounds are also muted alongside the track.")] public BindableBool AffectsHitSounds { get; } = new BindableBool(true); From ba0990d43e217fc4a7be954366549b4cdd2fe873 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Nov 2022 01:44:52 +0900 Subject: [PATCH 0768/2991] Update test assumptions --- .../Visual/UserInterface/TestSceneRoundedButton.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneRoundedButton.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneRoundedButton.cs index 178a68b599..6a8fe83176 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneRoundedButton.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneRoundedButton.cs @@ -9,7 +9,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; -using osu.Game.Graphics; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Overlays; using osu.Game.Overlays.Settings; @@ -56,8 +55,8 @@ namespace osu.Game.Tests.Visual.UserInterface public void TestBackgroundColour() { AddStep("set red scheme", () => CreateThemedContent(OverlayColourScheme.Red)); - AddAssert("rounded button has correct colour", () => Cell(0, 1).ChildrenOfType().First().BackgroundColour == new OsuColour().Blue3); - AddAssert("settings button has correct colour", () => Cell(0, 1).ChildrenOfType().First().BackgroundColour == new OverlayColourProvider(OverlayColourScheme.Red).Highlight1); + AddAssert("rounded button has correct colour", () => Cell(0, 1).ChildrenOfType().First().BackgroundColour == new OverlayColourProvider(OverlayColourScheme.Red).Colour3); + AddAssert("settings button has correct colour", () => Cell(0, 1).ChildrenOfType().First().BackgroundColour == new OverlayColourProvider(OverlayColourScheme.Red).Colour3); } } } From 65e5c9a3ae32c0786171d2a09d949e075569a5f7 Mon Sep 17 00:00:00 2001 From: Derrick Timmermans Date: Fri, 25 Nov 2022 08:27:22 +0100 Subject: [PATCH 0769/2991] Dispose DrawableRulesetDependencies in HitObjectComposer --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index d19ab2239e..d0164d0f2e 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Edit protected readonly Ruleset Ruleset; // Provides `Playfield` - private DependencyContainer dependencies; + private DrawableRulesetDependencies dependencies; [Resolved] protected EditorClock EditorClock { get; private set; } @@ -410,6 +410,13 @@ namespace osu.Game.Rulesets.Edit } #endregion + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + dependencies.Dispose(); + } } /// From 25410c9962ab4fb8d4e45314630987f3b0de0c76 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Nov 2022 19:47:55 +0900 Subject: [PATCH 0770/2991] Avoid changing ruleset when presenting a beatmap if it can be converted Closes #21415. --- osu.Game/OsuGame.cs | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index a93c187e53..7eae27eabd 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -520,11 +520,29 @@ namespace osu.Game } else { - Logger.Log($"Completing {nameof(PresentBeatmap)} with beatmap {beatmap} ruleset {selection.Ruleset}"); - Ruleset.Value = selection.Ruleset; - Beatmap.Value = BeatmapManager.GetWorkingBeatmap(selection); + // Don't change the local ruleset if the user is on another ruleset and is showing converted beatmaps at song select. + // Eventually we probably want to check whether conversion is actually possible for the current ruleset. + bool requiresRulesetSwitch = !selection.Ruleset.Equals(Ruleset.Value) + && (selection.Ruleset.OnlineID > 0 || !LocalConfig.Get(OsuSetting.ShowConvertedBeatmaps)); + + if (requiresRulesetSwitch) + { + Ruleset.Value = selection.Ruleset; + Beatmap.Value = BeatmapManager.GetWorkingBeatmap(selection); + + Logger.Log($"Completing {nameof(PresentBeatmap)} with beatmap {beatmap} ruleset {selection.Ruleset}"); + } + else + { + Beatmap.Value = BeatmapManager.GetWorkingBeatmap(selection); + + Logger.Log($"Completing {nameof(PresentBeatmap)} with beatmap {beatmap} (maintaining ruleset)"); + } } - }, validScreens: new[] { typeof(SongSelect), typeof(IHandlePresentBeatmap) }); + }, validScreens: new[] + { + typeof(SongSelect), typeof(IHandlePresentBeatmap) + }); } /// From 2425878e676c10205f54d74388630ebba518b237 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Nov 2022 20:06:36 +0900 Subject: [PATCH 0771/2991] Add test coverage --- .../Navigation/TestScenePresentBeatmap.cs | 66 ++++++++++++++----- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs index 02b348b439..ce8c8d4af5 100644 --- a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs +++ b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs @@ -9,8 +9,10 @@ using NUnit.Framework; using osu.Framework.Screens; using osu.Framework.Testing; using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Extensions; using osu.Game.Rulesets; +using osu.Game.Rulesets.Catch; using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Osu; using osu.Game.Screens.Menu; @@ -71,17 +73,51 @@ namespace osu.Game.Tests.Visual.Navigation } [Test] - public void TestFromSongSelectDifferentRuleset() + public void TestFromSongSelectDifferentRulesetWithConvertDisallowed() { - var firstImport = importBeatmap(1); - presentAndConfirm(firstImport); + AddStep("Set converts disallowed", () => Game.LocalConfig.SetValue(OsuSetting.ShowConvertedBeatmaps, false)); - var secondImport = importBeatmap(3, new ManiaRuleset().RulesetInfo); - confirmBeatmapInSongSelect(secondImport); - presentAndConfirm(secondImport); + var osuImport = importBeatmap(1); + presentAndConfirm(osuImport); - presentSecondDifficultyAndConfirm(firstImport, 1); - presentSecondDifficultyAndConfirm(secondImport, 3); + var maniaImport = importBeatmap(2, new ManiaRuleset().RulesetInfo); + confirmBeatmapInSongSelect(maniaImport); + presentAndConfirm(maniaImport); + + var catchImport = importBeatmap(3, new CatchRuleset().RulesetInfo); + confirmBeatmapInSongSelect(catchImport); + presentAndConfirm(catchImport); + + // Ruleset is always changed. + presentSecondDifficultyAndConfirm(maniaImport, 2); + presentSecondDifficultyAndConfirm(osuImport, 1); + presentSecondDifficultyAndConfirm(catchImport, 3); + } + + [Test] + public void TestFromSongSelectDifferentRulesetWithConvertAllowed() + { + AddStep("Set converts allowed", () => Game.LocalConfig.SetValue(OsuSetting.ShowConvertedBeatmaps, true)); + + var osuImport = importBeatmap(1); + presentAndConfirm(osuImport); + + var maniaImport = importBeatmap(2, new ManiaRuleset().RulesetInfo); + confirmBeatmapInSongSelect(maniaImport); + presentAndConfirm(maniaImport); + + var catchImport = importBeatmap(3, new CatchRuleset().RulesetInfo); + confirmBeatmapInSongSelect(catchImport); + presentAndConfirm(catchImport); + + // force ruleset to osu!mania + presentSecondDifficultyAndConfirm(maniaImport, 2); + + // ruleset is not changed as we can convert osu! beatmap. + presentSecondDifficultyAndConfirm(osuImport, 1, expectedRulesetOnlineID: 3); + + // ruleset is changed as we cannot convert. + presentSecondDifficultyAndConfirm(catchImport, 3); } private void returnToMenu() @@ -112,19 +148,19 @@ namespace osu.Game.Tests.Visual.Navigation imported = Game.BeatmapManager.Import(new BeatmapSetInfo { Hash = Guid.NewGuid().ToString(), - OnlineID = i, + OnlineID = i * 1024, Beatmaps = { new BeatmapInfo { - OnlineID = i * 1024, + OnlineID = i * 1024 + 1, Metadata = metadata, Difficulty = new BeatmapDifficulty(), Ruleset = ruleset ?? new OsuRuleset().RulesetInfo }, new BeatmapInfo { - OnlineID = i * 2048, + OnlineID = i * 1024 + 2, Metadata = metadata, Difficulty = new BeatmapDifficulty(), Ruleset = ruleset ?? new OsuRuleset().RulesetInfo @@ -156,14 +192,14 @@ namespace osu.Game.Tests.Visual.Navigation AddAssert("correct ruleset selected", () => Game.Ruleset.Value, () => Is.EqualTo(getImport().Beatmaps.First().Ruleset)); } - private void presentSecondDifficultyAndConfirm(Func getImport, int importedID) + private void presentSecondDifficultyAndConfirm(Func getImport, int importedID, int? expectedRulesetOnlineID = null) { - Predicate pred = b => b.OnlineID == importedID * 2048; + Predicate pred = b => b.OnlineID == importedID * 1024 + 2; AddStep("present difficulty", () => Game.PresentBeatmap(getImport(), pred)); AddUntilStep("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect songSelect && songSelect.IsLoaded); - AddUntilStep("correct beatmap displayed", () => Game.Beatmap.Value.BeatmapInfo.OnlineID, () => Is.EqualTo(importedID * 2048)); - AddAssert("correct ruleset selected", () => Game.Ruleset.Value, () => Is.EqualTo(getImport().Beatmaps.First().Ruleset)); + AddUntilStep("correct beatmap displayed", () => Game.Beatmap.Value.BeatmapInfo.OnlineID, () => Is.EqualTo(importedID * 1024 + 2)); + AddAssert("correct ruleset selected", () => Game.Ruleset.Value.OnlineID, () => Is.EqualTo(expectedRulesetOnlineID ?? getImport().Beatmaps.First().Ruleset.OnlineID)); } } } From 4cb068ceb9f495cbd311c57aa33d50959eef1984 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Nov 2022 20:10:04 +0900 Subject: [PATCH 0772/2991] Change `AimCount` to not consider height --- osu.Game/Graphics/Backgrounds/TrianglesV2.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs index 5fc32ff704..02ab9a9367 100644 --- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs +++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs @@ -172,7 +172,7 @@ namespace osu.Game.Graphics.Backgrounds // Limited by the maximum size of QuadVertexBuffer for safety. const int max_triangles = ushort.MaxValue / (IRenderer.VERTICES_PER_QUAD + 2); - AimCount = (int)Math.Min(max_triangles, DrawWidth * DrawHeight * 0.0005f * SpawnRatio); + AimCount = (int)Math.Min(max_triangles, DrawWidth * 0.02f * SpawnRatio); int currentCount = parts.Count; From b0f14d49633ecf9febd4fa90cb3e6ce08c5d8d36 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Nov 2022 20:14:21 +0900 Subject: [PATCH 0773/2991] Clamp `AimCount` to ensure at least one triangle is spawned --- osu.Game/Graphics/Backgrounds/TrianglesV2.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs index 02ab9a9367..77d30d50d6 100644 --- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs +++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs @@ -172,7 +172,7 @@ namespace osu.Game.Graphics.Backgrounds // Limited by the maximum size of QuadVertexBuffer for safety. const int max_triangles = ushort.MaxValue / (IRenderer.VERTICES_PER_QUAD + 2); - AimCount = (int)Math.Min(max_triangles, DrawWidth * 0.02f * SpawnRatio); + AimCount = (int)Math.Clamp(DrawWidth * 0.02f * SpawnRatio, 1, max_triangles); int currentCount = parts.Count; From d0c46376837c1e7cda2f771428eadda7d63cc44b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Nov 2022 20:18:21 +0900 Subject: [PATCH 0774/2991] Lighten colour of multiplayer create game button --- .../Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs index 7c4b71b920..ea4df23c4a 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs @@ -475,7 +475,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match [BackgroundDependencyLoader] private void load(OsuColour colours) { - BackgroundColour = colours.Yellow; + BackgroundColour = colours.YellowDark; } } From 76e9382e0be1812f50e9c5147717cf524bf0aca7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Nov 2022 20:18:35 +0900 Subject: [PATCH 0775/2991] Fix triangles showing on `ExpandableButton`s when in contracted state --- osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs | 10 +++++----- osu.Game/Rulesets/Edit/ExpandableButton.cs | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs b/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs index 4de4a14042..c40622190f 100644 --- a/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs +++ b/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs @@ -18,7 +18,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 { public class RoundedButton : OsuButton, IFilterable { - private TrianglesV2? triangles; + protected TrianglesV2? Triangles { get; private set; } protected override float HoverLayerFinalAlpha => 0; @@ -63,7 +63,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 updateCornerRadius(); - Add(triangles = new TrianglesV2 + Add(Triangles = new TrianglesV2 { Thickness = 0.02f, SpawnRatio = 0.6f, @@ -76,13 +76,13 @@ namespace osu.Game.Graphics.UserInterfaceV2 private void updateColours() { - if (triangles == null) + if (Triangles == null) return; Debug.Assert(triangleGradientSecondColour != null); - triangles.ColourTop = triangleGradientSecondColour.Value; - triangles.ColourBottom = BackgroundColour; + Triangles.ColourTop = triangleGradientSecondColour.Value; + Triangles.ColourBottom = BackgroundColour; } protected override bool OnHover(HoverEvent e) diff --git a/osu.Game/Rulesets/Edit/ExpandableButton.cs b/osu.Game/Rulesets/Edit/ExpandableButton.cs index a66600bd58..91bcc21c1b 100644 --- a/osu.Game/Rulesets/Edit/ExpandableButton.cs +++ b/osu.Game/Rulesets/Edit/ExpandableButton.cs @@ -86,6 +86,7 @@ namespace osu.Game.Rulesets.Edit SpriteText.Font = OsuFont.GetFont(weight: FontWeight.Bold); base.Height = actualHeight; Background.Show(); + Triangles?.Show(); } else { @@ -94,6 +95,7 @@ namespace osu.Game.Rulesets.Edit SpriteText.Font = OsuFont.GetFont(weight: FontWeight.Regular); base.Height = actualHeight / 2; Background.Hide(); + Triangles?.Hide(); } }, true); } From 5ada9efa60cbb984957d12869a2090441ca14d7e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 Nov 2022 22:10:20 +0900 Subject: [PATCH 0776/2991] Update outdated comment regarding colour choices --- osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs b/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs index c40622190f..fef9993932 100644 --- a/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs +++ b/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs @@ -50,9 +50,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 [BackgroundDependencyLoader(true)] private void load(OverlayColourProvider? overlayColourProvider, OsuColour colours) { - // According to flyte, buttons are supposed to have explicit colours for now. - // Not sure this is the correct direction, but we haven't decided on an `OverlayColourProvider` stand-in yet. - // This is a better default. See `SettingsButton` for an override which uses `OverlayColourProvider`. + // Many buttons have local colours, but this provides a sane default for all other cases. DefaultBackgroundColour = overlayColourProvider?.Colour3 ?? colours.Blue3; triangleGradientSecondColour ??= overlayColourProvider?.Colour1 ?? colours.Blue3.Lighten(0.2f); } From a2ea7a3f58f6177ed116bf297b9af92e017a0858 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 8 Sep 2022 02:20:48 +0800 Subject: [PATCH 0777/2991] show selected mod and use ILocalisedBindableString in np --- .../Online/TestSceneNowPlayingCommand.cs | 11 +++++ osu.Game/Online/Chat/NowPlayingCommand.cs | 48 +++++++++++++++---- 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs b/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs index 2df9089a8a..6dbe9a71d9 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs @@ -11,6 +11,7 @@ using osu.Game.Beatmaps; using osu.Game.Online.API; using osu.Game.Online.Chat; using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; using osu.Game.Users; namespace osu.Game.Tests.Visual.Online @@ -77,6 +78,16 @@ namespace osu.Game.Tests.Visual.Online AddAssert("Check link not present", () => !postTarget.LastMessage.Contains("https://")); } + [Test] + public void TestModPresence() + { + AddStep("Add Hidden mod", () => SelectedMods.Value = new[] { Ruleset.Value.CreateInstance().CreateMod() }); + + AddStep("Run command", () => Add(new NowPlayingCommand())); + + AddAssert("Check mod is present", () => postTarget.LastMessage.Contains("+Hidden")); + } + public class PostTarget : Component, IChannelPostTarget { public void PostMessage(string text, bool isAction = false, Channel target = null) diff --git a/osu.Game/Online/Chat/NowPlayingCommand.cs b/osu.Game/Online/Chat/NowPlayingCommand.cs index 6a25ceb919..ea44bd93d8 100644 --- a/osu.Game/Online/Chat/NowPlayingCommand.cs +++ b/osu.Game/Online/Chat/NowPlayingCommand.cs @@ -1,13 +1,15 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - +using System.Collections.Generic; +using System.Text; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Online.API; +using osu.Game.Rulesets.Mods; using osu.Game.Users; namespace osu.Game.Online.Chat @@ -15,21 +17,27 @@ namespace osu.Game.Online.Chat public class NowPlayingCommand : Component { [Resolved] - private IChannelPostTarget channelManager { get; set; } + private IChannelPostTarget channelManager { get; set; } = null!; [Resolved] - private IAPIProvider api { get; set; } + private IAPIProvider api { get; set; } = null!; [Resolved] - private Bindable currentBeatmap { get; set; } + private Bindable currentBeatmap { get; set; } = null!; - private readonly Channel target; + [Resolved] + private Bindable> selectedMods { get; set; } = null!; + + [Resolved] + private LocalisationManager localisation { get; set; } = null!; + + private readonly Channel? target; /// /// Creates a new to post the currently-playing beatmap to a parenting . /// /// The target channel to post to. If null, the currently-selected channel will be posted to. - public NowPlayingCommand(Channel target = null) + public NowPlayingCommand(Channel? target = null) { this.target = target; } @@ -59,9 +67,31 @@ namespace osu.Game.Online.Chat break; } - string beatmapString = beatmapInfo.OnlineID > 0 ? $"[{api.WebsiteRootUrl}/b/{beatmapInfo.OnlineID} {beatmapInfo}]" : beatmapInfo.ToString(); + string beatmapString() + { + string beatmapInfoString = localisation.GetLocalisedBindableString(beatmapInfo.GetDisplayTitleRomanisable()).Value; - channelManager.PostMessage($"is {verb} {beatmapString}", true, target); + return beatmapInfo.OnlineID > 0 ? $"[{api.WebsiteRootUrl}/b/{beatmapInfo.OnlineID} {beatmapInfoString}]" : beatmapInfoString; + } + + string modString() + { + if (selectedMods.Value.Count == 0) + { + return string.Empty; + } + + StringBuilder modS = new StringBuilder(); + + foreach (var mod in selectedMods.Value) + { + modS.Append($"+{mod.Name} "); + } + + return modS.ToString(); + } + + channelManager.PostMessage($"is {verb} {beatmapString()} {modString()}", true, target); Expire(); } } From bbbc1d0428c2aad95e138e8411520b50974d1fb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 25 Nov 2022 18:23:28 +0100 Subject: [PATCH 0778/2991] Darken colour of playlists create button To match d0c46376837c1e7cda2f771428eadda7d63cc44b. --- .../OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs index e4fcf0cbac..2ee55da77b 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs @@ -425,7 +425,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists [BackgroundDependencyLoader] private void load(OsuColour colours) { - BackgroundColour = colours.Yellow; + BackgroundColour = colours.YellowDark; } } From 92ed2ed4eff4516b292da3ebc58969589d64103a Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sat, 26 Nov 2022 12:19:08 +0100 Subject: [PATCH 0779/2991] Refactor star "DifficultyRangeFilterControl" into generic range slider class --- .../TestSceneDifficultyRangeFilterControl.cs | 28 --- .../UserInterface/TestSceneRangeSlider.cs | 60 +++++ .../Graphics/UserInterface/RangeSlider.cs | 210 ++++++++++++++++++ .../Select/DifficultyRangeFilterControl.cs | 152 ------------- osu.Game/Screens/Select/FilterControl.cs | 10 +- 5 files changed, 279 insertions(+), 181 deletions(-) delete mode 100644 osu.Game.Tests/Visual/SongSelect/TestSceneDifficultyRangeFilterControl.cs create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs create mode 100644 osu.Game/Graphics/UserInterface/RangeSlider.cs delete mode 100644 osu.Game/Screens/Select/DifficultyRangeFilterControl.cs diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneDifficultyRangeFilterControl.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneDifficultyRangeFilterControl.cs deleted file mode 100644 index 7ae2c6e5e2..0000000000 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneDifficultyRangeFilterControl.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using NUnit.Framework; -using osu.Framework.Graphics; -using osu.Game.Screens.Select; -using osuTK; - -namespace osu.Game.Tests.Visual.SongSelect -{ - public class TestSceneDifficultyRangeFilterControl : OsuTestScene - { - [Test] - public void TestBasic() - { - AddStep("create control", () => - { - Child = new DifficultyRangeFilterControl - { - Width = 200, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Scale = new Vector2(3), - }; - }); - } - } -} diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs new file mode 100644 index 0000000000..6a8a6304c8 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs @@ -0,0 +1,60 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays; +using osuTK; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneRangeSlider : OsuTestScene + { + [Cached] + private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); + + private readonly BindableNumber customStart = new BindableNumber + { + MinValue = 0, + MaxValue = 100, + Precision = 0.001f + }; + + private readonly BindableNumber customEnd = new BindableNumber(100) + { + MinValue = 0, + MaxValue = 100, + Precision = 0.1f + }; + + [Test] + public void TestBasic() + { + AddStep("create Control", () => Child = new RangeSlider + { + Width = 200, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Scale = new Vector2(3), + LowerBound = customStart, + UpperBound = customEnd, + TooltipSuffix = "suffix", + NubWidth = Nub.HEIGHT * 2, + DefaultStringLowerBound = "Start", + DefaultStringUpperBound = "End" + }); + AddStep("Test Range", () => + { + customStart.Value = 50; + customEnd.Value = 75; + }); + AddStep("Test nub pushing", () => + { + customStart.Value = 90; + }); + } + } +} diff --git a/osu.Game/Graphics/UserInterface/RangeSlider.cs b/osu.Game/Graphics/UserInterface/RangeSlider.cs new file mode 100644 index 0000000000..d654adf626 --- /dev/null +++ b/osu.Game/Graphics/UserInterface/RangeSlider.cs @@ -0,0 +1,210 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Input.Events; +using osu.Framework.Localisation; +using osu.Game.Graphics.Sprites; +using osu.Game.Overlays; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Graphics.UserInterface +{ + public class RangeSlider : CompositeDrawable + { + /// + /// The lower limiting value + /// + public Bindable LowerBound + { + set => lowerBound.Current = value; + } + + /// + /// The upper limiting value + /// + public Bindable UpperBound + { + set => upperBound.Current = value; + } + + /// + /// Text that describes this RangeSlider's functionality + /// + public string Label + { + set => label.Text = value; + } + + public float NubWidth + { + set => lowerBound.NubWidth = upperBound.NubWidth = value; + } + + /// + /// Minimum difference between the lower bound and higher bound + /// + public float MinRange + { + set => minRange = value; + } + + /// + /// lower bound display for when it is set to its default value + /// + public string DefaultStringLowerBound + { + set => lowerBound.DefaultString = value; + } + + /// + /// upper bound display for when it is set to its default value + /// + public string DefaultStringUpperBound + { + set => upperBound.DefaultString = value; + } + + public LocalisableString DefaultTooltipLowerBound + { + set => lowerBound.DefaultTooltip = value; + } + + public LocalisableString DefaultTooltipUpperBound + { + set => upperBound.DefaultTooltip = value; + } + + public string TooltipSuffix + { + set => upperBound.TooltipSuffix = lowerBound.TooltipSuffix = value; + } + + private float minRange = 0.1f; + + private readonly OsuSpriteText label; + + private readonly LowerBoundSlider lowerBound; + private readonly UpperBoundSlider upperBound; + + public RangeSlider() + { + const float vertical_offset = 13; + + InternalChildren = new Drawable[] + { + label = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 14), + }, + upperBound = new UpperBoundSlider + { + KeyboardStep = 0.1f, + RelativeSizeAxes = Axes.X, + Y = vertical_offset, + }, + lowerBound = new LowerBoundSlider + { + KeyboardStep = 0.1f, + RelativeSizeAxes = Axes.X, + Y = vertical_offset, + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + lowerBound.Current.ValueChanged += min => upperBound.Current.Value = Math.Max(min.NewValue + minRange, upperBound.Current.Value); + upperBound.Current.ValueChanged += max => lowerBound.Current.Value = Math.Min(max.NewValue - minRange, lowerBound.Current.Value); + } + + private class LowerBoundSlider : BoundSlider + { + protected override void LoadComplete() + { + base.LoadComplete(); + + LeftBox.Height = 6; // hide any colour bleeding from overlap + + AccentColour = BackgroundColour; + BackgroundColour = Color4.Transparent; + } + + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => + base.ReceivePositionalInputAt(screenSpacePos) + && screenSpacePos.X <= Nub.ScreenSpaceDrawQuad.TopRight.X; + } + + private class UpperBoundSlider : BoundSlider + { + protected override void LoadComplete() + { + base.LoadComplete(); + + RightBox.Height = 6; // just to match the left bar height really + } + + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => + base.ReceivePositionalInputAt(screenSpacePos) + && screenSpacePos.X >= Nub.ScreenSpaceDrawQuad.TopLeft.X; + } + + protected class BoundSlider : OsuSliderBar + { + public string? DefaultString; + public LocalisableString? DefaultTooltip; + public string? TooltipSuffix; + public float NubWidth { get; set; } = Nub.HEIGHT; + + public override LocalisableString TooltipText => + (Current.IsDefault ? DefaultTooltip : Current.Value.ToString($@"0.## {TooltipSuffix}")) ?? Current.Value.ToString($@"0.## {TooltipSuffix}"); + + protected override bool OnHover(HoverEvent e) + { + base.OnHover(e); + return true; // Make sure only one nub shows hover effect at once. + } + + protected override void LoadComplete() + { + base.LoadComplete(); + Nub.Width = NubWidth; + RangePadding = Nub.Width / 2; + + OsuSpriteText currentDisplay; + + Nub.Add(currentDisplay = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Y = -0.5f, + Colour = Color4.White, + Font = OsuFont.Torus.With(size: 10), + }); + + Current.BindValueChanged(current => + { + currentDisplay.Text = (current.NewValue != Current.Default ? current.NewValue.ToString("N1") : DefaultString) ?? current.NewValue.ToString("N1"); + }, true); + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider? colourProvider) + { + if (colourProvider == null) return; + + AccentColour = colourProvider.Background2; + Nub.AccentColour = colourProvider.Background2; + Nub.GlowingAccentColour = colourProvider.Background1; + Nub.GlowColour = colourProvider.Background2; + } + } + } +} diff --git a/osu.Game/Screens/Select/DifficultyRangeFilterControl.cs b/osu.Game/Screens/Select/DifficultyRangeFilterControl.cs deleted file mode 100644 index 45e7ff4caa..0000000000 --- a/osu.Game/Screens/Select/DifficultyRangeFilterControl.cs +++ /dev/null @@ -1,152 +0,0 @@ -// 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.Allocation; -using osu.Framework.Bindables; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Input.Events; -using osu.Framework.Localisation; -using osu.Game.Configuration; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using osu.Game.Localisation; -using osuTK; -using osuTK.Graphics; - -namespace osu.Game.Screens.Select -{ - internal class DifficultyRangeFilterControl : CompositeDrawable - { - private Bindable lowerStars = null!; - private Bindable upperStars = null!; - - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) - { - const float vertical_offset = 13; - - InternalChildren = new Drawable[] - { - new OsuSpriteText - { - Text = "Difficulty range", - Font = OsuFont.GetFont(size: 14), - }, - new MaximumStarsSlider - { - Current = config.GetBindable(OsuSetting.DisplayStarsMaximum), - KeyboardStep = 0.1f, - RelativeSizeAxes = Axes.X, - Y = vertical_offset, - }, - new MinimumStarsSlider - { - Current = config.GetBindable(OsuSetting.DisplayStarsMinimum), - KeyboardStep = 0.1f, - RelativeSizeAxes = Axes.X, - Y = vertical_offset, - } - }; - - lowerStars = config.GetBindable(OsuSetting.DisplayStarsMinimum); - upperStars = config.GetBindable(OsuSetting.DisplayStarsMaximum); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - lowerStars.ValueChanged += min => upperStars.Value = Math.Max(min.NewValue + 0.1, upperStars.Value); - upperStars.ValueChanged += max => lowerStars.Value = Math.Min(max.NewValue - 0.1, lowerStars.Value); - } - - private class MinimumStarsSlider : StarsSlider - { - public MinimumStarsSlider() - : base("0") - { - } - - public override LocalisableString TooltipText => Current.Value.ToString(@"0.## stars"); - - protected override void LoadComplete() - { - base.LoadComplete(); - - LeftBox.Height = 6; // hide any colour bleeding from overlap - - AccentColour = BackgroundColour; - BackgroundColour = Color4.Transparent; - } - - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => - base.ReceivePositionalInputAt(screenSpacePos) - && screenSpacePos.X <= Nub.ScreenSpaceDrawQuad.TopRight.X; - } - - private class MaximumStarsSlider : StarsSlider - { - public MaximumStarsSlider() - : base("∞") - { - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - RightBox.Height = 6; // just to match the left bar height really - } - - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => - base.ReceivePositionalInputAt(screenSpacePos) - && screenSpacePos.X >= Nub.ScreenSpaceDrawQuad.TopLeft.X; - } - - private class StarsSlider : OsuSliderBar - { - private readonly string defaultString; - - public override LocalisableString TooltipText => Current.IsDefault - ? UserInterfaceStrings.NoLimit - : Current.Value.ToString(@"0.## stars"); - - protected StarsSlider(string defaultString) - { - this.defaultString = defaultString; - } - - protected override bool OnHover(HoverEvent e) - { - base.OnHover(e); - return true; // Make sure only one nub shows hover effect at once. - } - - protected override void LoadComplete() - { - base.LoadComplete(); - Nub.Width = Nub.HEIGHT; - RangePadding = Nub.Width / 2; - - OsuSpriteText currentDisplay; - - Nub.Add(currentDisplay = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Y = -0.5f, - Colour = Color4.White, - Font = OsuFont.Torus.With(size: 10), - }); - - Current.BindValueChanged(current => - { - currentDisplay.Text = current.NewValue != Current.Default ? current.NewValue.ToString("N1") : defaultString; - }, true); - } - } - } -} diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index ae82285fba..91ba394416 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -16,6 +16,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Resources.Localisation.Web; using osu.Game.Rulesets; using osu.Game.Screens.Select.Filter; @@ -172,12 +173,19 @@ namespace osu.Game.Screens.Select Height = 40, Children = new Drawable[] { - new DifficultyRangeFilterControl + new RangeSlider { Anchor = Anchor.TopLeft, Origin = Anchor.TopLeft, + Label = "Difficulty range", + LowerBound = config.GetBindable(OsuSetting.DisplayStarsMinimum), + UpperBound = config.GetBindable(OsuSetting.DisplayStarsMaximum), RelativeSizeAxes = Axes.Both, Width = 0.48f, + DefaultStringLowerBound = "0", + DefaultStringUpperBound = "∞", + DefaultTooltipUpperBound = UserInterfaceStrings.NoLimit, + TooltipSuffix = "stars" }, collectionDropdown = new CollectionDropdown { From 1ebaf4963d2cc71c8de39f473cba4d0414f6b432 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sat, 26 Nov 2022 13:59:05 +0100 Subject: [PATCH 0780/2991] Improve tests slightly --- .../Visual/UserInterface/TestSceneRangeSlider.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs index 6a8a6304c8..189a6b61f5 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs @@ -14,13 +14,13 @@ namespace osu.Game.Tests.Visual.UserInterface public class TestSceneRangeSlider : OsuTestScene { [Cached] - private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); + private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Red); private readonly BindableNumber customStart = new BindableNumber { MinValue = 0, MaxValue = 100, - Precision = 0.001f + Precision = 0.1f }; private readonly BindableNumber customEnd = new BindableNumber(100) @@ -44,7 +44,8 @@ namespace osu.Game.Tests.Visual.UserInterface TooltipSuffix = "suffix", NubWidth = Nub.HEIGHT * 2, DefaultStringLowerBound = "Start", - DefaultStringUpperBound = "End" + DefaultStringUpperBound = "End", + MinRange = 10 }); AddStep("Test Range", () => { From a1c559ae0597f71ba96c2c8cb872aef54cc34060 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 27 Nov 2022 00:00:12 +0900 Subject: [PATCH 0781/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index eab3c1fe11..b1d6231210 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index cd32ff2fd1..9d7ef7fb22 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 4426eba75a..ae0bc2d0c0 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From 7bc8908ca9c026fed1d831eb6e58df7624a8d614 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Thu, 24 Nov 2022 14:32:20 +0900 Subject: [PATCH 0782/2991] Partial everything --- .../TestSceneOsuGame.cs | 2 +- .../TestSceneOsuPlayer.cs | 2 +- .../EmptyFreeformInputManager.cs | 2 +- .../EmptyFreeformRuleset.cs | 4 ++-- .../DrawableEmptyFreeformHitObject.cs | 2 +- .../UI/DrawableEmptyFreeformRuleset.cs | 2 +- .../UI/EmptyFreeformPlayfield.cs | 2 +- .../TestSceneOsuGame.cs | 2 +- .../TestSceneOsuPlayer.cs | 2 +- .../Drawables/DrawablePippidonHitObject.cs | 2 +- .../PippidonInputManager.cs | 2 +- .../PippidonRulesetIcon.cs | 2 +- .../UI/DrawablePippidonRuleset.cs | 2 +- .../UI/PippidonCursorContainer.cs | 2 +- .../UI/PippidonPlayfield.cs | 2 +- .../PippidonPlayfieldAdjustmentContainer.cs | 2 +- .../TestSceneOsuGame.cs | 2 +- .../TestSceneOsuPlayer.cs | 2 +- .../EmptyScrollingInputManager.cs | 2 +- .../DrawableEmptyScrollingHitObject.cs | 2 +- .../UI/DrawableEmptyScrollingRuleset.cs | 2 +- .../UI/EmptyScrollingPlayfield.cs | 2 +- .../TestSceneOsuGame.cs | 2 +- .../TestSceneOsuPlayer.cs | 2 +- .../Drawables/DrawablePippidonHitObject.cs | 2 +- .../PippidonInputManager.cs | 2 +- .../PippidonRulesetIcon.cs | 2 +- .../UI/DrawablePippidonRuleset.cs | 2 +- .../UI/PippidonCharacter.cs | 2 +- .../UI/PippidonPlayfield.cs | 6 +++--- osu.Desktop/DiscordRichPresence.cs | 2 +- osu.Desktop/OsuGameDesktop.cs | 2 +- .../Security/ElevatedPrivilegesChecker.cs | 4 ++-- osu.Desktop/Updater/SquirrelUpdateManager.cs | 2 +- osu.Desktop/Windows/GameplayWinKeyBlocker.cs | 2 +- .../CatchSkinnableTestScene.cs | 2 +- .../Editor/CatchEditorTestSceneContainer.cs | 4 ++-- .../CatchPlacementBlueprintTestScene.cs | 2 +- .../CatchSelectionBlueprintTestScene.cs | 4 ++-- ...TestSceneBananaShowerPlacementBlueprint.cs | 2 +- .../Editor/TestSceneCatchDistanceSnapGrid.cs | 2 +- .../Editor/TestSceneEditor.cs | 2 +- .../TestSceneFruitPlacementBlueprint.cs | 2 +- .../TestSceneJuiceStreamPlacementBlueprint.cs | 2 +- .../TestSceneJuiceStreamSelectionBlueprint.cs | 2 +- .../Mods/TestSceneCatchModFlashlight.cs | 2 +- .../Mods/TestSceneCatchModNoScope.cs | 2 +- .../Mods/TestSceneCatchModPerfect.cs | 2 +- .../Mods/TestSceneCatchModRelax.cs | 2 +- .../TestSceneAutoJuiceStream.cs | 2 +- .../TestSceneBananaShower.cs | 2 +- .../TestSceneCatchModHidden.cs | 2 +- .../TestSceneCatchPlayer.cs | 2 +- .../TestSceneCatchPlayerLegacySkin.cs | 2 +- .../TestSceneCatchReplay.cs | 2 +- .../TestSceneCatchSkinConfiguration.cs | 2 +- .../TestSceneCatchStacker.cs | 2 +- .../TestSceneCatchTouchInput.cs | 2 +- .../TestSceneCatcher.cs | 4 ++-- .../TestSceneCatcherArea.cs | 4 ++-- .../TestSceneComboCounter.cs | 2 +- .../TestSceneDrawableHitObjects.cs | 2 +- .../TestSceneDrawableHitObjectsHidden.cs | 2 +- .../TestSceneFruitObjects.cs | 4 ++-- .../TestSceneFruitRandomness.cs | 2 +- .../TestSceneFruitVisualChange.cs | 2 +- .../TestSceneHyperDash.cs | 2 +- .../TestSceneHyperDashColouring.cs | 2 +- .../TestSceneJuiceStream.cs | 2 +- .../TestSceneLegacyBeatmapSkin.cs | 4 ++-- osu.Game.Rulesets.Catch/CatchInputManager.cs | 2 +- .../BananaShowerPlacementBlueprint.cs | 2 +- .../BananaShowerSelectionBlueprint.cs | 2 +- .../Blueprints/CatchPlacementBlueprint.cs | 2 +- .../Blueprints/CatchSelectionBlueprint.cs | 2 +- .../Blueprints/Components/EditablePath.cs | 2 +- .../Blueprints/Components/FruitOutline.cs | 2 +- .../Components/NestedOutlineContainer.cs | 2 +- .../Components/PlacementEditablePath.cs | 2 +- .../Blueprints/Components/ScrollingPath.cs | 2 +- .../Components/SelectionEditablePath.cs | 2 +- .../Blueprints/Components/TimeSpanOutline.cs | 2 +- .../Edit/Blueprints/Components/VertexPiece.cs | 2 +- .../Blueprints/FruitPlacementBlueprint.cs | 2 +- .../Blueprints/FruitSelectionBlueprint.cs | 2 +- .../JuiceStreamPlacementBlueprint.cs | 2 +- .../JuiceStreamSelectionBlueprint.cs | 2 +- .../Edit/CatchBlueprintContainer.cs | 2 +- .../Edit/CatchDistanceSnapGrid.cs | 2 +- .../Edit/CatchEditorPlayfield.cs | 2 +- ...CatchEditorPlayfieldAdjustmentContainer.cs | 4 ++-- .../Edit/CatchHitObjectComposer.cs | 2 +- .../Edit/CatchSelectionHandler.cs | 2 +- .../Edit/DrawableCatchEditorRuleset.cs | 2 +- .../Mods/CatchModFlashlight.cs | 4 ++-- osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs | 4 ++-- .../Objects/Drawables/CaughtBanana.cs | 2 +- .../Objects/Drawables/CaughtDroplet.cs | 2 +- .../Objects/Drawables/CaughtFruit.cs | 2 +- .../Objects/Drawables/CaughtObject.cs | 2 +- .../Objects/Drawables/DrawableBanana.cs | 2 +- .../Objects/Drawables/DrawableBananaShower.cs | 2 +- .../Drawables/DrawableCatchHitObject.cs | 2 +- .../Objects/Drawables/DrawableDroplet.cs | 2 +- .../Objects/Drawables/DrawableFruit.cs | 2 +- .../Objects/Drawables/DrawableJuiceStream.cs | 2 +- .../DrawablePalpableCatchHitObject.cs | 2 +- .../Objects/Drawables/DrawableTinyDroplet.cs | 2 +- .../Scoring/CatchScoreProcessor.cs | 2 +- .../Skinning/Argon/ArgonBananaPiece.cs | 2 +- .../Skinning/Argon/ArgonCatcher.cs | 2 +- .../Skinning/Argon/ArgonDropletPiece.cs | 2 +- .../Skinning/Argon/ArgonFruitPiece.cs | 2 +- .../Skinning/Argon/ArgonHitExplosion.cs | 2 +- .../Skinning/Argon/ArgonJudgementPiece.cs | 6 +++--- .../Skinning/Default/BananaPiece.cs | 2 +- .../Skinning/Default/BananaPulpFormation.cs | 2 +- .../Skinning/Default/BorderPiece.cs | 2 +- .../Skinning/Default/CatchHitObjectPiece.cs | 2 +- .../Skinning/Default/DefaultCatcher.cs | 2 +- .../Skinning/Default/DefaultHitExplosion.cs | 2 +- .../Skinning/Default/DropletPiece.cs | 2 +- .../Skinning/Default/FruitPiece.cs | 2 +- .../Skinning/Default/FruitPulpFormation.cs | 2 +- .../Skinning/Default/HyperBorderPiece.cs | 2 +- .../Default/HyperDropletBorderPiece.cs | 2 +- .../Skinning/Default/Pulp.cs | 2 +- .../Skinning/Default/PulpFormation.cs | 2 +- .../Skinning/Legacy/LegacyBananaPiece.cs | 2 +- .../Legacy/LegacyCatchComboCounter.cs | 2 +- .../Legacy/LegacyCatchHitObjectPiece.cs | 2 +- .../Skinning/Legacy/LegacyCatcherNew.cs | 2 +- .../Skinning/Legacy/LegacyCatcherOld.cs | 2 +- .../Skinning/Legacy/LegacyDropletPiece.cs | 2 +- .../Skinning/Legacy/LegacyFruitPiece.cs | 2 +- .../Skinning/Legacy/LegacyHitExplosion.cs | 2 +- .../UI/CatchComboDisplay.cs | 2 +- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 2 +- .../UI/CatchPlayfieldAdjustmentContainer.cs | 4 ++-- .../UI/CatchReplayRecorder.cs | 2 +- .../UI/CatchTouchInputMapper.cs | 4 ++-- osu.Game.Rulesets.Catch/UI/Catcher.cs | 2 +- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 2 +- osu.Game.Rulesets.Catch/UI/CatcherTrail.cs | 2 +- .../UI/CatcherTrailDisplay.cs | 2 +- .../UI/DrawableCatchRuleset.cs | 2 +- .../UI/DroppedObjectContainer.cs | 2 +- osu.Game.Rulesets.Catch/UI/HitExplosion.cs | 2 +- .../UI/HitExplosionContainer.cs | 2 +- .../UI/SkinnableCatcher.cs | 2 +- .../ManiaPlacementBlueprintTestScene.cs | 2 +- .../ManiaSelectionBlueprintTestScene.cs | 2 +- .../Editor/TestSceneEditor.cs | 2 +- .../TestSceneHoldNotePlacementBlueprint.cs | 2 +- .../TestSceneHoldNoteSelectionBlueprint.cs | 2 +- .../Editor/TestSceneManiaBeatSnapGrid.cs | 4 ++-- .../Editor/TestSceneManiaComposeScreen.cs | 2 +- .../Editor/TestSceneManiaHitObjectComposer.cs | 4 ++-- .../Editor/TestSceneNotePlacementBlueprint.cs | 2 +- .../Editor/TestSceneNoteSelectionBlueprint.cs | 2 +- .../ManiaInputTestScene.cs | 6 +++--- .../Mods/TestSceneManiaModConstantSpeed.cs | 2 +- .../Mods/TestSceneManiaModFlashlight.cs | 2 +- .../Mods/TestSceneManiaModHoldOff.cs | 2 +- .../Mods/TestSceneManiaModInvert.cs | 2 +- .../Mods/TestSceneManiaModPerfect.cs | 2 +- .../Skinning/ColumnTestContainer.cs | 2 +- .../Skinning/ManiaHitObjectTestScene.cs | 2 +- .../Skinning/ManiaSkinnableTestScene.cs | 2 +- .../Skinning/TestSceneBarLine.cs | 2 +- .../Skinning/TestSceneColumnBackground.cs | 2 +- .../Skinning/TestSceneColumnHitObjectArea.cs | 2 +- .../Skinning/TestSceneDrawableJudgement.cs | 2 +- .../Skinning/TestSceneHitExplosion.cs | 2 +- .../Skinning/TestSceneHoldNote.cs | 2 +- .../Skinning/TestSceneNote.cs | 2 +- .../Skinning/TestScenePlayfield.cs | 2 +- .../Skinning/TestSceneStage.cs | 2 +- .../Skinning/TestSceneStageBackground.cs | 2 +- .../Skinning/TestSceneStageForeground.cs | 2 +- .../TestSceneAutoGeneration.cs | 2 +- .../TestSceneColumn.cs | 2 +- .../TestSceneDrawableManiaHitObject.cs | 2 +- .../TestSceneHoldNoteInput.cs | 4 ++-- .../TestSceneManiaHitObjectSamples.cs | 2 +- .../TestSceneManiaPlayer.cs | 2 +- .../TestSceneNotes.cs | 4 ++-- .../TestSceneOutOfOrderHits.cs | 4 ++-- .../TestScenePlayfieldCoveringContainer.cs | 2 +- .../TestSceneStage.cs | 2 +- .../TestSceneTimingBasedNoteColouring.cs | 2 +- .../Blueprints/Components/EditBodyPiece.cs | 2 +- .../Blueprints/Components/EditNotePiece.cs | 2 +- .../Blueprints/HoldNotePlacementBlueprint.cs | 2 +- .../Blueprints/HoldNoteSelectionBlueprint.cs | 2 +- .../Blueprints/ManiaPlacementBlueprint.cs | 2 +- .../Blueprints/ManiaSelectionBlueprint.cs | 2 +- .../Edit/Blueprints/NotePlacementBlueprint.cs | 2 +- .../Edit/Blueprints/NoteSelectionBlueprint.cs | 2 +- .../Edit/DrawableManiaEditorRuleset.cs | 2 +- .../Edit/ManiaBeatSnapGrid.cs | 4 ++-- .../Edit/ManiaBlueprintContainer.cs | 2 +- .../Edit/ManiaEditorPlayfield.cs | 2 +- .../Edit/ManiaHitObjectComposer.cs | 2 +- .../Edit/ManiaSelectionHandler.cs | 2 +- .../Edit/Setup/ManiaSetupSection.cs | 2 +- osu.Game.Rulesets.Mania/ManiaInputManager.cs | 2 +- .../ManiaSettingsSubsection.cs | 4 ++-- .../Mods/ManiaModFlashlight.cs | 4 ++-- .../Objects/Drawables/DrawableBarLine.cs | 2 +- .../Objects/Drawables/DrawableHoldNote.cs | 2 +- .../Objects/Drawables/DrawableHoldNoteHead.cs | 2 +- .../Objects/Drawables/DrawableHoldNoteTail.cs | 2 +- .../Objects/Drawables/DrawableHoldNoteTick.cs | 2 +- .../Drawables/DrawableManiaHitObject.cs | 4 ++-- .../Objects/Drawables/DrawableNote.cs | 2 +- .../Scoring/ManiaHealthProcessor.cs | 2 +- .../Scoring/ManiaScoreProcessor.cs | 2 +- .../Skinning/Argon/ArgonColumnBackground.cs | 2 +- .../Skinning/Argon/ArgonHitExplosion.cs | 2 +- .../Skinning/Argon/ArgonHitTarget.cs | 2 +- .../Skinning/Argon/ArgonHoldBodyPiece.cs | 2 +- .../Skinning/Argon/ArgonHoldNoteTailPiece.cs | 2 +- .../Skinning/Argon/ArgonJudgementPiece.cs | 6 +++--- .../Skinning/Argon/ArgonKeyArea.cs | 2 +- .../Skinning/Argon/ArgonNotePiece.cs | 2 +- .../Skinning/Argon/ArgonStageBackground.cs | 2 +- .../Skinning/Default/DefaultBodyPiece.cs | 4 ++-- .../Skinning/Default/DefaultNotePiece.cs | 2 +- .../Legacy/HitTargetInsetContainer.cs | 2 +- .../Skinning/Legacy/LegacyBodyPiece.cs | 2 +- .../Skinning/Legacy/LegacyColumnBackground.cs | 2 +- .../Skinning/Legacy/LegacyHitExplosion.cs | 2 +- .../Skinning/Legacy/LegacyHitTarget.cs | 2 +- .../Legacy/LegacyHoldNoteHeadPiece.cs | 2 +- .../Legacy/LegacyHoldNoteTailPiece.cs | 2 +- .../Skinning/Legacy/LegacyKeyArea.cs | 2 +- .../Legacy/LegacyManiaColumnElement.cs | 2 +- .../Legacy/LegacyManiaJudgementPiece.cs | 2 +- .../Skinning/Legacy/LegacyNotePiece.cs | 2 +- .../Skinning/Legacy/LegacyStageBackground.cs | 4 ++-- .../Skinning/Legacy/LegacyStageForeground.cs | 2 +- osu.Game.Rulesets.Mania/UI/Column.cs | 4 ++-- osu.Game.Rulesets.Mania/UI/ColumnFlow.cs | 2 +- .../UI/Components/ColumnHitObjectArea.cs | 2 +- .../UI/Components/DefaultColumnBackground.cs | 2 +- .../UI/Components/DefaultHitTarget.cs | 2 +- .../UI/Components/DefaultKeyArea.cs | 2 +- .../UI/Components/DefaultStageBackground.cs | 2 +- .../UI/Components/HitObjectArea.cs | 2 +- .../UI/DefaultHitExplosion.cs | 2 +- .../UI/DrawableManiaJudgement.cs | 4 ++-- .../UI/DrawableManiaRuleset.cs | 2 +- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 2 +- .../UI/ManiaPlayfieldAdjustmentContainer.cs | 2 +- .../UI/ManiaReplayRecorder.cs | 2 +- .../UI/PlayfieldCoveringWrapper.cs | 2 +- .../UI/PoolableHitExplosion.cs | 2 +- osu.Game.Rulesets.Mania/UI/Stage.cs | 2 +- .../TestSceneHitCirclePlacementBlueprint.cs | 2 +- .../TestSceneHitCircleSelectionBlueprint.cs | 4 ++-- .../Editor/TestSceneObjectBeatSnap.cs | 2 +- .../Editor/TestSceneObjectMerging.cs | 2 +- .../Editor/TestSceneObjectObjectSnap.cs | 2 +- .../Editor/TestSceneOsuComposerSelection.cs | 2 +- .../Editor/TestSceneOsuDistanceSnapGrid.cs | 4 ++-- .../Editor/TestSceneOsuEditor.cs | 2 +- .../Editor/TestSceneOsuEditorGrids.cs | 2 +- .../TestSceneOsuEditorSelectInvalidPath.cs | 2 +- .../TestScenePathControlPointVisualiser.cs | 2 +- .../TestSceneSliderControlPointPiece.cs | 6 +++--- .../Editor/TestSceneSliderLengthValidity.cs | 2 +- .../TestSceneSliderPlacementBlueprint.cs | 2 +- .../TestSceneSliderSelectionBlueprint.cs | 6 +++--- .../Editor/TestSceneSliderSnapping.cs | 2 +- .../Editor/TestSceneSliderSplitting.cs | 2 +- .../Editor/TestSceneSliderStreamConversion.cs | 2 +- .../Editor/TestSceneSliderVelocityAdjust.cs | 2 +- .../TestSceneSpinnerPlacementBlueprint.cs | 2 +- .../TestSceneSpinnerSelectionBlueprint.cs | 2 +- .../Editor/TestSliderScaling.cs | 2 +- .../LegacyMainCirclePieceTest.cs | 4 ++-- .../Mods/OsuModTestScene.cs | 2 +- .../Mods/TestSceneOsuModAlternate.cs | 2 +- .../Mods/TestSceneOsuModAutoplay.cs | 2 +- .../Mods/TestSceneOsuModDifficultyAdjust.cs | 2 +- .../Mods/TestSceneOsuModDoubleTime.cs | 2 +- .../Mods/TestSceneOsuModFlashlight.cs | 2 +- .../Mods/TestSceneOsuModFreezeFrame.cs | 2 +- .../Mods/TestSceneOsuModHidden.cs | 2 +- .../Mods/TestSceneOsuModMagnetised.cs | 2 +- .../Mods/TestSceneOsuModMuted.cs | 2 +- .../Mods/TestSceneOsuModNoScope.cs | 2 +- .../Mods/TestSceneOsuModPerfect.cs | 2 +- .../Mods/TestSceneOsuModRandom.cs | 2 +- .../Mods/TestSceneOsuModRepel.cs | 2 +- .../Mods/TestSceneOsuModSingleTap.cs | 2 +- .../Mods/TestSceneOsuModSpunOut.cs | 2 +- .../OsuSkinnableTestScene.cs | 2 +- .../TestPlayfieldBorder.cs | 2 +- .../TestSceneAccuracyHeatmap.cs | 6 +++--- .../TestSceneCursorParticles.cs | 2 +- .../TestSceneCursorTrail.cs | 6 +++--- .../TestSceneDrawableJudgement.cs | 4 ++-- .../TestSceneFollowPoints.cs | 4 ++-- .../TestSceneGameplayCursor.cs | 6 +++--- .../TestSceneHitCircle.cs | 6 +++--- .../TestSceneHitCircleApplication.cs | 2 +- .../TestSceneHitCircleArea.cs | 2 +- .../TestSceneHitCircleComboChange.cs | 2 +- .../TestSceneHitCircleHidden.cs | 2 +- .../TestSceneHitCircleKiai.cs | 2 +- .../TestSceneHitCircleLongCombo.cs | 2 +- .../TestSceneLegacyBeatmapSkin.cs | 2 +- .../TestSceneMissHitWindowJudgements.cs | 2 +- .../TestSceneNoSpinnerStacking.cs | 2 +- .../TestSceneObjectOrderedHitPolicy.cs | 4 ++-- .../TestSceneOsuHitObjectSamples.cs | 2 +- .../TestSceneOsuPlayer.cs | 2 +- .../TestSceneResumeOverlay.cs | 4 ++-- .../TestSceneShaking.cs | 2 +- .../TestSceneSkinFallbacks.cs | 4 ++-- .../TestSceneSlider.cs | 2 +- .../TestSceneSliderApplication.cs | 2 +- .../TestSceneSliderComboChange.cs | 2 +- .../TestSceneSliderFollowCircleInput.cs | 4 ++-- .../TestSceneSliderHidden.cs | 2 +- .../TestSceneSliderInput.cs | 4 ++-- .../TestSceneSliderSnaking.cs | 2 +- osu.Game.Rulesets.Osu.Tests/TestSceneSmoke.cs | 6 +++--- .../TestSceneSpinner.cs | 4 ++-- .../TestSceneSpinnerApplication.cs | 2 +- .../TestSceneSpinnerHidden.cs | 2 +- .../TestSceneSpinnerRotation.cs | 4 ++-- .../TestSceneStartTimeOrderedHitPolicy.cs | 4 ++-- .../TestSceneTrianglesSpinnerRotation.cs | 4 ++-- .../Edit/Blueprints/BlueprintPiece.cs | 2 +- .../Components/HitCircleOverlapMarker.cs | 2 +- .../HitCircles/Components/HitCirclePiece.cs | 2 +- .../HitCircles/HitCirclePlacementBlueprint.cs | 2 +- .../HitCircles/HitCircleSelectionBlueprint.cs | 2 +- .../Edit/Blueprints/OsuSelectionBlueprint.cs | 2 +- .../PathControlPointConnectionPiece.cs | 2 +- .../Components/PathControlPointPiece.cs | 2 +- .../Components/PathControlPointVisualiser.cs | 2 +- .../Sliders/Components/SliderBodyPiece.cs | 2 +- .../Blueprints/Sliders/SliderCircleOverlay.cs | 2 +- .../Sliders/SliderPlacementBlueprint.cs | 2 +- .../Sliders/SliderSelectionBlueprint.cs | 2 +- .../Spinners/Components/SpinnerPiece.cs | 2 +- .../Spinners/SpinnerPlacementBlueprint.cs | 2 +- .../Spinners/SpinnerSelectionBlueprint.cs | 2 +- .../Edit/DrawableOsuEditorRuleset.cs | 4 ++-- .../Edit/OsuBlueprintContainer.cs | 2 +- .../Edit/OsuDistanceSnapGrid.cs | 2 +- .../Edit/OsuHitObjectComposer.cs | 2 +- .../Edit/OsuRectangularPositionSnapGrid.cs | 2 +- .../Edit/OsuSelectionHandler.cs | 2 +- .../Edit/Setup/OsuSetupSection.cs | 2 +- .../Mods/InputBlockingMod.cs | 4 ++-- osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs | 6 +++--- .../Mods/OsuModFlashlight.cs | 4 ++-- .../Mods/OsuModStrictTracking.cs | 4 ++-- .../Drawables/Connections/FollowPoint.cs | 2 +- .../Connections/FollowPointConnection.cs | 2 +- .../Connections/FollowPointRenderer.cs | 2 +- .../Objects/Drawables/DrawableHitCircle.cs | 6 +++--- .../Objects/Drawables/DrawableOsuHitObject.cs | 2 +- .../Objects/Drawables/DrawableOsuJudgement.cs | 4 ++-- .../Objects/Drawables/DrawableSlider.cs | 4 ++-- .../Objects/Drawables/DrawableSliderBall.cs | 2 +- .../Objects/Drawables/DrawableSliderHead.cs | 2 +- .../Objects/Drawables/DrawableSliderRepeat.cs | 2 +- .../Objects/Drawables/DrawableSliderTail.cs | 2 +- .../Objects/Drawables/DrawableSliderTick.cs | 2 +- .../Objects/Drawables/DrawableSpinner.cs | 2 +- .../Drawables/DrawableSpinnerBonusTick.cs | 2 +- .../Objects/Drawables/DrawableSpinnerTick.cs | 2 +- .../Objects/Drawables/SkinnableLighting.cs | 2 +- osu.Game.Rulesets.Osu/OsuInputManager.cs | 4 ++-- .../Scoring/OsuScoreProcessor.cs | 2 +- .../Skinning/Argon/ArgonCursor.cs | 2 +- .../Skinning/Argon/ArgonCursorTrail.cs | 2 +- .../Skinning/Argon/ArgonFollowCircle.cs | 2 +- .../Skinning/Argon/ArgonFollowPoint.cs | 2 +- .../Skinning/Argon/ArgonJudgementPiece.cs | 4 ++-- .../Skinning/Argon/ArgonMainCirclePiece.cs | 4 ++-- .../Skinning/Argon/ArgonReverseArrow.cs | 2 +- .../Skinning/Argon/ArgonSliderBall.cs | 2 +- .../Skinning/Argon/ArgonSliderBody.cs | 4 ++-- .../Skinning/Argon/ArgonSliderScorePoint.cs | 2 +- .../Skinning/Argon/ArgonSpinner.cs | 2 +- .../Skinning/Argon/ArgonSpinnerDisc.cs | 2 +- .../Skinning/Argon/ArgonSpinnerProgressArc.cs | 2 +- .../Skinning/Argon/ArgonSpinnerRingArc.cs | 2 +- .../Skinning/Argon/ArgonSpinnerTicks.cs | 2 +- .../Skinning/Default/CirclePiece.cs | 2 +- .../Skinning/Default/DefaultApproachCircle.cs | 2 +- .../Skinning/Default/DefaultFollowCircle.cs | 2 +- .../Skinning/Default/DefaultSliderBall.cs | 2 +- .../Skinning/Default/DefaultSmokeSegment.cs | 2 +- .../Skinning/Default/DefaultSpinner.cs | 2 +- .../Skinning/Default/DefaultSpinnerDisc.cs | 2 +- .../Skinning/Default/DrawableSliderPath.cs | 2 +- .../Skinning/Default/ExplodePiece.cs | 2 +- .../Skinning/Default/FlashPiece.cs | 2 +- .../Skinning/Default/GlowPiece.cs | 2 +- .../Skinning/Default/KiaiFlash.cs | 2 +- .../Skinning/Default/MainCirclePiece.cs | 2 +- .../Skinning/Default/ManualSliderBody.cs | 2 +- .../Skinning/Default/NumberPiece.cs | 2 +- .../Skinning/Default/PlaySliderBody.cs | 2 +- .../Skinning/Default/ReverseArrowPiece.cs | 2 +- .../Skinning/Default/RingPiece.cs | 2 +- .../Default/SpinnerBackgroundLayer.cs | 2 +- .../Skinning/Default/SpinnerCentreLayer.cs | 2 +- .../Skinning/Default/SpinnerFill.cs | 2 +- .../Default/SpinnerRotationTracker.cs | 2 +- .../Skinning/Default/SpinnerSpmCalculator.cs | 2 +- .../Skinning/Default/SpinnerTicks.cs | 2 +- .../Skinning/Default/TrianglesPiece.cs | 2 +- .../Skinning/FollowCircle.cs | 2 +- .../Skinning/Legacy/LegacyApproachCircle.cs | 2 +- .../Skinning/Legacy/LegacyCursor.cs | 2 +- .../Skinning/Legacy/LegacyCursorParticles.cs | 4 ++-- .../Skinning/Legacy/LegacyCursorTrail.cs | 2 +- .../Skinning/Legacy/LegacyFollowCircle.cs | 2 +- .../Skinning/Legacy/LegacyMainCirclePiece.cs | 2 +- .../Skinning/Legacy/LegacyNewStyleSpinner.cs | 2 +- .../Skinning/Legacy/LegacyOldStyleSpinner.cs | 2 +- .../Skinning/Legacy/LegacyReverseArrow.cs | 2 +- .../Skinning/Legacy/LegacySliderBall.cs | 2 +- .../Skinning/Legacy/LegacySliderBody.cs | 4 ++-- .../Legacy/LegacySliderHeadHitCircle.cs | 2 +- .../Skinning/Legacy/LegacySmokeSegment.cs | 2 +- .../Skinning/Legacy/LegacySpinner.cs | 2 +- .../Skinning/NonPlayfieldSprite.cs | 2 +- osu.Game.Rulesets.Osu/Skinning/SliderBody.cs | 4 ++-- .../Skinning/SmokeSegment.cs | 2 +- .../Skinning/SnakingSliderBody.cs | 2 +- .../Statistics/AccuracyHeatmap.cs | 4 ++-- .../UI/Cursor/CursorTrail.cs | 2 +- osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs | 4 ++-- .../UI/Cursor/OsuCursorContainer.cs | 4 ++-- .../UI/Cursor/OsuCursorSprite.cs | 2 +- .../UI/DrawableOsuRuleset.cs | 2 +- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 6 +++--- .../UI/OsuPlayfieldAdjustmentContainer.cs | 4 ++-- osu.Game.Rulesets.Osu/UI/OsuReplayRecorder.cs | 2 +- osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs | 4 ++-- .../UI/OsuSettingsSubsection.cs | 2 +- osu.Game.Rulesets.Osu/UI/SmokeContainer.cs | 4 ++-- .../DrawableTaikoRulesetTestScene.cs | 2 +- .../DrawableTestHit.cs | 2 +- .../DrawableTestStrongHit.cs | 2 +- .../Editor/TestSceneEditor.cs | 2 +- .../Editor/TestSceneTaikoEditorSaving.cs | 2 +- .../Editor/TestSceneTaikoHitObjectComposer.cs | 4 ++-- .../HitObjectApplicationTestScene.cs | 2 +- .../Judgements/JudgementTest.cs | 4 ++-- .../Judgements/TestSceneDrumRollJudgements.cs | 2 +- .../Judgements/TestSceneHitJudgements.cs | 2 +- .../Judgements/TestSceneSwellJudgements.cs | 2 +- .../Mods/TaikoModTestScene.cs | 2 +- .../Mods/TestSceneTaikoModFlashlight.cs | 6 +++--- .../Mods/TestSceneTaikoModHidden.cs | 2 +- .../Mods/TestSceneTaikoModPerfect.cs | 6 +++--- .../Skinning/TaikoSkinnableTestScene.cs | 2 +- .../Skinning/TestSceneDrawableBarLine.cs | 2 +- .../Skinning/TestSceneDrawableDrumRoll.cs | 2 +- .../Skinning/TestSceneDrawableHit.cs | 2 +- .../Skinning/TestSceneDrawableSwell.cs | 2 +- .../Skinning/TestSceneDrawableTaikoMascot.cs | 2 +- .../Skinning/TestSceneHitExplosion.cs | 2 +- .../Skinning/TestSceneInputDrum.cs | 2 +- .../Skinning/TestSceneKiaiHitExplosion.cs | 2 +- .../Skinning/TestSceneTaikoPlayfield.cs | 2 +- .../Skinning/TestSceneTaikoScroller.cs | 2 +- .../TestSceneBarLineApplication.cs | 2 +- .../TestSceneBarLineGeneration.cs | 2 +- .../TestSceneDrumRollApplication.cs | 2 +- .../TestSceneDrumTouchInputArea.cs | 2 +- .../TestSceneFlyingHits.cs | 2 +- .../TestSceneHitApplication.cs | 2 +- .../TestSceneHits.cs | 2 +- .../TestSceneSampleOutput.cs | 2 +- .../TestSceneTaikoHitObjectSamples.cs | 2 +- .../TestSceneTaikoPlayer.cs | 2 +- .../TestSceneTaikoPlayerLegacySkin.cs | 2 +- .../TestSceneTaikoSuddenDeath.cs | 2 +- .../Blueprints/DrumRollPlacementBlueprint.cs | 2 +- .../Edit/Blueprints/HitPiece.cs | 2 +- .../Edit/Blueprints/HitPlacementBlueprint.cs | 2 +- .../Edit/Blueprints/LengthPiece.cs | 2 +- .../Blueprints/SwellPlacementBlueprint.cs | 2 +- .../Blueprints/TaikoSelectionBlueprint.cs | 2 +- .../Blueprints/TaikoSpanPlacementBlueprint.cs | 2 +- .../Edit/TaikoBlueprintContainer.cs | 2 +- .../Edit/TaikoHitObjectComposer.cs | 2 +- .../Edit/TaikoSelectionHandler.cs | 2 +- .../Mods/TaikoModFlashlight.cs | 4 ++-- .../Objects/Drawables/DrawableBarLine.cs | 2 +- .../Objects/Drawables/DrawableDrumRoll.cs | 4 ++-- .../Objects/Drawables/DrawableDrumRollTick.cs | 4 ++-- .../Objects/Drawables/DrawableFlyingHit.cs | 2 +- .../Objects/Drawables/DrawableHit.cs | 4 ++-- .../Drawables/DrawableStrongNestedHit.cs | 2 +- .../Objects/Drawables/DrawableSwell.cs | 2 +- .../Objects/Drawables/DrawableSwellTick.cs | 2 +- .../Drawables/DrawableTaikoHitObject.cs | 6 +++--- .../DrawableTaikoStrongableHitObject.cs | 2 +- .../Scoring/TaikoHealthProcessor.cs | 2 +- .../Scoring/TaikoScoreProcessor.cs | 2 +- .../Skinning/Argon/ArgonBarLine.cs | 2 +- .../Skinning/Argon/ArgonCentreCirclePiece.cs | 2 +- .../Skinning/Argon/ArgonCirclePiece.cs | 2 +- .../Argon/ArgonElongatedCirclePiece.cs | 2 +- .../Skinning/Argon/ArgonHitExplosion.cs | 2 +- .../Skinning/Argon/ArgonHitTarget.cs | 2 +- .../Skinning/Argon/ArgonInputDrum.cs | 4 ++-- .../Skinning/Argon/ArgonJudgementPiece.cs | 6 +++--- .../Argon/ArgonPlayfieldBackgroundLeft.cs | 2 +- .../Argon/ArgonPlayfieldBackgroundRight.cs | 2 +- .../Skinning/Argon/ArgonRimCirclePiece.cs | 2 +- .../Skinning/Argon/ArgonSwellCirclePiece.cs | 2 +- .../Skinning/Argon/ArgonTickPiece.cs | 2 +- .../Skinning/Argon/RingPiece.cs | 2 +- .../Skinning/Default/CentreHitCirclePiece.cs | 4 ++-- .../Skinning/Default/CirclePiece.cs | 2 +- .../Skinning/Default/DefaultBarLine.cs | 2 +- .../Skinning/Default/DefaultHitExplosion.cs | 2 +- .../Skinning/Default/DefaultInputDrum.cs | 4 ++-- .../Skinning/Default/DefaultJudgementPiece.cs | 2 +- .../Default/DefaultKiaiHitExplosion.cs | 2 +- .../Skinning/Default/ElongatedCirclePiece.cs | 2 +- .../Skinning/Default/RimHitCirclePiece.cs | 4 ++-- .../Skinning/Default/SwellSymbolPiece.cs | 4 ++-- .../Skinning/Default/TickPiece.cs | 2 +- .../Skinning/Legacy/LegacyBarLine.cs | 2 +- .../Skinning/Legacy/LegacyCirclePiece.cs | 2 +- .../Skinning/Legacy/LegacyDrumRoll.cs | 2 +- .../Skinning/Legacy/LegacyHit.cs | 2 +- .../Skinning/Legacy/LegacyHitExplosion.cs | 2 +- .../Skinning/Legacy/LegacyInputDrum.cs | 4 ++-- .../Skinning/Legacy/LegacyTaikoScroller.cs | 4 ++-- .../Skinning/Legacy/TaikoLegacyHitTarget.cs | 2 +- .../TaikoLegacyPlayfieldBackgroundRight.cs | 2 +- osu.Game.Rulesets.Taiko/TaikoInputManager.cs | 2 +- .../UI/BarLinePlayfield.cs | 2 +- .../UI/DrawableTaikoJudgement.cs | 2 +- .../UI/DrawableTaikoMascot.cs | 2 +- .../UI/DrawableTaikoRuleset.cs | 2 +- .../UI/DrumRollHitContainer.cs | 2 +- .../UI/DrumSamplePlayer.cs | 2 +- .../UI/DrumSampleTriggerSource.cs | 2 +- .../UI/DrumTouchInputArea.cs | 4 ++-- osu.Game.Rulesets.Taiko/UI/HitExplosion.cs | 2 +- .../UI/HitExplosionPool.cs | 2 +- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 2 +- .../UI/KiaiHitExplosion.cs | 2 +- .../UI/PlayfieldBackgroundLeft.cs | 2 +- .../UI/PlayfieldBackgroundRight.cs | 2 +- osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs | 2 +- .../UI/TaikoMascotAnimation.cs | 6 +++--- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 4 ++-- .../UI/TaikoPlayfieldAdjustmentContainer.cs | 2 +- .../UI/TaikoReplayRecorder.cs | 2 +- .../TestSceneBeatmapDifficultyCache.cs | 4 ++-- .../Beatmaps/TestSceneEditorBeatmap.cs | 2 +- .../Beatmaps/WorkingBeatmapManagerTest.cs | 2 +- .../Chat/TestSceneChannelManager.cs | 4 ++-- .../BackgroundBeatmapProcessorTests.cs | 4 ++-- osu.Game.Tests/Database/RealmTest.cs | 4 ++-- .../Database/TestRealmKeyBindingStore.cs | 4 ++-- ...tSceneHitObjectComposerDistanceSnapping.cs | 4 ++-- .../TestSceneHitObjectContainerEventBuffer.cs | 8 ++++---- .../TransactionalCommitComponentTest.cs | 4 ++-- .../TestSceneDrainingHealthProcessor.cs | 2 +- .../Gameplay/TestSceneDrawableHitObject.cs | 4 ++-- .../TestSceneHitObjectAccentColour.cs | 4 ++-- .../Gameplay/TestSceneHitObjectContainer.cs | 4 ++-- .../Gameplay/TestSceneHitObjectSamples.cs | 2 +- .../TestSceneMasterGameplayClockContainer.cs | 2 +- .../Gameplay/TestSceneProxyContainer.cs | 6 +++--- .../Gameplay/TestSceneScoreProcessor.cs | 2 +- .../Gameplay/TestSceneStoryboardSamples.cs | 4 ++-- osu.Game.Tests/ImportTest.cs | 4 ++-- .../Input/ConfineMouseTrackerTest.cs | 2 +- .../Mods/SettingsSourceAttributeTest.cs | 6 +++--- .../NonVisual/FirstAvailableHitWindowsTest.cs | 4 ++-- .../NonVisual/GameplayClockContainerTest.cs | 4 ++-- .../StatefulMultiplayerClientTest.cs | 2 +- .../NonVisual/OngoingOperationTrackerTest.cs | 4 ++-- .../Skinning/LegacySkinAnimationTest.cs | 2 +- .../Online/TestDummyAPIRequestHandling.cs | 2 +- .../Online/TestSceneBeatmapDownloading.cs | 2 +- ...eneOnlinePlayBeatmapAvailabilityTracker.cs | 2 +- .../OnlinePlay/TestSceneCatchUpSyncManager.cs | 2 +- .../Rulesets/Scoring/ScoreProcessorTest.cs | 4 ++-- .../TestSceneBrokenRulesetHandling.cs | 2 +- .../TestSceneDrawableRulesetDependencies.cs | 4 ++-- .../TestSceneRulesetSkinProvidingContainer.cs | 4 ++-- .../TestSceneBeatmapSkinLookupDisables.cs | 4 ++-- .../Skins/TestSceneBeatmapSkinResources.cs | 2 +- .../Skins/TestSceneSkinConfigurationLookup.cs | 4 ++-- .../Skins/TestSceneSkinProvidingContainer.cs | 4 ++-- .../Skins/TestSceneSkinResources.cs | 2 +- .../Testing/TestSceneRulesetDependencies.cs | 2 +- .../Visual/Audio/TestSceneAudioFilter.cs | 2 +- .../TestSceneBackgroundScreenDefault.cs | 8 ++++---- .../TestSceneSeasonalBackgroundLoader.cs | 2 +- .../TestSceneTrianglesBackground.cs | 2 +- .../Background/TestSceneUserDimBackgrounds.cs | 14 ++++++------- .../Background/TestSceneUserDimContainer.cs | 4 ++-- .../Visual/Beatmaps/TestSceneBeatmapCard.cs | 2 +- .../TestSceneBeatmapCardDifficultyList.cs | 2 +- .../TestSceneBeatmapCardDownloadButton.cs | 2 +- .../TestSceneBeatmapCardFavouriteButton.cs | 2 +- .../Beatmaps/TestSceneBeatmapCardThumbnail.cs | 2 +- .../TestSceneBeatmapSetOnlineStatusPill.cs | 2 +- .../TestSceneDifficultySpectrumDisplay.cs | 2 +- .../TestSceneManageCollectionsDialog.cs | 2 +- .../Colours/TestSceneStarDifficultyColours.cs | 2 +- .../Visual/Components/TestSceneIdleTracker.cs | 4 ++-- .../Components/TestScenePollingComponent.cs | 6 +++--- .../TestScenePreviewTrackManager.cs | 8 ++++---- .../Editing/TestSceneBeatDivisorControl.cs | 2 +- .../Editing/TestSceneBlueprintOrdering.cs | 2 +- .../Visual/Editing/TestSceneComposeScreen.cs | 2 +- .../Editing/TestSceneComposeSelectBox.cs | 2 +- .../Editing/TestSceneComposerSelection.cs | 2 +- .../Visual/Editing/TestSceneDesignSection.cs | 4 ++-- .../Editing/TestSceneDifficultyDelete.cs | 2 +- .../Editing/TestSceneDifficultySwitching.cs | 2 +- .../Editing/TestSceneDistanceSnapGrid.cs | 4 ++-- .../Editing/TestSceneEditorBeatmapCreation.cs | 2 +- .../Visual/Editing/TestSceneEditorBindings.cs | 2 +- .../Editing/TestSceneEditorChangeStates.cs | 2 +- .../Editing/TestSceneEditorClipboard.cs | 2 +- .../Visual/Editing/TestSceneEditorClock.cs | 2 +- .../TestSceneEditorComposeRadioButtons.cs | 2 +- .../Visual/Editing/TestSceneEditorMenuBar.cs | 2 +- .../Editing/TestSceneEditorNavigation.cs | 2 +- .../Editing/TestSceneEditorSamplePlayback.cs | 2 +- .../Visual/Editing/TestSceneEditorSaving.cs | 2 +- .../Editing/TestSceneEditorScreenModes.cs | 2 +- .../Editing/TestSceneEditorSeekSnapping.cs | 6 +++--- .../Visual/Editing/TestSceneEditorSeeking.cs | 2 +- .../Editing/TestSceneEditorSummaryTimeline.cs | 2 +- .../Editing/TestSceneEditorTestGameplay.cs | 2 +- .../Editing/TestSceneHitObjectComposer.cs | 4 ++-- ...ceneHitObjectDifficultyPointAdjustments.cs | 2 +- ...estSceneHitObjectSamplePointAdjustments.cs | 2 +- .../Editing/TestSceneLabelledTimeSignature.cs | 2 +- .../Editing/TestSceneMetadataSection.cs | 4 ++-- .../Editing/TestScenePlaybackControl.cs | 2 +- .../TestSceneRectangularPositionSnapGrid.cs | 4 ++-- .../TestSceneSelectionBlueprintDeselection.cs | 2 +- .../Visual/Editing/TestSceneSetupScreen.cs | 2 +- .../Visual/Editing/TestSceneTapButton.cs | 2 +- .../Editing/TestSceneTapTimingControl.cs | 2 +- .../TestSceneTimelineBlueprintContainer.cs | 2 +- .../TestSceneTimelineHitObjectBlueprint.cs | 2 +- .../Editing/TestSceneTimelineSelection.cs | 2 +- .../Editing/TestSceneTimelineTickDisplay.cs | 2 +- .../Visual/Editing/TestSceneTimelineZoom.cs | 2 +- .../Visual/Editing/TestSceneTimingScreen.cs | 2 +- .../Visual/Editing/TestSceneWaveform.cs | 4 ++-- .../TestSceneZoomableScrollContainer.cs | 2 +- .../Visual/Editing/TimelineTestScene.cs | 6 +++--- .../Visual/Gameplay/OsuPlayerTestScene.cs | 2 +- .../SkinnableHUDComponentTestScene.cs | 2 +- .../Gameplay/TestSceneAllRulesetPlayers.cs | 2 +- .../Visual/Gameplay/TestSceneAutoplay.cs | 2 +- .../Gameplay/TestSceneBeatmapOffsetControl.cs | 2 +- .../Gameplay/TestSceneBeatmapSkinFallbacks.cs | 2 +- .../Gameplay/TestSceneBezierConverter.cs | 2 +- .../Visual/Gameplay/TestSceneBreakTracker.cs | 4 ++-- .../TestSceneClicksPerSecondCalculator.cs | 2 +- .../Gameplay/TestSceneColourHitErrorMeter.cs | 2 +- .../TestSceneCompletionCancellation.cs | 4 ++-- .../TestSceneDrawableScrollingRuleset.cs | 14 ++++++------- .../TestSceneDrawableStoryboardSprite.cs | 2 +- .../Visual/Gameplay/TestSceneFailAnimation.cs | 4 ++-- .../Visual/Gameplay/TestSceneFailJudgement.cs | 4 ++-- .../Visual/Gameplay/TestSceneFailingLayer.cs | 4 ++-- .../TestSceneFrameStabilityContainer.cs | 4 ++-- .../Gameplay/TestSceneGameplayLeaderboard.cs | 4 ++-- .../Gameplay/TestSceneGameplayMenuOverlay.cs | 2 +- .../Gameplay/TestSceneGameplayRewinding.cs | 2 +- .../TestSceneGameplaySamplePlayback.cs | 2 +- .../TestSceneGameplaySampleTriggerSource.cs | 4 ++-- .../Visual/Gameplay/TestSceneHUDOverlay.cs | 2 +- .../Visual/Gameplay/TestSceneHitErrorMeter.cs | 6 +++--- .../Gameplay/TestSceneHoldForMenuButton.cs | 2 +- .../Visual/Gameplay/TestSceneKeyBindings.cs | 6 +++--- .../Visual/Gameplay/TestSceneKeyCounter.cs | 2 +- .../Visual/Gameplay/TestSceneLeadIn.cs | 4 ++-- .../Visual/Gameplay/TestSceneMedalOverlay.cs | 2 +- .../Visual/Gameplay/TestSceneModValidity.cs | 2 +- .../TestSceneNightcoreBeatContainer.cs | 2 +- .../Gameplay/TestSceneOverlayActivation.cs | 4 ++-- .../Gameplay/TestSceneParticleExplosion.cs | 2 +- .../Gameplay/TestSceneParticleSpewer.cs | 4 ++-- .../Visual/Gameplay/TestScenePause.cs | 4 ++-- .../Gameplay/TestScenePauseWhenInactive.cs | 2 +- .../TestScenePerformancePointsCounter.cs | 2 +- .../Visual/Gameplay/TestScenePlayerLoader.cs | 6 +++--- .../TestScenePlayerLocalScoreImport.cs | 2 +- .../TestScenePlayerReferenceLeaking.cs | 2 +- .../TestScenePlayerScoreSubmission.cs | 4 ++-- .../Gameplay/TestScenePoolingRuleset.cs | 10 +++++----- .../Visual/Gameplay/TestSceneReplay.cs | 4 ++-- .../Gameplay/TestSceneReplayDownloadButton.cs | 4 ++-- .../Visual/Gameplay/TestSceneReplayPlayer.cs | 2 +- .../Gameplay/TestSceneReplayRecorder.cs | 10 +++++----- .../Visual/Gameplay/TestSceneScoring.cs | 6 +++--- .../Gameplay/TestSceneScrollingHitObjects.cs | 10 +++++----- .../Visual/Gameplay/TestSceneSkinEditor.cs | 2 +- .../TestSceneSkinEditorComponentsList.cs | 2 +- .../TestSceneSkinEditorMultipleSkins.cs | 2 +- .../TestSceneSkinnableAccuracyCounter.cs | 2 +- .../TestSceneSkinnableComboCounter.cs | 2 +- .../Gameplay/TestSceneSkinnableDrawable.cs | 20 +++++++++---------- .../Gameplay/TestSceneSkinnableHUDOverlay.cs | 2 +- .../TestSceneSkinnableHealthDisplay.cs | 2 +- .../TestSceneSkinnableScoreCounter.cs | 2 +- .../Gameplay/TestSceneSkinnableSound.cs | 4 ++-- .../Visual/Gameplay/TestSceneSkipOverlay.cs | 4 ++-- .../Visual/Gameplay/TestSceneSliderPath.cs | 2 +- .../TestSceneSoloGameplayLeaderboard.cs | 2 +- .../Visual/Gameplay/TestSceneSongProgress.cs | 2 +- .../Gameplay/TestSceneSongProgressGraph.cs | 4 ++-- .../Visual/Gameplay/TestSceneSpectator.cs | 4 ++-- .../Visual/Gameplay/TestSceneSpectatorHost.cs | 2 +- .../Gameplay/TestSceneSpectatorPlayback.cs | 10 +++++----- .../Visual/Gameplay/TestSceneStarCounter.cs | 2 +- .../Visual/Gameplay/TestSceneStoryboard.cs | 2 +- .../TestSceneStoryboardSamplePlayback.cs | 2 +- .../Gameplay/TestSceneStoryboardWithOutro.cs | 4 ++-- .../Visual/Gameplay/TestSceneUnknownMod.cs | 2 +- .../Gameplay/TestSceneUnstableRateCounter.cs | 4 ++-- osu.Game.Tests/Visual/Menus/IntroTestScene.cs | 2 +- .../Visual/Menus/TestSceneDisclaimer.cs | 2 +- .../Visual/Menus/TestSceneIntroCircles.cs | 2 +- .../Visual/Menus/TestSceneIntroTriangles.cs | 2 +- .../Visual/Menus/TestSceneIntroWelcome.cs | 2 +- .../Visual/Menus/TestSceneLoader.cs | 8 ++++---- .../Visual/Menus/TestSceneLoginPanel.cs | 2 +- .../Menus/TestSceneMusicActionHandling.cs | 2 +- .../Visual/Menus/TestSceneSideOverlays.cs | 2 +- .../Visual/Menus/TestSceneSongTicker.cs | 2 +- .../Visual/Menus/TestSceneToolbar.cs | 4 ++-- .../Visual/Menus/TestSceneToolbarClock.cs | 2 +- .../Menus/TestSceneToolbarUserButton.cs | 2 +- .../Visual/Mods/TestSceneModFailCondition.cs | 2 +- ...MultiplayerGameplayLeaderboardTestScene.cs | 2 +- .../Visual/Multiplayer/QueueModeTestScene.cs | 2 +- .../TestSceneAllPlayersQueueMode.cs | 2 +- .../TestSceneCreateMultiplayerMatchButton.cs | 2 +- .../TestSceneDrawableLoungeRoom.cs | 2 +- .../Multiplayer/TestSceneDrawableRoom.cs | 2 +- .../TestSceneDrawableRoomParticipantsList.cs | 2 +- .../TestSceneDrawableRoomPlaylist.cs | 4 ++-- .../TestSceneFreeModSelectOverlay.cs | 2 +- .../TestSceneGameplayChatDisplay.cs | 2 +- .../Multiplayer/TestSceneHostOnlyQueueMode.cs | 2 +- .../TestSceneLoungeRoomsContainer.cs | 2 +- .../TestSceneMatchBeatmapDetailArea.cs | 2 +- .../Multiplayer/TestSceneMatchLeaderboard.cs | 2 +- .../Multiplayer/TestSceneMatchStartControl.cs | 2 +- .../Multiplayer/TestSceneMultiHeader.cs | 4 ++-- .../TestSceneMultiSpectatorLeaderboard.cs | 2 +- .../TestSceneMultiSpectatorScreen.cs | 2 +- .../Multiplayer/TestSceneMultiplayer.cs | 2 +- ...TestSceneMultiplayerGameplayLeaderboard.cs | 4 ++-- ...ceneMultiplayerGameplayLeaderboardTeams.cs | 2 +- .../TestSceneMultiplayerLoungeSubScreen.cs | 2 +- .../TestSceneMultiplayerMatchFooter.cs | 2 +- .../TestSceneMultiplayerMatchSongSelect.cs | 4 ++-- .../TestSceneMultiplayerMatchSubScreen.cs | 4 ++-- .../TestSceneMultiplayerParticipantsList.cs | 2 +- .../Multiplayer/TestSceneMultiplayerPlayer.cs | 2 +- .../TestSceneMultiplayerPlaylist.cs | 2 +- .../TestSceneMultiplayerQueueList.cs | 2 +- .../TestSceneMultiplayerResults.cs | 2 +- .../TestSceneMultiplayerSpectateButton.cs | 2 +- ...TestSceneMultiplayerSpectatorPlayerGrid.cs | 4 ++-- .../TestSceneMultiplayerTeamResults.cs | 2 +- .../TestScenePlaylistsRoomSettingsPlaylist.cs | 4 ++-- .../TestScenePlaylistsSongSelect.cs | 4 ++-- .../Multiplayer/TestSceneRankRangePill.cs | 2 +- .../TestSceneStarRatingRangeDisplay.cs | 2 +- .../Visual/Multiplayer/TestSceneTeamVersus.cs | 2 +- .../TestSceneButtonSystemNavigation.cs | 2 +- .../TestSceneChangeAndUseGameplayBindings.cs | 2 +- .../Navigation/TestSceneEditDefaultSkin.cs | 2 +- .../Navigation/TestSceneFirstRunGame.cs | 4 ++-- .../TestSceneInterProcessCommunication.cs | 2 +- .../TestSceneMouseWheelVolumeAdjust.cs | 2 +- .../Visual/Navigation/TestSceneOsuGame.cs | 2 +- .../Navigation/TestScenePerformFromScreen.cs | 8 ++++---- .../Navigation/TestScenePresentBeatmap.cs | 2 +- .../Navigation/TestScenePresentScore.cs | 2 +- .../Navigation/TestSceneScreenNavigation.cs | 4 ++-- .../TestSceneSkinEditorNavigation.cs | 2 +- .../TestSceneStartupBeatmapDisplay.cs | 2 +- .../TestSceneStartupBeatmapSetDisplay.cs | 2 +- .../Navigation/TestSceneStartupImport.cs | 2 +- .../Navigation/TestSceneStartupRuleset.cs | 2 +- .../Navigation/TestSettingsMigration.cs | 2 +- .../Online/TestSceneAccountCreationOverlay.cs | 2 +- .../Online/TestSceneBeatmapAvailability.cs | 2 +- .../Online/TestSceneBeatmapDownloadButton.cs | 4 ++-- .../Online/TestSceneBeatmapListingOverlay.cs | 2 +- .../Online/TestSceneBeatmapRulesetSelector.cs | 2 +- .../Online/TestSceneBeatmapSetOverlay.cs | 4 ++-- .../TestSceneBeatmapSetOverlayDetails.cs | 4 ++-- .../TestSceneBeatmapSetOverlaySuccessRate.cs | 4 ++-- .../TestSceneBundledBeatmapDownloader.cs | 2 +- .../Online/TestSceneChangelogOverlay.cs | 4 ++-- .../TestSceneChangelogSupporterPromo.cs | 2 +- .../Visual/Online/TestSceneChannelList.cs | 2 +- .../Visual/Online/TestSceneChannelListing.cs | 2 +- .../Online/TestSceneChatLineTruncation.cs | 4 ++-- .../Visual/Online/TestSceneChatLink.cs | 4 ++-- .../Visual/Online/TestSceneChatOverlay.cs | 6 +++--- .../Visual/Online/TestSceneChatTextBox.cs | 2 +- .../Visual/Online/TestSceneCommentActions.cs | 2 +- .../Online/TestSceneCommentReportButton.cs | 2 +- .../Online/TestSceneCommentsContainer.cs | 2 +- .../Visual/Online/TestSceneCommentsHeader.cs | 2 +- .../TestSceneCurrentlyPlayingDisplay.cs | 4 ++-- .../Online/TestSceneDashboardOverlay.cs | 2 +- .../Visual/Online/TestSceneDrawableComment.cs | 2 +- .../Online/TestSceneExternalLinkButton.cs | 2 +- .../Visual/Online/TestSceneFavouriteButton.cs | 2 +- .../Visual/Online/TestSceneFriendDisplay.cs | 2 +- .../Online/TestSceneFullscreenOverlay.cs | 8 ++++---- .../Visual/Online/TestSceneGraph.cs | 2 +- .../Online/TestSceneHistoricalSection.cs | 2 +- .../Visual/Online/TestSceneHomeNewsPanel.cs | 2 +- .../Visual/Online/TestSceneKudosuHistory.cs | 2 +- .../Online/TestSceneLeaderboardModSelector.cs | 2 +- .../TestSceneLeaderboardScopeSelector.cs | 2 +- .../Visual/Online/TestSceneMessageNotifier.cs | 4 ++-- .../Visual/Online/TestSceneNewsCard.cs | 2 +- .../Visual/Online/TestSceneNewsHeader.cs | 4 ++-- .../Visual/Online/TestSceneNewsOverlay.cs | 2 +- .../Visual/Online/TestSceneNewsSidebar.cs | 4 ++-- .../Online/TestSceneNowPlayingCommand.cs | 4 ++-- .../TestSceneOfflineCommentsContainer.cs | 4 ++-- .../TestSceneOnlineBeatmapListingOverlay.cs | 2 +- .../TestSceneOnlineBeatmapSetOverlay.cs | 2 +- .../Online/TestSceneOnlineViewContainer.cs | 4 ++-- .../Online/TestScenePlayHistorySubsection.cs | 2 +- .../Online/TestSceneProfileRulesetSelector.cs | 2 +- .../Visual/Online/TestSceneRankGraph.cs | 2 +- .../Online/TestSceneRankingsCountryFilter.cs | 2 +- .../Visual/Online/TestSceneRankingsHeader.cs | 2 +- .../Visual/Online/TestSceneRankingsOverlay.cs | 4 ++-- .../TestSceneRankingsSpotlightSelector.cs | 2 +- .../Visual/Online/TestSceneRankingsTables.cs | 2 +- .../Visual/Online/TestSceneScoreboardTime.cs | 2 +- .../Visual/Online/TestSceneScoresContainer.cs | 4 ++-- .../Visual/Online/TestSceneShowMoreButton.cs | 2 +- .../Online/TestSceneSpotlightsLayout.cs | 2 +- .../Online/TestSceneStandAloneChatDisplay.cs | 4 ++-- .../Online/TestSceneTotalCommentsCounter.cs | 2 +- .../Online/TestSceneUserHistoryGraph.cs | 2 +- .../Visual/Online/TestSceneUserPanel.cs | 4 ++-- .../Online/TestSceneUserProfileHeader.cs | 2 +- .../Online/TestSceneUserProfileOverlay.cs | 4 ++-- .../TestSceneUserProfilePreviousUsernames.cs | 2 +- .../TestSceneUserProfileRecentSection.cs | 2 +- .../Online/TestSceneUserProfileScores.cs | 4 ++-- .../Visual/Online/TestSceneUserRanks.cs | 2 +- .../Visual/Online/TestSceneUserRequest.cs | 4 ++-- .../Visual/Online/TestSceneVotePill.cs | 4 ++-- .../Visual/Online/TestSceneWikiHeader.cs | 4 ++-- .../Visual/Online/TestSceneWikiMainPage.cs | 2 +- .../Online/TestSceneWikiMarkdownContainer.cs | 6 +++--- .../Visual/Online/TestSceneWikiOverlay.cs | 2 +- .../Visual/Online/TestSceneWikiSidebar.cs | 2 +- .../TestScenePlaylistsLoungeSubScreen.cs | 4 ++-- .../TestScenePlaylistsMatchSettingsOverlay.cs | 4 ++-- .../TestScenePlaylistsParticipantsList.cs | 2 +- .../TestScenePlaylistsResultsScreen.cs | 4 ++-- .../TestScenePlaylistsRoomCreation.cs | 4 ++-- .../Playlists/TestScenePlaylistsScreen.cs | 2 +- .../Visual/Ranking/TestSceneAccuracyCircle.cs | 2 +- .../TestSceneContractedPanelMiddleContent.cs | 4 ++-- .../TestSceneExpandedPanelMiddleContent.cs | 4 ++-- .../TestSceneExpandedPanelTopContent.cs | 2 +- ...estSceneHitEventTimingDistributionGraph.cs | 2 +- .../Visual/Ranking/TestSceneResultsScreen.cs | 10 +++++----- .../Visual/Ranking/TestSceneScorePanel.cs | 2 +- .../Visual/Ranking/TestSceneScorePanelList.cs | 2 +- .../Ranking/TestSceneSimpleStatisticTable.cs | 2 +- .../Ranking/TestSceneStatisticsPanel.cs | 2 +- .../Settings/TestSceneDirectorySelector.cs | 2 +- .../Visual/Settings/TestSceneFileSelector.cs | 2 +- .../Settings/TestSceneKeyBindingPanel.cs | 2 +- .../TestSceneLatencyCertifierScreen.cs | 2 +- .../Settings/TestSceneMigrationScreens.cs | 6 +++--- .../TestSceneRestoreDefaultValueButton.cs | 2 +- .../Visual/Settings/TestSceneSettingsItem.cs | 2 +- .../Settings/TestSceneSettingsNumberBox.cs | 2 +- .../Visual/Settings/TestSceneSettingsPanel.cs | 2 +- .../Settings/TestSceneSettingsSource.cs | 2 +- .../Settings/TestSceneTabletSettings.cs | 2 +- .../SongSelect/TestSceneAdvancedStats.cs | 4 ++-- .../SongSelect/TestSceneBeatmapCarousel.cs | 4 ++-- .../SongSelect/TestSceneBeatmapDetails.cs | 2 +- .../SongSelect/TestSceneBeatmapInfoWedge.cs | 4 ++-- .../SongSelect/TestSceneBeatmapLeaderboard.cs | 4 ++-- .../TestSceneBeatmapMetadataDisplay.cs | 4 ++-- .../TestSceneBeatmapOptionsOverlay.cs | 2 +- .../TestSceneBeatmapRecommendations.cs | 2 +- .../TestSceneDifficultyRangeFilterControl.cs | 2 +- .../SongSelect/TestSceneFilterControl.cs | 2 +- .../SongSelect/TestScenePlaySongSelect.cs | 4 ++-- .../SongSelect/TestSceneSongSelectFooter.cs | 2 +- .../SongSelect/TestSceneTopLocalRank.cs | 2 +- .../TestSceneUpdateBeatmapSetButton.cs | 2 +- .../TestSceneUserTopScoreContainer.cs | 2 +- .../Visual/TestMultiplayerComponents.cs | 4 ++-- .../Visual/TestSceneOsuScreenStack.cs | 14 ++++++------- .../UserInterface/TestSceneBackButton.cs | 2 +- .../TestSceneBeatSyncedContainer.cs | 6 +++--- ...stSceneBeatmapListingCardSizeTabControl.cs | 2 +- .../TestSceneBeatmapListingSearchControl.cs | 2 +- .../TestSceneBeatmapListingSortTabControl.cs | 2 +- .../TestSceneBeatmapSearchFilter.cs | 2 +- .../TestSceneBreadcrumbControl.cs | 4 ++-- .../TestSceneBreadcrumbControlHeader.cs | 6 +++--- .../UserInterface/TestSceneButtonSystem.cs | 2 +- .../UserInterface/TestSceneColourPicker.cs | 4 ++-- .../UserInterface/TestSceneCommentEditor.cs | 6 +++--- .../TestSceneCommentRepliesButton.cs | 4 ++-- .../UserInterface/TestSceneContextMenu.cs | 6 +++--- .../Visual/UserInterface/TestSceneCursors.cs | 8 ++++---- .../TestSceneDashboardBeatmapListing.cs | 2 +- .../TestSceneDeleteLocalScore.cs | 2 +- .../UserInterface/TestSceneDialogOverlay.cs | 6 +++--- .../TestSceneDifficultyMultiplierDisplay.cs | 2 +- .../UserInterface/TestSceneDrawableDate.cs | 4 ++-- .../UserInterface/TestSceneEditorSidebar.cs | 2 +- .../UserInterface/TestSceneExpandingBar.cs | 2 +- .../TestSceneExpandingContainer.cs | 4 ++-- .../UserInterface/TestSceneFPSCounter.cs | 2 +- .../TestSceneFirstRunScreenBehaviour.cs | 2 +- .../TestSceneFirstRunScreenBundledBeatmaps.cs | 2 +- ...TestSceneFirstRunScreenImportFromStable.cs | 2 +- .../TestSceneFirstRunScreenUIScale.cs | 2 +- .../TestSceneFirstRunSetupOverlay.cs | 2 +- .../TestSceneFooterButtonMods.cs | 4 ++-- .../TestSceneFriendsOnlineStatusControl.cs | 2 +- .../UserInterface/TestSceneHistoryTextBox.cs | 2 +- .../TestSceneHoldToConfirmOverlay.cs | 4 ++-- .../UserInterface/TestSceneIconButton.cs | 6 +++--- .../TestSceneLabelledColourPalette.cs | 2 +- .../TestSceneLabelledDrawable.cs | 6 +++--- .../TestSceneLabelledDropdown.cs | 2 +- .../TestSceneLabelledSliderBar.cs | 4 ++-- .../TestSceneLabelledSwitchButton.cs | 2 +- .../UserInterface/TestSceneLabelledTextBox.cs | 2 +- .../UserInterface/TestSceneLoadingLayer.cs | 4 ++-- .../UserInterface/TestSceneLoadingSpinner.cs | 2 +- .../UserInterface/TestSceneLogoAnimation.cs | 2 +- .../TestSceneLogoTrackingContainer.cs | 4 ++-- .../UserInterface/TestSceneModColumn.cs | 4 ++-- .../TestSceneModDifficultyAdjustSettings.cs | 2 +- .../UserInterface/TestSceneModDisplay.cs | 2 +- .../UserInterface/TestSceneModFlowDisplay.cs | 2 +- .../Visual/UserInterface/TestSceneModIcon.cs | 2 +- .../Visual/UserInterface/TestSceneModPanel.cs | 2 +- .../UserInterface/TestSceneModPresetColumn.cs | 2 +- .../UserInterface/TestSceneModPresetPanel.cs | 2 +- .../TestSceneModSelectOverlay.cs | 4 ++-- .../UserInterface/TestSceneModSettingsArea.cs | 2 +- .../UserInterface/TestSceneModSwitchSmall.cs | 2 +- .../UserInterface/TestSceneModSwitchTiny.cs | 2 +- .../TestSceneModsEffectDisplay.cs | 4 ++-- .../TestSceneNotificationOverlay.cs | 6 +++--- .../TestSceneNowPlayingOverlay.cs | 2 +- .../UserInterface/TestSceneOnScreenDisplay.cs | 8 ++++---- .../TestSceneOsuAnimatedButton.cs | 4 ++-- .../UserInterface/TestSceneOsuButton.cs | 2 +- .../UserInterface/TestSceneOsuDropdown.cs | 2 +- .../Visual/UserInterface/TestSceneOsuFont.cs | 2 +- .../TestSceneOsuHoverContainer.cs | 4 ++-- .../Visual/UserInterface/TestSceneOsuIcon.cs | 4 ++-- .../Visual/UserInterface/TestSceneOsuLogo.cs | 2 +- .../TestSceneOsuMarkdownContainer.cs | 2 +- .../Visual/UserInterface/TestSceneOsuMenu.cs | 2 +- .../UserInterface/TestSceneOsuPopover.cs | 6 +++--- .../UserInterface/TestSceneOsuTextBox.cs | 2 +- .../UserInterface/TestSceneOverlayHeader.cs | 16 +++++++-------- .../TestSceneOverlayHeaderBackground.cs | 2 +- .../TestSceneOverlayRulesetSelector.cs | 4 ++-- .../TestSceneOverlayScrollContainer.cs | 4 ++-- .../UserInterface/TestScenePageSelector.cs | 2 +- .../TestSceneParallaxContainer.cs | 2 +- .../UserInterface/TestScenePlaylistOverlay.cs | 2 +- .../UserInterface/TestScenePopupDialog.cs | 4 ++-- .../TestSceneProfileSubsectionHeader.cs | 2 +- .../TestSceneRankingsSortTabControl.cs | 2 +- .../UserInterface/TestSceneRoundedButton.cs | 2 +- .../TestSceneSafeAreaHandling.cs | 2 +- .../TestSceneScalingContainer.cs | 2 +- .../TestSceneScreenBreadcrumbControl.cs | 8 ++++---- .../TestSceneSectionsContainer.cs | 6 +++--- .../TestSceneSettingsCheckbox.cs | 4 ++-- .../TestSceneSettingsToolboxGroup.cs | 2 +- .../UserInterface/TestSceneShearedButtons.cs | 2 +- .../TestSceneShearedOverlayContainer.cs | 4 ++-- .../TestSceneShearedOverlayHeader.cs | 2 +- .../TestSceneShearedSearchTextBox.cs | 2 +- .../TestSceneSizePreservingSpriteText.cs | 2 +- .../TestSceneStarRatingDisplay.cs | 2 +- .../TestSceneStatefulMenuItem.cs | 2 +- .../UserInterface/TestSceneSwitchButton.cs | 2 +- .../UserInterface/TestSceneTabControl.cs | 2 +- .../UserInterface/TestSceneToggleMenuItem.cs | 2 +- .../TestSceneToolbarRulesetSelector.cs | 4 ++-- .../UserInterface/TestSceneTwoLayerButton.cs | 2 +- ...tSceneUpdateableBeatmapBackgroundSprite.cs | 4 ++-- .../TestSceneUpdateableBeatmapSetCover.cs | 6 +++--- ...tSceneUprightAspectMaintainingContainer.cs | 2 +- .../UserInterface/TestSceneUserListToolbar.cs | 2 +- .../UserInterface/TestSceneVolumeOverlay.cs | 2 +- .../UserInterface/TestSceneVolumePieces.cs | 2 +- .../UserInterface/TestSceneWaveContainer.cs | 2 +- .../UserInterface/ThemeComparisonTestScene.cs | 2 +- .../Components/TestSceneDateTextBox.cs | 2 +- .../TestSceneDrawableTournamentMatch.cs | 2 +- .../TestSceneDrawableTournamentTeam.cs | 2 +- .../Components/TestSceneMatchHeader.cs | 2 +- .../Components/TestSceneMatchScoreDisplay.cs | 2 +- .../Components/TestSceneRoundDisplay.cs | 2 +- .../Components/TestSceneSongBar.cs | 2 +- .../TestSceneTournamentBeatmapPanel.cs | 2 +- .../TestSceneTournamentMatchChatDisplay.cs | 2 +- .../TestSceneTournamentModDisplay.cs | 2 +- .../NonVisual/DataLoadTest.cs | 4 ++-- .../Screens/TestSceneDrawingsScreen.cs | 2 +- .../Screens/TestSceneGameplayScreen.cs | 2 +- .../Screens/TestSceneLadderEditorScreen.cs | 2 +- .../Screens/TestSceneLadderScreen.cs | 2 +- .../Screens/TestSceneMapPoolScreen.cs | 2 +- .../Screens/TestSceneRoundEditorScreen.cs | 2 +- .../Screens/TestSceneScheduleScreen.cs | 2 +- .../Screens/TestSceneSeedingEditorScreen.cs | 2 +- .../Screens/TestSceneSeedingScreen.cs | 2 +- .../Screens/TestSceneSetupScreen.cs | 2 +- .../Screens/TestSceneShowcaseScreen.cs | 2 +- .../TestSceneStablePathSelectScreen.cs | 4 ++-- .../Screens/TestSceneTeamEditorScreen.cs | 2 +- .../Screens/TestSceneTeamIntroScreen.cs | 2 +- .../Screens/TestSceneTeamWinScreen.cs | 2 +- .../TestSceneTournamentSceneManager.cs | 2 +- .../TournamentTestBrowser.cs | 2 +- .../TournamentTestScene.cs | 4 ++-- .../Components/ControlPanel.cs | 4 ++-- osu.Game.Tournament/Components/DateTextBox.cs | 2 +- .../Components/DrawableTeamFlag.cs | 2 +- .../Components/DrawableTeamHeader.cs | 2 +- .../Components/DrawableTeamTitle.cs | 2 +- .../Components/DrawableTeamTitleWithHeader.cs | 2 +- .../Components/DrawableTeamWithPlayers.cs | 2 +- .../DrawableTournamentHeaderLogo.cs | 4 ++-- .../DrawableTournamentHeaderText.cs | 4 ++-- .../Components/DrawableTournamentTeam.cs | 2 +- .../Components/IPCErrorDialog.cs | 2 +- .../Components/RoundDisplay.cs | 2 +- osu.Game.Tournament/Components/SongBar.cs | 4 ++-- .../Components/TournamentBeatmapPanel.cs | 2 +- .../Components/TournamentMatchChatDisplay.cs | 6 +++--- .../Components/TournamentModIcon.cs | 2 +- .../TournamentSpriteTextWithBackground.cs | 2 +- .../Components/TourneyVideo.cs | 2 +- osu.Game.Tournament/IPC/FileBasedIPC.cs | 2 +- osu.Game.Tournament/IPC/MatchIPCInfo.cs | 2 +- osu.Game.Tournament/SaveChangesOverlay.cs | 2 +- .../Screens/BeatmapInfoScreen.cs | 2 +- .../Screens/Drawings/Components/Group.cs | 2 +- .../Drawings/Components/GroupContainer.cs | 2 +- .../Screens/Drawings/Components/GroupTeam.cs | 2 +- .../Components/ScrollingTeamContainer.cs | 4 ++-- .../Components/VisualiserContainer.cs | 4 ++-- .../Screens/Drawings/DrawingsScreen.cs | 2 +- .../Screens/Editors/LadderEditorScreen.cs | 4 ++-- .../Screens/Editors/RoundEditorScreen.cs | 8 ++++---- .../Screens/Editors/SeedingEditorScreen.cs | 8 ++++---- .../Screens/Editors/TeamEditorScreen.cs | 8 ++++---- .../Screens/Editors/TournamentEditorScreen.cs | 2 +- .../Gameplay/Components/MatchHeader.cs | 2 +- .../Gameplay/Components/MatchRoundDisplay.cs | 2 +- .../Gameplay/Components/TeamDisplay.cs | 2 +- .../Screens/Gameplay/Components/TeamScore.cs | 6 +++--- .../Gameplay/Components/TeamScoreDisplay.cs | 2 +- .../Components/TournamentMatchScoreDisplay.cs | 4 ++-- .../Screens/Gameplay/GameplayScreen.cs | 4 ++-- .../Ladder/Components/DrawableMatchTeam.cs | 2 +- .../Components/DrawableTournamentMatch.cs | 2 +- .../Components/DrawableTournamentRound.cs | 2 +- .../Ladder/Components/LadderEditorSettings.cs | 4 ++-- .../Ladder/Components/ProgressionPath.cs | 2 +- .../Ladder/Components/SettingsTeamDropdown.cs | 2 +- .../Screens/Ladder/LadderDragContainer.cs | 2 +- .../Screens/Ladder/LadderScreen.cs | 2 +- .../Screens/MapPool/MapPoolScreen.cs | 2 +- .../Screens/Schedule/ScheduleScreen.cs | 8 ++++---- .../Screens/Setup/ActionableInfo.cs | 2 +- .../Screens/Setup/ResolutionSelector.cs | 2 +- .../Screens/Setup/SetupScreen.cs | 2 +- .../Screens/Setup/StablePathSelectScreen.cs | 2 +- .../Screens/Setup/TournamentSwitcher.cs | 2 +- .../Screens/Showcase/ShowcaseScreen.cs | 2 +- .../Screens/Showcase/TournamentLogo.cs | 2 +- .../Screens/TeamIntro/SeedingScreen.cs | 14 ++++++------- .../Screens/TeamIntro/TeamIntroScreen.cs | 2 +- .../Screens/TeamWin/TeamWinScreen.cs | 2 +- .../Screens/TournamentMatchScreen.cs | 2 +- .../Screens/TournamentScreen.cs | 2 +- osu.Game.Tournament/TournamentGame.cs | 2 +- osu.Game.Tournament/TournamentGameBase.cs | 4 ++-- osu.Game.Tournament/TournamentSceneManager.cs | 6 +++--- osu.Game.Tournament/TournamentSpriteText.cs | 2 +- osu.Game.Tournament/TourneyButton.cs | 2 +- osu.Game.Tournament/WarningBox.cs | 2 +- osu.Game/Audio/Effects/AudioFilter.cs | 2 +- osu.Game/Audio/PreviewTrack.cs | 2 +- osu.Game/Audio/PreviewTrackManager.cs | 4 ++-- osu.Game/BackgroundBeatmapProcessor.cs | 2 +- osu.Game/Beatmaps/BeatmapDifficultyCache.cs | 2 +- .../Beatmaps/BeatmapOnlineChangeIngest.cs | 2 +- osu.Game/Beatmaps/BeatmapStatisticIcon.cs | 2 +- osu.Game/Beatmaps/DifficultyRecommender.cs | 2 +- .../Drawables/BeatmapBackgroundSprite.cs | 2 +- .../Drawables/BeatmapDownloadButton.cs | 2 +- .../Drawables/BeatmapSetOnlineStatusPill.cs | 2 +- .../Drawables/BundledBeatmapDownloader.cs | 2 +- .../Beatmaps/Drawables/Cards/BeatmapCard.cs | 2 +- .../Drawables/Cards/BeatmapCardContent.cs | 2 +- .../Cards/BeatmapCardContentBackground.cs | 2 +- .../Cards/BeatmapCardDifficultyList.cs | 4 ++-- .../Cards/BeatmapCardDownloadProgressBar.cs | 2 +- .../Drawables/Cards/BeatmapCardExtra.cs | 2 +- .../Cards/BeatmapCardExtraInfoRow.cs | 2 +- .../Drawables/Cards/BeatmapCardNormal.cs | 2 +- .../Drawables/Cards/BeatmapCardThumbnail.cs | 2 +- .../Cards/Buttons/BeatmapCardIconButton.cs | 2 +- .../Drawables/Cards/Buttons/DownloadButton.cs | 2 +- .../Cards/Buttons/FavouriteButton.cs | 2 +- .../Cards/Buttons/GoToBeatmapButton.cs | 2 +- .../Drawables/Cards/Buttons/PlayButton.cs | 2 +- .../Cards/CollapsibleButtonContainer.cs | 2 +- .../Cards/ExpandedContentScrollContainer.cs | 4 ++-- .../Drawables/Cards/HoverHandlingContainer.cs | 2 +- osu.Game/Beatmaps/Drawables/Cards/IconPill.cs | 2 +- .../Statistics/BeatmapCardDateStatistic.cs | 2 +- .../Cards/Statistics/BeatmapCardStatistic.cs | 2 +- .../Cards/Statistics/FavouritesStatistic.cs | 2 +- .../Cards/Statistics/HypesStatistic.cs | 2 +- .../Cards/Statistics/NominationsStatistic.cs | 2 +- .../Cards/Statistics/PlayCountStatistic.cs | 2 +- .../Drawables/Cards/StoryboardIconPill.cs | 2 +- .../Beatmaps/Drawables/Cards/VideoIconPill.cs | 2 +- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 2 +- .../Drawables/DifficultyIconTooltip.cs | 2 +- .../Drawables/DifficultySpectrumDisplay.cs | 6 +++--- .../Beatmaps/Drawables/DownloadProgressBar.cs | 2 +- .../Drawables/OnlineBeatmapSetCover.cs | 2 +- .../Beatmaps/Drawables/StarRatingDisplay.cs | 2 +- .../UpdateableBeatmapBackgroundSprite.cs | 2 +- .../UpdateableOnlineBeatmapSetCover.cs | 2 +- osu.Game/Beatmaps/FramedBeatmapClock.cs | 2 +- osu.Game/Collections/CollectionDropdown.cs | 8 ++++---- .../Collections/DeleteCollectionDialog.cs | 2 +- .../Collections/DrawableCollectionList.cs | 6 +++--- .../Collections/DrawableCollectionListItem.cs | 8 ++++---- .../Collections/ManageCollectionsDialog.cs | 2 +- .../Configuration/SettingSourceAttribute.cs | 6 +++--- osu.Game/Database/BeatmapLookupCache.cs | 2 +- .../Database/ImportProgressNotification.cs | 2 +- osu.Game/Database/LegacyImportManager.cs | 2 +- osu.Game/Database/MemoryCachingComponent.cs | 2 +- osu.Game/Database/ModelDownloader.cs | 6 +++--- osu.Game/Database/OnlineLookupCache.cs | 2 +- .../Database/TooManyDownloadsNotification.cs | 2 +- osu.Game/Database/UserLookupCache.cs | 2 +- osu.Game/Graphics/Backgrounds/Background.cs | 2 +- .../Graphics/Backgrounds/BeatmapBackground.cs | 2 +- .../BeatmapBackgroundWithStoryboard.cs | 2 +- .../Backgrounds/SeasonalBackgroundLoader.cs | 4 ++-- .../Graphics/Backgrounds/SkinBackground.cs | 2 +- osu.Game/Graphics/Backgrounds/Triangles.cs | 2 +- .../Containers/BeatSyncedContainer.cs | 2 +- .../Containers/ConstrainedIconContainer.cs | 2 +- .../Containers/ExpandingButtonContainer.cs | 2 +- .../Graphics/Containers/ExpandingContainer.cs | 2 +- .../Containers/HoldToConfirmContainer.cs | 2 +- .../Graphics/Containers/LinkFlowContainer.cs | 2 +- .../Containers/LogoTrackingContainer.cs | 6 +++--- .../Markdown/OsuMarkdownContainer.cs | 2 +- .../Markdown/OsuMarkdownFencedCodeBlock.cs | 6 +++--- .../Containers/Markdown/OsuMarkdownHeading.cs | 4 ++-- .../Containers/Markdown/OsuMarkdownImage.cs | 2 +- .../Markdown/OsuMarkdownLinkText.cs | 4 ++-- .../Markdown/OsuMarkdownListItem.cs | 2 +- .../Markdown/OsuMarkdownOrderedListItem.cs | 2 +- .../Markdown/OsuMarkdownQuoteBlock.cs | 4 ++-- .../Markdown/OsuMarkdownSeparator.cs | 4 ++-- .../Containers/Markdown/OsuMarkdownTable.cs | 2 +- .../Markdown/OsuMarkdownTableCell.cs | 8 ++++---- .../Markdown/OsuMarkdownTextFlowContainer.cs | 4 ++-- .../Markdown/OsuMarkdownUnorderedListItem.cs | 2 +- .../Containers/OsuClickableContainer.cs | 2 +- .../Containers/OsuFocusedOverlayContainer.cs | 2 +- .../Graphics/Containers/OsuHoverContainer.cs | 2 +- .../OsuRearrangeableListContainer.cs | 2 +- .../Containers/OsuRearrangeableListItem.cs | 4 ++-- .../Graphics/Containers/OsuScrollContainer.cs | 6 +++--- .../Containers/OsuTextFlowContainer.cs | 2 +- .../Graphics/Containers/ParallaxContainer.cs | 2 +- .../ReverseChildIDFillFlowContainer.cs | 2 +- .../Graphics/Containers/ScalingContainer.cs | 8 ++++---- .../Graphics/Containers/SectionsContainer.cs | 2 +- .../SelectionCycleFillFlowContainer.cs | 2 +- .../Graphics/Containers/ShakeContainer.cs | 2 +- .../UprightAspectMaintainingContainer.cs | 2 +- .../Graphics/Containers/UserDimContainer.cs | 2 +- .../Containers/UserTrackingScrollContainer.cs | 4 ++-- osu.Game/Graphics/Containers/WaveContainer.cs | 4 ++-- .../Graphics/Cursor/GlobalCursorDisplay.cs | 2 +- .../Graphics/Cursor/MenuCursorContainer.cs | 6 +++--- .../Cursor/OsuContextMenuContainer.cs | 2 +- .../Graphics/Cursor/OsuTooltipContainer.cs | 4 ++-- osu.Game/Graphics/DateTooltip.cs | 2 +- osu.Game/Graphics/DrawableDate.cs | 2 +- osu.Game/Graphics/ErrorTextFlowContainer.cs | 2 +- osu.Game/Graphics/InputBlockingContainer.cs | 2 +- osu.Game/Graphics/ParticleExplosion.cs | 2 +- osu.Game/Graphics/ParticleSpewer.cs | 2 +- osu.Game/Graphics/ScreenshotManager.cs | 2 +- .../Graphics/Sprites/GlowingSpriteText.cs | 2 +- osu.Game/Graphics/Sprites/LogoAnimation.cs | 2 +- osu.Game/Graphics/Sprites/OsuSpriteText.cs | 2 +- .../Sprites/SizePreservingSpriteText.cs | 2 +- osu.Game/Graphics/UserInterface/BackButton.cs | 4 ++-- osu.Game/Graphics/UserInterface/Bar.cs | 2 +- osu.Game/Graphics/UserInterface/BarGraph.cs | 2 +- .../UserInterface/BasicSearchTextBox.cs | 2 +- .../UserInterface/BreadcrumbControl.cs | 4 ++-- .../CommaSeparatedScoreCounter.cs | 2 +- .../UserInterface/DangerousTriangleButton.cs | 2 +- .../Graphics/UserInterface/DialogButton.cs | 2 +- .../Graphics/UserInterface/DownloadButton.cs | 2 +- .../UserInterface/DrawableOsuMenuItem.cs | 4 ++-- .../UserInterface/DrawableStatefulMenuItem.cs | 4 ++-- .../UserInterface/ExpandableSlider.cs | 4 ++-- .../Graphics/UserInterface/ExpandingBar.cs | 2 +- .../UserInterface/ExternalLinkButton.cs | 2 +- osu.Game/Graphics/UserInterface/FPSCounter.cs | 2 +- .../UserInterface/FPSCounterTooltip.cs | 2 +- .../Graphics/UserInterface/FocusedTextBox.cs | 2 +- .../UserInterface/GradientLineTabControl.cs | 4 ++-- osu.Game/Graphics/UserInterface/GrayButton.cs | 2 +- .../Graphics/UserInterface/HistoryTextBox.cs | 2 +- .../UserInterface/HoverClickSounds.cs | 2 +- .../HoverSampleDebounceComponent.cs | 2 +- .../Graphics/UserInterface/HoverSounds.cs | 2 +- osu.Game/Graphics/UserInterface/IconButton.cs | 2 +- osu.Game/Graphics/UserInterface/LineGraph.cs | 2 +- .../Graphics/UserInterface/LoadingButton.cs | 2 +- .../Graphics/UserInterface/LoadingLayer.cs | 2 +- .../Graphics/UserInterface/LoadingSpinner.cs | 2 +- osu.Game/Graphics/UserInterface/Nub.cs | 2 +- .../UserInterface/OsuAnimatedButton.cs | 2 +- osu.Game/Graphics/UserInterface/OsuButton.cs | 2 +- .../Graphics/UserInterface/OsuCheckbox.cs | 2 +- .../Graphics/UserInterface/OsuContextMenu.cs | 2 +- .../UserInterface/OsuContextMenuSamples.cs | 2 +- .../Graphics/UserInterface/OsuDropdown.cs | 10 +++++----- .../Graphics/UserInterface/OsuEnumDropdown.cs | 2 +- osu.Game/Graphics/UserInterface/OsuMenu.cs | 2 +- .../Graphics/UserInterface/OsuNumberBox.cs | 2 +- .../UserInterface/OsuPasswordTextBox.cs | 6 +++--- .../Graphics/UserInterface/OsuSliderBar.cs | 2 +- .../Graphics/UserInterface/OsuTabControl.cs | 4 ++-- .../UserInterface/OsuTabControlCheckbox.cs | 2 +- .../Graphics/UserInterface/OsuTabDropdown.cs | 8 ++++---- osu.Game/Graphics/UserInterface/OsuTextBox.cs | 6 +++--- .../PageSelector/PageEllipsis.cs | 2 +- .../PageSelector/PageSelector.cs | 2 +- .../PageSelector/PageSelectorButton.cs | 2 +- .../PageSelector/PageSelectorPageButton.cs | 2 +- .../PageSelectorPrevNextButton.cs | 2 +- .../Graphics/UserInterface/PageTabControl.cs | 4 ++-- .../UserInterface/PercentageCounter.cs | 2 +- .../Graphics/UserInterface/ProgressBar.cs | 2 +- .../Graphics/UserInterface/RollingCounter.cs | 2 +- .../Graphics/UserInterface/ScoreCounter.cs | 2 +- .../UserInterface/ScreenBreadcrumbControl.cs | 2 +- .../Graphics/UserInterface/SearchTextBox.cs | 2 +- .../UserInterface/SeekLimitedSearchTextBox.cs | 2 +- .../Graphics/UserInterface/ShearedButton.cs | 2 +- .../UserInterface/ShearedOverlayHeader.cs | 2 +- .../UserInterface/ShearedSearchTextBox.cs | 6 +++--- .../UserInterface/ShearedToggleButton.cs | 2 +- .../Graphics/UserInterface/ShowMoreButton.cs | 4 ++-- .../UserInterface/SlimEnumDropdown.cs | 4 ++-- .../Graphics/UserInterface/StarCounter.cs | 6 +++--- osu.Game/Graphics/UserInterface/TimeSlider.cs | 2 +- .../Graphics/UserInterface/TriangleButton.cs | 2 +- .../Graphics/UserInterface/TwoLayerButton.cs | 4 ++-- .../Graphics/UserInterfaceV2/ColourDisplay.cs | 4 ++-- .../Graphics/UserInterfaceV2/ColourPalette.cs | 4 ++-- .../UserInterfaceV2/LabelledColourPalette.cs | 2 +- .../UserInterfaceV2/LabelledComponent.cs | 2 +- .../UserInterfaceV2/LabelledDrawable.cs | 2 +- .../UserInterfaceV2/LabelledDropdown.cs | 2 +- .../UserInterfaceV2/LabelledEnumDropdown.cs | 2 +- .../UserInterfaceV2/LabelledNumberBox.cs | 2 +- .../UserInterfaceV2/LabelledSliderBar.cs | 2 +- .../UserInterfaceV2/LabelledSwitchButton.cs | 2 +- .../UserInterfaceV2/LabelledTextBox.cs | 2 +- .../UserInterfaceV2/OsuColourPicker.cs | 2 +- .../UserInterfaceV2/OsuDirectorySelector.cs | 2 +- .../OsuDirectorySelectorBreadcrumbDisplay.cs | 6 +++--- .../OsuDirectorySelectorDirectory.cs | 4 ++-- .../OsuDirectorySelectorHiddenToggle.cs | 2 +- .../OsuDirectorySelectorParentDirectory.cs | 2 +- .../UserInterfaceV2/OsuFileSelector.cs | 4 ++-- .../UserInterfaceV2/OsuHSVColourPicker.cs | 10 +++++----- .../UserInterfaceV2/OsuHexColourPicker.cs | 4 ++-- .../Graphics/UserInterfaceV2/OsuPopover.cs | 2 +- .../Graphics/UserInterfaceV2/RoundedButton.cs | 2 +- .../Graphics/UserInterfaceV2/SwitchButton.cs | 4 ++-- .../Bindings/DatabasedKeyBindingContainer.cs | 2 +- .../Input/Bindings/GlobalActionContainer.cs | 2 +- osu.Game/Input/ConfineMouseTracker.cs | 2 +- osu.Game/Input/GameIdleTracker.cs | 2 +- osu.Game/Input/IdleTracker.cs | 2 +- osu.Game/Input/OsuUserInputManager.cs | 2 +- osu.Game/Online/API/APIAccess.cs | 2 +- osu.Game/Online/API/DummyAPIAccess.cs | 2 +- osu.Game/Online/BeatmapDownloadTracker.cs | 2 +- osu.Game/Online/Chat/ChannelManager.cs | 2 +- osu.Game/Online/Chat/DrawableLinkCompiler.cs | 4 ++-- osu.Game/Online/Chat/ExternalLinkOpener.cs | 4 ++-- osu.Game/Online/Chat/MessageNotifier.cs | 8 ++++---- osu.Game/Online/Chat/NowPlayingCommand.cs | 2 +- osu.Game/Online/Chat/StandAloneChatDisplay.cs | 10 +++++----- osu.Game/Online/DownloadTracker.cs | 2 +- osu.Game/Online/Leaderboards/DrawableRank.cs | 2 +- osu.Game/Online/Leaderboards/Leaderboard.cs | 2 +- .../Online/Leaderboards/LeaderboardScore.cs | 8 ++++---- .../Leaderboards/LeaderboardScoreTooltip.cs | 6 +++--- .../Online/Leaderboards/UpdateableRank.cs | 2 +- .../Leaderboards/UserTopScoreContainer.cs | 2 +- osu.Game/Online/Metadata/MetadataClient.cs | 2 +- .../Online/Metadata/OnlineMetadataClient.cs | 2 +- .../Online/Multiplayer/MultiplayerClient.cs | 2 +- .../Multiplayer/OnlineMultiplayerClient.cs | 2 +- .../Multiplayer/ServerShutdownNotification.cs | 2 +- osu.Game/Online/OnlineViewContainer.cs | 2 +- .../Placeholders/ClickablePlaceholder.cs | 2 +- .../Online/Placeholders/LoginPlaceholder.cs | 2 +- .../Online/Placeholders/MessagePlaceholder.cs | 2 +- osu.Game/Online/Placeholders/Placeholder.cs | 2 +- osu.Game/Online/PollingComponent.cs | 2 +- osu.Game/Online/Rooms/APICreatedRoom.cs | 2 +- .../OnlinePlayBeatmapAvailabilityTracker.cs | 2 +- osu.Game/Online/Rooms/Room.cs | 2 +- osu.Game/Online/ScoreDownloadTracker.cs | 2 +- .../Online/Spectator/OnlineSpectatorClient.cs | 2 +- osu.Game/Online/Spectator/SpectatorClient.cs | 2 +- .../Spectator/SpectatorScoreProcessor.cs | 2 +- osu.Game/OsuGame.cs | 2 +- .../AccountCreationBackground.cs | 2 +- .../AccountCreation/AccountCreationScreen.cs | 2 +- .../Overlays/AccountCreation/ScreenEntry.cs | 2 +- .../Overlays/AccountCreation/ScreenWarning.cs | 2 +- .../Overlays/AccountCreation/ScreenWelcome.cs | 2 +- osu.Game/Overlays/AccountCreationOverlay.cs | 2 +- .../BeatmapListingCardSizeTabControl.cs | 4 ++-- .../BeatmapListingFilterControl.cs | 2 +- .../BeatmapListing/BeatmapListingHeader.cs | 4 ++-- .../BeatmapListingSearchControl.cs | 6 +++--- .../BeatmapListingSortTabControl.cs | 8 ++++---- .../BeatmapListing/BeatmapSearchFilterRow.cs | 8 ++++---- .../BeatmapSearchGeneralFilterRow.cs | 6 +++--- ...BeatmapSearchMultipleSelectionFilterRow.cs | 6 +++--- .../BeatmapSearchRulesetFilterRow.cs | 6 +++--- .../BeatmapSearchScoreFilterRow.cs | 6 +++--- .../Overlays/BeatmapListing/FilterTabItem.cs | 2 +- osu.Game/Overlays/BeatmapListingOverlay.cs | 6 +++--- osu.Game/Overlays/BeatmapSet/AuthorInfo.cs | 4 ++-- osu.Game/Overlays/BeatmapSet/BasicStats.cs | 4 ++-- .../BeatmapSet/BeatmapAvailability.cs | 2 +- osu.Game/Overlays/BeatmapSet/BeatmapBadge.cs | 2 +- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 8 ++++---- .../BeatmapSet/BeatmapRulesetSelector.cs | 2 +- .../BeatmapSet/BeatmapRulesetTabItem.cs | 2 +- .../Overlays/BeatmapSet/BeatmapSetHeader.cs | 4 ++-- .../BeatmapSet/BeatmapSetHeaderContent.cs | 2 +- .../BeatmapSet/BeatmapSetLayoutSection.cs | 2 +- .../BeatmapSet/Buttons/FavouriteButton.cs | 2 +- .../BeatmapSet/Buttons/HeaderButton.cs | 2 +- .../Buttons/HeaderDownloadButton.cs | 2 +- .../Overlays/BeatmapSet/Buttons/PlayButton.cs | 2 +- .../BeatmapSet/Buttons/PreviewButton.cs | 2 +- osu.Game/Overlays/BeatmapSet/Details.cs | 4 ++-- .../BeatmapSet/ExplicitContentBeatmapBadge.cs | 2 +- .../BeatmapSet/FeaturedArtistBeatmapBadge.cs | 2 +- osu.Game/Overlays/BeatmapSet/Info.cs | 2 +- .../BeatmapSet/LeaderboardModSelector.cs | 4 ++-- .../BeatmapSet/LeaderboardScopeSelector.cs | 4 ++-- .../Overlays/BeatmapSet/MetadataSection.cs | 2 +- .../BeatmapSet/Scores/DrawableTopScore.cs | 4 ++-- .../BeatmapSet/Scores/NoScoresPlaceholder.cs | 2 +- .../Scores/NotSupporterPlaceholder.cs | 2 +- .../Overlays/BeatmapSet/Scores/ScoreTable.cs | 6 +++--- .../Scores/ScoreTableRowBackground.cs | 2 +- .../BeatmapSet/Scores/ScoreboardTime.cs | 2 +- .../BeatmapSet/Scores/ScoresContainer.cs | 2 +- .../Scores/TopScoreStatisticsSection.cs | 8 ++++---- .../BeatmapSet/Scores/TopScoreUserSection.cs | 2 +- .../BeatmapSet/SpotlightBeatmapBadge.cs | 2 +- osu.Game/Overlays/BeatmapSet/SuccessRate.cs | 4 ++-- osu.Game/Overlays/BeatmapSetOverlay.cs | 4 ++-- .../BreadcrumbControlOverlayHeader.cs | 6 +++--- osu.Game/Overlays/Changelog/ChangelogBuild.cs | 2 +- .../Overlays/Changelog/ChangelogContent.cs | 2 +- osu.Game/Overlays/Changelog/ChangelogEntry.cs | 2 +- .../Overlays/Changelog/ChangelogHeader.cs | 4 ++-- .../Overlays/Changelog/ChangelogListing.cs | 2 +- .../Changelog/ChangelogSingleBuild.cs | 6 +++--- .../Changelog/ChangelogSupporterPromo.cs | 6 +++--- .../Changelog/ChangelogUpdateStreamControl.cs | 2 +- .../Changelog/ChangelogUpdateStreamItem.cs | 2 +- osu.Game/Overlays/ChangelogOverlay.cs | 2 +- .../Overlays/Chat/ChannelList/ChannelList.cs | 4 ++-- .../Chat/ChannelList/ChannelListItem.cs | 2 +- .../ChannelList/ChannelListItemCloseButton.cs | 2 +- .../ChannelList/ChannelListItemMentionPill.cs | 2 +- .../Overlays/Chat/ChannelScrollContainer.cs | 2 +- osu.Game/Overlays/Chat/ChatLine.cs | 4 ++-- osu.Game/Overlays/Chat/ChatOverlayTopBar.cs | 2 +- osu.Game/Overlays/Chat/ChatTextBar.cs | 2 +- osu.Game/Overlays/Chat/ChatTextBox.cs | 2 +- osu.Game/Overlays/Chat/DaySeparator.cs | 2 +- osu.Game/Overlays/Chat/DrawableChannel.cs | 2 +- .../Overlays/Chat/Listing/ChannelListing.cs | 2 +- .../Chat/Listing/ChannelListingItem.cs | 2 +- osu.Game/Overlays/ChatOverlay.cs | 2 +- .../Comments/Buttons/ChevronButton.cs | 2 +- .../Comments/Buttons/CommentRepliesButton.cs | 2 +- .../Comments/Buttons/LoadRepliesButton.cs | 4 ++-- .../Comments/Buttons/ShowMoreRepliesButton.cs | 2 +- .../Comments/Buttons/ShowRepliesButton.cs | 2 +- .../Comments/CancellableCommentEditor.cs | 4 ++-- osu.Game/Overlays/Comments/CommentEditor.cs | 6 +++--- .../Comments/CommentMarkdownContainer.cs | 4 ++-- .../Overlays/Comments/CommentReportButton.cs | 2 +- .../Overlays/Comments/CommentsContainer.cs | 4 ++-- osu.Game/Overlays/Comments/CommentsHeader.cs | 4 ++-- .../Comments/CommentsShowMoreButton.cs | 2 +- .../Comments/DeletedCommentsCounter.cs | 2 +- osu.Game/Overlays/Comments/DrawableComment.cs | 6 +++--- osu.Game/Overlays/Comments/HeaderButton.cs | 2 +- .../Overlays/Comments/ReportCommentPopover.cs | 2 +- .../Overlays/Comments/TotalCommentsCounter.cs | 2 +- osu.Game/Overlays/Comments/VotePill.cs | 2 +- .../Dashboard/CurrentlyPlayingDisplay.cs | 4 ++-- .../Dashboard/DashboardOverlayHeader.cs | 4 ++-- .../Dashboard/Friends/FriendDisplay.cs | 2 +- .../Friends/FriendOnlineStreamControl.cs | 2 +- .../Friends/FriendsOnlineStatusItem.cs | 2 +- .../Dashboard/Friends/UserListToolbar.cs | 2 +- .../Dashboard/Friends/UserSortTabControl.cs | 2 +- .../Dashboard/Home/DashboardBeatmapListing.cs | 2 +- .../Dashboard/Home/DashboardBeatmapPanel.cs | 2 +- .../Home/DashboardNewBeatmapPanel.cs | 2 +- .../Home/DashboardPopularBeatmapPanel.cs | 2 +- .../Dashboard/Home/DrawableBeatmapList.cs | 2 +- .../Dashboard/Home/DrawableNewBeatmapList.cs | 2 +- .../Home/DrawablePopularBeatmapList.cs | 2 +- osu.Game/Overlays/Dashboard/Home/HomePanel.cs | 2 +- .../Home/News/FeaturedNewsItemPanel.cs | 6 +++--- .../Dashboard/Home/News/NewsGroupItem.cs | 4 ++-- .../Dashboard/Home/News/NewsItemGroupPanel.cs | 2 +- .../Dashboard/Home/News/NewsTitleLink.cs | 2 +- .../Dashboard/Home/News/ShowMoreNewsPanel.cs | 2 +- osu.Game/Overlays/DashboardOverlay.cs | 2 +- osu.Game/Overlays/Dialog/ConfirmDialog.cs | 2 +- .../Dialog/DeleteConfirmationDialog.cs | 2 +- osu.Game/Overlays/Dialog/PopupDialog.cs | 2 +- osu.Game/Overlays/Dialog/PopupDialogButton.cs | 2 +- .../Dialog/PopupDialogCancelButton.cs | 2 +- .../Dialog/PopupDialogDangerousButton.cs | 4 ++-- .../Overlays/Dialog/PopupDialogOkButton.cs | 2 +- osu.Game/Overlays/DialogOverlay.cs | 2 +- .../FirstRunSetup/FirstRunSetupScreen.cs | 2 +- .../FirstRunSetup/ProgressRoundedButton.cs | 2 +- .../Overlays/FirstRunSetup/ScreenBeatmaps.cs | 2 +- .../Overlays/FirstRunSetup/ScreenBehaviour.cs | 2 +- .../FirstRunSetup/ScreenImportFromStable.cs | 8 ++++---- .../Overlays/FirstRunSetup/ScreenUIScale.cs | 12 +++++------ .../Overlays/FirstRunSetup/ScreenWelcome.cs | 6 +++--- osu.Game/Overlays/FirstRunSetupOverlay.cs | 2 +- osu.Game/Overlays/FullscreenOverlay.cs | 2 +- osu.Game/Overlays/HoldToConfirmOverlay.cs | 2 +- osu.Game/Overlays/Login/LoginForm.cs | 2 +- osu.Game/Overlays/Login/LoginPanel.cs | 2 +- osu.Game/Overlays/Login/UserDropdown.cs | 8 ++++---- osu.Game/Overlays/LoginOverlay.cs | 2 +- osu.Game/Overlays/MedalOverlay.cs | 6 +++--- .../Overlays/MedalSplash/DrawableMedal.cs | 2 +- osu.Game/Overlays/Mods/AddPresetButton.cs | 2 +- osu.Game/Overlays/Mods/AddPresetPopover.cs | 2 +- .../Overlays/Mods/DeleteModPresetDialog.cs | 2 +- .../Overlays/Mods/DeselectAllModsButton.cs | 2 +- .../Mods/DifficultyMultiplierDisplay.cs | 2 +- .../Mods/IncompatibilityDisplayingModPanel.cs | 2 +- .../Mods/IncompatibilityDisplayingTooltip.cs | 2 +- osu.Game/Overlays/Mods/ModButtonTooltip.cs | 2 +- osu.Game/Overlays/Mods/ModColumn.cs | 4 ++-- osu.Game/Overlays/Mods/ModPanel.cs | 2 +- osu.Game/Overlays/Mods/ModPresetColumn.cs | 2 +- osu.Game/Overlays/Mods/ModPresetPanel.cs | 2 +- osu.Game/Overlays/Mods/ModPresetTooltip.cs | 4 ++-- osu.Game/Overlays/Mods/ModSelectColumn.cs | 2 +- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 10 +++++----- osu.Game/Overlays/Mods/ModSelectPanel.cs | 2 +- osu.Game/Overlays/Mods/ModSettingsArea.cs | 4 ++-- osu.Game/Overlays/Mods/ModsEffectDisplay.cs | 4 ++-- osu.Game/Overlays/Mods/SelectAllModsButton.cs | 2 +- .../Overlays/Mods/ShearedOverlayContainer.cs | 2 +- .../Overlays/Mods/UserModSelectOverlay.cs | 4 ++-- osu.Game/Overlays/Music/FilterControl.cs | 4 ++-- .../Overlays/Music/MusicKeyBindingHandler.cs | 4 ++-- .../Music/NowPlayingCollectionDropdown.cs | 6 +++--- osu.Game/Overlays/Music/Playlist.cs | 2 +- osu.Game/Overlays/Music/PlaylistItem.cs | 2 +- osu.Game/Overlays/Music/PlaylistOverlay.cs | 2 +- osu.Game/Overlays/MusicController.cs | 2 +- .../Overlays/News/Displays/ArticleListing.cs | 2 +- osu.Game/Overlays/News/NewsCard.cs | 4 ++-- osu.Game/Overlays/News/NewsHeader.cs | 4 ++-- osu.Game/Overlays/News/NewsPostBackground.cs | 2 +- .../Overlays/News/Sidebar/MonthSection.cs | 8 ++++---- osu.Game/Overlays/News/Sidebar/NewsSidebar.cs | 2 +- osu.Game/Overlays/News/Sidebar/YearsPanel.cs | 4 ++-- osu.Game/Overlays/NewsOverlay.cs | 2 +- osu.Game/Overlays/NotificationOverlay.cs | 2 +- .../Overlays/NotificationOverlayToastTray.cs | 2 +- .../Overlays/Notifications/Notification.cs | 8 ++++---- .../Notifications/NotificationSection.cs | 6 +++--- .../ProgressCompletionNotification.cs | 2 +- .../Notifications/ProgressNotification.cs | 4 ++-- .../Notifications/SimpleErrorNotification.cs | 2 +- .../Notifications/SimpleNotification.cs | 2 +- osu.Game/Overlays/NowPlayingOverlay.cs | 10 +++++----- osu.Game/Overlays/OSD/CopyUrlToast.cs | 2 +- osu.Game/Overlays/OSD/Toast.cs | 2 +- osu.Game/Overlays/OSD/TrackedSettingToast.cs | 4 ++-- osu.Game/Overlays/OnScreenDisplay.cs | 2 +- osu.Game/Overlays/OnlineOverlay.cs | 2 +- osu.Game/Overlays/OverlayHeader.cs | 2 +- osu.Game/Overlays/OverlayHeaderBackground.cs | 4 ++-- .../OverlayPanelDisplayStyleControl.cs | 4 ++-- osu.Game/Overlays/OverlayRulesetSelector.cs | 2 +- osu.Game/Overlays/OverlayRulesetTabItem.cs | 2 +- osu.Game/Overlays/OverlayScrollContainer.cs | 4 ++-- osu.Game/Overlays/OverlaySidebar.cs | 2 +- osu.Game/Overlays/OverlaySortTabControl.cs | 8 ++++---- osu.Game/Overlays/OverlayStreamControl.cs | 2 +- osu.Game/Overlays/OverlayStreamItem.cs | 2 +- osu.Game/Overlays/OverlayTabControl.cs | 4 ++-- osu.Game/Overlays/OverlayTitle.cs | 4 ++-- osu.Game/Overlays/OverlayView.cs | 2 +- .../Profile/Header/BottomHeaderContainer.cs | 2 +- .../Profile/Header/CentreHeaderContainer.cs | 2 +- .../Header/Components/DrawableBadge.cs | 2 +- .../Header/Components/ExpandDetailsButton.cs | 2 +- .../Header/Components/FollowersButton.cs | 2 +- .../Profile/Header/Components/LevelBadge.cs | 2 +- .../Header/Components/LevelProgressBar.cs | 2 +- .../Components/MappingSubscribersButton.cs | 2 +- .../Header/Components/MessageUserButton.cs | 2 +- .../Components/OverlinedInfoContainer.cs | 2 +- .../Components/OverlinedTotalPlayTime.cs | 2 +- .../Header/Components/PreviousUsernames.cs | 4 ++-- .../Header/Components/ProfileHeaderButton.cs | 2 +- .../ProfileHeaderStatisticsButton.cs | 2 +- .../Components/ProfileRulesetSelector.cs | 2 +- .../Components/ProfileRulesetTabItem.cs | 4 ++-- .../Profile/Header/Components/RankGraph.cs | 2 +- .../Header/Components/SupporterIcon.cs | 2 +- .../Profile/Header/DetailHeaderContainer.cs | 4 ++-- .../Profile/Header/MedalHeaderContainer.cs | 2 +- .../Profile/Header/TopHeaderContainer.cs | 4 ++-- osu.Game/Overlays/Profile/ProfileHeader.cs | 6 +++--- osu.Game/Overlays/Profile/ProfileSection.cs | 4 ++-- .../Overlays/Profile/Sections/AboutSection.cs | 2 +- .../Sections/BeatmapMetadataContainer.cs | 2 +- .../Beatmaps/PaginatedBeatmapContainer.cs | 2 +- .../Profile/Sections/BeatmapsSection.cs | 2 +- .../Overlays/Profile/Sections/CounterPill.cs | 2 +- .../Historical/ChartProfileSubsection.cs | 2 +- .../Historical/DrawableMostPlayedBeatmap.cs | 8 ++++---- .../PaginatedMostPlayedBeatmapContainer.cs | 2 +- .../Historical/PlayHistorySubsection.cs | 2 +- .../Sections/Historical/ProfileLineChart.cs | 6 +++--- .../Sections/Historical/ReplaysSubsection.cs | 2 +- .../Sections/Historical/UserHistoryGraph.cs | 2 +- .../Profile/Sections/HistoricalSection.cs | 2 +- .../Kudosu/DrawableKudosuHistoryItem.cs | 2 +- .../Profile/Sections/Kudosu/KudosuInfo.cs | 6 +++--- .../Kudosu/PaginatedKudosuHistoryContainer.cs | 2 +- .../Profile/Sections/KudosuSection.cs | 2 +- .../Profile/Sections/MedalsSection.cs | 2 +- .../Sections/PaginatedProfileSubsection.cs | 2 +- .../Profile/Sections/ProfileItemContainer.cs | 2 +- .../Profile/Sections/ProfileSubsection.cs | 2 +- .../Sections/ProfileSubsectionHeader.cs | 2 +- .../Sections/Ranks/DrawableProfileScore.cs | 4 ++-- .../Ranks/DrawableProfileWeightedScore.cs | 2 +- .../Sections/Ranks/PaginatedScoreContainer.cs | 2 +- .../Overlays/Profile/Sections/RanksSection.cs | 2 +- .../Sections/Recent/DrawableRecentActivity.cs | 2 +- .../Profile/Sections/Recent/MedalIcon.cs | 2 +- .../PaginatedRecentActivityContainer.cs | 2 +- .../Sections/Recent/RecentActivityIcon.cs | 2 +- .../Profile/Sections/RecentSection.cs | 2 +- osu.Game/Overlays/Profile/UserGraph.cs | 6 +++--- osu.Game/Overlays/Rankings/CountryFilter.cs | 2 +- osu.Game/Overlays/Rankings/CountryPill.cs | 4 ++-- .../Rankings/RankingsOverlayHeader.cs | 4 ++-- .../Rankings/RankingsSortTabControl.cs | 2 +- .../Overlays/Rankings/SpotlightSelector.cs | 8 ++++---- .../Overlays/Rankings/SpotlightsLayout.cs | 2 +- .../Rankings/Tables/CountriesTable.cs | 4 ++-- .../Rankings/Tables/PerformanceTable.cs | 2 +- .../Overlays/Rankings/Tables/RankingsTable.cs | 8 ++++---- .../Overlays/Rankings/Tables/ScoresTable.cs | 2 +- .../Rankings/Tables/TableRowBackground.cs | 2 +- .../Rankings/Tables/UserBasedTable.cs | 4 ++-- osu.Game/Overlays/RankingsOverlay.cs | 2 +- .../Overlays/RestoreDefaultValueButton.cs | 2 +- .../Settings/DangerousSettingsButton.cs | 2 +- osu.Game/Overlays/Settings/OutlinedTextBox.cs | 2 +- .../Settings/RulesetSettingsSubsection.cs | 2 +- .../Sections/Audio/AudioDevicesSettings.cs | 6 +++--- .../Settings/Sections/Audio/OffsetSettings.cs | 2 +- .../Settings/Sections/Audio/VolumeSettings.cs | 4 ++-- .../Settings/Sections/AudioSection.cs | 2 +- .../Settings/Sections/DebugSection.cs | 2 +- .../Sections/DebugSettings/GeneralSettings.cs | 2 +- .../Sections/DebugSettings/MemorySettings.cs | 2 +- .../Sections/Gameplay/AudioSettings.cs | 2 +- .../Sections/Gameplay/BackgroundSettings.cs | 2 +- .../Sections/Gameplay/BeatmapSettings.cs | 2 +- .../Sections/Gameplay/GeneralSettings.cs | 2 +- .../Settings/Sections/Gameplay/HUDSettings.cs | 2 +- .../Sections/Gameplay/InputSettings.cs | 2 +- .../Sections/Gameplay/ModsSettings.cs | 2 +- .../Settings/Sections/GameplaySection.cs | 2 +- .../Sections/General/LanguageSettings.cs | 2 +- .../Sections/General/UpdateSettings.cs | 2 +- .../Settings/Sections/GeneralSection.cs | 2 +- .../Sections/Graphics/LayoutSettings.cs | 14 ++++++------- .../Sections/Graphics/RendererSettings.cs | 2 +- .../Sections/Graphics/ScreenshotSettings.cs | 2 +- .../Sections/Graphics/VideoSettings.cs | 2 +- .../Settings/Sections/GraphicsSection.cs | 2 +- .../Sections/Input/BindingSettings.cs | 2 +- .../Input/GlobalKeyBindingsSection.cs | 14 ++++++------- .../Sections/Input/JoystickSettings.cs | 2 +- .../Sections/Input/KeyBindingPanel.cs | 2 +- .../Settings/Sections/Input/KeyBindingRow.cs | 8 ++++---- .../Sections/Input/KeyBindingsSubsection.cs | 4 ++-- .../Settings/Sections/Input/MouseSettings.cs | 6 +++--- .../Sections/Input/RotationPresetButtons.cs | 4 ++-- .../Sections/Input/RulesetBindingsSection.cs | 2 +- .../Sections/Input/TabletAreaSelection.cs | 2 +- .../Settings/Sections/Input/TabletSettings.cs | 2 +- .../Input/VariantBindingsSubsection.cs | 2 +- .../Settings/Sections/InputSection.cs | 4 ++-- .../Sections/Maintenance/BeatmapSettings.cs | 2 +- .../Maintenance/CollectionsSettings.cs | 2 +- .../Maintenance/DirectorySelectScreen.cs | 2 +- .../MassDeleteConfirmationDialog.cs | 2 +- .../MassVideoDeleteConfirmationDialog.cs | 2 +- .../Maintenance/MigrationRunScreen.cs | 2 +- .../Maintenance/MigrationSelectScreen.cs | 2 +- .../Sections/Maintenance/ModPresetSettings.cs | 2 +- .../Sections/Maintenance/ScoreSettings.cs | 2 +- .../Sections/Maintenance/SkinSettings.cs | 2 +- .../StableDirectoryLocationDialog.cs | 2 +- .../StableDirectorySelectScreen.cs | 2 +- .../Settings/Sections/MaintenanceSection.cs | 2 +- .../Online/AlertsAndPrivacySettings.cs | 2 +- .../Sections/Online/IntegrationSettings.cs | 2 +- .../Settings/Sections/Online/WebSettings.cs | 2 +- .../Settings/Sections/OnlineSection.cs | 2 +- .../Settings/Sections/RulesetSection.cs | 2 +- .../Overlays/Settings/Sections/SizeSlider.cs | 2 +- .../Overlays/Settings/Sections/SkinSection.cs | 10 +++++----- .../Sections/UserInterface/GeneralSettings.cs | 2 +- .../UserInterface/MainMenuSettings.cs | 2 +- .../UserInterface/SongSelectSettings.cs | 2 +- .../Settings/Sections/UserInterfaceSection.cs | 2 +- osu.Game/Overlays/Settings/SettingsButton.cs | 2 +- .../Overlays/Settings/SettingsCheckbox.cs | 2 +- .../Overlays/Settings/SettingsDropdown.cs | 4 ++-- .../Overlays/Settings/SettingsEnumDropdown.cs | 4 ++-- osu.Game/Overlays/Settings/SettingsFooter.cs | 4 ++-- osu.Game/Overlays/Settings/SettingsHeader.cs | 2 +- osu.Game/Overlays/Settings/SettingsItem.cs | 2 +- .../Overlays/Settings/SettingsNumberBox.cs | 6 +++--- osu.Game/Overlays/Settings/SettingsSection.cs | 2 +- osu.Game/Overlays/Settings/SettingsSidebar.cs | 2 +- osu.Game/Overlays/Settings/SettingsSlider.cs | 4 ++-- .../Overlays/Settings/SettingsSubsection.cs | 2 +- osu.Game/Overlays/Settings/SettingsTextBox.cs | 2 +- osu.Game/Overlays/Settings/SidebarButton.cs | 2 +- .../Overlays/Settings/SidebarIconButton.cs | 2 +- osu.Game/Overlays/SettingsOverlay.cs | 2 +- osu.Game/Overlays/SettingsPanel.cs | 6 +++--- osu.Game/Overlays/SettingsSubPanel.cs | 4 ++-- osu.Game/Overlays/SettingsToolboxGroup.cs | 2 +- osu.Game/Overlays/TabControlOverlayHeader.cs | 6 +++--- osu.Game/Overlays/TabbableOnlineOverlay.cs | 2 +- .../Overlays/Toolbar/AnalogClockDisplay.cs | 8 ++++---- osu.Game/Overlays/Toolbar/ClockDisplay.cs | 2 +- .../Overlays/Toolbar/DigitalClockDisplay.cs | 2 +- osu.Game/Overlays/Toolbar/Toolbar.cs | 4 ++-- .../Toolbar/ToolbarBeatmapListingButton.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarButton.cs | 4 ++-- .../Toolbar/ToolbarChangelogButton.cs | 2 +- .../Overlays/Toolbar/ToolbarChatButton.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarClock.cs | 2 +- .../Overlays/Toolbar/ToolbarHomeButton.cs | 2 +- .../Overlays/Toolbar/ToolbarMusicButton.cs | 2 +- .../Overlays/Toolbar/ToolbarNewsButton.cs | 2 +- .../Toolbar/ToolbarNotificationButton.cs | 4 ++-- .../Toolbar/ToolbarOverlayToggleButton.cs | 2 +- .../Overlays/Toolbar/ToolbarRankingsButton.cs | 2 +- .../Toolbar/ToolbarRulesetSelector.cs | 2 +- .../Toolbar/ToolbarRulesetTabButton.cs | 4 ++-- .../Overlays/Toolbar/ToolbarSettingsButton.cs | 2 +- .../Overlays/Toolbar/ToolbarSocialButton.cs | 2 +- .../Overlays/Toolbar/ToolbarUserButton.cs | 2 +- .../Overlays/Toolbar/ToolbarWikiButton.cs | 2 +- osu.Game/Overlays/UserProfileOverlay.cs | 8 ++++---- osu.Game/Overlays/VersionManager.cs | 2 +- osu.Game/Overlays/Volume/MuteButton.cs | 2 +- .../Overlays/Volume/VolumeControlReceptor.cs | 2 +- osu.Game/Overlays/Volume/VolumeMeter.cs | 2 +- osu.Game/Overlays/VolumeOverlay.cs | 2 +- osu.Game/Overlays/WaveOverlayContainer.cs | 2 +- .../Wiki/Markdown/WikiMarkdownContainer.cs | 4 ++-- .../Wiki/Markdown/WikiMarkdownImage.cs | 2 +- .../Wiki/Markdown/WikiMarkdownImageBlock.cs | 8 ++++---- .../Wiki/Markdown/WikiNoticeContainer.cs | 4 ++-- osu.Game/Overlays/Wiki/WikiArticlePage.cs | 4 ++-- osu.Game/Overlays/Wiki/WikiHeader.cs | 4 ++-- osu.Game/Overlays/Wiki/WikiMainPage.cs | 2 +- osu.Game/Overlays/Wiki/WikiPanelContainer.cs | 6 +++--- osu.Game/Overlays/Wiki/WikiSidebar.cs | 2 +- osu.Game/Overlays/Wiki/WikiTableOfContents.cs | 4 ++-- osu.Game/Overlays/WikiOverlay.cs | 2 +- osu.Game/PerformFromMenuRunner.cs | 2 +- .../Performance/HighPerformanceSession.cs | 2 +- .../Edit/DistancedHitObjectComposer.cs | 4 ++-- .../Edit/DrawableEditorRulesetWrapper.cs | 2 +- osu.Game/Rulesets/Edit/EditorToolboxGroup.cs | 2 +- osu.Game/Rulesets/Edit/ExpandableButton.cs | 2 +- .../Edit/ExpandingToolboxContainer.cs | 2 +- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 4 ++-- .../Edit/HitObjectSelectionBlueprint.cs | 4 ++-- osu.Game/Rulesets/Edit/PlacementBlueprint.cs | 2 +- osu.Game/Rulesets/Edit/SelectionBlueprint.cs | 2 +- .../Judgements/DefaultJudgementPiece.cs | 2 +- .../Rulesets/Judgements/DrawableJudgement.cs | 2 +- .../Mods/DifficultyAdjustSettingsControl.cs | 4 ++-- osu.Game/Rulesets/Mods/MetronomeBeat.cs | 2 +- osu.Game/Rulesets/Mods/ModFlashlight.cs | 4 ++-- osu.Game/Rulesets/Mods/ModMuted.cs | 2 +- osu.Game/Rulesets/Mods/ModNightcore.cs | 4 ++-- osu.Game/Rulesets/Mods/ModNoScope.cs | 2 +- .../Objects/Drawables/DrawableHitObject.cs | 4 ++-- .../Pooling/PoolableDrawableWithLifetime.cs | 2 +- .../PooledDrawableWithLifetimeContainer.cs | 2 +- osu.Game/Rulesets/RulesetConfigCache.cs | 2 +- osu.Game/Rulesets/RulesetSelector.cs | 2 +- .../Scoring/AccumulatingHealthProcessor.cs | 2 +- .../Scoring/DrainingHealthProcessor.cs | 2 +- osu.Game/Rulesets/Scoring/HealthProcessor.cs | 2 +- .../Rulesets/Scoring/JudgementProcessor.cs | 2 +- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 2 +- osu.Game/Rulesets/UI/DrawableRuleset.cs | 4 ++-- .../Rulesets/UI/FrameStabilityContainer.cs | 2 +- .../Rulesets/UI/GameplayCursorContainer.cs | 2 +- .../UI/GameplaySampleTriggerSource.cs | 2 +- osu.Game/Rulesets/UI/HitObjectContainer.cs | 2 +- osu.Game/Rulesets/UI/JudgementContainer.cs | 2 +- osu.Game/Rulesets/UI/ModIcon.cs | 2 +- osu.Game/Rulesets/UI/ModSwitchSmall.cs | 2 +- osu.Game/Rulesets/UI/ModSwitchTiny.cs | 2 +- osu.Game/Rulesets/UI/Playfield.cs | 4 ++-- .../UI/PlayfieldAdjustmentContainer.cs | 2 +- osu.Game/Rulesets/UI/PlayfieldBorder.cs | 4 ++-- osu.Game/Rulesets/UI/ReplayRecorder.cs | 4 ++-- osu.Game/Rulesets/UI/RulesetInputManager.cs | 8 ++++---- .../UI/Scrolling/DrawableScrollingRuleset.cs | 2 +- .../Scrolling/ScrollingHitObjectContainer.cs | 2 +- .../UI/Scrolling/ScrollingPlayfield.cs | 2 +- ...UnprocessedPerformancePointsPlaceholder.cs | 2 +- osu.Game/Scoring/ScorePerformanceCache.cs | 2 +- osu.Game/Screens/BackgroundScreen.cs | 2 +- osu.Game/Screens/BackgroundScreenStack.cs | 2 +- .../Backgrounds/BackgroundScreenBeatmap.cs | 4 ++-- .../Backgrounds/BackgroundScreenBlack.cs | 2 +- .../Backgrounds/BackgroundScreenCustom.cs | 2 +- .../Backgrounds/BackgroundScreenDefault.cs | 2 +- osu.Game/Screens/Edit/BottomBar.cs | 2 +- .../Edit/Components/BottomBarContainer.cs | 2 +- .../Screens/Edit/Components/EditorSidebar.cs | 2 +- .../Edit/Components/EditorSidebarSection.cs | 4 ++-- .../Edit/Components/Menus/EditorMenuBar.cs | 14 ++++++------- .../Menus/EditorScreenSwitcherControl.cs | 4 ++-- .../Edit/Components/PlaybackControl.cs | 6 +++--- .../RadioButtons/EditorRadioButton.cs | 2 +- .../EditorRadioButtonCollection.cs | 2 +- .../TernaryButtons/DrawableTernaryButton.cs | 2 +- .../Edit/Components/TimeInfoContainer.cs | 2 +- .../Timelines/Summary/Parts/BookmarkPart.cs | 4 ++-- .../Timelines/Summary/Parts/BreakPart.cs | 4 ++-- .../Summary/Parts/ControlPointPart.cs | 2 +- .../Parts/ControlPointVisualisation.cs | 2 +- .../Summary/Parts/EffectPointVisualisation.cs | 2 +- .../Summary/Parts/GroupVisualisation.cs | 2 +- .../Timelines/Summary/Parts/MarkerPart.cs | 4 ++-- .../Timelines/Summary/Parts/TimelinePart.cs | 4 ++-- .../Timelines/Summary/SummaryTimeline.cs | 2 +- .../Timelines/Summary/TestGameplayButton.cs | 2 +- .../Visualisations/DurationVisualisation.cs | 2 +- .../Visualisations/PointVisualisation.cs | 2 +- .../Compose/Components/BeatDivisorControl.cs | 16 +++++++-------- .../Compose/Components/BlueprintContainer.cs | 2 +- .../Components/CircularDistanceSnapGrid.cs | 4 ++-- .../Components/ComposeBlueprintContainer.cs | 2 +- .../Compose/Components/DistanceSnapGrid.cs | 2 +- .../Edit/Compose/Components/DragBox.cs | 4 ++-- .../Components/EditorBlueprintContainer.cs | 2 +- .../Components/EditorSelectionHandler.cs | 2 +- .../HitObjectOrderedSelectionContainer.cs | 2 +- .../Components/RectangularPositionSnapGrid.cs | 2 +- .../Compose/Components/ScrollingDragBox.cs | 2 +- .../Edit/Compose/Components/SelectionBox.cs | 2 +- .../Compose/Components/SelectionBoxButton.cs | 2 +- .../Compose/Components/SelectionBoxControl.cs | 2 +- .../Components/SelectionBoxDragHandle.cs | 2 +- .../SelectionBoxDragHandleContainer.cs | 2 +- .../Components/SelectionBoxRotationHandle.cs | 2 +- .../Components/SelectionBoxScaleHandle.cs | 2 +- .../Compose/Components/SelectionHandler.cs | 2 +- .../Components/Timeline/CentreMarker.cs | 2 +- .../Timeline/DifficultyPointPiece.cs | 4 ++-- .../Timeline/HitObjectPointPiece.cs | 2 +- .../Components/Timeline/SamplePointPiece.cs | 4 ++-- .../Compose/Components/Timeline/Timeline.cs | 2 +- .../Components/Timeline/TimelineArea.cs | 2 +- .../Timeline/TimelineBlueprintContainer.cs | 6 +++--- .../Components/Timeline/TimelineButton.cs | 2 +- .../Timeline/TimelineControlPointDisplay.cs | 2 +- .../Timeline/TimelineControlPointGroup.cs | 2 +- .../Components/Timeline/TimelineDragBox.cs | 2 +- .../Timeline/TimelineHitObjectBlueprint.cs | 10 +++++----- .../Timeline/TimelineSelectionHandler.cs | 2 +- .../Timeline/TimelineTickDisplay.cs | 2 +- .../Components/Timeline/TimingPointPiece.cs | 2 +- .../Components/Timeline/TopPointPiece.cs | 2 +- .../Timeline/ZoomableScrollContainer.cs | 2 +- .../Screens/Edit/Compose/ComposeScreen.cs | 2 +- .../Screens/Edit/CreateNewDifficultyDialog.cs | 2 +- .../DeleteDifficultyConfirmationDialog.cs | 2 +- osu.Game/Screens/Edit/Design/DesignScreen.cs | 2 +- osu.Game/Screens/Edit/Editor.cs | 4 ++-- osu.Game/Screens/Edit/EditorBeatmap.cs | 2 +- osu.Game/Screens/Edit/EditorChangeHandler.cs | 2 +- osu.Game/Screens/Edit/EditorClock.cs | 2 +- osu.Game/Screens/Edit/EditorLoader.cs | 2 +- .../Edit/EditorRoundedScreenSettings.cs | 2 +- .../EditorRoundedScreenSettingsSection.cs | 2 +- osu.Game/Screens/Edit/EditorScreen.cs | 2 +- .../Screens/Edit/EditorScreenWithTimeline.cs | 2 +- .../Edit/EditorSkinProvidingContainer.cs | 2 +- osu.Game/Screens/Edit/EditorTable.cs | 6 +++--- .../Screens/Edit/GameplayTest/EditorPlayer.cs | 2 +- .../Edit/GameplayTest/EditorPlayerLoader.cs | 2 +- .../SaveBeforeGameplayTestDialog.cs | 2 +- osu.Game/Screens/Edit/PromptForSaveDialog.cs | 2 +- osu.Game/Screens/Edit/Setup/ColoursSection.cs | 2 +- osu.Game/Screens/Edit/Setup/DesignSection.cs | 2 +- .../Screens/Edit/Setup/DifficultySection.cs | 2 +- .../Screens/Edit/Setup/LabelledFileChooser.cs | 4 ++-- .../Edit/Setup/LabelledRomanisedTextBox.cs | 4 ++-- .../Edit/Setup/LabelledTextBoxWithPopover.cs | 4 ++-- .../Screens/Edit/Setup/MetadataSection.cs | 2 +- .../Screens/Edit/Setup/ResourcesSection.cs | 2 +- .../Screens/Edit/Setup/RulesetSetupSection.cs | 2 +- osu.Game/Screens/Edit/Setup/SetupScreen.cs | 4 ++-- .../Screens/Edit/Setup/SetupScreenHeader.cs | 8 ++++---- .../Edit/Setup/SetupScreenHeaderBackground.cs | 2 +- osu.Game/Screens/Edit/Setup/SetupSection.cs | 2 +- .../Edit/Timing/ControlPointSettings.cs | 2 +- .../Screens/Edit/Timing/ControlPointTable.cs | 4 ++-- osu.Game/Screens/Edit/Timing/EffectSection.cs | 2 +- osu.Game/Screens/Edit/Timing/GroupSection.cs | 2 +- .../IndeterminateSliderWithTextBoxInput.cs | 2 +- .../Edit/Timing/LabelledTimeSignature.cs | 4 ++-- .../Screens/Edit/Timing/MetronomeDisplay.cs | 2 +- .../Edit/Timing/RepeatingButtonBehaviour.cs | 2 +- osu.Game/Screens/Edit/Timing/RowAttribute.cs | 2 +- .../RowAttributes/AttributeProgressBar.cs | 2 +- .../Timing/RowAttributes/AttributeText.cs | 2 +- .../RowAttributes/DifficultyRowAttribute.cs | 2 +- .../RowAttributes/EffectRowAttribute.cs | 2 +- .../RowAttributes/SampleRowAttribute.cs | 2 +- .../RowAttributes/TimingRowAttribute.cs | 2 +- osu.Game/Screens/Edit/Timing/Section.cs | 2 +- .../Edit/Timing/SliderWithTextBoxInput.cs | 2 +- osu.Game/Screens/Edit/Timing/TapButton.cs | 4 ++-- .../Screens/Edit/Timing/TapTimingControl.cs | 4 ++-- .../Screens/Edit/Timing/TimingAdjustButton.cs | 4 ++-- osu.Game/Screens/Edit/Timing/TimingScreen.cs | 4 ++-- osu.Game/Screens/Edit/Timing/TimingSection.cs | 4 ++-- .../Edit/Timing/WaveformComparisonDisplay.cs | 6 +++--- .../Edit/TransactionalCommitComponent.cs | 2 +- .../Edit/Verify/InterpretationSection.cs | 2 +- osu.Game/Screens/Edit/Verify/IssueList.cs | 2 +- osu.Game/Screens/Edit/Verify/IssueSettings.cs | 2 +- osu.Game/Screens/Edit/Verify/IssueTable.cs | 2 +- osu.Game/Screens/Edit/Verify/VerifyScreen.cs | 2 +- .../Screens/Edit/Verify/VisibilitySection.cs | 2 +- osu.Game/Screens/Import/FileImportScreen.cs | 2 +- osu.Game/Screens/Loader.cs | 4 ++-- osu.Game/Screens/Menu/ButtonArea.cs | 4 ++-- osu.Game/Screens/Menu/ButtonSystem.cs | 2 +- .../Menu/ConfirmDiscardChangesDialog.cs | 2 +- osu.Game/Screens/Menu/ConfirmExitDialog.cs | 2 +- osu.Game/Screens/Menu/Disclaimer.cs | 2 +- osu.Game/Screens/Menu/ExitConfirmOverlay.cs | 2 +- .../Screens/Menu/FlowContainerWithOrigin.cs | 2 +- osu.Game/Screens/Menu/IntroCircles.cs | 2 +- osu.Game/Screens/Menu/IntroScreen.cs | 2 +- osu.Game/Screens/Menu/IntroSequence.cs | 4 ++-- osu.Game/Screens/Menu/IntroTriangles.cs | 14 ++++++------- osu.Game/Screens/Menu/IntroWelcome.cs | 4 ++-- osu.Game/Screens/Menu/LogoVisualisation.cs | 2 +- osu.Game/Screens/Menu/MainMenu.cs | 2 +- osu.Game/Screens/Menu/MainMenuButton.cs | 2 +- .../Screens/Menu/MenuLogoVisualisation.cs | 2 +- osu.Game/Screens/Menu/MenuSideFlashes.cs | 2 +- osu.Game/Screens/Menu/OsuLogo.cs | 2 +- osu.Game/Screens/Menu/SongTicker.cs | 2 +- osu.Game/Screens/Menu/StorageErrorDialog.cs | 2 +- .../OnlinePlay/Components/BeatmapTitle.cs | 2 +- .../Components/DisableableTabControl.cs | 4 ++-- .../OnlinePlay/Components/DrawableGameType.cs | 4 ++-- .../Components/ListingPollingComponent.cs | 2 +- .../Components/MatchBeatmapDetailArea.cs | 2 +- .../Components/OnlinePlayBackgroundScreen.cs | 2 +- .../Components/OnlinePlayBackgroundSprite.cs | 2 +- .../OnlinePlay/Components/OverlinedHeader.cs | 2 +- .../Components/OverlinedPlaylistHeader.cs | 2 +- .../Components/ParticipantCountDisplay.cs | 2 +- .../Components/ParticipantsDisplay.cs | 2 +- .../OnlinePlay/Components/ParticipantsList.cs | 4 ++-- .../Components/PlaylistItemBackground.cs | 2 +- .../OnlinePlay/Components/ReadyButton.cs | 2 +- .../Components/RoomLocalUserInfo.cs | 2 +- .../OnlinePlay/Components/RoomManager.cs | 2 +- .../Components/RoomPollingComponent.cs | 2 +- .../Components/SelectionPollingComponent.cs | 2 +- .../Components/StarRatingRangeDisplay.cs | 2 +- .../Components/StatusColouredContainer.cs | 2 +- .../OnlinePlay/DrawableRoomPlaylist.cs | 2 +- .../OnlinePlay/DrawableRoomPlaylistItem.cs | 14 ++++++------- .../OnlinePlay/FooterButtonFreeMods.cs | 2 +- .../OnlinePlay/FreeModSelectOverlay.cs | 2 +- osu.Game/Screens/OnlinePlay/Header.cs | 4 ++-- .../Lounge/Components/DrawableRoom.cs | 8 ++++---- .../DrawableRoomParticipantsList.cs | 6 +++--- .../Lounge/Components/EndDateInfo.cs | 4 ++-- .../Lounge/Components/MatchTypePill.cs | 2 +- .../Lounge/Components/PillContainer.cs | 2 +- .../Lounge/Components/PlaylistCountPill.cs | 2 +- .../Lounge/Components/QueueModePill.cs | 2 +- .../Lounge/Components/RankRangePill.cs | 2 +- .../Components/RoomSpecialCategoryPill.cs | 2 +- .../Lounge/Components/RoomStatusPill.cs | 2 +- .../Lounge/Components/RoomsContainer.cs | 2 +- .../OnlinePlay/Lounge/DrawableLoungeRoom.cs | 4 ++-- .../Lounge/LoungeBackgroundScreen.cs | 2 +- .../OnlinePlay/Lounge/LoungeSubScreen.cs | 2 +- .../Match/Components/CreateRoomButton.cs | 2 +- .../Match/Components/MatchChatDisplay.cs | 2 +- .../Match/Components/MatchLeaderboard.cs | 2 +- .../Match/Components/MatchLeaderboardScore.cs | 2 +- .../Match/Components/MatchTypePicker.cs | 4 ++-- .../Match/Components/PurpleTriangleButton.cs | 2 +- .../Components/RoomAvailabilityPicker.cs | 4 ++-- .../Match/Components/RoomSettingsOverlay.cs | 6 +++--- .../OnlinePlay/Match/DrawableMatchRoom.cs | 4 ++-- .../OnlinePlay/Match/RoomBackgroundScreen.cs | 2 +- .../Screens/OnlinePlay/Match/RoomSubScreen.cs | 4 ++-- .../CreateMultiplayerMatchButton.cs | 2 +- .../Multiplayer/GameplayChatDisplay.cs | 2 +- .../Multiplayer/GameplayMatchScoreDisplay.cs | 2 +- .../Multiplayer/Match/MatchStartControl.cs | 2 +- .../Match/MultiplayerCountdownButton.cs | 2 +- .../Match/MultiplayerMatchFooter.cs | 2 +- .../Match/MultiplayerMatchSettingsOverlay.cs | 6 +++--- .../Match/MultiplayerReadyButton.cs | 2 +- .../Match/MultiplayerSpectateButton.cs | 4 ++-- .../Match/Playlist/MultiplayerHistoryList.cs | 4 ++-- .../Match/Playlist/MultiplayerPlaylist.cs | 2 +- .../Playlist/MultiplayerPlaylistTabControl.cs | 4 ++-- .../Match/Playlist/MultiplayerQueueList.cs | 6 +++--- .../OnlinePlay/Multiplayer/Multiplayer.cs | 2 +- .../Multiplayer/MultiplayerLoungeSubScreen.cs | 4 ++-- .../Multiplayer/MultiplayerMatchSongSelect.cs | 2 +- .../Multiplayer/MultiplayerMatchSubScreen.cs | 4 ++-- .../Multiplayer/MultiplayerPlayer.cs | 2 +- .../Multiplayer/MultiplayerPlayerLoader.cs | 2 +- .../Multiplayer/MultiplayerResultsScreen.cs | 2 +- .../Multiplayer/MultiplayerRoomComposite.cs | 2 +- .../Multiplayer/MultiplayerRoomManager.cs | 2 +- .../Multiplayer/MultiplayerRoomSounds.cs | 2 +- .../MultiplayerTeamResultsScreen.cs | 2 +- .../Participants/ParticipantPanel.cs | 4 ++-- .../Participants/ParticipantsList.cs | 2 +- .../Participants/ParticipantsListHeader.cs | 2 +- .../Multiplayer/Participants/StateDisplay.cs | 2 +- .../Multiplayer/Participants/TeamDisplay.cs | 2 +- .../Spectate/MultiSpectatorLeaderboard.cs | 2 +- .../Spectate/MultiSpectatorPlayer.cs | 2 +- .../Spectate/MultiSpectatorPlayerLoader.cs | 2 +- .../Spectate/MultiSpectatorScreen.cs | 2 +- .../Multiplayer/Spectate/PlayerArea.cs | 4 ++-- .../Multiplayer/Spectate/PlayerGrid_Cell.cs | 2 +- .../Multiplayer/Spectate/PlayerGrid_Facade.cs | 2 +- .../Spectate/SpectatorSyncManager.cs | 2 +- .../OnlinePlay/OngoingOperationTracker.cs | 2 +- .../Screens/OnlinePlay/OnlinePlayComposite.cs | 2 +- .../Screens/OnlinePlay/OnlinePlayScreen.cs | 4 ++-- .../OnlinePlay/OnlinePlaySongSelect.cs | 2 +- .../Screens/OnlinePlay/OnlinePlaySubScreen.cs | 2 +- .../OnlinePlay/OnlinePlaySubScreenStack.cs | 2 +- .../Playlists/CreatePlaylistsRoomButton.cs | 2 +- .../Screens/OnlinePlay/Playlists/Playlists.cs | 2 +- .../Playlists/PlaylistsLoungeSubScreen.cs | 2 +- .../OnlinePlay/Playlists/PlaylistsPlayer.cs | 2 +- .../Playlists/PlaylistsReadyButton.cs | 2 +- .../Playlists/PlaylistsResultsScreen.cs | 4 ++-- .../Playlists/PlaylistsRoomFooter.cs | 2 +- .../Playlists/PlaylistsRoomSettingsOverlay.cs | 8 ++++---- .../PlaylistsRoomSettingsPlaylist.cs | 2 +- .../Playlists/PlaylistsRoomSubScreen.cs | 2 +- .../Playlists/PlaylistsSongSelect.cs | 2 +- osu.Game/Screens/OsuScreen.cs | 2 +- osu.Game/Screens/OsuScreenStack.cs | 2 +- .../Screens/Play/BeatmapMetadataDisplay.cs | 6 +++--- osu.Game/Screens/Play/Break/BlurredIcon.cs | 2 +- osu.Game/Screens/Play/Break/BreakArrows.cs | 2 +- osu.Game/Screens/Play/Break/BreakInfo.cs | 2 +- osu.Game/Screens/Play/Break/BreakInfoLine.cs | 4 ++-- osu.Game/Screens/Play/Break/GlowIcon.cs | 2 +- .../Screens/Play/Break/LetterboxOverlay.cs | 2 +- .../Play/Break/RemainingTimeCounter.cs | 2 +- osu.Game/Screens/Play/BreakOverlay.cs | 2 +- osu.Game/Screens/Play/BreakTracker.cs | 2 +- osu.Game/Screens/Play/ComboEffects.cs | 2 +- osu.Game/Screens/Play/DimmableStoryboard.cs | 2 +- osu.Game/Screens/Play/EpilepsyWarning.cs | 2 +- osu.Game/Screens/Play/FailAnimation.cs | 2 +- osu.Game/Screens/Play/FailOverlay.cs | 2 +- .../Screens/Play/GameplayClockContainer.cs | 2 +- osu.Game/Screens/Play/GameplayMenuOverlay.cs | 4 ++-- .../ClicksPerSecondCalculator.cs | 2 +- .../ClicksPerSecond/ClicksPerSecondCounter.cs | 4 ++-- osu.Game/Screens/Play/HUD/ComboCounter.cs | 2 +- .../Play/HUD/DefaultAccuracyCounter.cs | 2 +- .../Screens/Play/HUD/DefaultComboCounter.cs | 2 +- .../Screens/Play/HUD/DefaultHealthDisplay.cs | 2 +- .../Screens/Play/HUD/DefaultScoreCounter.cs | 2 +- .../Screens/Play/HUD/DefaultSongProgress.cs | 2 +- osu.Game/Screens/Play/HUD/FailingLayer.cs | 2 +- .../Play/HUD/GameplayAccuracyCounter.cs | 2 +- .../Screens/Play/HUD/GameplayLeaderboard.cs | 4 ++-- .../Play/HUD/GameplayLeaderboardScore.cs | 2 +- .../Screens/Play/HUD/GameplayScoreCounter.cs | 2 +- osu.Game/Screens/Play/HUD/HealthDisplay.cs | 2 +- .../HUD/HitErrorMeters/BarHitErrorMeter.cs | 4 ++-- .../HUD/HitErrorMeters/ColourHitErrorMeter.cs | 6 +++--- .../Play/HUD/HitErrorMeters/HitErrorMeter.cs | 2 +- .../Screens/Play/HUD/HoldForMenuButton.cs | 4 ++-- .../Screens/Play/HUD/LongestComboCounter.cs | 4 ++-- .../Screens/Play/HUD/MatchScoreDisplay.cs | 4 ++-- osu.Game/Screens/Play/HUD/ModDisplay.cs | 2 +- osu.Game/Screens/Play/HUD/ModFlowDisplay.cs | 2 +- .../HUD/MultiplayerGameplayLeaderboard.cs | 2 +- .../Play/HUD/PerformancePointsCounter.cs | 4 ++-- .../Screens/Play/HUD/PlayerSettingsOverlay.cs | 2 +- .../Play/HUD/SoloGameplayLeaderboard.cs | 2 +- osu.Game/Screens/Play/HUD/SongProgress.cs | 2 +- osu.Game/Screens/Play/HUD/SongProgressBar.cs | 2 +- .../Screens/Play/HUD/SongProgressGraph.cs | 2 +- osu.Game/Screens/Play/HUD/SongProgressInfo.cs | 2 +- .../Screens/Play/HUD/UnstableRateCounter.cs | 4 ++-- osu.Game/Screens/Play/HUDOverlay.cs | 4 ++-- osu.Game/Screens/Play/HotkeyExitOverlay.cs | 2 +- osu.Game/Screens/Play/HotkeyRetryOverlay.cs | 2 +- osu.Game/Screens/Play/KeyCounter.cs | 2 +- osu.Game/Screens/Play/KeyCounterAction.cs | 2 +- osu.Game/Screens/Play/KeyCounterDisplay.cs | 4 ++-- osu.Game/Screens/Play/KeyCounterKeyboard.cs | 2 +- osu.Game/Screens/Play/KeyCounterMouse.cs | 2 +- .../Play/MasterGameplayClockContainer.cs | 2 +- osu.Game/Screens/Play/PauseOverlay.cs | 2 +- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Screens/Play/PlayerLoader.cs | 6 +++--- .../Play/PlayerSettings/AudioSettings.cs | 2 +- .../PlayerSettings/BeatmapOffsetControl.cs | 6 +++--- .../Play/PlayerSettings/DiscussionSettings.cs | 2 +- .../Play/PlayerSettings/InputSettings.cs | 2 +- .../Play/PlayerSettings/PlaybackSettings.cs | 2 +- .../Play/PlayerSettings/PlayerCheckbox.cs | 4 ++-- .../PlayerSettings/PlayerSettingsGroup.cs | 2 +- .../Play/PlayerSettings/PlayerSliderBar.cs | 4 ++-- .../Play/PlayerSettings/VisualSettings.cs | 2 +- osu.Game/Screens/Play/ReplayPlayer.cs | 2 +- osu.Game/Screens/Play/ReplayPlayerLoader.cs | 2 +- osu.Game/Screens/Play/ResumeOverlay.cs | 2 +- osu.Game/Screens/Play/RoomSubmittingPlayer.cs | 2 +- .../Screens/Play/SaveFailedScoreButton.cs | 2 +- .../Screens/Play/ScreenSuspensionHandler.cs | 2 +- .../Play/ScreenWithBeatmapBackground.cs | 2 +- osu.Game/Screens/Play/SkipOverlay.cs | 8 ++++---- osu.Game/Screens/Play/SoloPlayer.cs | 2 +- osu.Game/Screens/Play/SoloSpectator.cs | 2 +- osu.Game/Screens/Play/SoloSpectatorPlayer.cs | 2 +- osu.Game/Screens/Play/SpectatorPlayer.cs | 2 +- .../Screens/Play/SpectatorPlayerLoader.cs | 2 +- .../Screens/Play/SpectatorResultsScreen.cs | 2 +- osu.Game/Screens/Play/SquareGraph.cs | 4 ++-- osu.Game/Screens/Play/SubmittingPlayer.cs | 2 +- osu.Game/Screens/Ranking/AspectContainer.cs | 2 +- .../ContractedPanelMiddleContent.cs | 2 +- .../Contracted/ContractedPanelTopContent.cs | 2 +- .../Expanded/Accuracy/AccuracyCircle.cs | 2 +- .../Ranking/Expanded/Accuracy/RankBadge.cs | 2 +- .../Ranking/Expanded/Accuracy/RankNotch.cs | 2 +- .../Ranking/Expanded/Accuracy/RankText.cs | 2 +- .../Accuracy/SmoothCircularProgress.cs | 2 +- .../Expanded/ExpandedPanelMiddleContent.cs | 4 ++-- .../Expanded/ExpandedPanelTopContent.cs | 2 +- .../Expanded/Statistics/AccuracyStatistic.cs | 4 ++-- .../Expanded/Statistics/ComboStatistic.cs | 2 +- .../Expanded/Statistics/CounterStatistic.cs | 2 +- .../Expanded/Statistics/HitResultStatistic.cs | 2 +- .../Statistics/PerformanceStatistic.cs | 2 +- .../Expanded/Statistics/StatisticCounter.cs | 2 +- .../Expanded/Statistics/StatisticDisplay.cs | 2 +- .../Ranking/Expanded/TotalScoreCounter.cs | 2 +- .../Screens/Ranking/ReplayDownloadButton.cs | 2 +- osu.Game/Screens/Ranking/ResultsScreen.cs | 4 ++-- osu.Game/Screens/Ranking/RetryButton.cs | 2 +- osu.Game/Screens/Ranking/ScorePanel.cs | 2 +- osu.Game/Screens/Ranking/ScorePanelList.cs | 6 +++--- .../Ranking/ScorePanelTrackingContainer.cs | 2 +- osu.Game/Screens/Ranking/SoloResultsScreen.cs | 2 +- .../Ranking/Statistics/AverageHitError.cs | 2 +- .../HitEventTimingDistributionGraph.cs | 4 ++-- .../Statistics/PerformanceBreakdownChart.cs | 2 +- .../Ranking/Statistics/SimpleStatisticItem.cs | 4 ++-- .../Statistics/SimpleStatisticTable.cs | 4 ++-- .../Ranking/Statistics/StatisticContainer.cs | 2 +- .../Ranking/Statistics/StatisticsPanel.cs | 2 +- .../Ranking/Statistics/UnstableRate.cs | 2 +- osu.Game/Screens/ScreenWhiteBox.cs | 6 +++--- osu.Game/Screens/Select/BeatmapCarousel.cs | 4 ++-- .../Select/BeatmapClearScoresDialog.cs | 2 +- .../Screens/Select/BeatmapDeleteDialog.cs | 2 +- osu.Game/Screens/Select/BeatmapDetailArea.cs | 2 +- .../Select/BeatmapDetailAreaTabControl.cs | 2 +- osu.Game/Screens/Select/BeatmapDetails.cs | 4 ++-- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 6 +++--- .../Select/BeatmapInfoWedgeBackground.cs | 2 +- .../Screens/Select/Carousel/CarouselHeader.cs | 4 ++-- .../Carousel/DrawableCarouselBeatmap.cs | 2 +- .../Carousel/DrawableCarouselBeatmapSet.cs | 2 +- .../Select/Carousel/DrawableCarouselItem.cs | 2 +- .../Carousel/FilterableDifficultyIcon.cs | 2 +- .../Select/Carousel/GroupedDifficultyIcon.cs | 2 +- .../Select/Carousel/SetPanelBackground.cs | 2 +- .../Select/Carousel/SetPanelContent.cs | 2 +- .../Screens/Select/Carousel/TopLocalRank.cs | 2 +- .../Select/Carousel/UpdateBeatmapSetButton.cs | 2 +- .../Carousel/UpdateLocalConfirmationDialog.cs | 2 +- .../Screens/Select/Details/AdvancedStats.cs | 4 ++-- .../Screens/Select/Details/FailRetryGraph.cs | 2 +- .../Screens/Select/Details/UserRatings.cs | 2 +- .../Select/DifficultyRangeFilterControl.cs | 8 ++++---- osu.Game/Screens/Select/FilterControl.cs | 2 +- osu.Game/Screens/Select/Footer.cs | 2 +- osu.Game/Screens/Select/FooterButton.cs | 2 +- osu.Game/Screens/Select/FooterButtonMods.cs | 2 +- .../Screens/Select/FooterButtonOptions.cs | 2 +- osu.Game/Screens/Select/FooterButtonRandom.cs | 2 +- .../Select/Leaderboards/BeatmapLeaderboard.cs | 2 +- .../Screens/Select/LocalScoreDeleteDialog.cs | 2 +- .../Screens/Select/NoResultsPlaceholder.cs | 2 +- .../Select/Options/BeatmapOptionsButton.cs | 2 +- .../Select/Options/BeatmapOptionsOverlay.cs | 2 +- .../Screens/Select/PlayBeatmapDetailArea.cs | 2 +- osu.Game/Screens/Select/PlaySongSelect.cs | 2 +- osu.Game/Screens/Select/SkinDeleteDialog.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 8 ++++---- osu.Game/Screens/Select/WedgeBackground.cs | 2 +- osu.Game/Screens/Spectate/SpectatorScreen.cs | 2 +- osu.Game/Screens/StartupScreen.cs | 2 +- osu.Game/Screens/Utility/ButtonWithKeyBind.cs | 2 +- osu.Game/Screens/Utility/CircleGameplay.cs | 4 ++-- osu.Game/Screens/Utility/LatencyArea.cs | 2 +- .../Screens/Utility/LatencyCertifierScreen.cs | 2 +- .../LatencyCursorContainer.cs | 4 ++-- .../SampleComponents/LatencyMovableBox.cs | 2 +- .../LatencySampleComponent.cs | 2 +- osu.Game/Screens/Utility/ScrollingGameplay.cs | 4 ++-- .../Skinning/BeatmapSkinProvidingContainer.cs | 2 +- osu.Game/Skinning/Components/BigBlackBox.cs | 2 +- osu.Game/Skinning/Editor/SkinBlueprint.cs | 4 ++-- .../Skinning/Editor/SkinBlueprintContainer.cs | 2 +- .../Skinning/Editor/SkinComponentToolbox.cs | 6 +++--- osu.Game/Skinning/Editor/SkinEditor.cs | 4 ++-- osu.Game/Skinning/Editor/SkinEditorOverlay.cs | 2 +- .../Skinning/Editor/SkinEditorSceneLibrary.cs | 4 ++-- .../Skinning/Editor/SkinSelectionHandler.cs | 2 +- .../Skinning/Editor/SkinSettingsToolbox.cs | 2 +- osu.Game/Skinning/LegacyAccuracyCounter.cs | 2 +- osu.Game/Skinning/LegacyComboCounter.cs | 2 +- osu.Game/Skinning/LegacyHealthDisplay.cs | 16 +++++++-------- osu.Game/Skinning/LegacyJudgementPieceNew.cs | 2 +- osu.Game/Skinning/LegacyJudgementPieceOld.cs | 2 +- .../Skinning/LegacyKiaiFlashingDrawable.cs | 2 +- osu.Game/Skinning/LegacyRollingCounter.cs | 2 +- osu.Game/Skinning/LegacyScoreCounter.cs | 2 +- osu.Game/Skinning/LegacySkinExtensions.cs | 4 ++-- osu.Game/Skinning/LegacySongProgress.cs | 2 +- osu.Game/Skinning/LegacySpriteText.cs | 2 +- osu.Game/Skinning/PausableSkinnableSound.cs | 2 +- osu.Game/Skinning/PoolableSkinnableSample.cs | 2 +- .../Skinning/RulesetSkinProvidingContainer.cs | 2 +- osu.Game/Skinning/SkinProvidingContainer.cs | 2 +- osu.Game/Skinning/SkinReloadableDrawable.cs | 2 +- osu.Game/Skinning/SkinnableDrawable.cs | 2 +- osu.Game/Skinning/SkinnableSound.cs | 2 +- osu.Game/Skinning/SkinnableSprite.cs | 6 +++--- osu.Game/Skinning/SkinnableSpriteText.cs | 2 +- .../SkinnableTargetComponentsContainer.cs | 2 +- osu.Game/Skinning/SkinnableTargetContainer.cs | 2 +- .../Drawables/DrawableStoryboard.cs | 2 +- .../Drawables/DrawableStoryboardAnimation.cs | 2 +- .../Drawables/DrawableStoryboardLayer.cs | 4 ++-- .../Drawables/DrawableStoryboardSample.cs | 2 +- .../Drawables/DrawableStoryboardSprite.cs | 2 +- .../Drawables/DrawableStoryboardVideo.cs | 2 +- osu.Game/Storyboards/StoryboardVideoLayer.cs | 4 ++-- .../Tests/Beatmaps/HitObjectSampleTest.cs | 2 +- .../Beatmaps/LegacyBeatmapSkinColourTest.cs | 4 ++-- osu.Game/Tests/OsuTestBrowser.cs | 2 +- .../Visual/DependencyProvidingContainer.cs | 2 +- osu.Game/Tests/Visual/EditorClockTestScene.cs | 2 +- .../Tests/Visual/EditorSavingTestScene.cs | 2 +- osu.Game/Tests/Visual/EditorTestScene.cs | 6 +++--- .../Tests/Visual/LegacySkinPlayerTestScene.cs | 4 ++-- osu.Game/Tests/Visual/ModPerfectTestScene.cs | 4 ++-- osu.Game/Tests/Visual/ModTestScene.cs | 4 ++-- .../Multiplayer/MultiplayerTestScene.cs | 2 +- .../Multiplayer/TestMultiplayerClient.cs | 2 +- .../Multiplayer/TestMultiplayerRoomManager.cs | 2 +- .../Visual/OnlinePlay/OnlinePlayTestScene.cs | 2 +- .../Visual/OnlinePlay/TestRoomManager.cs | 2 +- osu.Game/Tests/Visual/OsuGameTestScene.cs | 8 ++++---- osu.Game/Tests/Visual/OsuGridTestScene.cs | 2 +- .../Visual/OsuManualInputManagerTestScene.cs | 2 +- osu.Game/Tests/Visual/OsuTestScene.cs | 4 ++-- .../Visual/PlacementBlueprintTestScene.cs | 2 +- osu.Game/Tests/Visual/PlayerTestScene.cs | 2 +- .../Visual/RateAdjustedBeatmapTestScene.cs | 2 +- osu.Game/Tests/Visual/ScreenTestScene.cs | 2 +- .../Tests/Visual/ScrollingTestContainer.cs | 2 +- .../Visual/SelectionBlueprintTestScene.cs | 2 +- osu.Game/Tests/Visual/SkinnableTestScene.cs | 4 ++-- .../Visual/Spectator/TestSpectatorClient.cs | 2 +- osu.Game/Tests/Visual/TestPlayer.cs | 2 +- osu.Game/Tests/Visual/TestReplayPlayer.cs | 2 +- osu.Game/Tests/Visual/TestUserLookupCache.cs | 2 +- osu.Game/Updater/NoActionUpdateManager.cs | 2 +- osu.Game/Updater/SimpleUpdateManager.cs | 2 +- osu.Game/Updater/UpdateManager.cs | 8 ++++---- osu.Game/Users/Drawables/ClickableAvatar.cs | 4 ++-- osu.Game/Users/Drawables/DrawableAvatar.cs | 2 +- osu.Game/Users/Drawables/DrawableFlag.cs | 2 +- osu.Game/Users/Drawables/UpdateableAvatar.cs | 2 +- osu.Game/Users/Drawables/UpdateableFlag.cs | 2 +- osu.Game/Users/ExtendedUserPanel.cs | 2 +- osu.Game/Users/UserBrickPanel.cs | 2 +- osu.Game/Users/UserCoverBackground.cs | 4 ++-- osu.Game/Users/UserGridPanel.cs | 2 +- osu.Game/Users/UserListPanel.cs | 2 +- osu.Game/Users/UserPanel.cs | 2 +- 2331 files changed, 3218 insertions(+), 3218 deletions(-) diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/TestSceneOsuGame.cs b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/TestSceneOsuGame.cs index 5973db908c..ca73074789 100644 --- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/TestSceneOsuGame.cs +++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/TestSceneOsuGame.cs @@ -9,7 +9,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.EmptyFreeform.Tests { - public class TestSceneOsuGame : OsuTestScene + public partial class TestSceneOsuGame : OsuTestScene { [BackgroundDependencyLoader] private void load() diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/TestSceneOsuPlayer.cs b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/TestSceneOsuPlayer.cs index 0f2ddf82a5..4b99fa7e09 100644 --- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/TestSceneOsuPlayer.cs +++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/TestSceneOsuPlayer.cs @@ -7,7 +7,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.EmptyFreeform.Tests { [TestFixture] - public class TestSceneOsuPlayer : PlayerTestScene + public partial class TestSceneOsuPlayer : PlayerTestScene { protected override Ruleset CreatePlayerRuleset() => new EmptyFreeformRuleset(); } diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/EmptyFreeformInputManager.cs b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/EmptyFreeformInputManager.cs index b292a28c0d..feac0f22f5 100644 --- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/EmptyFreeformInputManager.cs +++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/EmptyFreeformInputManager.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.EmptyFreeform { - public class EmptyFreeformInputManager : RulesetInputManager + public partial class EmptyFreeformInputManager : RulesetInputManager { public EmptyFreeformInputManager(RulesetInfo ruleset) : base(ruleset, 0, SimultaneousBindingMode.Unique) diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/EmptyFreeformRuleset.cs b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/EmptyFreeformRuleset.cs index 1e88f87f09..d7ef84541f 100644 --- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/EmptyFreeformRuleset.cs +++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/EmptyFreeformRuleset.cs @@ -21,7 +21,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.EmptyFreeform { - public class EmptyFreeformRuleset : Ruleset + public partial class EmptyFreeformRuleset : Ruleset { public override string Description => "a very emptyfreeformruleset ruleset"; @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.EmptyFreeform public override Drawable CreateIcon() => new Icon(ShortName[0]); - public class Icon : CompositeDrawable + public partial class Icon : CompositeDrawable { public Icon(char c) { diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Objects/Drawables/DrawableEmptyFreeformHitObject.cs b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Objects/Drawables/DrawableEmptyFreeformHitObject.cs index 0f38e9fdf8..744e207b57 100644 --- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Objects/Drawables/DrawableEmptyFreeformHitObject.cs +++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Objects/Drawables/DrawableEmptyFreeformHitObject.cs @@ -9,7 +9,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.EmptyFreeform.Objects.Drawables { - public class DrawableEmptyFreeformHitObject : DrawableHitObject + public partial class DrawableEmptyFreeformHitObject : DrawableHitObject { public DrawableEmptyFreeformHitObject(EmptyFreeformHitObject hitObject) : base(hitObject) diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/UI/DrawableEmptyFreeformRuleset.cs b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/UI/DrawableEmptyFreeformRuleset.cs index 290f35f516..608e8d3c07 100644 --- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/UI/DrawableEmptyFreeformRuleset.cs +++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/UI/DrawableEmptyFreeformRuleset.cs @@ -17,7 +17,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.EmptyFreeform.UI { [Cached] - public class DrawableEmptyFreeformRuleset : DrawableRuleset + public partial class DrawableEmptyFreeformRuleset : DrawableRuleset { public DrawableEmptyFreeformRuleset(EmptyFreeformRuleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) : base(ruleset, beatmap, mods) diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/UI/EmptyFreeformPlayfield.cs b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/UI/EmptyFreeformPlayfield.cs index 9df5935c45..532e88d55e 100644 --- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/UI/EmptyFreeformPlayfield.cs +++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/UI/EmptyFreeformPlayfield.cs @@ -8,7 +8,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.EmptyFreeform.UI { [Cached] - public class EmptyFreeformPlayfield : Playfield + public partial class EmptyFreeformPlayfield : Playfield { [BackgroundDependencyLoader] private void load() diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuGame.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuGame.cs index b75a5ec187..c105e9c040 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuGame.cs +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuGame.cs @@ -9,7 +9,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Pippidon.Tests { - public class TestSceneOsuGame : OsuTestScene + public partial class TestSceneOsuGame : OsuTestScene { [BackgroundDependencyLoader] private void load() diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuPlayer.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuPlayer.cs index f00528900c..793d3933d7 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuPlayer.cs +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuPlayer.cs @@ -7,7 +7,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Pippidon.Tests { [TestFixture] - public class TestSceneOsuPlayer : PlayerTestScene + public partial class TestSceneOsuPlayer : PlayerTestScene { protected override Ruleset CreatePlayerRuleset() => new PippidonRuleset(); } diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs index 399d6adda2..29203f0a20 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Pippidon.Objects.Drawables { - public class DrawablePippidonHitObject : DrawableHitObject + public partial class DrawablePippidonHitObject : DrawableHitObject { private const double time_preempt = 600; private const double time_fadein = 400; diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/PippidonInputManager.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/PippidonInputManager.cs index aa7fa3188b..85b264bc67 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/PippidonInputManager.cs +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/PippidonInputManager.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Pippidon { - public class PippidonInputManager : RulesetInputManager + public partial class PippidonInputManager : RulesetInputManager { public PippidonInputManager(RulesetInfo ruleset) : base(ruleset, 0, SimultaneousBindingMode.Unique) diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/PippidonRulesetIcon.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/PippidonRulesetIcon.cs index ff10233b50..1a672d10dd 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/PippidonRulesetIcon.cs +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/PippidonRulesetIcon.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Textures; namespace osu.Game.Rulesets.Pippidon { - public class PippidonRulesetIcon : Sprite + public partial class PippidonRulesetIcon : Sprite { private readonly Ruleset ruleset; diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/UI/DrawablePippidonRuleset.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/UI/DrawablePippidonRuleset.cs index d923963bef..982a80cb7a 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/UI/DrawablePippidonRuleset.cs +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/UI/DrawablePippidonRuleset.cs @@ -17,7 +17,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Pippidon.UI { [Cached] - public class DrawablePippidonRuleset : DrawableRuleset + public partial class DrawablePippidonRuleset : DrawableRuleset { public DrawablePippidonRuleset(PippidonRuleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) : base(ruleset, beatmap, mods) diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/UI/PippidonCursorContainer.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/UI/PippidonCursorContainer.cs index 9de3f4ba14..20dd2e7c31 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/UI/PippidonCursorContainer.cs +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/UI/PippidonCursorContainer.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Rulesets.Pippidon.UI { - public class PippidonCursorContainer : GameplayCursorContainer + public partial class PippidonCursorContainer : GameplayCursorContainer { private Sprite cursorSprite; private Texture cursorTexture; diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/UI/PippidonPlayfield.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/UI/PippidonPlayfield.cs index b5a97c5ea3..62e162ae4b 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/UI/PippidonPlayfield.cs +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/UI/PippidonPlayfield.cs @@ -8,7 +8,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Pippidon.UI { [Cached] - public class PippidonPlayfield : Playfield + public partial class PippidonPlayfield : Playfield { protected override GameplayCursorContainer CreateCursor() => new PippidonCursorContainer(); diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/UI/PippidonPlayfieldAdjustmentContainer.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/UI/PippidonPlayfieldAdjustmentContainer.cs index 9236683827..b46e795bbc 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/UI/PippidonPlayfieldAdjustmentContainer.cs +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/UI/PippidonPlayfieldAdjustmentContainer.cs @@ -7,7 +7,7 @@ using osuTK; namespace osu.Game.Rulesets.Pippidon.UI { - public class PippidonPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer + public partial class PippidonPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer { public PippidonPlayfieldAdjustmentContainer() { diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/TestSceneOsuGame.cs b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/TestSceneOsuGame.cs index ffe921b54c..a9a3c2eb5b 100644 --- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/TestSceneOsuGame.cs +++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/TestSceneOsuGame.cs @@ -9,7 +9,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.EmptyScrolling.Tests { - public class TestSceneOsuGame : OsuTestScene + public partial class TestSceneOsuGame : OsuTestScene { [BackgroundDependencyLoader] private void load() diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/TestSceneOsuPlayer.cs b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/TestSceneOsuPlayer.cs index 9460576196..2be3862833 100644 --- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/TestSceneOsuPlayer.cs +++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/TestSceneOsuPlayer.cs @@ -7,7 +7,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.EmptyScrolling.Tests { [TestFixture] - public class TestSceneOsuPlayer : PlayerTestScene + public partial class TestSceneOsuPlayer : PlayerTestScene { protected override Ruleset CreatePlayerRuleset() => new EmptyScrollingRuleset(); } diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/EmptyScrollingInputManager.cs b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/EmptyScrollingInputManager.cs index 632e04f301..a7b4ae61f0 100644 --- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/EmptyScrollingInputManager.cs +++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/EmptyScrollingInputManager.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.EmptyScrolling { - public class EmptyScrollingInputManager : RulesetInputManager + public partial class EmptyScrollingInputManager : RulesetInputManager { public EmptyScrollingInputManager(RulesetInfo ruleset) : base(ruleset, 0, SimultaneousBindingMode.Unique) diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Objects/Drawables/DrawableEmptyScrollingHitObject.cs b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Objects/Drawables/DrawableEmptyScrollingHitObject.cs index b5ff0cde7c..a3c3b89105 100644 --- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Objects/Drawables/DrawableEmptyScrollingHitObject.cs +++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Objects/Drawables/DrawableEmptyScrollingHitObject.cs @@ -9,7 +9,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.EmptyScrolling.Objects.Drawables { - public class DrawableEmptyScrollingHitObject : DrawableHitObject + public partial class DrawableEmptyScrollingHitObject : DrawableHitObject { public DrawableEmptyScrollingHitObject(EmptyScrollingHitObject hitObject) : base(hitObject) diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/UI/DrawableEmptyScrollingRuleset.cs b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/UI/DrawableEmptyScrollingRuleset.cs index 620a4abc51..99598fc113 100644 --- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/UI/DrawableEmptyScrollingRuleset.cs +++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/UI/DrawableEmptyScrollingRuleset.cs @@ -18,7 +18,7 @@ using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.EmptyScrolling.UI { [Cached] - public class DrawableEmptyScrollingRuleset : DrawableScrollingRuleset + public partial class DrawableEmptyScrollingRuleset : DrawableScrollingRuleset { public DrawableEmptyScrollingRuleset(EmptyScrollingRuleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) : base(ruleset, beatmap, mods) diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/UI/EmptyScrollingPlayfield.cs b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/UI/EmptyScrollingPlayfield.cs index 56620e44b3..3770ba8172 100644 --- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/UI/EmptyScrollingPlayfield.cs +++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/UI/EmptyScrollingPlayfield.cs @@ -8,7 +8,7 @@ using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.EmptyScrolling.UI { [Cached] - public class EmptyScrollingPlayfield : ScrollingPlayfield + public partial class EmptyScrollingPlayfield : ScrollingPlayfield { [BackgroundDependencyLoader] private void load() diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuGame.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuGame.cs index b75a5ec187..c105e9c040 100644 --- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuGame.cs +++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuGame.cs @@ -9,7 +9,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Pippidon.Tests { - public class TestSceneOsuGame : OsuTestScene + public partial class TestSceneOsuGame : OsuTestScene { [BackgroundDependencyLoader] private void load() diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuPlayer.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuPlayer.cs index f00528900c..793d3933d7 100644 --- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuPlayer.cs +++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuPlayer.cs @@ -7,7 +7,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Pippidon.Tests { [TestFixture] - public class TestSceneOsuPlayer : PlayerTestScene + public partial class TestSceneOsuPlayer : PlayerTestScene { protected override Ruleset CreatePlayerRuleset() => new PippidonRuleset(); } diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs index e458cacef9..554d03c79f 100644 --- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs +++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Pippidon.Objects.Drawables { - public class DrawablePippidonHitObject : DrawableHitObject + public partial class DrawablePippidonHitObject : DrawableHitObject { private BindableNumber currentLane; diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/PippidonInputManager.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/PippidonInputManager.cs index c9e6e6faaa..a31c1bf832 100644 --- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/PippidonInputManager.cs +++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/PippidonInputManager.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Pippidon { - public class PippidonInputManager : RulesetInputManager + public partial class PippidonInputManager : RulesetInputManager { public PippidonInputManager(RulesetInfo ruleset) : base(ruleset, 0, SimultaneousBindingMode.Unique) diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/PippidonRulesetIcon.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/PippidonRulesetIcon.cs index 6b87d93951..75005a3743 100644 --- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/PippidonRulesetIcon.cs +++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/PippidonRulesetIcon.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics.Textures; namespace osu.Game.Rulesets.Pippidon { - public class PippidonRulesetIcon : Sprite + public partial class PippidonRulesetIcon : Sprite { private readonly Ruleset ruleset; diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/UI/DrawablePippidonRuleset.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/UI/DrawablePippidonRuleset.cs index 9a73dd7790..1e7e09be67 100644 --- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/UI/DrawablePippidonRuleset.cs +++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/UI/DrawablePippidonRuleset.cs @@ -18,7 +18,7 @@ using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Pippidon.UI { [Cached] - public class DrawablePippidonRuleset : DrawableScrollingRuleset + public partial class DrawablePippidonRuleset : DrawableScrollingRuleset { public DrawablePippidonRuleset(PippidonRuleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) : base(ruleset, beatmap, mods) diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/UI/PippidonCharacter.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/UI/PippidonCharacter.cs index 98dba622d0..33d349da62 100644 --- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/UI/PippidonCharacter.cs +++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/UI/PippidonCharacter.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Rulesets.Pippidon.UI { - public class PippidonCharacter : BeatSyncedContainer, IKeyBindingHandler + public partial class PippidonCharacter : BeatSyncedContainer, IKeyBindingHandler { public readonly BindableInt LanePosition = new BindableInt { diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/UI/PippidonPlayfield.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/UI/PippidonPlayfield.cs index ab8c6bb2e9..a90326e935 100644 --- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/UI/PippidonPlayfield.cs +++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/UI/PippidonPlayfield.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Pippidon.UI { [Cached] - public class PippidonPlayfield : ScrollingPlayfield + public partial class PippidonPlayfield : ScrollingPlayfield { public const float LANE_HEIGHT = 70; @@ -60,7 +60,7 @@ namespace osu.Game.Rulesets.Pippidon.UI }); } - private class LaneContainer : BeatSyncedContainer + private partial class LaneContainer : BeatSyncedContainer { private OsuColour colours; private FillFlowContainer fill; @@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Pippidon.UI } } - private class Lane : CompositeDrawable + private partial class Lane : CompositeDrawable { public Lane() { diff --git a/osu.Desktop/DiscordRichPresence.cs b/osu.Desktop/DiscordRichPresence.cs index 9cf68d88d9..2c4577f239 100644 --- a/osu.Desktop/DiscordRichPresence.cs +++ b/osu.Desktop/DiscordRichPresence.cs @@ -20,7 +20,7 @@ using LogLevel = osu.Framework.Logging.LogLevel; namespace osu.Desktop { - internal class DiscordRichPresence : Component + internal partial class DiscordRichPresence : Component { private const string client_id = "367827983903490050"; diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index 09f7292845..4c93c2286f 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -26,7 +26,7 @@ using SDL2; namespace osu.Desktop { - internal class OsuGameDesktop : OsuGame + internal partial class OsuGameDesktop : OsuGame { private OsuSchemeLinkIPCChannel? osuSchemeLinkIPCChannel; diff --git a/osu.Desktop/Security/ElevatedPrivilegesChecker.cs b/osu.Desktop/Security/ElevatedPrivilegesChecker.cs index cc4337fb02..6665733656 100644 --- a/osu.Desktop/Security/ElevatedPrivilegesChecker.cs +++ b/osu.Desktop/Security/ElevatedPrivilegesChecker.cs @@ -16,7 +16,7 @@ namespace osu.Desktop.Security /// /// Checks if the game is running with elevated privileges (as admin in Windows, root in Unix) and displays a warning notification if so. /// - public class ElevatedPrivilegesChecker : Component + public partial class ElevatedPrivilegesChecker : Component { [Resolved] private INotificationOverlay notifications { get; set; } = null!; @@ -63,7 +63,7 @@ namespace osu.Desktop.Security return false; } - private class ElevatedPrivilegesNotification : SimpleNotification + private partial class ElevatedPrivilegesNotification : SimpleNotification { public override bool IsImportant => true; diff --git a/osu.Desktop/Updater/SquirrelUpdateManager.cs b/osu.Desktop/Updater/SquirrelUpdateManager.cs index 84bac9da7c..3d4db88471 100644 --- a/osu.Desktop/Updater/SquirrelUpdateManager.cs +++ b/osu.Desktop/Updater/SquirrelUpdateManager.cs @@ -17,7 +17,7 @@ using UpdateManager = osu.Game.Updater.UpdateManager; namespace osu.Desktop.Updater { [SupportedOSPlatform("windows")] - public class SquirrelUpdateManager : UpdateManager + public partial class SquirrelUpdateManager : UpdateManager { private Squirrel.UpdateManager? updateManager; private INotificationOverlay notificationOverlay = null!; diff --git a/osu.Desktop/Windows/GameplayWinKeyBlocker.cs b/osu.Desktop/Windows/GameplayWinKeyBlocker.cs index 284d25306d..560f6fdd7f 100644 --- a/osu.Desktop/Windows/GameplayWinKeyBlocker.cs +++ b/osu.Desktop/Windows/GameplayWinKeyBlocker.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Play; namespace osu.Desktop.Windows { - public class GameplayWinKeyBlocker : Component + public partial class GameplayWinKeyBlocker : Component { private Bindable disableWinKey = null!; private IBindable localUserPlaying = null!; diff --git a/osu.Game.Rulesets.Catch.Tests/CatchSkinnableTestScene.cs b/osu.Game.Rulesets.Catch.Tests/CatchSkinnableTestScene.cs index be6622f06e..2af851a561 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchSkinnableTestScene.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchSkinnableTestScene.cs @@ -7,7 +7,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Catch.Tests { - public abstract class CatchSkinnableTestScene : SkinnableTestScene + public abstract partial class CatchSkinnableTestScene : SkinnableTestScene { protected override Ruleset CreateRulesetForSkinProvider() => new CatchRuleset(); } diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/CatchEditorTestSceneContainer.cs b/osu.Game.Rulesets.Catch.Tests/Editor/CatchEditorTestSceneContainer.cs index 78f56b4937..39508359a4 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/CatchEditorTestSceneContainer.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/CatchEditorTestSceneContainer.cs @@ -16,7 +16,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Catch.Tests.Editor { - public class CatchEditorTestSceneContainer : Container + public partial class CatchEditorTestSceneContainer : Container { [Cached(typeof(Playfield))] public readonly ScrollingPlayfield Playfield; @@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor }; } - private class TestCatchPlayfield : CatchEditorPlayfield + private partial class TestCatchPlayfield : CatchEditorPlayfield { public TestCatchPlayfield() : base(new BeatmapDifficulty { CircleSize = 0 }) diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/CatchPlacementBlueprintTestScene.cs b/osu.Game.Rulesets.Catch.Tests/Editor/CatchPlacementBlueprintTestScene.cs index 9060fa5aa0..aae759d934 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/CatchPlacementBlueprintTestScene.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/CatchPlacementBlueprintTestScene.cs @@ -21,7 +21,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Catch.Tests.Editor { - public abstract class CatchPlacementBlueprintTestScene : PlacementBlueprintTestScene + public abstract partial class CatchPlacementBlueprintTestScene : PlacementBlueprintTestScene { protected const double TIME_SNAP = 100; diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/CatchSelectionBlueprintTestScene.cs b/osu.Game.Rulesets.Catch.Tests/Editor/CatchSelectionBlueprintTestScene.cs index 60fb31d1e0..033dca587e 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/CatchSelectionBlueprintTestScene.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/CatchSelectionBlueprintTestScene.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Tests.Editor { - public abstract class CatchSelectionBlueprintTestScene : SelectionBlueprintTestScene + public abstract partial class CatchSelectionBlueprintTestScene : SelectionBlueprintTestScene { protected ScrollingHitObjectContainer HitObjectContainer => contentContainer.Playfield.HitObjectContainer; @@ -62,7 +62,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor InputManager.MoveMouseTo(pos); }); - private class EditorBeatmapDependencyContainer : Container + private partial class EditorBeatmapDependencyContainer : Container { [Cached] private readonly EditorClock editorClock; diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneBananaShowerPlacementBlueprint.cs b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneBananaShowerPlacementBlueprint.cs index d08acc90cd..2db4102513 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneBananaShowerPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneBananaShowerPlacementBlueprint.cs @@ -20,7 +20,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Catch.Tests.Editor { - public class TestSceneBananaShowerPlacementBlueprint : CatchPlacementBlueprintTestScene + public partial class TestSceneBananaShowerPlacementBlueprint : CatchPlacementBlueprintTestScene { protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableBananaShower((BananaShower)hitObject); diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneCatchDistanceSnapGrid.cs b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneCatchDistanceSnapGrid.cs index 405bab971c..1e057cf3fb 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneCatchDistanceSnapGrid.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneCatchDistanceSnapGrid.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Tests.Editor { - public class TestSceneCatchDistanceSnapGrid : OsuManualInputManagerTestScene + public partial class TestSceneCatchDistanceSnapGrid : OsuManualInputManagerTestScene { private readonly ManualClock manualClock = new ManualClock(); diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneEditor.cs b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneEditor.cs index 9ecfd5f5c5..5593f3d319 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneEditor.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneEditor.cs @@ -9,7 +9,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Catch.Tests.Editor { [TestFixture] - public class TestSceneEditor : EditorTestScene + public partial class TestSceneEditor : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new CatchRuleset(); } diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneFruitPlacementBlueprint.cs b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneFruitPlacementBlueprint.cs index 94574b564d..93b24d92fb 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneFruitPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneFruitPlacementBlueprint.cs @@ -17,7 +17,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Catch.Tests.Editor { - public class TestSceneFruitPlacementBlueprint : CatchPlacementBlueprintTestScene + public partial class TestSceneFruitPlacementBlueprint : CatchPlacementBlueprintTestScene { protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableFruit((Fruit)hitObject); diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamPlacementBlueprint.cs b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamPlacementBlueprint.cs index 691ebc7efc..18d3d29bdc 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamPlacementBlueprint.cs @@ -19,7 +19,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Catch.Tests.Editor { - public class TestSceneJuiceStreamPlacementBlueprint : CatchPlacementBlueprintTestScene + public partial class TestSceneJuiceStreamPlacementBlueprint : CatchPlacementBlueprintTestScene { private const double velocity_factor = 0.5; diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs index 8635a88d79..f25b66c360 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs @@ -19,7 +19,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Catch.Tests.Editor { - public class TestSceneJuiceStreamSelectionBlueprint : CatchSelectionBlueprintTestScene + public partial class TestSceneJuiceStreamSelectionBlueprint : CatchSelectionBlueprintTestScene { private JuiceStream hitObject; diff --git a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModFlashlight.cs b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModFlashlight.cs index 538fc7fac6..f89ed5ce8e 100644 --- a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModFlashlight.cs +++ b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModFlashlight.cs @@ -7,7 +7,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Catch.Tests.Mods { - public class TestSceneCatchModFlashlight : ModTestScene + public partial class TestSceneCatchModFlashlight : ModTestScene { protected override Ruleset CreatePlayerRuleset() => new CatchRuleset(); diff --git a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModNoScope.cs b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModNoScope.cs index bbe543e73e..50b928d509 100644 --- a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModNoScope.cs +++ b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModNoScope.cs @@ -14,7 +14,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Catch.Tests.Mods { - public class TestSceneCatchModNoScope : ModTestScene + public partial class TestSceneCatchModNoScope : ModTestScene { protected override Ruleset CreatePlayerRuleset() => new CatchRuleset(); diff --git a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs index 3e06e78dba..71df523951 100644 --- a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs +++ b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModPerfect.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Tests.Mods { - public class TestSceneCatchModPerfect : ModPerfectTestScene + public partial class TestSceneCatchModPerfect : ModPerfectTestScene { protected override Ruleset CreatePlayerRuleset() => new CatchRuleset(); diff --git a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs index c01aff0aa0..8472b995e8 100644 --- a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs +++ b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Tests.Mods { - public class TestSceneCatchModRelax : ModTestScene + public partial class TestSceneCatchModRelax : ModTestScene { protected override Ruleset CreatePlayerRuleset() => new CatchRuleset(); diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs index 202228c9e7..40dc7d2403 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Tests { - public class TestSceneAutoJuiceStream : TestSceneCatchPlayer + public partial class TestSceneAutoJuiceStream : TestSceneCatchPlayer { protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) { diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs index 0ddc58eb25..402f8f548d 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Catch.Objects; namespace osu.Game.Rulesets.Catch.Tests { [TestFixture] - public class TestSceneBananaShower : TestSceneCatchPlayer + public partial class TestSceneBananaShower : TestSceneCatchPlayer { [Test] public void TestBananaShower() diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModHidden.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModHidden.cs index 7e1c39f6a8..05d3361dc3 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModHidden.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchModHidden.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Tests { - public class TestSceneCatchModHidden : ModTestScene + public partial class TestSceneCatchModHidden : ModTestScene { [Test] public void TestJuiceStream() diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchPlayer.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchPlayer.cs index 16942f3f35..01cce88d9d 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchPlayer.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchPlayer.cs @@ -9,7 +9,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Catch.Tests { [TestFixture] - public class TestSceneCatchPlayer : PlayerTestScene + public partial class TestSceneCatchPlayer : PlayerTestScene { protected override Ruleset CreatePlayerRuleset() => new CatchRuleset(); } diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchPlayerLegacySkin.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchPlayerLegacySkin.cs index 2078e1453f..8f3f39be9b 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchPlayerLegacySkin.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchPlayerLegacySkin.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Tests { [TestFixture] - public class TestSceneCatchPlayerLegacySkin : LegacySkinPlayerTestScene + public partial class TestSceneCatchPlayerLegacySkin : LegacySkinPlayerTestScene { protected override Ruleset CreatePlayerRuleset() => new CatchRuleset(); diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchReplay.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchReplay.cs index 6e12dacf29..cbf900ebc0 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchReplay.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchReplay.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Catch.UI; namespace osu.Game.Rulesets.Catch.Tests { - public class TestSceneCatchReplay : TestSceneCatchPlayer + public partial class TestSceneCatchReplay : TestSceneCatchPlayer { protected override bool Autoplay => true; diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs index a2d4e7fb1e..75ab4ad9d2 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs @@ -23,7 +23,7 @@ using Direction = osu.Game.Rulesets.Catch.UI.Direction; namespace osu.Game.Rulesets.Catch.Tests { - public class TestSceneCatchSkinConfiguration : OsuTestScene + public partial class TestSceneCatchSkinConfiguration : OsuTestScene { private Catcher catcher; diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs index 1405e0018d..c8979381fe 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Catch.UI; namespace osu.Game.Rulesets.Catch.Tests { [TestFixture] - public class TestSceneCatchStacker : TestSceneCatchPlayer + public partial class TestSceneCatchStacker : TestSceneCatchPlayer { protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) { diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchTouchInput.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchTouchInput.cs index cf6a8169c4..836adcc912 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchTouchInput.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchTouchInput.cs @@ -15,7 +15,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Catch.Tests { [TestFixture] - public class TestSceneCatchTouchInput : OsuTestScene + public partial class TestSceneCatchTouchInput : OsuTestScene { [Test] public void TestBasic() diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs index 2dc99077d3..e8231b07ad 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs @@ -27,7 +27,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Tests { [TestFixture] - public class TestSceneCatcher : OsuTestScene + public partial class TestSceneCatcher : OsuTestScene { [Resolved] private OsuConfigManager config { get; set; } @@ -324,7 +324,7 @@ namespace osu.Game.Rulesets.Catch.Tests } } - public class TestCatcher : Catcher + public partial class TestCatcher : Catcher { public IEnumerable CaughtObjects => this.ChildrenOfType(); diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs index 150c1f8406..99c2fc570d 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs @@ -23,7 +23,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Tests { [TestFixture] - public class TestSceneCatcherArea : CatchSkinnableTestScene + public partial class TestSceneCatcherArea : CatchSkinnableTestScene { private RulesetInfo catchRuleset; @@ -120,7 +120,7 @@ namespace osu.Game.Rulesets.Catch.Tests catchRuleset = rulesets.GetRuleset(2); } - private class TestCatcherArea : CatcherArea + private partial class TestCatcherArea : CatcherArea { public TestCatcherArea(IBeatmapDifficultyInfo beatmapDifficulty) { diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneComboCounter.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneComboCounter.cs index f3161f32be..391297a252 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneComboCounter.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneComboCounter.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Tests { - public class TestSceneComboCounter : CatchSkinnableTestScene + public partial class TestSceneComboCounter : CatchSkinnableTestScene { private ScoreProcessor scoreProcessor = null!; diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs index 94c870a444..11d6419507 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Tests { - public class TestSceneDrawableHitObjects : OsuTestScene + public partial class TestSceneDrawableHitObjects : OsuTestScene { private DrawableCatchRuleset drawableRuleset; private double playfieldTime => drawableRuleset.Playfield.Time.Current; diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjectsHidden.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjectsHidden.cs index 868f498e8c..007f309f3f 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjectsHidden.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjectsHidden.cs @@ -8,7 +8,7 @@ using osu.Game.Rulesets.Catch.Mods; namespace osu.Game.Rulesets.Catch.Tests { - public class TestSceneDrawableHitObjectsHidden : TestSceneDrawableHitObjects + public partial class TestSceneDrawableHitObjectsHidden : TestSceneDrawableHitObjects { [SetUp] public void SetUp() => Schedule(() => diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs index 7d72633e34..223c4e57fc 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs @@ -15,7 +15,7 @@ using osu.Game.Rulesets.Catch.Objects.Drawables; namespace osu.Game.Rulesets.Catch.Tests { [TestFixture] - public class TestSceneFruitObjects : CatchSkinnableTestScene + public partial class TestSceneFruitObjects : CatchSkinnableTestScene { protected override void LoadComplete() { @@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Catch.Tests private Drawable createDrawableTinyDroplet() => new TestDrawableCatchHitObjectSpecimen(new DrawableTinyDroplet(new TinyDroplet())); } - public class TestDrawableCatchHitObjectSpecimen : CompositeDrawable + public partial class TestDrawableCatchHitObjectSpecimen : CompositeDrawable { public readonly ManualClock ManualClock; diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneFruitRandomness.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitRandomness.cs index c7d130b440..995daaceb1 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneFruitRandomness.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitRandomness.cs @@ -12,7 +12,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Tests { - public class TestSceneFruitRandomness : OsuTestScene + public partial class TestSceneFruitRandomness : OsuTestScene { private readonly DrawableFruit drawableFruit; private readonly DrawableBanana drawableBanana; diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneFruitVisualChange.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitVisualChange.cs index f7abd8d519..4b2873e0a8 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneFruitVisualChange.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitVisualChange.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Catch.Objects.Drawables; namespace osu.Game.Rulesets.Catch.Tests { - public class TestSceneFruitVisualChange : TestSceneFruitObjects + public partial class TestSceneFruitVisualChange : TestSceneFruitObjects { private readonly Bindable indexInBeatmap = new Bindable(); private readonly Bindable hyperDash = new Bindable(); diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs index 4886942dc6..f8c43a221e 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Tests { [TestFixture] - public class TestSceneHyperDash : TestSceneCatchPlayer + public partial class TestSceneHyperDash : TestSceneCatchPlayer { protected override bool Autoplay => true; diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDashColouring.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDashColouring.cs index cf49b7fe12..b343174e6b 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDashColouring.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDashColouring.cs @@ -24,7 +24,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Tests { - public class TestSceneHyperDashColouring : OsuTestScene + public partial class TestSceneHyperDashColouring : OsuTestScene { [Resolved] private SkinManager skins { get; set; } diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs index 81589459c4..c91f07891c 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Tests { - public class TestSceneJuiceStream : TestSceneCatchPlayer + public partial class TestSceneJuiceStream : TestSceneCatchPlayer { [Test] public void TestJuiceStreamEndingCombo() diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs index 786353bb00..aa66fc8741 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Tests { - public class TestSceneLegacyBeatmapSkin : LegacyBeatmapSkinColourTest + public partial class TestSceneLegacyBeatmapSkin : LegacyBeatmapSkinColourTest { [Resolved] private AudioManager audio { get; set; } @@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Catch.Tests protected override ExposedPlayer CreateTestPlayer(bool userHasCustomColours) => new CatchExposedPlayer(userHasCustomColours); - private class CatchExposedPlayer : ExposedPlayer + private partial class CatchExposedPlayer : ExposedPlayer { public CatchExposedPlayer(bool userHasCustomColours) : base(userHasCustomColours) diff --git a/osu.Game.Rulesets.Catch/CatchInputManager.cs b/osu.Game.Rulesets.Catch/CatchInputManager.cs index 0f76953003..1ef9e55d2d 100644 --- a/osu.Game.Rulesets.Catch/CatchInputManager.cs +++ b/osu.Game.Rulesets.Catch/CatchInputManager.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Catch { [Cached] - public class CatchInputManager : RulesetInputManager + public partial class CatchInputManager : RulesetInputManager { public CatchInputManager(RulesetInfo ruleset) : base(ruleset, 0, SimultaneousBindingMode.Unique) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerPlacementBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerPlacementBlueprint.cs index 86fdf09a72..166fa44303 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerPlacementBlueprint.cs @@ -12,7 +12,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Catch.Edit.Blueprints { - public class BananaShowerPlacementBlueprint : CatchPlacementBlueprint + public partial class BananaShowerPlacementBlueprint : CatchPlacementBlueprint { private readonly TimeSpanOutline outline; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerSelectionBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerSelectionBlueprint.cs index 7e4aca180c..2c545e8f0e 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerSelectionBlueprint.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.Catch.Objects; namespace osu.Game.Rulesets.Catch.Edit.Blueprints { - public class BananaShowerSelectionBlueprint : CatchSelectionBlueprint + public partial class BananaShowerSelectionBlueprint : CatchSelectionBlueprint { public BananaShowerSelectionBlueprint(BananaShower hitObject) : base(hitObject) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchPlacementBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchPlacementBlueprint.cs index 8a1ced7eea..94373147d2 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchPlacementBlueprint.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Edit.Blueprints { - public class CatchPlacementBlueprint : PlacementBlueprint + public partial class CatchPlacementBlueprint : PlacementBlueprint where THitObject : CatchHitObject, new() { protected new THitObject HitObject => (THitObject)base.HitObject; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchSelectionBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchSelectionBlueprint.cs index e7c04cd132..87c33a9cb8 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchSelectionBlueprint.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Edit.Blueprints { - public abstract class CatchSelectionBlueprint : HitObjectSelectionBlueprint + public abstract partial class CatchSelectionBlueprint : HitObjectSelectionBlueprint where THitObject : CatchHitObject { protected override bool AlwaysShowWhenSelected => true; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs index 8473eda663..006ea6e9cf 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components { - public abstract class EditablePath : CompositeDrawable + public abstract partial class EditablePath : CompositeDrawable { public int PathId => path.InvalidationID; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/FruitOutline.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/FruitOutline.cs index 86006a99fc..dc2b038e01 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/FruitOutline.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/FruitOutline.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components { - public class FruitOutline : CompositeDrawable + public partial class FruitOutline : CompositeDrawable { public FruitOutline() { diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/NestedOutlineContainer.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/NestedOutlineContainer.cs index a6f1732bc1..ac0c850bca 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/NestedOutlineContainer.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/NestedOutlineContainer.cs @@ -13,7 +13,7 @@ using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components { - public class NestedOutlineContainer : CompositeDrawable + public partial class NestedOutlineContainer : CompositeDrawable { private readonly List nestedHitObjects = new List(); diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/PlacementEditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/PlacementEditablePath.cs index 27df064be4..ba2f5ed0eb 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/PlacementEditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/PlacementEditablePath.cs @@ -9,7 +9,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components { - public class PlacementEditablePath : EditablePath + public partial class PlacementEditablePath : EditablePath { /// /// The original position of the last added vertex. diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/ScrollingPath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/ScrollingPath.cs index 3a62b07816..6deb5a174f 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/ScrollingPath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/ScrollingPath.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components { - public class ScrollingPath : CompositeDrawable + public partial class ScrollingPath : CompositeDrawable { private readonly Path drawablePath; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs index 4576e9f8ee..3a44f7ac8a 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs @@ -18,7 +18,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components { - public class SelectionEditablePath : EditablePath, IHasContextMenu + public partial class SelectionEditablePath : EditablePath, IHasContextMenu { public MenuItem[] ContextMenuItems => getContextMenuItems().ToArray(); diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/TimeSpanOutline.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/TimeSpanOutline.cs index 2586a81ef5..a1d5d7ae3e 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/TimeSpanOutline.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/TimeSpanOutline.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components { - public class TimeSpanOutline : CompositeDrawable + public partial class TimeSpanOutline : CompositeDrawable { private const float border_width = 4; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/VertexPiece.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/VertexPiece.cs index 236d27753a..49570d3735 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/VertexPiece.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/VertexPiece.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components { - public class VertexPiece : Circle + public partial class VertexPiece : Circle { [Resolved] private OsuColour osuColour { get; set; } diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitPlacementBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitPlacementBlueprint.cs index 686840ae55..af75023e68 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitPlacementBlueprint.cs @@ -11,7 +11,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Catch.Edit.Blueprints { - public class FruitPlacementBlueprint : CatchPlacementBlueprint + public partial class FruitPlacementBlueprint : CatchPlacementBlueprint { private readonly FruitOutline outline; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitSelectionBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitSelectionBlueprint.cs index b5a25dbf62..319b1b5e20 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitSelectionBlueprint.cs @@ -8,7 +8,7 @@ using osu.Game.Rulesets.Catch.Objects; namespace osu.Game.Rulesets.Catch.Edit.Blueprints { - public class FruitSelectionBlueprint : CatchSelectionBlueprint + public partial class FruitSelectionBlueprint : CatchSelectionBlueprint { private readonly FruitOutline outline; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamPlacementBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamPlacementBlueprint.cs index fcdd055b56..0e2ee334ff 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamPlacementBlueprint.cs @@ -14,7 +14,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Catch.Edit.Blueprints { - public class JuiceStreamPlacementBlueprint : CatchPlacementBlueprint + public partial class JuiceStreamPlacementBlueprint : CatchPlacementBlueprint { private readonly ScrollingPath scrollingPath; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs index fc2b5e08fe..99ec5e2b0c 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs @@ -22,7 +22,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Catch.Edit.Blueprints { - public class JuiceStreamSelectionBlueprint : CatchSelectionBlueprint + public partial class JuiceStreamSelectionBlueprint : CatchSelectionBlueprint { public override Quad SelectionQuad => HitObjectContainer.ToScreenSpace(getBoundingBox().Offset(new Vector2(0, HitObjectContainer.DrawHeight))); diff --git a/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs b/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs index a0a11424d0..9408a9f95c 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs @@ -11,7 +11,7 @@ using osu.Game.Screens.Edit.Compose.Components; namespace osu.Game.Rulesets.Catch.Edit { - public class CatchBlueprintContainer : ComposeBlueprintContainer + public partial class CatchBlueprintContainer : ComposeBlueprintContainer { public CatchBlueprintContainer(CatchHitObjectComposer composer) : base(composer) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchDistanceSnapGrid.cs b/osu.Game.Rulesets.Catch/Edit/CatchDistanceSnapGrid.cs index 718c76abfc..e5cdcf706c 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchDistanceSnapGrid.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchDistanceSnapGrid.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Catch.Edit /// The guide lines used in the osu!catch editor to compose patterns that can be caught with constant speed. /// Currently, only forward placement (an object is snapped based on the previous object, not the opposite) is supported. /// - public class CatchDistanceSnapGrid : CompositeDrawable + public partial class CatchDistanceSnapGrid : CompositeDrawable { public double StartTime { get; set; } diff --git a/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs b/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs index b9a875fe8a..bca89c6024 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs @@ -8,7 +8,7 @@ using osu.Game.Rulesets.Catch.UI; namespace osu.Game.Rulesets.Catch.Edit { - public class CatchEditorPlayfield : CatchPlayfield + public partial class CatchEditorPlayfield : CatchPlayfield { // TODO fixme: the size of the catcher is not changed when circle size is changed in setup screen. public CatchEditorPlayfield(IBeatmapDifficultyInfo difficulty) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfieldAdjustmentContainer.cs index 0a0f91c781..0271005dd1 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfieldAdjustmentContainer.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Edit { - public class CatchEditorPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer + public partial class CatchEditorPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer { protected override Container Content => content; private readonly Container content; @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.Edit }; } - private class ScalingContainer : Container + private partial class ScalingContainer : Container { public ScalingContainer() { diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index 220bc49203..bbdffbf39c 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -28,7 +28,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Edit { - public class CatchHitObjectComposer : DistancedHitObjectComposer + public partial class CatchHitObjectComposer : DistancedHitObjectComposer { private const float distance_snap_radius = 50; diff --git a/osu.Game.Rulesets.Catch/Edit/CatchSelectionHandler.cs b/osu.Game.Rulesets.Catch/Edit/CatchSelectionHandler.cs index 5aac521d0b..d9d7047920 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchSelectionHandler.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchSelectionHandler.cs @@ -18,7 +18,7 @@ using Direction = osu.Framework.Graphics.Direction; namespace osu.Game.Rulesets.Catch.Edit { - public class CatchSelectionHandler : EditorSelectionHandler + public partial class CatchSelectionHandler : EditorSelectionHandler { protected ScrollingHitObjectContainer HitObjectContainer => (ScrollingHitObjectContainer)playfield.HitObjectContainer; diff --git a/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs b/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs index 67238f66d4..0a50ad1df4 100644 --- a/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs +++ b/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Catch.Edit { - public class DrawableCatchEditorRuleset : DrawableCatchRuleset + public partial class DrawableCatchEditorRuleset : DrawableCatchRuleset { public readonly BindableDouble TimeRangeMultiplier = new BindableDouble(1); diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs b/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs index a9e9e8fbd5..40450c6729 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Mods { - public class CatchModFlashlight : ModFlashlight + public partial class CatchModFlashlight : ModFlashlight { public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.12 : 1; @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Catch.Mods base.ApplyToDrawableRuleset(drawableRuleset); } - private class CatchFlashlight : Flashlight + private partial class CatchFlashlight : Flashlight { private readonly CatchPlayfield playfield; diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs b/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs index 3f7560844c..83ad96d5b4 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Mods { - public class CatchModRelax : ModRelax, IApplicableToDrawableRuleset, IApplicableToPlayer + public partial class CatchModRelax : ModRelax, IApplicableToDrawableRuleset, IApplicableToPlayer { public override LocalisableString Description => @"Use the mouse to control the catcher."; @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Catch.Mods } } - private class MouseInputHelper : Drawable, IKeyBindingHandler, IRequireHighFrequencyMousePosition + private partial class MouseInputHelper : Drawable, IKeyBindingHandler, IRequireHighFrequencyMousePosition { private readonly CatcherArea catcherArea; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtBanana.cs index 31a27b6047..65d91bffe2 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtBanana.cs @@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables /// /// Represents a caught by the catcher. /// - public class CaughtBanana : CaughtObject + public partial class CaughtBanana : CaughtObject { public CaughtBanana() : base(CatchSkinComponents.Banana, _ => new BananaPiece()) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtDroplet.cs index 6d5dd0ed25..ed8bf17747 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtDroplet.cs @@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables /// /// Represents a caught by the catcher. /// - public class CaughtDroplet : CaughtObject + public partial class CaughtDroplet : CaughtObject { public override bool StaysOnPlate => false; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtFruit.cs index 89757748ab..d296052220 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtFruit.cs @@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables /// /// Represents a caught by the catcher. /// - public class CaughtFruit : CaughtObject + public partial class CaughtFruit : CaughtObject { public CaughtFruit() : base(CatchSkinComponents.Fruit, _ => new FruitPiece()) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs index 8ac5eac227..436edf6367 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables /// Represents a caught by the catcher. /// [Cached(typeof(IHasCatchObjectState))] - public abstract class CaughtObject : SkinnableDrawable, IHasCatchObjectState + public abstract partial class CaughtObject : SkinnableDrawable, IHasCatchObjectState { public PalpableCatchHitObject HitObject { get; private set; } public Bindable AccentColour { get; } = new Bindable(); diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs index 80a4150d98..51addaebd5 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs @@ -11,7 +11,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch.Objects.Drawables { - public class DrawableBanana : DrawablePalpableCatchHitObject + public partial class DrawableBanana : DrawablePalpableCatchHitObject { public DrawableBanana() : this(null) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBananaShower.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBananaShower.cs index f061f206ff..c5ae1b5526 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBananaShower.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Catch.Objects.Drawables { - public class DrawableBananaShower : DrawableCatchHitObject + public partial class DrawableBananaShower : DrawableCatchHitObject { private readonly Container bananaContainer; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs index 23264edf3d..c25bc7d076 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs @@ -15,7 +15,7 @@ using osu.Game.Utils; namespace osu.Game.Rulesets.Catch.Objects.Drawables { - public abstract class DrawableCatchHitObject : DrawableHitObject + public abstract partial class DrawableCatchHitObject : DrawableHitObject { public readonly Bindable OriginalXBindable = new Bindable(); public readonly Bindable XOffsetBindable = new Bindable(); diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs index a81d87480a..e8b0c4a9fb 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs @@ -11,7 +11,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch.Objects.Drawables { - public class DrawableDroplet : DrawablePalpableCatchHitObject + public partial class DrawableDroplet : DrawablePalpableCatchHitObject { public DrawableDroplet() : this(null) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs index d7fd79929b..4347c77383 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs @@ -11,7 +11,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch.Objects.Drawables { - public class DrawableFruit : DrawablePalpableCatchHitObject + public partial class DrawableFruit : DrawablePalpableCatchHitObject { public DrawableFruit() : this(null) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs index 12a44c909e..1ad1664122 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Catch.Objects.Drawables { - public class DrawableJuiceStream : DrawableCatchHitObject + public partial class DrawableJuiceStream : DrawableCatchHitObject { private readonly Container dropletContainer; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs index dd09b6c06d..8468cc0a6a 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawables { [Cached(typeof(IHasCatchObjectState))] - public abstract class DrawablePalpableCatchHitObject : DrawableCatchHitObject, IHasCatchObjectState + public abstract partial class DrawablePalpableCatchHitObject : DrawableCatchHitObject, IHasCatchObjectState { public new PalpableCatchHitObject HitObject => (PalpableCatchHitObject)base.HitObject; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableTinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableTinyDroplet.cs index 8c48b62c7e..8e98efdbda 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableTinyDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableTinyDroplet.cs @@ -7,7 +7,7 @@ using JetBrains.Annotations; namespace osu.Game.Rulesets.Catch.Objects.Drawables { - public class DrawableTinyDroplet : DrawableDroplet + public partial class DrawableTinyDroplet : DrawableDroplet { protected override float ScaleFactor => base.ScaleFactor / 2; diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index ba3d529212..b784fc4c19 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Scoring { - public class CatchScoreProcessor : ScoreProcessor + public partial class CatchScoreProcessor : ScoreProcessor { public CatchScoreProcessor() : base(new CatchRuleset()) diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs index 9a657c9216..8cdb490922 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonBananaPiece.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Skinning.Argon { - internal class ArgonBananaPiece : ArgonFruitPiece + internal partial class ArgonBananaPiece : ArgonFruitPiece { private Container stabilisedPieceContainer = null!; diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonCatcher.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonCatcher.cs index 4db0df4a34..82374085c8 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonCatcher.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonCatcher.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Skinning.Argon { - public class ArgonCatcher : CompositeDrawable + public partial class ArgonCatcher : CompositeDrawable { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonDropletPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonDropletPiece.cs index 267f8a06a3..38fe7916f5 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonDropletPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonDropletPiece.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Skinning.Argon { - internal class ArgonDropletPiece : CatchHitObjectPiece + internal partial class ArgonDropletPiece : CatchHitObjectPiece { protected override Drawable HyperBorderPiece => hyperBorderPiece; diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs index 28538d48b3..4b5319e859 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonFruitPiece.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Skinning.Argon { - internal class ArgonFruitPiece : CatchHitObjectPiece + internal partial class ArgonFruitPiece : CatchHitObjectPiece { protected override Drawable HyperBorderPiece => hyperBorderPiece; diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonHitExplosion.cs index 90dca49dfd..a3c0c8c108 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonHitExplosion.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonHitExplosion.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Skinning.Argon { - public class ArgonHitExplosion : CompositeDrawable, IHitExplosion + public partial class ArgonHitExplosion : CompositeDrawable, IHitExplosion { public override bool RemoveWhenNotAlive => true; diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonJudgementPiece.cs index 59e8b5a0b3..82d10e500d 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonJudgementPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonJudgementPiece.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Skinning.Argon { - public class ArgonJudgementPiece : CompositeDrawable, IAnimatableJudgement + public partial class ArgonJudgementPiece : CompositeDrawable, IAnimatableJudgement { protected readonly HitResult Result; @@ -100,7 +100,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon public Drawable? GetAboveHitObjectsProxiedContent() => null; - private class RingExplosion : CompositeDrawable + private partial class RingExplosion : CompositeDrawable { private readonly float travel = 52; @@ -169,7 +169,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon this.FadeOutFromOne(1000, Easing.OutQuint); } - public class RingPiece : CircularContainer + public partial class RingPiece : CircularContainer { public RingPiece(float thickness = 9) { diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/BananaPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/BananaPiece.cs index 359756f159..80ee9d5a0c 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/BananaPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/BananaPiece.cs @@ -5,7 +5,7 @@ using osu.Framework.Graphics; namespace osu.Game.Rulesets.Catch.Skinning.Default { - public class BananaPiece : CatchHitObjectPiece + public partial class BananaPiece : CatchHitObjectPiece { protected override Drawable BorderPiece { get; } diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/BananaPulpFormation.cs b/osu.Game.Rulesets.Catch/Skinning/Default/BananaPulpFormation.cs index ee1cc68f7d..26c8558e74 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/BananaPulpFormation.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/BananaPulpFormation.cs @@ -5,7 +5,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Skinning.Default { - public class BananaPulpFormation : PulpFormation + public partial class BananaPulpFormation : PulpFormation { public BananaPulpFormation() { diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/BorderPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/BorderPiece.cs index 8d8ee49af7..f0bdcfa1ba 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/BorderPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/BorderPiece.cs @@ -9,7 +9,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Skinning.Default { - public class BorderPiece : Circle + public partial class BorderPiece : Circle { public BorderPiece() { diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs index e84e4d4ad2..7cc425966d 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs @@ -11,7 +11,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Skinning.Default { - public abstract class CatchHitObjectPiece : CompositeDrawable + public abstract partial class CatchHitObjectPiece : CompositeDrawable { public readonly Bindable AccentColour = new Bindable(); public readonly Bindable HyperDash = new Bindable(); diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultCatcher.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultCatcher.cs index e423f21b98..72208b763b 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultCatcher.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultCatcher.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets.Catch.UI; namespace osu.Game.Rulesets.Catch.Skinning.Default { - public class DefaultCatcher : CompositeDrawable + public partial class DefaultCatcher : CompositeDrawable { public Bindable CurrentState { get; } = new Bindable(); diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs index 2650ba765b..3af178fe4d 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Skinning.Default { - public class DefaultHitExplosion : CompositeDrawable, IHitExplosion + public partial class DefaultHitExplosion : CompositeDrawable, IHitExplosion { private CircularContainer largeFaint = null!; private CircularContainer smallFaint = null!; diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs index 59e74bff74..f002457b61 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs @@ -7,7 +7,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Skinning.Default { - public class DropletPiece : CatchHitObjectPiece + public partial class DropletPiece : CatchHitObjectPiece { protected override Drawable HyperBorderPiece { get; } diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs index 3bd8032649..31e30d8073 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.Catch.Objects; namespace osu.Game.Rulesets.Catch.Skinning.Default { - internal class FruitPiece : CatchHitObjectPiece + internal partial class FruitPiece : CatchHitObjectPiece { /// /// Because we're adding a border around the fruit, we need to scale down some. diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPulpFormation.cs b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPulpFormation.cs index f097361d2a..c031e50e34 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPulpFormation.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPulpFormation.cs @@ -7,7 +7,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Skinning.Default { - public class FruitPulpFormation : PulpFormation + public partial class FruitPulpFormation : PulpFormation { public readonly Bindable VisualRepresentation = new Bindable(); diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/HyperBorderPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/HyperBorderPiece.cs index c8895f32f4..c025c8e435 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/HyperBorderPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/HyperBorderPiece.cs @@ -6,7 +6,7 @@ using osu.Game.Rulesets.Catch.UI; namespace osu.Game.Rulesets.Catch.Skinning.Default { - public class HyperBorderPiece : BorderPiece + public partial class HyperBorderPiece : BorderPiece { public HyperBorderPiece() { diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/HyperDropletBorderPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/HyperDropletBorderPiece.cs index 53a487b97f..1462bc3515 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/HyperDropletBorderPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/HyperDropletBorderPiece.cs @@ -3,7 +3,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default { - public class HyperDropletBorderPiece : HyperBorderPiece + public partial class HyperDropletBorderPiece : HyperBorderPiece { public HyperDropletBorderPiece() { diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/Pulp.cs b/osu.Game.Rulesets.Catch/Skinning/Default/Pulp.cs index 96c6233b41..4b4d6f3788 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/Pulp.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/Pulp.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Skinning.Default { - public class Pulp : Circle + public partial class Pulp : Circle { public readonly Bindable AccentColour = new Bindable(); diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/PulpFormation.cs b/osu.Game.Rulesets.Catch/Skinning/Default/PulpFormation.cs index 8753aa4077..21502e6fa0 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/PulpFormation.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/PulpFormation.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Skinning.Default { - public abstract class PulpFormation : CompositeDrawable + public abstract partial class PulpFormation : CompositeDrawable { public readonly Bindable AccentColour = new Bindable(); diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyBananaPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyBananaPiece.cs index 310da8bf78..26832b7271 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyBananaPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyBananaPiece.cs @@ -5,7 +5,7 @@ using osu.Framework.Graphics.Textures; namespace osu.Game.Rulesets.Catch.Skinning.Legacy { - public class LegacyBananaPiece : LegacyCatchHitObjectPiece + public partial class LegacyBananaPiece : LegacyCatchHitObjectPiece { protected override void LoadComplete() { diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchComboCounter.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchComboCounter.cs index b4d29988d9..eba837a52d 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchComboCounter.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchComboCounter.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy /// /// A combo counter implementation that visually behaves almost similar to stable's osu!catch combo counter. /// - public class LegacyCatchComboCounter : CompositeDrawable, ICatchComboCounter + public partial class LegacyCatchComboCounter : CompositeDrawable, ICatchComboCounter { private readonly LegacyRollingCounter counter; diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchHitObjectPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchHitObjectPiece.cs index 1231ed6d5a..2184ecc363 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchHitObjectPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchHitObjectPiece.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Skinning.Legacy { - public abstract class LegacyCatchHitObjectPiece : PoolableDrawable + public abstract partial class LegacyCatchHitObjectPiece : PoolableDrawable { protected readonly Bindable IndexInBeatmap = new Bindable(); diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs index 667622e6f2..b36d7f11cb 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Skinning.Legacy { - public class LegacyCatcherNew : CompositeDrawable + public partial class LegacyCatcherNew : CompositeDrawable { [Resolved] private Bindable currentState { get; set; } = null!; diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherOld.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherOld.cs index 5f09d1e254..1e21d8eab1 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherOld.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherOld.cs @@ -9,7 +9,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Skinning.Legacy { - public class LegacyCatcherOld : CompositeDrawable + public partial class LegacyCatcherOld : CompositeDrawable { public LegacyCatcherOld() { diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyDropletPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyDropletPiece.cs index 7007f1cc29..7ffd682698 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyDropletPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyDropletPiece.cs @@ -6,7 +6,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Skinning.Legacy { - public class LegacyDropletPiece : LegacyCatchHitObjectPiece + public partial class LegacyDropletPiece : LegacyCatchHitObjectPiece { public LegacyDropletPiece() { diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyFruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyFruitPiece.cs index f002bab219..85b60561dd 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyFruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyFruitPiece.cs @@ -5,7 +5,7 @@ using osu.Game.Rulesets.Catch.Objects; namespace osu.Game.Rulesets.Catch.Skinning.Legacy { - internal class LegacyFruitPiece : LegacyCatchHitObjectPiece + internal partial class LegacyFruitPiece : LegacyCatchHitObjectPiece { protected override void LoadComplete() { diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs index 393a1076af..47660503dc 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Skinning.Legacy { - public class LegacyHitExplosion : CompositeDrawable, IHitExplosion + public partial class LegacyHitExplosion : CompositeDrawable, IHitExplosion { [Resolved] private Catcher catcher { get; set; } = null!; diff --git a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs index 03f0bc6a55..ffdc5299d0 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.UI /// /// Represents a component that displays a skinned and handles combo judgement results for updating it accordingly. /// - public class CatchComboDisplay : SkinnableDrawable + public partial class CatchComboDisplay : SkinnableDrawable { private int currentCombo; diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index ce000b0fad..4df297565e 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.UI { - public class CatchPlayfield : ScrollingPlayfield + public partial class CatchPlayfield : ScrollingPlayfield { /// /// The width of the playfield. diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs index 82b85f54e4..c03179dc50 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.UI { - public class CatchPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer + public partial class CatchPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer { private const float playfield_size_adjust = 0.8f; @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Catch.UI /// /// A which scales its content relative to a target width. /// - private class ScalingContainer : Container + private partial class ScalingContainer : Container { protected override void Update() { diff --git a/osu.Game.Rulesets.Catch/UI/CatchReplayRecorder.cs b/osu.Game.Rulesets.Catch/UI/CatchReplayRecorder.cs index c118c14e3f..9ea150a2cf 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchReplayRecorder.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchReplayRecorder.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Catch.UI { - public class CatchReplayRecorder : ReplayRecorder + public partial class CatchReplayRecorder : ReplayRecorder { private readonly CatchPlayfield playfield; diff --git a/osu.Game.Rulesets.Catch/UI/CatchTouchInputMapper.cs b/osu.Game.Rulesets.Catch/UI/CatchTouchInputMapper.cs index 12d695393f..d23913136d 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchTouchInputMapper.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchTouchInputMapper.cs @@ -15,7 +15,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Catch.UI { - public class CatchTouchInputMapper : VisibilityContainer + public partial class CatchTouchInputMapper : VisibilityContainer { public override bool PropagatePositionalInputSubTree => true; public override bool PropagateNonPositionalInputSubTree => true; @@ -205,7 +205,7 @@ namespace osu.Game.Rulesets.Catch.UI protected override void PopOut() => mainContent.FadeOut(300, Easing.OutQuint); - private class InputArea : CompositeDrawable, IKeyBindingHandler + private partial class InputArea : CompositeDrawable, IKeyBindingHandler { private readonly TouchCatchAction handledAction; diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 61fefcfd99..086b4ff285 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -26,7 +26,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.UI { [Cached] - public class Catcher : SkinReloadableDrawable + public partial class Catcher : SkinReloadableDrawable { /// /// The size of the catcher at 1x scale. diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 7a29ba9801..d0da05bc44 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Catch.UI /// It holds a as a child and translates input to the catcher movement. /// It also holds a combo display that is above the catcher, and judgment results are translated to the catcher and the combo display. /// - public class CatcherArea : Container, IKeyBindingHandler + public partial class CatcherArea : Container, IKeyBindingHandler { public Catcher Catcher { diff --git a/osu.Game.Rulesets.Catch/UI/CatcherTrail.cs b/osu.Game.Rulesets.Catch/UI/CatcherTrail.cs index afaa037574..f486633e12 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherTrail.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherTrail.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Catch.UI /// A trail of the catcher. /// It also represents a hyper dash afterimage. /// - public class CatcherTrail : PoolableDrawableWithLifetime + public partial class CatcherTrail : PoolableDrawableWithLifetime { private readonly SkinnableCatcher body; diff --git a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs index d255937fed..e982be53d8 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.UI /// Represents a component responsible for displaying /// the appropriate catcher trails when requested to. /// - public class CatcherTrailDisplay : PooledDrawableWithLifetimeContainer + public partial class CatcherTrailDisplay : PooledDrawableWithLifetimeContainer { /// /// The most recent time a dash trail was added to this container. diff --git a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs index e02b915508..0be271b236 100644 --- a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs @@ -21,7 +21,7 @@ using osu.Game.Scoring; namespace osu.Game.Rulesets.Catch.UI { - public class DrawableCatchRuleset : DrawableScrollingRuleset + public partial class DrawableCatchRuleset : DrawableScrollingRuleset { protected override ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Constant; diff --git a/osu.Game.Rulesets.Catch/UI/DroppedObjectContainer.cs b/osu.Game.Rulesets.Catch/UI/DroppedObjectContainer.cs index 1e4da479d2..cb2d8498cc 100644 --- a/osu.Game.Rulesets.Catch/UI/DroppedObjectContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/DroppedObjectContainer.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Catch.Objects.Drawables; namespace osu.Game.Rulesets.Catch.UI { - public class DroppedObjectContainer : Container + public partial class DroppedObjectContainer : Container { public DroppedObjectContainer() { diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs index 9b32893efe..c53957100a 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs @@ -8,7 +8,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch.UI { - public class HitExplosion : PoolableDrawableWithLifetime + public partial class HitExplosion : PoolableDrawableWithLifetime { private readonly SkinnableDrawable skinnableExplosion; diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs b/osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs index 2004c971ad..e1dd665bf2 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Objects.Pooling; namespace osu.Game.Rulesets.Catch.UI { - public class HitExplosionContainer : PooledDrawableWithLifetimeContainer + public partial class HitExplosionContainer : PooledDrawableWithLifetimeContainer { protected override bool RemoveRewoundEntry => true; diff --git a/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs b/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs index fa6ccf6bd6..78a71f26a2 100644 --- a/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs +++ b/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.UI /// The visual representation of the . /// It includes the body part of the catcher and the catcher plate. /// - public class SkinnableCatcher : SkinnableDrawable + public partial class SkinnableCatcher : SkinnableDrawable { /// /// This is used by skin elements to determine which texture of the catcher is used. diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/ManiaPlacementBlueprintTestScene.cs b/osu.Game.Rulesets.Mania.Tests/Editor/ManiaPlacementBlueprintTestScene.cs index 0e4f612999..d2a44122aa 100644 --- a/osu.Game.Rulesets.Mania.Tests/Editor/ManiaPlacementBlueprintTestScene.cs +++ b/osu.Game.Rulesets.Mania.Tests/Editor/ManiaPlacementBlueprintTestScene.cs @@ -21,7 +21,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Tests.Editor { - public abstract class ManiaPlacementBlueprintTestScene : PlacementBlueprintTestScene + public abstract partial class ManiaPlacementBlueprintTestScene : PlacementBlueprintTestScene { private readonly Column column; diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/ManiaSelectionBlueprintTestScene.cs b/osu.Game.Rulesets.Mania.Tests/Editor/ManiaSelectionBlueprintTestScene.cs index 4cadcf138b..2fda012f07 100644 --- a/osu.Game.Rulesets.Mania.Tests/Editor/ManiaSelectionBlueprintTestScene.cs +++ b/osu.Game.Rulesets.Mania.Tests/Editor/ManiaSelectionBlueprintTestScene.cs @@ -15,7 +15,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Mania.Tests.Editor { - public abstract class ManiaSelectionBlueprintTestScene : SelectionBlueprintTestScene + public abstract partial class ManiaSelectionBlueprintTestScene : SelectionBlueprintTestScene { protected override Container Content => blueprints ?? base.Content; diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneEditor.cs b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneEditor.cs index 99850f33b8..0a21098d0d 100644 --- a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneEditor.cs +++ b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneEditor.cs @@ -14,7 +14,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Mania.Tests.Editor { [TestFixture] - public class TestSceneEditor : EditorTestScene + public partial class TestSceneEditor : EditorTestScene { private readonly Bindable direction = new Bindable(); diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneHoldNotePlacementBlueprint.cs b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneHoldNotePlacementBlueprint.cs index ddec1f3432..4b332c3faa 100644 --- a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneHoldNotePlacementBlueprint.cs +++ b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneHoldNotePlacementBlueprint.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Mania.Tests.Editor { - public class TestSceneHoldNotePlacementBlueprint : ManiaPlacementBlueprintTestScene + public partial class TestSceneHoldNotePlacementBlueprint : ManiaPlacementBlueprintTestScene { protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableHoldNote((HoldNote)hitObject); protected override PlacementBlueprint CreateBlueprint() => new HoldNotePlacementBlueprint(); diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneHoldNoteSelectionBlueprint.cs b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneHoldNoteSelectionBlueprint.cs index b70d4e4fa6..a65f949cec 100644 --- a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneHoldNoteSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneHoldNoteSelectionBlueprint.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Mania.Objects.Drawables; namespace osu.Game.Rulesets.Mania.Tests.Editor { - public class TestSceneHoldNoteSelectionBlueprint : ManiaSelectionBlueprintTestScene + public partial class TestSceneHoldNoteSelectionBlueprint : ManiaSelectionBlueprintTestScene { public TestSceneHoldNoteSelectionBlueprint() : base(4) diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs index ef140995ec..653c75baac 100644 --- a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs +++ b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs @@ -24,7 +24,7 @@ using osuTK; namespace osu.Game.Rulesets.Mania.Tests.Editor { - public class TestSceneManiaBeatSnapGrid : EditorClockTestScene + public partial class TestSceneManiaBeatSnapGrid : EditorClockTestScene { [Cached(typeof(IScrollingInfo))] private ScrollingTestContainer.TestScrollingInfo scrollingInfo = new ScrollingTestContainer.TestScrollingInfo(); @@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor public ManiaPlayfield Playfield { get; } } - public class TestHitObjectComposer : HitObjectComposer + public partial class TestHitObjectComposer : HitObjectComposer { public override Playfield Playfield { get; } public override IEnumerable HitObjects => Enumerable.Empty(); diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaComposeScreen.cs b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaComposeScreen.cs index e082b90d3b..a1f4b234c4 100644 --- a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaComposeScreen.cs +++ b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaComposeScreen.cs @@ -22,7 +22,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Mania.Tests.Editor { - public class TestSceneManiaComposeScreen : EditorClockTestScene + public partial class TestSceneManiaComposeScreen : EditorClockTestScene { [Resolved] private SkinManager skins { get; set; } diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaHitObjectComposer.cs index a3985be936..8e0b51dcf8 100644 --- a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaHitObjectComposer.cs +++ b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaHitObjectComposer.cs @@ -27,7 +27,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Mania.Tests.Editor { - public class TestSceneManiaHitObjectComposer : EditorClockTestScene + public partial class TestSceneManiaHitObjectComposer : EditorClockTestScene { private TestComposer composer; @@ -193,7 +193,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor private void setScrollStep(ScrollingDirection direction) => AddStep($"set scroll direction = {direction}", () => ((Bindable)composer.Composer.ScrollingInfo.Direction).Value = direction); - private class TestComposer : CompositeDrawable + private partial class TestComposer : CompositeDrawable { [Cached(typeof(EditorBeatmap))] [Cached(typeof(IBeatSnapProvider))] diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneNotePlacementBlueprint.cs b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneNotePlacementBlueprint.cs index 28c002eef8..a446f13cbf 100644 --- a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneNotePlacementBlueprint.cs +++ b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneNotePlacementBlueprint.cs @@ -21,7 +21,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Mania.Tests.Editor { - public class TestSceneNotePlacementBlueprint : ManiaPlacementBlueprintTestScene + public partial class TestSceneNotePlacementBlueprint : ManiaPlacementBlueprintTestScene { [SetUp] public void Setup() => Schedule(() => diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneNoteSelectionBlueprint.cs b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneNoteSelectionBlueprint.cs index f61d416e3b..86e87e7486 100644 --- a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneNoteSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneNoteSelectionBlueprint.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Mania.Objects.Drawables; namespace osu.Game.Rulesets.Mania.Tests.Editor { - public class TestSceneNoteSelectionBlueprint : ManiaSelectionBlueprintTestScene + public partial class TestSceneNoteSelectionBlueprint : ManiaSelectionBlueprintTestScene { public TestSceneNoteSelectionBlueprint() : base(4) diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaInputTestScene.cs b/osu.Game.Rulesets.Mania.Tests/ManiaInputTestScene.cs index e456659ac4..c85583c1fd 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaInputTestScene.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaInputTestScene.cs @@ -12,7 +12,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Mania.Tests { - public abstract class ManiaInputTestScene : OsuTestScene + public abstract partial class ManiaInputTestScene : OsuTestScene { private readonly Container content; protected override Container Content => content ?? base.Content; @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Mania.Tests base.Content.Add(content = new LocalInputManager(keys)); } - private class LocalInputManager : ManiaInputManager + private partial class LocalInputManager : ManiaInputManager { public LocalInputManager(int variant) : base(new ManiaRuleset().RulesetInfo, variant) @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Mania.Tests protected override KeyBindingContainer CreateKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) => new LocalKeyBindingContainer(ruleset, variant, unique); - private class LocalKeyBindingContainer : RulesetKeyBindingContainer + private partial class LocalKeyBindingContainer : RulesetKeyBindingContainer { public LocalKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) : base(ruleset, variant, unique) diff --git a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModConstantSpeed.cs b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModConstantSpeed.cs index 60363aaeef..dc4f660a45 100644 --- a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModConstantSpeed.cs +++ b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModConstantSpeed.cs @@ -13,7 +13,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Mania.Tests.Mods { - public class TestSceneManiaModConstantSpeed : ModTestScene + public partial class TestSceneManiaModConstantSpeed : ModTestScene { protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset(); diff --git a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModFlashlight.cs b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModFlashlight.cs index 0e222fea89..001d53c887 100644 --- a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModFlashlight.cs +++ b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModFlashlight.cs @@ -7,7 +7,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Mania.Tests.Mods { - public class TestSceneManiaModFlashlight : ModTestScene + public partial class TestSceneManiaModFlashlight : ModTestScene { protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset(); diff --git a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHoldOff.cs b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHoldOff.cs index d27a79c41d..3011a93755 100644 --- a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHoldOff.cs +++ b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHoldOff.cs @@ -13,7 +13,7 @@ using osu.Game.Rulesets.Mania.Beatmaps; namespace osu.Game.Rulesets.Mania.Tests.Mods { - public class TestSceneManiaModHoldOff : ModTestScene + public partial class TestSceneManiaModHoldOff : ModTestScene { protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset(); diff --git a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModInvert.cs b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModInvert.cs index f2cc254e38..2977241dc6 100644 --- a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModInvert.cs +++ b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModInvert.cs @@ -7,7 +7,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Mania.Tests.Mods { - public class TestSceneManiaModInvert : ModTestScene + public partial class TestSceneManiaModInvert : ModTestScene { protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset(); diff --git a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModPerfect.cs b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModPerfect.cs index 2e3b21aed7..97a6ee28f4 100644 --- a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModPerfect.cs +++ b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModPerfect.cs @@ -8,7 +8,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Mania.Tests.Mods { - public class TestSceneManiaModPerfect : ModPerfectTestScene + public partial class TestSceneManiaModPerfect : ModPerfectTestScene { protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset(); diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/ColumnTestContainer.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/ColumnTestContainer.cs index d3e90170b2..0c55cebf0d 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/ColumnTestContainer.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/ColumnTestContainer.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning /// /// A container to be used in a to provide a resolvable dependency. /// - public class ColumnTestContainer : Container + public partial class ColumnTestContainer : Container { protected override Container Content => content; diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaHitObjectTestScene.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaHitObjectTestScene.cs index 75175c43d8..25e120edc5 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaHitObjectTestScene.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaHitObjectTestScene.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning /// /// A test scene for a mania hitobject. /// - public abstract class ManiaHitObjectTestScene : ManiaSkinnableTestScene + public abstract partial class ManiaHitObjectTestScene : ManiaSkinnableTestScene { [SetUp] public void SetUp() => Schedule(() => diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaSkinnableTestScene.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaSkinnableTestScene.cs index 2c5535a65f..30bd600d9d 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaSkinnableTestScene.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/ManiaSkinnableTestScene.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning /// /// A test scene for skinnable mania components. /// - public abstract class ManiaSkinnableTestScene : SkinnableTestScene + public abstract partial class ManiaSkinnableTestScene : SkinnableTestScene { [Cached(Type = typeof(IScrollingInfo))] private readonly TestScrollingInfo scrollingInfo = new TestScrollingInfo(); diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneBarLine.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneBarLine.cs index 1bfe55b074..ab9f57ecc3 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneBarLine.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneBarLine.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Mania.UI; namespace osu.Game.Rulesets.Mania.Tests.Skinning { - public class TestSceneBarLine : ManiaSkinnableTestScene + public partial class TestSceneBarLine : ManiaSkinnableTestScene { [Test] public void TestMinor() diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs index 3dece20308..3881aae22e 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Mania.Tests.Skinning { - public class TestSceneColumnBackground : ManiaSkinnableTestScene + public partial class TestSceneColumnBackground : ManiaSkinnableTestScene { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnHitObjectArea.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnHitObjectArea.cs index 1fb9d448a9..9cccc2dd86 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnHitObjectArea.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnHitObjectArea.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Mania.Tests.Skinning { - public class TestSceneColumnHitObjectArea : ManiaSkinnableTestScene + public partial class TestSceneColumnHitObjectArea : ManiaSkinnableTestScene { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneDrawableJudgement.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneDrawableJudgement.cs index 8b12d37fe9..2a9727dbd4 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneDrawableJudgement.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneDrawableJudgement.cs @@ -17,7 +17,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Mania.Tests.Skinning { - public class TestSceneDrawableJudgement : ManiaSkinnableTestScene + public partial class TestSceneDrawableJudgement : ManiaSkinnableTestScene { public TestSceneDrawableJudgement() { diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneHitExplosion.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneHitExplosion.cs index 744721f1a3..30dd83123d 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneHitExplosion.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneHitExplosion.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Rulesets.Mania.Tests.Skinning { [TestFixture] - public class TestSceneHitExplosion : ManiaSkinnableTestScene + public partial class TestSceneHitExplosion : ManiaSkinnableTestScene { private readonly List> hitExplosionPools = new List>(); diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneHoldNote.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneHoldNote.cs index 0947ddfeb0..0b9ca42af8 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneHoldNote.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneHoldNote.cs @@ -15,7 +15,7 @@ using osu.Game.Rulesets.Mania.Objects.Drawables; namespace osu.Game.Rulesets.Mania.Tests.Skinning { - public class TestSceneHoldNote : ManiaHitObjectTestScene + public partial class TestSceneHoldNote : ManiaHitObjectTestScene { [Test] public void TestHoldNote() diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneNote.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneNote.cs index 85995e6994..d049d88ea8 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneNote.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneNote.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Mania.Objects.Drawables; namespace osu.Game.Rulesets.Mania.Tests.Skinning { - public class TestSceneNote : ManiaHitObjectTestScene + public partial class TestSceneNote : ManiaHitObjectTestScene { protected override DrawableManiaHitObject CreateHitObject() { diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestScenePlayfield.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestScenePlayfield.cs index 9817719c94..f85e303940 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestScenePlayfield.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestScenePlayfield.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Mania.UI; namespace osu.Game.Rulesets.Mania.Tests.Skinning { - public class TestScenePlayfield : ManiaSkinnableTestScene + public partial class TestScenePlayfield : ManiaSkinnableTestScene { private List stageDefinitions = new List(); diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStage.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStage.cs index 07aa0b845f..25e24929c9 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStage.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStage.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Mania.UI; namespace osu.Game.Rulesets.Mania.Tests.Skinning { - public class TestSceneStage : ManiaSkinnableTestScene + public partial class TestSceneStage : ManiaSkinnableTestScene { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs index 5c8e038eed..0557a201c8 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs @@ -10,7 +10,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania.Tests.Skinning { - public class TestSceneStageBackground : ManiaSkinnableTestScene + public partial class TestSceneStageBackground : ManiaSkinnableTestScene { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs index f9c17ee7f4..04d2eee83e 100644 --- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs +++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs @@ -9,7 +9,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania.Tests.Skinning { - public class TestSceneStageForeground : ManiaSkinnableTestScene + public partial class TestSceneStageForeground : ManiaSkinnableTestScene { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneAutoGeneration.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneAutoGeneration.cs index 3abeb8a5f6..9fdd93bcc9 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneAutoGeneration.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneAutoGeneration.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania.Tests { [TestFixture] [HeadlessTest] - public class TestSceneAutoGeneration : OsuTestScene + public partial class TestSceneAutoGeneration : OsuTestScene { /// /// The number of frames which are generated at the start of a replay regardless of hitobject content. diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneColumn.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneColumn.cs index 83491b6fe9..b96fab9ec0 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneColumn.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneColumn.cs @@ -24,7 +24,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Tests { [TestFixture] - public class TestSceneColumn : ManiaInputTestScene + public partial class TestSceneColumn : ManiaInputTestScene { [Cached(typeof(IReadOnlyList))] private IReadOnlyList mods { get; set; } = Array.Empty(); diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneDrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneDrawableManiaHitObject.cs index d273f5cb35..51c2bac6d1 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneDrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneDrawableManiaHitObject.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Tests { - public class TestSceneDrawableManiaHitObject : OsuTestScene + public partial class TestSceneDrawableManiaHitObject : OsuTestScene { private readonly ManualClock clock = new ManualClock(); diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs index 0cba2076be..42e2099e3f 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Mania.Tests /// x : button press /// o : button release /// - public class TestSceneHoldNoteInput : RateAdjustedBeatmapTestScene + public partial class TestSceneHoldNoteInput : RateAdjustedBeatmapTestScene { private const double time_before_head = 250; private const double time_head = 1500; @@ -572,7 +572,7 @@ namespace osu.Game.Rulesets.Mania.Tests AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor?.HasCompleted.Value == true); } - private class ScoreAccessibleReplayPlayer : ReplayPlayer + private partial class ScoreAccessibleReplayPlayer : ReplayPlayer { public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneManiaHitObjectSamples.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneManiaHitObjectSamples.cs index 00f0fcefd9..7021c081b7 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneManiaHitObjectSamples.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneManiaHitObjectSamples.cs @@ -10,7 +10,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Mania.Tests { - public class TestSceneManiaHitObjectSamples : HitObjectSampleTest + public partial class TestSceneManiaHitObjectSamples : HitObjectSampleTest { protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset(); protected override IResourceStore RulesetResources => new DllResourceStore(Assembly.GetAssembly(typeof(TestSceneManiaHitObjectSamples))); diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneManiaPlayer.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneManiaPlayer.cs index 9abedc22f9..98046320cb 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneManiaPlayer.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneManiaPlayer.cs @@ -7,7 +7,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Mania.Tests { - public class TestSceneManiaPlayer : PlayerTestScene + public partial class TestSceneManiaPlayer : PlayerTestScene { protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset(); } diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneNotes.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneNotes.cs index df831d8c9f..31ff57395c 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneNotes.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneNotes.cs @@ -29,7 +29,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Tests { [TestFixture] - public class TestSceneNotes : OsuTestScene + public partial class TestSceneNotes : OsuTestScene { [Test] public void TestVariousNotes() @@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Mania.Tests private bool verifyAnchors(DrawableHoldNote holdNote, Anchor expectedAnchor) => verifyAnchors((DrawableHitObject)holdNote, expectedAnchor) && holdNote.NestedHitObjects.All(n => verifyAnchors(n, expectedAnchor)); - private class NoteContainer : Container + private partial class NoteContainer : Container { private readonly Container content; protected override Container Content => content; diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs index 464dbecee5..e49b259615 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneOutOfOrderHits.cs @@ -24,7 +24,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Mania.Tests { - public class TestSceneOutOfOrderHits : RateAdjustedBeatmapTestScene + public partial class TestSceneOutOfOrderHits : RateAdjustedBeatmapTestScene { [Test] public void TestPreviousHitWindowDoesNotExtendPastNextObject() @@ -171,7 +171,7 @@ namespace osu.Game.Rulesets.Mania.Tests AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } - private class ScoreAccessibleReplayPlayer : ReplayPlayer + private partial class ScoreAccessibleReplayPlayer : ReplayPlayer { public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; diff --git a/osu.Game.Rulesets.Mania.Tests/TestScenePlayfieldCoveringContainer.cs b/osu.Game.Rulesets.Mania.Tests/TestScenePlayfieldCoveringContainer.cs index 64e7eafb1b..f497c88bcc 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestScenePlayfieldCoveringContainer.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestScenePlayfieldCoveringContainer.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Tests { - public class TestScenePlayfieldCoveringContainer : OsuTestScene + public partial class TestScenePlayfieldCoveringContainer : OsuTestScene { private readonly ScrollingTestContainer scrollingContainer; private readonly PlayfieldCoveringWrapper cover; diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneStage.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneStage.cs index 6387dac957..86499a7c6e 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneStage.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneStage.cs @@ -24,7 +24,7 @@ using osuTK; namespace osu.Game.Rulesets.Mania.Tests { [TestFixture] - public class TestSceneStage : ManiaInputTestScene + public partial class TestSceneStage : ManiaInputTestScene { private const int columns = 4; diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneTimingBasedNoteColouring.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneTimingBasedNoteColouring.cs index 9f2e3d2502..81557c198d 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneTimingBasedNoteColouring.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneTimingBasedNoteColouring.cs @@ -24,7 +24,7 @@ using osu.Game.Rulesets.Mania.UI; namespace osu.Game.Rulesets.Mania.Tests { [TestFixture] - public class TestSceneTimingBasedNoteColouring : OsuTestScene + public partial class TestSceneTimingBasedNoteColouring : OsuTestScene { private Bindable configTimingBasedNoteColouring; diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditBodyPiece.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditBodyPiece.cs index 52995b73f4..be1cc9a7fe 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditBodyPiece.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Mania.Skinning.Default; namespace osu.Game.Rulesets.Mania.Edit.Blueprints.Components { - public class EditBodyPiece : DefaultBodyPiece + public partial class EditBodyPiece : DefaultBodyPiece { [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditNotePiece.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditNotePiece.cs index 23475ef924..ef7ce9073c 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditNotePiece.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditNotePiece.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Mania.Skinning.Default; namespace osu.Game.Rulesets.Mania.Edit.Blueprints.Components { - public class EditNotePiece : CompositeDrawable + public partial class EditNotePiece : CompositeDrawable { public EditNotePiece() { diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs index 7c720b30aa..21beee0769 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs @@ -16,7 +16,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Mania.Edit.Blueprints { - public class HoldNotePlacementBlueprint : ManiaPlacementBlueprint + public partial class HoldNotePlacementBlueprint : ManiaPlacementBlueprint { private readonly EditBodyPiece bodyPiece; private readonly EditNotePiece headPiece; diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNoteSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNoteSelectionBlueprint.cs index f76f170af0..8ec5213d5f 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNoteSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNoteSelectionBlueprint.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Rulesets.Mania.Edit.Blueprints { - public class HoldNoteSelectionBlueprint : ManiaSelectionBlueprint + public partial class HoldNoteSelectionBlueprint : ManiaSelectionBlueprint { [Resolved] private OsuColour colours { get; set; } diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs index 7c7c802111..5e0512b5dc 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs @@ -15,7 +15,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Mania.Edit.Blueprints { - public abstract class ManiaPlacementBlueprint : PlacementBlueprint + public abstract partial class ManiaPlacementBlueprint : PlacementBlueprint where T : ManiaHitObject { protected new T HitObject => (T)base.HitObject; diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs index 5aa3b44f0d..cf4bca0030 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs @@ -13,7 +13,7 @@ using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Mania.Edit.Blueprints { - public abstract class ManiaSelectionBlueprint : HitObjectSelectionBlueprint + public abstract partial class ManiaSelectionBlueprint : HitObjectSelectionBlueprint where T : ManiaHitObject { [Resolved] diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/NotePlacementBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/NotePlacementBlueprint.cs index e3cb830b80..d77abca350 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/NotePlacementBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/NotePlacementBlueprint.cs @@ -12,7 +12,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Mania.Edit.Blueprints { - public class NotePlacementBlueprint : ManiaPlacementBlueprint + public partial class NotePlacementBlueprint : ManiaPlacementBlueprint { private readonly EditNotePiece piece; diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/NoteSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/NoteSelectionBlueprint.cs index 929fdc29e0..a1392f09fa 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/NoteSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/NoteSelectionBlueprint.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Mania.Objects; namespace osu.Game.Rulesets.Mania.Edit.Blueprints { - public class NoteSelectionBlueprint : ManiaSelectionBlueprint + public partial class NoteSelectionBlueprint : ManiaSelectionBlueprint { public NoteSelectionBlueprint(Note note) : base(note) diff --git a/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditorRuleset.cs b/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditorRuleset.cs index a3a9591964..4a070e70b4 100644 --- a/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditorRuleset.cs +++ b/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditorRuleset.cs @@ -14,7 +14,7 @@ using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Mania.Edit { - public class DrawableManiaEditorRuleset : DrawableManiaRuleset + public partial class DrawableManiaEditorRuleset : DrawableManiaRuleset { public new IScrollingInfo ScrollingInfo => base.ScrollingInfo; diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaBeatSnapGrid.cs b/osu.Game.Rulesets.Mania/Edit/ManiaBeatSnapGrid.cs index b0019d8b6e..d1d5492b7a 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaBeatSnapGrid.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaBeatSnapGrid.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Mania.Edit /// /// A grid which displays coloured beat divisor lines in proximity to the selection or placement cursor. /// - public class ManiaBeatSnapGrid : Component + public partial class ManiaBeatSnapGrid : Component { private const double visible_range = 750; @@ -166,7 +166,7 @@ namespace osu.Game.Rulesets.Mania.Edit } } - private class DrawableGridLine : DrawableHitObject + private partial class DrawableGridLine : DrawableHitObject { [Resolved] private IScrollingInfo scrollingInfo { get; set; } diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs index f438d6497c..05d8ccc73f 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs @@ -11,7 +11,7 @@ using osu.Game.Screens.Edit.Compose.Components; namespace osu.Game.Rulesets.Mania.Edit { - public class ManiaBlueprintContainer : ComposeBlueprintContainer + public partial class ManiaBlueprintContainer : ComposeBlueprintContainer { public ManiaBlueprintContainer(HitObjectComposer composer) : base(composer) diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaEditorPlayfield.cs b/osu.Game.Rulesets.Mania/Edit/ManiaEditorPlayfield.cs index 6683ab6bdc..0a697ca986 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaEditorPlayfield.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaEditorPlayfield.cs @@ -9,7 +9,7 @@ using System.Collections.Generic; namespace osu.Game.Rulesets.Mania.Edit { - public class ManiaEditorPlayfield : ManiaPlayfield + public partial class ManiaEditorPlayfield : ManiaPlayfield { public ManiaEditorPlayfield(List stages) : base(stages) diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs index 3585fd4e8c..5e577a2964 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Rulesets.Mania.Edit { - public class ManiaHitObjectComposer : HitObjectComposer + public partial class ManiaHitObjectComposer : HitObjectComposer { private DrawableManiaEditorRuleset drawableRuleset; private ManiaBeatSnapGrid beatSnapGrid; diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs b/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs index 7b9742a706..5e6ae9bb11 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs @@ -13,7 +13,7 @@ using osu.Game.Screens.Edit.Compose.Components; namespace osu.Game.Rulesets.Mania.Edit { - public class ManiaSelectionHandler : EditorSelectionHandler + public partial class ManiaSelectionHandler : EditorSelectionHandler { [Resolved] private HitObjectComposer composer { get; set; } diff --git a/osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs b/osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs index 81c41ab628..508733ad14 100644 --- a/osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs +++ b/osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Edit.Setup; namespace osu.Game.Rulesets.Mania.Edit.Setup { - public class ManiaSetupSection : RulesetSetupSection + public partial class ManiaSetupSection : RulesetSetupSection { private LabelledSwitchButton specialStyle; diff --git a/osu.Game.Rulesets.Mania/ManiaInputManager.cs b/osu.Game.Rulesets.Mania/ManiaInputManager.cs index e8e90d198a..9ad24d6256 100644 --- a/osu.Game.Rulesets.Mania/ManiaInputManager.cs +++ b/osu.Game.Rulesets.Mania/ManiaInputManager.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Mania { [Cached] // Used for touch input, see ColumnTouchInputArea. - public class ManiaInputManager : RulesetInputManager + public partial class ManiaInputManager : RulesetInputManager { public ManiaInputManager(RulesetInfo ruleset, int variant) : base(ruleset, variant, SimultaneousBindingMode.Unique) diff --git a/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs b/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs index e239068d1d..9ed555da51 100644 --- a/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs +++ b/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets.Mania.UI; namespace osu.Game.Rulesets.Mania { - public class ManiaSettingsSubsection : RulesetSettingsSubsection + public partial class ManiaSettingsSubsection : RulesetSettingsSubsection { protected override LocalisableString Header => "osu!mania"; @@ -47,7 +47,7 @@ namespace osu.Game.Rulesets.Mania }; } - private class ManiaScrollSlider : OsuSliderBar + private partial class ManiaScrollSlider : OsuSliderBar { public override LocalisableString TooltipText => $"{Current.Value}ms (speed {(int)Math.Round(DrawableManiaRuleset.MAX_TIME_RANGE / Current.Value)})"; } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs index 947915cdf9..2539945c20 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Rulesets.Mania.Mods { - public class ManiaModFlashlight : ModFlashlight + public partial class ManiaModFlashlight : ModFlashlight { public override double ScoreMultiplier => 1; public override Type[] IncompatibleMods => new[] { typeof(ModHidden) }; @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Mania.Mods protected override Flashlight CreateFlashlight() => new ManiaFlashlight(this); - private class ManiaFlashlight : Flashlight + private partial class ManiaFlashlight : Flashlight { private readonly LayoutValue flashlightProperties = new LayoutValue(Invalidation.DrawSize); diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs index a607ed572d..8381b8b24b 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs @@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// Visualises a . Although this derives DrawableManiaHitObject, /// this does not handle input/sound like a normal hit object. /// - public class DrawableBarLine : DrawableManiaHitObject + public partial class DrawableBarLine : DrawableManiaHitObject { public DrawableBarLine(BarLine barLine) : base(barLine) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 86d4ad0a36..759d2346e8 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// /// Visualises a hit object. /// - public class DrawableHoldNote : DrawableManiaHitObject, IKeyBindingHandler + public partial class DrawableHoldNote : DrawableManiaHitObject, IKeyBindingHandler { public override bool DisplayResult => false; diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteHead.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteHead.cs index ac646ea427..1aa6ee2507 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteHead.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteHead.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// /// The head of a . /// - public class DrawableHoldNoteHead : DrawableNote + public partial class DrawableHoldNoteHead : DrawableNote { protected override ManiaSkinComponents Component => ManiaSkinComponents.HoldNoteHead; diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs index 3084f71be2..bf477277c6 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// /// The tail of a . /// - public class DrawableHoldNoteTail : DrawableNote + public partial class DrawableHoldNoteTail : DrawableNote { /// /// Lenience of release hit windows. This is to make cases where the hold note release diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs index daec5ddbe7..ce6a83f79f 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// /// Visualises a hit object. /// - public class DrawableHoldNoteTick : DrawableManiaHitObject + public partial class DrawableHoldNoteTick : DrawableManiaHitObject { /// /// References the time at which the user started holding the hold note. diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index 51f8ab1cf8..8498fd36de 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -14,7 +14,7 @@ using osu.Game.Rulesets.Mania.UI; namespace osu.Game.Rulesets.Mania.Objects.Drawables { - public abstract class DrawableManiaHitObject : DrawableHitObject + public abstract partial class DrawableManiaHitObject : DrawableHitObject { /// /// The which causes this to be hit. @@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables public virtual void MissForcefully() => ApplyResult(r => r.Type = r.Judgement.MinResult); } - public abstract class DrawableManiaHitObject : DrawableManiaHitObject + public abstract partial class DrawableManiaHitObject : DrawableManiaHitObject where TObject : ManiaHitObject { public new TObject HitObject => (TObject)base.HitObject; diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index cf3149b065..0819e8401c 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// /// Visualises a hit object. /// - public class DrawableNote : DrawableManiaHitObject, IKeyBindingHandler + public partial class DrawableNote : DrawableManiaHitObject, IKeyBindingHandler { [Resolved] private OsuColour colours { get; set; } diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaHealthProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaHealthProcessor.cs index 3f0491e53f..5c6682ed73 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaHealthProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaHealthProcessor.cs @@ -8,7 +8,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Mania.Scoring { - public class ManiaHealthProcessor : DrainingHealthProcessor + public partial class ManiaHealthProcessor : DrainingHealthProcessor { /// public ManiaHealthProcessor(double drainStartTime, double drainLenience = 0) diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs index dbf3d02955..f724972a29 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Mania.Scoring { - internal class ManiaScoreProcessor : ScoreProcessor + internal partial class ManiaScoreProcessor : ScoreProcessor { public ManiaScoreProcessor() : base(new ManiaRuleset()) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonColumnBackground.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonColumnBackground.cs index 598a765d3c..52e6079877 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonColumnBackground.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Skinning.Argon { - public class ArgonColumnBackground : CompositeDrawable, IKeyBindingHandler + public partial class ArgonColumnBackground : CompositeDrawable, IKeyBindingHandler { private readonly IBindable direction = new Bindable(); diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitExplosion.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitExplosion.cs index af179d5580..e32de6f3f3 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitExplosion.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitExplosion.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Skinning.Argon { - public class ArgonHitExplosion : CompositeDrawable, IHitExplosion + public partial class ArgonHitExplosion : CompositeDrawable, IHitExplosion { public override bool RemoveWhenNotAlive => true; diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitTarget.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitTarget.cs index 9e449623d5..4ffb4a435b 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitTarget.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitTarget.cs @@ -11,7 +11,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Skinning.Argon { - public class ArgonHitTarget : CompositeDrawable + public partial class ArgonHitTarget : CompositeDrawable { private readonly IBindable direction = new Bindable(); diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldBodyPiece.cs index 757190c4ae..1f52f5f15f 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldBodyPiece.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon /// /// Represents length-wise portion of a hold note. /// - public class ArgonHoldBodyPiece : CompositeDrawable, IHoldNoteBody + public partial class ArgonHoldBodyPiece : CompositeDrawable, IHoldNoteBody { protected readonly Bindable AccentColour = new Bindable(); protected readonly IBindable IsHitting = new Bindable(); diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs index 00cd37b6cf..a2166a6708 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Skinning.Argon { - internal class ArgonHoldNoteTailPiece : CompositeDrawable + internal partial class ArgonHoldNoteTailPiece : CompositeDrawable { private readonly IBindable direction = new Bindable(); private readonly IBindable accentColour = new Bindable(); diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonJudgementPiece.cs index e7dfec256d..2dbf475c7e 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonJudgementPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonJudgementPiece.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Skinning.Argon { - public class ArgonJudgementPiece : CompositeDrawable, IAnimatableJudgement + public partial class ArgonJudgementPiece : CompositeDrawable, IAnimatableJudgement { protected readonly HitResult Result; @@ -100,7 +100,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon public Drawable? GetAboveHitObjectsProxiedContent() => null; - private class RingExplosion : CompositeDrawable + private partial class RingExplosion : CompositeDrawable { private readonly float travel = 52; @@ -169,7 +169,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon this.FadeOutFromOne(1000, Easing.OutQuint); } - public class RingPiece : CircularContainer + public partial class RingPiece : CircularContainer { public RingPiece(float thickness = 9) { diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonKeyArea.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonKeyArea.cs index 7670c9bdf2..95e24f8811 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonKeyArea.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonKeyArea.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Skinning.Argon { - public class ArgonKeyArea : CompositeDrawable, IKeyBindingHandler + public partial class ArgonKeyArea : CompositeDrawable, IKeyBindingHandler { private readonly IBindable direction = new Bindable(); diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonNotePiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonNotePiece.cs index 454a6b012b..25b1965c18 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonNotePiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonNotePiece.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Skinning.Argon { - internal class ArgonNotePiece : CompositeDrawable + internal partial class ArgonNotePiece : CompositeDrawable { public const float NOTE_HEIGHT = 42; diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonStageBackground.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonStageBackground.cs index 1881695b14..ec99177f98 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonStageBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonStageBackground.cs @@ -6,7 +6,7 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Rulesets.Mania.Skinning.Argon { - public class ArgonStageBackground : CompositeDrawable + public partial class ArgonStageBackground : CompositeDrawable { public ArgonStageBackground() { diff --git a/osu.Game.Rulesets.Mania/Skinning/Default/DefaultBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Default/DefaultBodyPiece.cs index f0e214b190..9f5ee0846f 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Default/DefaultBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Default/DefaultBodyPiece.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Default /// /// Represents length-wise portion of a hold note. /// - public class DefaultBodyPiece : CompositeDrawable, IHoldNoteBody + public partial class DefaultBodyPiece : CompositeDrawable, IHoldNoteBody { protected readonly Bindable AccentColour = new Bindable(); protected readonly IBindable IsHitting = new Bindable(); @@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Default private void onAccentChanged(ValueChangedEvent accent) => Background.Colour = accent.NewValue.Opacity(0.7f); - private class ForegroundPiece : CompositeDrawable + private partial class ForegroundPiece : CompositeDrawable { public readonly Bindable AccentColour = new Bindable(); public readonly IBindable IsHitting = new Bindable(); diff --git a/osu.Game.Rulesets.Mania/Skinning/Default/DefaultNotePiece.cs b/osu.Game.Rulesets.Mania/Skinning/Default/DefaultNotePiece.cs index 569740deee..e789335584 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Default/DefaultNotePiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Default/DefaultNotePiece.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Default /// /// Represents the static hit markers of notes. /// - internal class DefaultNotePiece : CompositeDrawable + internal partial class DefaultNotePiece : CompositeDrawable { public const float NOTE_HEIGHT = 12; diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/HitTargetInsetContainer.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/HitTargetInsetContainer.cs index 3c89e2c04a..608cde7272 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/HitTargetInsetContainer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/HitTargetInsetContainer.cs @@ -11,7 +11,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania.Skinning.Legacy { - public class HitTargetInsetContainer : Container + public partial class HitTargetInsetContainer : Container { private readonly IBindable direction = new Bindable(); diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs index 52bca2aaa0..c928ebb3e0 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Rulesets.Mania.Skinning.Legacy { - public class LegacyBodyPiece : LegacyManiaColumnElement + public partial class LegacyBodyPiece : LegacyManiaColumnElement { private DrawableHoldNote holdNote = null!; diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyColumnBackground.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyColumnBackground.cs index 0ed96cf6f1..ab996519a7 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyColumnBackground.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Skinning.Legacy { - public class LegacyColumnBackground : LegacyManiaColumnElement, IKeyBindingHandler + public partial class LegacyColumnBackground : LegacyManiaColumnElement, IKeyBindingHandler { private readonly IBindable direction = new Bindable(); diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitExplosion.cs index 6b0e1e5d8a..6c56db613c 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitExplosion.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Rulesets.Mania.Skinning.Legacy { - public class LegacyHitExplosion : LegacyManiaColumnElement, IHitExplosion + public partial class LegacyHitExplosion : LegacyManiaColumnElement, IHitExplosion { public const double FADE_IN_DURATION = 80; diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitTarget.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitTarget.cs index ed78cb6086..3a08a9d818 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitTarget.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitTarget.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Skinning.Legacy { - public class LegacyHitTarget : CompositeDrawable + public partial class LegacyHitTarget : CompositeDrawable { private readonly IBindable direction = new Bindable(); diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteHeadPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteHeadPiece.cs index c3ed0111be..19c3d8e7f8 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteHeadPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteHeadPiece.cs @@ -6,7 +6,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania.Skinning.Legacy { - public class LegacyHoldNoteHeadPiece : LegacyNotePiece + public partial class LegacyHoldNoteHeadPiece : LegacyNotePiece { protected override Drawable? GetAnimation(ISkinSource skin) { diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteTailPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteTailPiece.cs index 13edc6e495..387c5b393a 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteTailPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteTailPiece.cs @@ -8,7 +8,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania.Skinning.Legacy { - public class LegacyHoldNoteTailPiece : LegacyNotePiece + public partial class LegacyHoldNoteTailPiece : LegacyNotePiece { protected override void OnDirectionChanged(ValueChangedEvent direction) { diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyKeyArea.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyKeyArea.cs index e7dca3d946..48b92a8486 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyKeyArea.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyKeyArea.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Rulesets.Mania.Skinning.Legacy { - public class LegacyKeyArea : LegacyManiaColumnElement, IKeyBindingHandler + public partial class LegacyKeyArea : LegacyManiaColumnElement, IKeyBindingHandler { private readonly IBindable direction = new Bindable(); diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaColumnElement.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaColumnElement.cs index 4ffef18781..7e3fb0438c 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaColumnElement.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaColumnElement.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy /// /// A which is placed somewhere within a . /// - public class LegacyManiaColumnElement : CompositeDrawable + public partial class LegacyManiaColumnElement : CompositeDrawable { [Resolved] protected Column Column { get; private set; } = null!; diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaJudgementPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaJudgementPiece.cs index 670a0aad6e..d21a8cd140 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaJudgementPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaJudgementPiece.cs @@ -13,7 +13,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania.Skinning.Legacy { - public class LegacyManiaJudgementPiece : CompositeDrawable, IAnimatableJudgement + public partial class LegacyManiaJudgementPiece : CompositeDrawable, IAnimatableJudgement { private readonly HitResult result; private readonly Drawable animation; diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyNotePiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyNotePiece.cs index 8c5a594b3b..4291ec3c13 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyNotePiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyNotePiece.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Rulesets.Mania.Skinning.Legacy { - public class LegacyNotePiece : LegacyManiaColumnElement + public partial class LegacyNotePiece : LegacyManiaColumnElement { private readonly IBindable direction = new Bindable(); diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageBackground.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageBackground.cs index d039551cd7..758c8dd347 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageBackground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageBackground.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Skinning.Legacy { - public class LegacyStageBackground : CompositeDrawable + public partial class LegacyStageBackground : CompositeDrawable { private Drawable leftSprite; private Drawable rightSprite; @@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy rightSprite.Scale = new Vector2(1, DrawHeight / rightSprite.Height); } - private class ColumnBackground : CompositeDrawable + private partial class ColumnBackground : CompositeDrawable { private readonly int columnIndex; private readonly bool isLastColumn; diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageForeground.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageForeground.cs index 8e72e970ab..1a47fe5076 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageForeground.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageForeground.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Rulesets.Mania.Skinning.Legacy { - public class LegacyStageForeground : CompositeDrawable + public partial class LegacyStageForeground : CompositeDrawable { private readonly IBindable direction = new Bindable(); diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index de7424773b..6a31fb3fda 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -26,7 +26,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.UI { [Cached] - public class Column : ScrollingPlayfield, IKeyBindingHandler + public partial class Column : ScrollingPlayfield, IKeyBindingHandler { public const float COLUMN_WIDTH = 80; public const float SPECIAL_COLUMN_WIDTH = 70; @@ -185,7 +185,7 @@ namespace osu.Game.Rulesets.Mania.UI // This probably shouldn't exist as is, but the columns in the stage are separated by a 1px border => DrawRectangle.Inflate(new Vector2(Stage.COLUMN_SPACING / 2, 0)).Contains(ToLocalSpace(screenSpacePos)); - public class ColumnTouchInputArea : Drawable + public partial class ColumnTouchInputArea : Drawable { private readonly Column column; diff --git a/osu.Game.Rulesets.Mania/UI/ColumnFlow.cs b/osu.Game.Rulesets.Mania/UI/ColumnFlow.cs index 9b3f6d7033..0bc0bf4caf 100644 --- a/osu.Game.Rulesets.Mania/UI/ColumnFlow.cs +++ b/osu.Game.Rulesets.Mania/UI/ColumnFlow.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mania.UI /// Content can be added to individual columns via . /// /// The type of content in each column. - public class ColumnFlow : CompositeDrawable + public partial class ColumnFlow : CompositeDrawable where TContent : Drawable { /// diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs index e5a9ca1e85..c93be91a84 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs @@ -11,7 +11,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania.UI.Components { - public class ColumnHitObjectArea : HitObjectArea + public partial class ColumnHitObjectArea : HitObjectArea { public readonly Container Explosions; diff --git a/osu.Game.Rulesets.Mania/UI/Components/DefaultColumnBackground.cs b/osu.Game.Rulesets.Mania/UI/Components/DefaultColumnBackground.cs index 3680e7ea0a..fe34712c68 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/DefaultColumnBackground.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/DefaultColumnBackground.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.UI.Components { - public class DefaultColumnBackground : CompositeDrawable, IKeyBindingHandler + public partial class DefaultColumnBackground : CompositeDrawable, IKeyBindingHandler { private readonly IBindable direction = new Bindable(); diff --git a/osu.Game.Rulesets.Mania/UI/Components/DefaultHitTarget.cs b/osu.Game.Rulesets.Mania/UI/Components/DefaultHitTarget.cs index 97aa897782..bfc5fbc8f7 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/DefaultHitTarget.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/DefaultHitTarget.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.UI.Components { - public class DefaultHitTarget : CompositeDrawable + public partial class DefaultHitTarget : CompositeDrawable { private const float hit_target_bar_height = 2; diff --git a/osu.Game.Rulesets.Mania/UI/Components/DefaultKeyArea.cs b/osu.Game.Rulesets.Mania/UI/Components/DefaultKeyArea.cs index 600c9feb73..77ab9f60c1 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/DefaultKeyArea.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/DefaultKeyArea.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.UI.Components { - public class DefaultKeyArea : CompositeDrawable, IKeyBindingHandler + public partial class DefaultKeyArea : CompositeDrawable, IKeyBindingHandler { private const float key_icon_size = 10; private const float key_icon_corner_radius = 3; diff --git a/osu.Game.Rulesets.Mania/UI/Components/DefaultStageBackground.cs b/osu.Game.Rulesets.Mania/UI/Components/DefaultStageBackground.cs index 20d80580bf..ef34fc04ee 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/DefaultStageBackground.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/DefaultStageBackground.cs @@ -11,7 +11,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.UI.Components { - public class DefaultStageBackground : CompositeDrawable + public partial class DefaultStageBackground : CompositeDrawable { public DefaultStageBackground() { diff --git a/osu.Game.Rulesets.Mania/UI/Components/HitObjectArea.cs b/osu.Game.Rulesets.Mania/UI/Components/HitObjectArea.cs index 7f4b8eacde..41b2dba173 100644 --- a/osu.Game.Rulesets.Mania/UI/Components/HitObjectArea.cs +++ b/osu.Game.Rulesets.Mania/UI/Components/HitObjectArea.cs @@ -14,7 +14,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania.UI.Components { - public class HitObjectArea : SkinReloadableDrawable + public partial class HitObjectArea : SkinReloadableDrawable { protected readonly IBindable Direction = new Bindable(); public readonly HitObjectContainer HitObjectContainer; diff --git a/osu.Game.Rulesets.Mania/UI/DefaultHitExplosion.cs b/osu.Game.Rulesets.Mania/UI/DefaultHitExplosion.cs index 59716ee3e2..e0663e9878 100644 --- a/osu.Game.Rulesets.Mania/UI/DefaultHitExplosion.cs +++ b/osu.Game.Rulesets.Mania/UI/DefaultHitExplosion.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.UI { - public class DefaultHitExplosion : CompositeDrawable, IHitExplosion + public partial class DefaultHitExplosion : CompositeDrawable, IHitExplosion { private const float default_large_faint_size = 0.8f; diff --git a/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs index 923fc6863c..896dfb2b23 100644 --- a/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs +++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Mania.UI { - public class DrawableManiaJudgement : DrawableJudgement + public partial class DrawableManiaJudgement : DrawableJudgement { public DrawableManiaJudgement(JudgementResult result, DrawableHitObject judgedObject) : base(result, judgedObject) @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Mania.UI protected override Drawable CreateDefaultJudgement(HitResult result) => new DefaultManiaJudgementPiece(result); - private class DefaultManiaJudgementPiece : DefaultJudgementPiece + private partial class DefaultManiaJudgementPiece : DefaultJudgementPiece { public DefaultManiaJudgementPiece(HitResult result) : base(result) diff --git a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs index ea3b438ec8..af8758fb5e 100644 --- a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs @@ -30,7 +30,7 @@ using osu.Game.Scoring; namespace osu.Game.Rulesets.Mania.UI { - public class DrawableManiaRuleset : DrawableScrollingRuleset + public partial class DrawableManiaRuleset : DrawableScrollingRuleset { /// /// The minimum time range. This occurs at a of 40. diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 99b36bd366..01e9926ad7 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Rulesets.Mania.UI { [Cached] - public class ManiaPlayfield : ScrollingPlayfield + public partial class ManiaPlayfield : ScrollingPlayfield { public IReadOnlyList Stages => stages; diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfieldAdjustmentContainer.cs index 8020fcb3cc..d4621ab8f3 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfieldAdjustmentContainer.cs @@ -8,7 +8,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Mania.UI { - public class ManiaPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer + public partial class ManiaPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer { public ManiaPlayfieldAdjustmentContainer() { diff --git a/osu.Game.Rulesets.Mania/UI/ManiaReplayRecorder.cs b/osu.Game.Rulesets.Mania/UI/ManiaReplayRecorder.cs index 87d6c25ac2..56ac38a737 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaReplayRecorder.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaReplayRecorder.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Mania.UI { - public class ManiaReplayRecorder : ReplayRecorder + public partial class ManiaReplayRecorder : ReplayRecorder { public ManiaReplayRecorder(Score score) : base(score) diff --git a/osu.Game.Rulesets.Mania/UI/PlayfieldCoveringWrapper.cs b/osu.Game.Rulesets.Mania/UI/PlayfieldCoveringWrapper.cs index d397e7cc18..46cba01771 100644 --- a/osu.Game.Rulesets.Mania/UI/PlayfieldCoveringWrapper.cs +++ b/osu.Game.Rulesets.Mania/UI/PlayfieldCoveringWrapper.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mania.UI /// /// A that has its contents partially hidden by an adjustable "cover". This is intended to be used in a playfield. /// - public class PlayfieldCoveringWrapper : CompositeDrawable + public partial class PlayfieldCoveringWrapper : CompositeDrawable { /// /// The complete cover, including gradient and fill. diff --git a/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs b/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs index 8e5c8f9b75..4f6a84c60b 100644 --- a/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs +++ b/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs @@ -11,7 +11,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania.UI { - public class PoolableHitExplosion : PoolableDrawable + public partial class PoolableHitExplosion : PoolableDrawable { public const double DURATION = 200; diff --git a/osu.Game.Rulesets.Mania/UI/Stage.cs b/osu.Game.Rulesets.Mania/UI/Stage.cs index 8aeaa9cf35..fc38a96a35 100644 --- a/osu.Game.Rulesets.Mania/UI/Stage.cs +++ b/osu.Game.Rulesets.Mania/UI/Stage.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.UI /// /// A collection of s. /// - public class Stage : ScrollingPlayfield + public partial class Stage : ScrollingPlayfield { [Cached] public readonly StageDefinition Definition; diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneHitCirclePlacementBlueprint.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneHitCirclePlacementBlueprint.cs index 4d84d3e79f..587bd2de44 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneHitCirclePlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneHitCirclePlacementBlueprint.cs @@ -13,7 +13,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests.Editor { - public class TestSceneHitCirclePlacementBlueprint : PlacementBlueprintTestScene + public partial class TestSceneHitCirclePlacementBlueprint : PlacementBlueprintTestScene { protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableHitCircle((HitCircle)hitObject); protected override PlacementBlueprint CreateBlueprint() => new HitCirclePlacementBlueprint(); diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneHitCircleSelectionBlueprint.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneHitCircleSelectionBlueprint.cs index fde62c7a53..9ffbd25a40 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneHitCircleSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneHitCircleSelectionBlueprint.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests.Editor { - public class TestSceneHitCircleSelectionBlueprint : SelectionBlueprintTestScene + public partial class TestSceneHitCircleSelectionBlueprint : SelectionBlueprintTestScene { private HitCircle hitCircle; private DrawableHitCircle drawableObject; @@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddAssert("blueprint positioned over hitobject", () => blueprint.CirclePiece.Position == hitCircle.StackedPosition); } - private class TestBlueprint : HitCircleSelectionBlueprint + private partial class TestBlueprint : HitCircleSelectionBlueprint { public new HitCirclePiece CirclePiece => base.CirclePiece; diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectBeatSnap.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectBeatSnap.cs index a8829ef88c..56894242c8 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectBeatSnap.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectBeatSnap.cs @@ -14,7 +14,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Tests.Editor { [TestFixture] - public class TestSceneObjectBeatSnap : TestSceneOsuEditor + public partial class TestSceneObjectBeatSnap : TestSceneOsuEditor { private OsuPlayfield playfield; diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectMerging.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectMerging.cs index 5c5384e0b7..e7ac38c20e 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectMerging.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectMerging.cs @@ -14,7 +14,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Tests.Editor { - public class TestSceneObjectMerging : TestSceneOsuEditor + public partial class TestSceneObjectMerging : TestSceneOsuEditor { private OsuSelectionHandler selectionHandler => Editor.ChildrenOfType().First(); diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs index 6e8c7ff2bd..3b8a5a90a5 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectObjectSnap.cs @@ -17,7 +17,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Tests.Editor { [TestFixture] - public class TestSceneObjectObjectSnap : TestSceneOsuEditor + public partial class TestSceneObjectObjectSnap : TestSceneOsuEditor { private OsuPlayfield playfield; diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs index 800e6c0711..8641663ce8 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs @@ -21,7 +21,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Tests.Editor { [TestFixture] - public class TestSceneOsuComposerSelection : TestSceneOsuEditor + public partial class TestSceneOsuComposerSelection : TestSceneOsuEditor { protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(ruleset, false); diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs index 1b67fc2ca9..7579e8077b 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs @@ -27,7 +27,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Tests.Editor { - public class TestSceneOsuDistanceSnapGrid : OsuManualInputManagerTestScene + public partial class TestSceneOsuDistanceSnapGrid : OsuManualInputManagerTestScene { private const float beat_length = 100; @@ -217,7 +217,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor return Precision.AlmostEquals(expectedDistance, Vector2.Distance(snappedPosition, grid_position)); }); - private class SnappingCursorContainer : CompositeDrawable + private partial class SnappingCursorContainer : CompositeDrawable { public Func GetSnapPosition; diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditor.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditor.cs index 859290dbec..41a099e6e9 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditor.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditor.cs @@ -9,7 +9,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests.Editor { [TestFixture] - public class TestSceneOsuEditor : EditorTestScene + public partial class TestSceneOsuEditor : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); } diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs index f9cea5761b..59146bc05e 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs @@ -15,7 +15,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Tests.Editor { - public class TestSceneOsuEditorGrids : EditorTestScene + public partial class TestSceneOsuEditorGrids : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorSelectInvalidPath.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorSelectInvalidPath.cs index 536739bd48..bb29504ec3 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorSelectInvalidPath.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorSelectInvalidPath.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests.Editor { - public class TestSceneOsuEditorSelectInvalidPath : EditorTestScene + public partial class TestSceneOsuEditorSelectInvalidPath : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestScenePathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestScenePathControlPointVisualiser.cs index 6d93c3fcf9..d1a04e28e5 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestScenePathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestScenePathControlPointVisualiser.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests.Editor { - public class TestScenePathControlPointVisualiser : OsuManualInputManagerTestScene + public partial class TestScenePathControlPointVisualiser : OsuManualInputManagerTestScene { private Slider slider; private PathControlPointVisualiser visualiser; diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderControlPointPiece.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderControlPointPiece.cs index a177079b8c..112aab884b 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderControlPointPiece.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderControlPointPiece.cs @@ -23,7 +23,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Tests.Editor { - public class TestSceneSliderControlPointPiece : SelectionBlueprintTestScene + public partial class TestSceneSliderControlPointPiece : SelectionBlueprintTestScene { private Slider slider; private DrawableSlider drawableObject; @@ -349,7 +349,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor private void assertControlPointPosition(int index, Vector2 position) => AddAssert($"control point {index} at {position}", () => Precision.AlmostEquals(position, slider.Path.ControlPoints[index].Position, 1)); - private class TestSliderBlueprint : SliderSelectionBlueprint + private partial class TestSliderBlueprint : SliderSelectionBlueprint { public new SliderBodyPiece BodyPiece => base.BodyPiece; public new TestSliderCircleOverlay HeadOverlay => (TestSliderCircleOverlay)base.HeadOverlay; @@ -364,7 +364,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor protected override SliderCircleOverlay CreateCircleOverlay(Slider slider, SliderPosition position) => new TestSliderCircleOverlay(slider, position); } - private class TestSliderCircleOverlay : SliderCircleOverlay + private partial class TestSliderCircleOverlay : SliderCircleOverlay { public new HitCirclePiece CirclePiece => base.CirclePiece; diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderLengthValidity.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderLengthValidity.cs index 31b593e816..77e828e80a 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderLengthValidity.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderLengthValidity.cs @@ -19,7 +19,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Tests.Editor { [TestFixture] - public class TestSceneSliderLengthValidity : TestSceneOsuEditor + public partial class TestSceneSliderLengthValidity : TestSceneOsuEditor { private OsuPlayfield playfield; diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderPlacementBlueprint.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderPlacementBlueprint.cs index 5c3c537541..7542e00a94 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderPlacementBlueprint.cs @@ -18,7 +18,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Tests.Editor { - public class TestSceneSliderPlacementBlueprint : PlacementBlueprintTestScene + public partial class TestSceneSliderPlacementBlueprint : PlacementBlueprintTestScene { [SetUp] public void Setup() => Schedule(() => diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSelectionBlueprint.cs index f84204f01c..ad740b2977 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSelectionBlueprint.cs @@ -20,7 +20,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Tests.Editor { - public class TestSceneSliderSelectionBlueprint : SelectionBlueprintTestScene + public partial class TestSceneSliderSelectionBlueprint : SelectionBlueprintTestScene { private Slider slider; private DrawableSlider drawableObject; @@ -194,7 +194,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor private void checkControlPointSelected(int index, bool selected) => AddAssert($"control point {index} {(selected ? "selected" : "not selected")}", () => blueprint.ControlPointVisualiser.Pieces[index].IsSelected.Value == selected); - private class TestSliderBlueprint : SliderSelectionBlueprint + private partial class TestSliderBlueprint : SliderSelectionBlueprint { public new SliderBodyPiece BodyPiece => base.BodyPiece; public new TestSliderCircleOverlay HeadOverlay => (TestSliderCircleOverlay)base.HeadOverlay; @@ -209,7 +209,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor protected override SliderCircleOverlay CreateCircleOverlay(Slider slider, SliderPosition position) => new TestSliderCircleOverlay(slider, position); } - private class TestSliderCircleOverlay : SliderCircleOverlay + private partial class TestSliderCircleOverlay : SliderCircleOverlay { public new HitCirclePiece CirclePiece => base.CirclePiece; diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs index e864afe056..e9d50d5118 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs @@ -26,7 +26,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Tests.Editor { - public class TestSceneSliderSnapping : EditorTestScene + public partial class TestSceneSliderSnapping : EditorTestScene { private const double beat_length = 1000; diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSplitting.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSplitting.cs index 015952c59a..b2ac462c8f 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSplitting.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSplitting.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests.Editor { - public class TestSceneSliderSplitting : EditorTestScene + public partial class TestSceneSliderSplitting : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderStreamConversion.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderStreamConversion.cs index 0601dc6068..53465d43c9 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderStreamConversion.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderStreamConversion.cs @@ -15,7 +15,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Tests.Editor { - public class TestSceneSliderStreamConversion : TestSceneOsuEditor + public partial class TestSceneSliderStreamConversion : TestSceneOsuEditor { private BindableBeatDivisor beatDivisor => (BindableBeatDivisor)Editor.Dependencies.Get(typeof(BindableBeatDivisor)); diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderVelocityAdjust.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderVelocityAdjust.cs index ef9e332253..bb8c52bdfc 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderVelocityAdjust.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderVelocityAdjust.cs @@ -22,7 +22,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Tests.Editor { - public class TestSceneSliderVelocityAdjust : OsuGameTestScene + public partial class TestSceneSliderVelocityAdjust : OsuGameTestScene { private Screens.Edit.Editor editor => Game.ScreenStack.CurrentScreen as Screens.Edit.Editor; diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSpinnerPlacementBlueprint.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSpinnerPlacementBlueprint.cs index 53ef675cb3..6378097800 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSpinnerPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSpinnerPlacementBlueprint.cs @@ -13,7 +13,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests.Editor { - public class TestSceneSpinnerPlacementBlueprint : PlacementBlueprintTestScene + public partial class TestSceneSpinnerPlacementBlueprint : PlacementBlueprintTestScene { protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableSpinner((Spinner)hitObject); diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSpinnerSelectionBlueprint.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSpinnerSelectionBlueprint.cs index a1b946dd4c..c899f58c5a 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSpinnerSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSpinnerSelectionBlueprint.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests.Editor { - public class TestSceneSpinnerSelectionBlueprint : SelectionBlueprintTestScene + public partial class TestSceneSpinnerSelectionBlueprint : SelectionBlueprintTestScene { public TestSceneSpinnerSelectionBlueprint() { diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSliderScaling.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSliderScaling.cs index efe195d872..64d23090d0 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSliderScaling.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSliderScaling.cs @@ -19,7 +19,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Tests.Editor { [TestFixture] - public class TestSliderScaling : TestSceneOsuEditor + public partial class TestSliderScaling : TestSceneOsuEditor { private OsuPlayfield playfield; diff --git a/osu.Game.Rulesets.Osu.Tests/LegacyMainCirclePieceTest.cs b/osu.Game.Rulesets.Osu.Tests/LegacyMainCirclePieceTest.cs index b6c8103e3c..baaa24959f 100644 --- a/osu.Game.Rulesets.Osu.Tests/LegacyMainCirclePieceTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/LegacyMainCirclePieceTest.cs @@ -18,7 +18,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests { [HeadlessTest] - public class LegacyMainCirclePieceTest : OsuTestScene + public partial class LegacyMainCirclePieceTest : OsuTestScene { [Resolved] private IRenderer renderer { get; set; } = null!; @@ -101,7 +101,7 @@ namespace osu.Game.Rulesets.Osu.Tests AddAssert("check overlay sprite", () => piece.OverlaySprite?.Texture?.AssetName == expectedOverlay); } - private class TestLegacyMainCirclePiece : LegacyMainCirclePiece + private partial class TestLegacyMainCirclePiece : LegacyMainCirclePiece { public new Sprite? CircleSprite => base.CircleSprite.ChildrenOfType().DistinctBy(s => s.Texture.AssetName).SingleOrDefault(); public new Sprite? OverlaySprite => base.OverlaySprite.ChildrenOfType().DistinctBy(s => s.Texture.AssetName).SingleOrDefault(); diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/OsuModTestScene.cs b/osu.Game.Rulesets.Osu.Tests/Mods/OsuModTestScene.cs index d3cb3bcf59..82d7ac6bba 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/OsuModTestScene.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/OsuModTestScene.cs @@ -5,7 +5,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public abstract class OsuModTestScene : ModTestScene + public abstract partial class OsuModTestScene : ModTestScene { protected override Ruleset CreatePlayerRuleset() => new OsuRuleset(); } diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModAlternate.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModAlternate.cs index 521c10c10c..88c81c7a39 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModAlternate.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModAlternate.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModAlternate : OsuModTestScene + public partial class TestSceneOsuModAlternate : OsuModTestScene { [Test] public void TestInputAlternating() => CreateModTest(new ModTestData diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModAutoplay.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModAutoplay.cs index 3563995234..8fdab9f1f9 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModAutoplay.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModAutoplay.cs @@ -15,7 +15,7 @@ using osu.Game.Rulesets.Osu.UI; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModAutoplay : OsuModTestScene + public partial class TestSceneOsuModAutoplay : OsuModTestScene { [Test] public void TestSpmUnaffectedByRateAdjust() diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs index 88b6b9dd56..472c341bdd 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs @@ -15,7 +15,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModDifficultyAdjust : OsuModTestScene + public partial class TestSceneOsuModDifficultyAdjust : OsuModTestScene { [Test] public void TestNoAdjustment() => CreateModTest(new ModTestData diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs index 8df8afe147..f895b91151 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.Osu.Mods; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModDoubleTime : OsuModTestScene + public partial class TestSceneOsuModDoubleTime : OsuModTestScene { [TestCase(0.5)] [TestCase(1.01)] diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFlashlight.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFlashlight.cs index 704a548c61..a353914cd5 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFlashlight.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFlashlight.cs @@ -6,7 +6,7 @@ using osu.Game.Rulesets.Osu.Mods; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModFlashlight : OsuModTestScene + public partial class TestSceneOsuModFlashlight : OsuModTestScene { [TestCase(600)] [TestCase(120)] diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs index 7d7b2d9071..57d2b94188 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFreezeFrame.cs @@ -6,7 +6,7 @@ using osu.Game.Rulesets.Osu.Mods; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModFreezeFrame : OsuModTestScene + public partial class TestSceneOsuModFreezeFrame : OsuModTestScene { [Test] public void TestFreezeFrame() diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModHidden.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModHidden.cs index e692f8ecbc..3f84ac6935 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModHidden.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModHidden.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModHidden : OsuModTestScene + public partial class TestSceneOsuModHidden : OsuModTestScene { [Test] public void TestDefaultBeatmapTest() => CreateModTest(new ModTestData diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModMagnetised.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModMagnetised.cs index 9b49e60363..8a5a7706d1 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModMagnetised.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModMagnetised.cs @@ -6,7 +6,7 @@ using osu.Game.Rulesets.Osu.Mods; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModMagnetised : OsuModTestScene + public partial class TestSceneOsuModMagnetised : OsuModTestScene { [TestCase(0.1f)] [TestCase(0.5f)] diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModMuted.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModMuted.cs index d7d24c99ee..ac341d73b8 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModMuted.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModMuted.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Osu.Mods; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModMuted : OsuModTestScene + public partial class TestSceneOsuModMuted : OsuModTestScene { /// /// Ensures that a final volume combo of 0 (i.e. "always muted" mode) constantly plays metronome and completely mutes track. diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModNoScope.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModNoScope.cs index da6fac3269..9dfa76fc8e 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModNoScope.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModNoScope.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModNoScope : OsuModTestScene + public partial class TestSceneOsuModNoScope : OsuModTestScene { [Test] public void TestVisibleDuringBreak() diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModPerfect.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModPerfect.cs index 985baa8cf5..f0496efc19 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModPerfect.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModPerfect.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModPerfect : ModPerfectTestScene + public partial class TestSceneOsuModPerfect : ModPerfectTestScene { protected override Ruleset CreatePlayerRuleset() => new OsuRuleset(); diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModRandom.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModRandom.cs index c24ba6d530..060a845137 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModRandom.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModRandom.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModRandom : OsuModTestScene + public partial class TestSceneOsuModRandom : OsuModTestScene { [TestCase(1)] [TestCase(7)] diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModRepel.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModRepel.cs index 6bd41e2fa5..8a3d645b05 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModRepel.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModRepel.cs @@ -6,7 +6,7 @@ using osu.Game.Rulesets.Osu.Mods; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModRepel : OsuModTestScene + public partial class TestSceneOsuModRepel : OsuModTestScene { [TestCase(0.1f)] [TestCase(0.5f)] diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModSingleTap.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModSingleTap.cs index 1aed84be10..402c680b46 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModSingleTap.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModSingleTap.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModSingleTap : OsuModTestScene + public partial class TestSceneOsuModSingleTap : OsuModTestScene { [Test] public void TestInputSingular() => CreateModTest(new ModTestData diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModSpunOut.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModSpunOut.cs index e121e6103d..de3ea5f148 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModSpunOut.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModSpunOut.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests.Mods { - public class TestSceneOsuModSpunOut : OsuModTestScene + public partial class TestSceneOsuModSpunOut : OsuModTestScene { protected override bool AllowFail => true; diff --git a/osu.Game.Rulesets.Osu.Tests/OsuSkinnableTestScene.cs b/osu.Game.Rulesets.Osu.Tests/OsuSkinnableTestScene.cs index 415e4ebedd..574618c528 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuSkinnableTestScene.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuSkinnableTestScene.cs @@ -9,7 +9,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests { - public abstract class OsuSkinnableTestScene : SkinnableTestScene + public abstract partial class OsuSkinnableTestScene : SkinnableTestScene { private Container content; diff --git a/osu.Game.Rulesets.Osu.Tests/TestPlayfieldBorder.cs b/osu.Game.Rulesets.Osu.Tests/TestPlayfieldBorder.cs index 106a7f499f..5366a86bc0 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestPlayfieldBorder.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestPlayfieldBorder.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { - public class TestPlayfieldBorder : OsuTestScene + public partial class TestPlayfieldBorder : OsuTestScene { public TestPlayfieldBorder() { diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneAccuracyHeatmap.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneAccuracyHeatmap.cs index 805f4e6567..f99518997b 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneAccuracyHeatmap.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneAccuracyHeatmap.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneAccuracyHeatmap : OsuManualInputManagerTestScene + public partial class TestSceneAccuracyHeatmap : OsuManualInputManagerTestScene { private Box background; private Drawable object1; @@ -91,7 +91,7 @@ namespace osu.Game.Rulesets.Osu.Tests return true; } - private class TestAccuracyHeatmap : AccuracyHeatmap + private partial class TestAccuracyHeatmap : AccuracyHeatmap { public TestAccuracyHeatmap(ScoreInfo score) : base(score, new TestBeatmap(new OsuRuleset().RulesetInfo)) @@ -102,7 +102,7 @@ namespace osu.Game.Rulesets.Osu.Tests => base.AddPoint(start, end, hitPoint, radius); } - private class BorderCircle : CircularContainer + private partial class BorderCircle : CircularContainer { public BorderCircle() { diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneCursorParticles.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneCursorParticles.cs index 7f0ecaca2b..f6e460284b 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneCursorParticles.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneCursorParticles.cs @@ -22,7 +22,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneCursorParticles : TestSceneOsuPlayer + public partial class TestSceneCursorParticles : TestSceneOsuPlayer { protected override bool Autoplay => autoplay; protected override bool HasCustomSteps => true; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs index 30f0891344..9582ee491b 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs @@ -23,7 +23,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneCursorTrail : OsuTestScene + public partial class TestSceneCursorTrail : OsuTestScene { [Resolved] private IRenderer renderer { get; set; } @@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Osu.Tests }); [Cached(typeof(ISkinSource))] - private class LegacySkinContainer : Container, ISkinSource + private partial class LegacySkinContainer : Container, ISkinSource { private readonly IRenderer renderer; private readonly bool disjoint; @@ -131,7 +131,7 @@ namespace osu.Game.Rulesets.Osu.Tests } } - private class MovingCursorInputManager : ManualInputManager + private partial class MovingCursorInputManager : ManualInputManager { public MovingCursorInputManager() { diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs index cfa1841fb7..ff71300733 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneDrawableJudgement.cs @@ -22,7 +22,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneDrawableJudgement : OsuSkinnableTestScene + public partial class TestSceneDrawableJudgement : OsuSkinnableTestScene { [Resolved] private OsuConfigManager config { get; set; } @@ -106,7 +106,7 @@ namespace osu.Game.Rulesets.Osu.Tests }); } - private class TestDrawableOsuJudgement : DrawableOsuJudgement + private partial class TestDrawableOsuJudgement : DrawableOsuJudgement { public new SkinnableSprite Lighting => base.Lighting; public new SkinnableDrawable JudgementBody => base.JudgementBody; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneFollowPoints.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneFollowPoints.cs index 1e625cd4e6..eefaa3cae3 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneFollowPoints.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneFollowPoints.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneFollowPoints : OsuTestScene + public partial class TestSceneFollowPoints : OsuTestScene { private Container hitObjectContainer; private FollowPointRenderer followPointRenderer; @@ -278,7 +278,7 @@ namespace osu.Game.Rulesets.Osu.Tests private FollowPointConnection getGroup(int index) => followPointRenderer.ChildrenOfType().Single(c => c.Entry == getEntry(index)); - private class TestHitObjectContainer : Container + private partial class TestHitObjectContainer : Container { protected override int Compare(Drawable x, Drawable y) { diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs index 628082c2a9..907422858e 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs @@ -28,7 +28,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] - public class TestSceneGameplayCursor : OsuSkinnableTestScene + public partial class TestSceneGameplayCursor : OsuSkinnableTestScene { [Cached] private GameplayState gameplayState; @@ -135,7 +135,7 @@ namespace osu.Game.Rulesets.Osu.Tests } } - private class ClickingCursorContainer : OsuCursorContainer + private partial class ClickingCursorContainer : OsuCursorContainer { private bool pressed; @@ -161,7 +161,7 @@ namespace osu.Game.Rulesets.Osu.Tests } } - private class MovingCursorInputManager : ManualInputManager + private partial class MovingCursorInputManager : ManualInputManager { public MovingCursorInputManager() { diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircle.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircle.cs index be224b88ce..a418df605f 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircle.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircle.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] - public class TestSceneHitCircle : OsuSkinnableTestScene + public partial class TestSceneHitCircle : OsuSkinnableTestScene { private int depthIndex; @@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Osu.Tests Depth = depthIndex++ }; - protected class TestDrawableHitCircle : DrawableHitCircle + protected partial class TestDrawableHitCircle : DrawableHitCircle { private readonly bool auto; private readonly double hitOffset; @@ -131,7 +131,7 @@ namespace osu.Game.Rulesets.Osu.Tests } } - protected class TestOsuPlayfield : OsuPlayfield + protected partial class TestOsuPlayfield : OsuPlayfield { public TestOsuPlayfield() { diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleApplication.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleApplication.cs index 0bc65ac8e6..bcbff20016 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleApplication.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleApplication.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneHitCircleApplication : OsuTestScene + public partial class TestSceneHitCircleApplication : OsuTestScene { [Test] public void TestApplyNewCircle() diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs index 20aed514db..71174e3295 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneHitCircleArea : OsuManualInputManagerTestScene + public partial class TestSceneHitCircleArea : OsuManualInputManagerTestScene { private HitCircle hitCircle; private DrawableHitCircle drawableHitCircle; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleComboChange.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleComboChange.cs index 85951a95a2..34c67e8b9c 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleComboChange.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleComboChange.cs @@ -8,7 +8,7 @@ using osu.Game.Rulesets.Osu.Objects; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneHitCircleComboChange : TestSceneHitCircle + public partial class TestSceneHitCircleComboChange : TestSceneHitCircle { private readonly Bindable comboIndex = new Bindable(); diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleHidden.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleHidden.cs index a469f3dd99..b3498b9651 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleHidden.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleHidden.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Osu.Mods; namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] - public class TestSceneHitCircleHidden : TestSceneHitCircle + public partial class TestSceneHitCircleHidden : TestSceneHitCircle { [SetUp] public void SetUp() => Schedule(() => diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleKiai.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleKiai.cs index e694871408..2c9f1acd2c 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleKiai.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleKiai.cs @@ -10,7 +10,7 @@ using osu.Game.Beatmaps.ControlPoints; namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] - public class TestSceneHitCircleKiai : TestSceneHitCircle + public partial class TestSceneHitCircleKiai : TestSceneHitCircle { [SetUp] public void SetUp() => Schedule(() => diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleLongCombo.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleLongCombo.cs index bcf2449e32..93f1123341 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleLongCombo.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleLongCombo.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] - public class TestSceneHitCircleLongCombo : TestSceneOsuPlayer + public partial class TestSceneHitCircleLongCombo : TestSceneOsuPlayer { protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) { diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs index bb28b2b217..e70d45fb45 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs @@ -21,7 +21,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneLegacyBeatmapSkin : LegacyBeatmapSkinColourTest + public partial class TestSceneLegacyBeatmapSkin : LegacyBeatmapSkinColourTest { [Resolved] private AudioManager audio { get; set; } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneMissHitWindowJudgements.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneMissHitWindowJudgements.cs index 0c6afe6c3d..0d3fd77568 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneMissHitWindowJudgements.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneMissHitWindowJudgements.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneMissHitWindowJudgements : ModTestScene + public partial class TestSceneMissHitWindowJudgements : ModTestScene { protected override Ruleset CreatePlayerRuleset() => new OsuRuleset(); diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneNoSpinnerStacking.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneNoSpinnerStacking.cs index 9e524a1608..1f0e264cf7 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneNoSpinnerStacking.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneNoSpinnerStacking.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] - public class TestSceneNoSpinnerStacking : TestSceneOsuPlayer + public partial class TestSceneNoSpinnerStacking : TestSceneOsuPlayer { protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) { diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneObjectOrderedHitPolicy.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneObjectOrderedHitPolicy.cs index ed1891b7d9..5d9316a21b 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneObjectOrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneObjectOrderedHitPolicy.cs @@ -28,7 +28,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneObjectOrderedHitPolicy : RateAdjustedBeatmapTestScene + public partial class TestSceneObjectOrderedHitPolicy : RateAdjustedBeatmapTestScene { private const double early_miss_window = 1000; // time after -1000 to -500 is considered a miss private const double late_miss_window = 500; // time after +500 is considered a miss @@ -474,7 +474,7 @@ namespace osu.Game.Rulesets.Osu.Tests protected override DifficultyRange[] GetRanges() => ranges; } - private class ScoreAccessibleReplayPlayer : ReplayPlayer + private partial class ScoreAccessibleReplayPlayer : ReplayPlayer { public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuHitObjectSamples.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuHitObjectSamples.cs index 3bc55278d9..4d0b2cc406 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuHitObjectSamples.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuHitObjectSamples.cs @@ -10,7 +10,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneOsuHitObjectSamples : HitObjectSampleTest + public partial class TestSceneOsuHitObjectSamples : HitObjectSampleTest { protected override Ruleset CreatePlayerRuleset() => new OsuRuleset(); diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs index 6f378fc8b4..53c4e49807 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs @@ -9,7 +9,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] - public class TestSceneOsuPlayer : PlayerTestScene + public partial class TestSceneOsuPlayer : PlayerTestScene { protected override Ruleset CreatePlayerRuleset() => new OsuRuleset(); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneResumeOverlay.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneResumeOverlay.cs index e0d33c0e09..b66974d4b1 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneResumeOverlay.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneResumeOverlay.cs @@ -12,7 +12,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneResumeOverlay : OsuManualInputManagerTestScene + public partial class TestSceneResumeOverlay : OsuManualInputManagerTestScene { public TestSceneResumeOverlay() { @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Osu.Tests AddAssert("dismissed", () => resumeFired && resume.State.Value == Visibility.Hidden); } - private class ManualOsuInputManager : OsuInputManager + private partial class ManualOsuInputManager : OsuInputManager { public ManualOsuInputManager(RulesetInfo ruleset) : base(ruleset) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneShaking.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneShaking.cs index dd767bf5e0..bee7831625 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneShaking.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneShaking.cs @@ -13,7 +13,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneShaking : TestSceneHitCircle + public partial class TestSceneShaking : TestSceneHitCircle { private readonly List scheduledTasks = new List(); diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs index 878150e467..09b906cb10 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -29,7 +29,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] - public class TestSceneSkinFallbacks : TestSceneOsuPlayer + public partial class TestSceneSkinFallbacks : TestSceneOsuPlayer { private readonly TestSource testUserSkin; private readonly TestSource testBeatmapSkin; @@ -119,7 +119,7 @@ namespace osu.Game.Rulesets.Osu.Tests protected override ISkin GetSkin() => skin; } - public class SkinProvidingPlayer : TestPlayer + public partial class SkinProvidingPlayer : TestPlayer { private readonly TestSource userSkin; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs index a9ee276a9e..32d0cc8939 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs @@ -26,7 +26,7 @@ using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] - public class TestSceneSlider : OsuSkinnableTestScene + public partial class TestSceneSlider : OsuSkinnableTestScene { private int depthIndex; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderApplication.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderApplication.cs index 728aa27da2..88b70a8836 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderApplication.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderApplication.cs @@ -22,7 +22,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneSliderApplication : OsuTestScene + public partial class TestSceneSliderApplication : OsuTestScene { [Resolved] private SkinManager skinManager { get; set; } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderComboChange.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderComboChange.cs index b48789a709..dc8842a20a 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderComboChange.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderComboChange.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneSliderComboChange : TestSceneSlider + public partial class TestSceneSliderComboChange : TestSceneSlider { private readonly Bindable comboIndex = new Bindable(); diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs index 7a6e19575e..0af0ff5604 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs @@ -24,7 +24,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { [HeadlessTest] - public class TestSceneSliderFollowCircleInput : RateAdjustedBeatmapTestScene + public partial class TestSceneSliderFollowCircleInput : RateAdjustedBeatmapTestScene { private List? judgementResults; private ScoreAccessibleReplayPlayer? currentPlayer; @@ -101,7 +101,7 @@ namespace osu.Game.Rulesets.Osu.Tests AddUntilStep("Wait for completion", () => currentPlayer?.ScoreProcessor.HasCompleted.Value == true); } - private class ScoreAccessibleReplayPlayer : ReplayPlayer + private partial class ScoreAccessibleReplayPlayer : ReplayPlayer { public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderHidden.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderHidden.cs index f70bdf8aa2..eb13995ad0 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderHidden.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderHidden.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Osu.Mods; namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] - public class TestSceneSliderHidden : TestSceneSlider + public partial class TestSceneSliderHidden : TestSceneSlider { [SetUp] public void SetUp() => Schedule(() => diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index e3cf5e9b05..5f27cdc191 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -24,7 +24,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneSliderInput : RateAdjustedBeatmapTestScene + public partial class TestSceneSliderInput : RateAdjustedBeatmapTestScene { private const double time_before_slider = 250; private const double time_slider_start = 1500; @@ -384,7 +384,7 @@ namespace osu.Game.Rulesets.Osu.Tests AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } - private class ScoreAccessibleReplayPlayer : ReplayPlayer + private partial class ScoreAccessibleReplayPlayer : ReplayPlayer { public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs index 0118ed6513..630049f408 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderSnaking.cs @@ -30,7 +30,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] - public class TestSceneSliderSnaking : TestSceneOsuPlayer + public partial class TestSceneSliderSnaking : TestSceneOsuPlayer { [Resolved] private AudioManager audioManager { get; set; } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSmoke.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSmoke.cs index 1cb64b71fc..d5d3cbb146 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSmoke.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSmoke.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneSmoke : OsuSkinnableTestScene + public partial class TestSceneSmoke : OsuSkinnableTestScene { [Test] public void TestSmoking() @@ -66,7 +66,7 @@ namespace osu.Game.Rulesets.Osu.Tests }); } - private class SmokingInputManager : ManualInputManager + private partial class SmokingInputManager : ManualInputManager { public double Duration { get; init; } @@ -102,7 +102,7 @@ namespace osu.Game.Rulesets.Osu.Tests } } - private class TestSmokeContainer : SmokeContainer + private partial class TestSmokeContainer : SmokeContainer { public double Duration { get; init; } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs index 8dc8f82b86..74d0fb42a3 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] - public class TestSceneSpinner : OsuSkinnableTestScene + public partial class TestSceneSpinner : OsuSkinnableTestScene { private int depthIndex; @@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.Osu.Tests return drawableSpinner; } - private class TestDrawableSpinner : DrawableSpinner + private partial class TestDrawableSpinner : DrawableSpinner { private readonly bool auto; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerApplication.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerApplication.cs index 14fa77245a..1ae17432be 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerApplication.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerApplication.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneSpinnerApplication : OsuTestScene + public partial class TestSceneSpinnerApplication : OsuTestScene { [Test] public void TestApplyNewSpinner() diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerHidden.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerHidden.cs index b7bc36722a..1aaba23e56 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerHidden.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerHidden.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Osu.Mods; namespace osu.Game.Rulesets.Osu.Tests { [TestFixture] - public class TestSceneSpinnerHidden : TestSceneSpinner + public partial class TestSceneSpinnerHidden : TestSceneSpinner { [SetUp] public void SetUp() => Schedule(() => diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs index 13ea46eadf..116c974f32 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs @@ -26,7 +26,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneSpinnerRotation : TestSceneOsuPlayer + public partial class TestSceneSpinnerRotation : TestSceneOsuPlayer { private const double spinner_start_time = 100; private const double spinner_duration = 6000; @@ -221,7 +221,7 @@ namespace osu.Game.Rulesets.Osu.Tests } }; - private class ScoreExposedPlayer : TestPlayer + private partial class ScoreExposedPlayer : TestPlayer { public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs index 96b26403e1..29e6fc4301 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs @@ -27,7 +27,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneStartTimeOrderedHitPolicy : RateAdjustedBeatmapTestScene + public partial class TestSceneStartTimeOrderedHitPolicy : RateAdjustedBeatmapTestScene { private const double early_miss_window = 1000; // time after -1000 to -500 is considered a miss private const double late_miss_window = 500; // time after +500 is considered a miss @@ -434,7 +434,7 @@ namespace osu.Game.Rulesets.Osu.Tests protected override DifficultyRange[] GetRanges() => ranges; } - private class ScoreAccessibleReplayPlayer : ReplayPlayer + private partial class ScoreAccessibleReplayPlayer : ReplayPlayer { public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneTrianglesSpinnerRotation.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneTrianglesSpinnerRotation.cs index 80e3af6cc0..1fef408088 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneTrianglesSpinnerRotation.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneTrianglesSpinnerRotation.cs @@ -28,7 +28,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneTrianglesSpinnerRotation : TestSceneOsuPlayer + public partial class TestSceneTrianglesSpinnerRotation : TestSceneOsuPlayer { private const double spinner_start_time = 100; private const double spinner_duration = 6000; @@ -136,7 +136,7 @@ namespace osu.Game.Rulesets.Osu.Tests } }; - private class ScoreExposedPlayer : TestPlayer + private partial class ScoreExposedPlayer : TestPlayer { public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/BlueprintPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/BlueprintPiece.cs index 55b7efc8af..41ab5a81b8 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/BlueprintPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/BlueprintPiece.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints /// A piece of a selection or placement blueprint which visualises an . /// /// The type of which this visualises. - public abstract class BlueprintPiece : CompositeDrawable + public abstract partial class BlueprintPiece : CompositeDrawable where T : OsuHitObject { /// diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs index f16b6c138e..e5cc8595d1 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components { - public class HitCircleOverlapMarker : BlueprintPiece + public partial class HitCircleOverlapMarker : BlueprintPiece { /// /// Hit objects are intentionally made to fade out at a constant slower rate than in gameplay. diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCirclePiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCirclePiece.cs index 984fbb83a8..1fed19da03 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCirclePiece.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components { - public class HitCirclePiece : BlueprintPiece + public partial class HitCirclePiece : BlueprintPiece { public HitCirclePiece() { diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCirclePlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCirclePlacementBlueprint.cs index ff4f61986f..26d18c7a17 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCirclePlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCirclePlacementBlueprint.cs @@ -11,7 +11,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles { - public class HitCirclePlacementBlueprint : PlacementBlueprint + public partial class HitCirclePlacementBlueprint : PlacementBlueprint { public new HitCircle HitObject => (HitCircle)base.HitObject; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCircleSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCircleSelectionBlueprint.cs index 73756d9326..1b3e7f3a8f 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCircleSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCircleSelectionBlueprint.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles { - public class HitCircleSelectionBlueprint : OsuSelectionBlueprint + public partial class HitCircleSelectionBlueprint : OsuSelectionBlueprint { protected new DrawableHitCircle DrawableObject => (DrawableHitCircle)base.DrawableObject; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs index 11527c9537..3e161089cd 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs @@ -13,7 +13,7 @@ using osu.Game.Screens.Edit; namespace osu.Game.Rulesets.Osu.Edit.Blueprints { - public abstract class OsuSelectionBlueprint : HitObjectSelectionBlueprint + public abstract partial class OsuSelectionBlueprint : HitObjectSelectionBlueprint where T : OsuHitObject { [Resolved] diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointConnectionPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointConnectionPiece.cs index 0b9ccc5c37..28e0d650c4 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointConnectionPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointConnectionPiece.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components /// /// A visualisation of the line between two s. /// - public class PathControlPointConnectionPiece : CompositeDrawable + public partial class PathControlPointConnectionPiece : CompositeDrawable { public readonly PathControlPoint ControlPoint; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs index 5dec5d1cb0..d83f35d13f 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components /// /// A visualisation of a single in a . /// - public class PathControlPointPiece : BlueprintPiece, IHasTooltip + public partial class PathControlPointPiece : BlueprintPiece, IHasTooltip { public Action RequestSelection; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index c7e3516d62..3a175888d9 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -29,7 +29,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { - public class PathControlPointVisualiser : CompositeDrawable, IKeyBindingHandler, IHasContextMenu + public partial class PathControlPointVisualiser : CompositeDrawable, IKeyBindingHandler, IHasContextMenu { public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; // allow context menu to appear outside of the playfield. diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs index da2a6ced67..ecd840dda6 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs @@ -13,7 +13,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { - public class SliderBodyPiece : BlueprintPiece + public partial class SliderBodyPiece : BlueprintPiece { private readonly ManualSliderBody body; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderCircleOverlay.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderCircleOverlay.cs index d48d43d532..3341a632c1 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderCircleOverlay.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderCircleOverlay.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Osu.Objects; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders { - public class SliderCircleOverlay : CompositeDrawable + public partial class SliderCircleOverlay : CompositeDrawable { protected readonly HitCirclePiece CirclePiece; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs index dd5335a743..f91d35e2e1 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs @@ -23,7 +23,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders { - public class SliderPlacementBlueprint : PlacementBlueprint + public partial class SliderPlacementBlueprint : PlacementBlueprint { public new Slider HitObject => (Slider)base.HitObject; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 3718f0c6bc..a51c223785 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -29,7 +29,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders { - public class SliderSelectionBlueprint : OsuSelectionBlueprint + public partial class SliderSelectionBlueprint : OsuSelectionBlueprint { protected new DrawableSlider DrawableObject => (DrawableSlider)base.DrawableObject; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs index b5a13a22ce..cc58acdc80 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/Components/SpinnerPiece.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners.Components { - public class SpinnerPiece : BlueprintPiece + public partial class SpinnerPiece : BlueprintPiece { private readonly Circle circle; private readonly Circle ring; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs index 97d53d8e95..e412c47c09 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs @@ -14,7 +14,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners { - public class SpinnerPlacementBlueprint : PlacementBlueprint + public partial class SpinnerPlacementBlueprint : PlacementBlueprint { public new Spinner HitObject => (Spinner)base.HitObject; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerSelectionBlueprint.cs index 5240c0bfeb..a80ec68c10 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerSelectionBlueprint.cs @@ -9,7 +9,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners { - public class SpinnerSelectionBlueprint : OsuSelectionBlueprint + public partial class SpinnerSelectionBlueprint : OsuSelectionBlueprint { private readonly SpinnerPiece piece; diff --git a/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditorRuleset.cs b/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditorRuleset.cs index a5f7707cb3..14e7b93f3a 100644 --- a/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditorRuleset.cs +++ b/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditorRuleset.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Edit { - public class DrawableOsuEditorRuleset : DrawableOsuRuleset + public partial class DrawableOsuEditorRuleset : DrawableOsuRuleset { public DrawableOsuEditorRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods) : base(ruleset, beatmap, mods) @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Edit public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new OsuPlayfieldAdjustmentContainer { Size = Vector2.One }; - private class OsuEditorPlayfield : OsuPlayfield + private partial class OsuEditorPlayfield : OsuPlayfield { protected override GameplayCursorContainer CreateCursor() => null; diff --git a/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs index c0fb0ae7db..173a664902 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs @@ -13,7 +13,7 @@ using osu.Game.Screens.Edit.Compose.Components; namespace osu.Game.Rulesets.Osu.Edit { - public class OsuBlueprintContainer : ComposeBlueprintContainer + public partial class OsuBlueprintContainer : ComposeBlueprintContainer { public OsuBlueprintContainer(HitObjectComposer composer) : base(composer) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuDistanceSnapGrid.cs b/osu.Game.Rulesets.Osu/Edit/OsuDistanceSnapGrid.cs index 23bf67ff29..848c994974 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuDistanceSnapGrid.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuDistanceSnapGrid.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Edit.Compose.Components; namespace osu.Game.Rulesets.Osu.Edit { - public class OsuDistanceSnapGrid : CircularDistanceSnapGrid + public partial class OsuDistanceSnapGrid : CircularDistanceSnapGrid { public OsuDistanceSnapGrid(OsuHitObject hitObject, [CanBeNull] OsuHitObject nextHitObject = null) : base(hitObject, hitObject.StackedEndPosition, hitObject.GetEndTime(), nextHitObject?.StartTime - 1) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 1460fae4d7..09ddc420a7 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -30,7 +30,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Edit { - public class OsuHitObjectComposer : DistancedHitObjectComposer + public partial class OsuHitObjectComposer : DistancedHitObjectComposer { public OsuHitObjectComposer(Ruleset ruleset) : base(ruleset) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuRectangularPositionSnapGrid.cs b/osu.Game.Rulesets.Osu/Edit/OsuRectangularPositionSnapGrid.cs index 35dad1a4fb..3234b03a3e 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuRectangularPositionSnapGrid.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuRectangularPositionSnapGrid.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Edit { - public class OsuRectangularPositionSnapGrid : RectangularPositionSnapGrid, IKeyBindingHandler + public partial class OsuRectangularPositionSnapGrid : RectangularPositionSnapGrid, IKeyBindingHandler { private static readonly int[] grid_sizes = { 4, 8, 16, 32 }; diff --git a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs index eddc1390f0..6d5280e528 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs @@ -22,7 +22,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Edit { - public class OsuSelectionHandler : EditorSelectionHandler + public partial class OsuSelectionHandler : EditorSelectionHandler { [Resolved(CanBeNull = true)] private IDistanceSnapProvider? snapProvider { get; set; } diff --git a/osu.Game.Rulesets.Osu/Edit/Setup/OsuSetupSection.cs b/osu.Game.Rulesets.Osu/Edit/Setup/OsuSetupSection.cs index 2889832ff1..ac567559b8 100644 --- a/osu.Game.Rulesets.Osu/Edit/Setup/OsuSetupSection.cs +++ b/osu.Game.Rulesets.Osu/Edit/Setup/OsuSetupSection.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Edit.Setup; namespace osu.Game.Rulesets.Osu.Edit.Setup { - public class OsuSetupSection : RulesetSetupSection + public partial class OsuSetupSection : RulesetSetupSection { private LabelledSliderBar stackLeniency; diff --git a/osu.Game.Rulesets.Osu/Mods/InputBlockingMod.cs b/osu.Game.Rulesets.Osu/Mods/InputBlockingMod.cs index e4e8905722..7db4e2625b 100644 --- a/osu.Game.Rulesets.Osu/Mods/InputBlockingMod.cs +++ b/osu.Game.Rulesets.Osu/Mods/InputBlockingMod.cs @@ -18,7 +18,7 @@ using osu.Game.Utils; namespace osu.Game.Rulesets.Osu.Mods { - public abstract class InputBlockingMod : Mod, IApplicableToDrawableRuleset, IUpdatableByPlayfield + public abstract partial class InputBlockingMod : Mod, IApplicableToDrawableRuleset, IUpdatableByPlayfield { public override double ScoreMultiplier => 1.0; public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(ModRelax), typeof(OsuModCinema) }; @@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.Mods return false; } - private class InputInterceptor : Component, IKeyBindingHandler + private partial class InputInterceptor : Component, IKeyBindingHandler { private readonly InputBlockingMod mod; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs index 4c72667f15..2e2d320313 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModBlinds : Mod, IApplicableToDrawableRuleset, IApplicableToHealthProcessor + public partial class OsuModBlinds : Mod, IApplicableToDrawableRuleset, IApplicableToHealthProcessor { public override string Name => "Blinds"; public override LocalisableString Description => "Play with blinds on your screen."; @@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Osu.Mods /// /// Element for the Blinds mod drawing 2 black boxes covering the whole screen which resize inside a restricted area with some leniency. /// - public class DrawableOsuBlinds : Container + public partial class DrawableOsuBlinds : Container { /// /// Black background boxes behind blind panel textures. @@ -204,7 +204,7 @@ namespace osu.Game.Rulesets.Osu.Mods /// public void AnimateClosedness(float value) => this.TransformTo(nameof(easing), value, 200, Easing.OutQuint); - public class ModBlindsPanel : Sprite + public partial class ModBlindsPanel : Sprite { [BackgroundDependencyLoader] private void load(TextureStore textures) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs index 1a86901d9c..efeac9a180 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModFlashlight : ModFlashlight, IApplicableToDrawableHitObject + public partial class OsuModFlashlight : ModFlashlight, IApplicableToDrawableHitObject { public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.12 : 1; public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModBlinds)).ToArray(); @@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Osu.Mods s.Tracking.ValueChanged += flashlight.OnSliderTrackingChange; } - private class OsuFlashlight : Flashlight, IRequireHighFrequencyMousePosition + private partial class OsuFlashlight : Flashlight, IRequireHighFrequencyMousePosition { private readonly double followDelay; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs b/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs index af37f1e2e5..7e4ffc7408 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs @@ -19,7 +19,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModStrictTracking : Mod, IApplicableAfterBeatmapConversion, IApplicableToDrawableHitObject, IApplicableToDrawableRuleset + public partial class OsuModStrictTracking : Mod, IApplicableAfterBeatmapConversion, IApplicableToDrawableHitObject, IApplicableToDrawableRuleset { public override string Name => @"Strict Tracking"; public override string Acronym => @"ST"; @@ -79,7 +79,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override Judgement CreateJudgement() => new OsuJudgement(); } - private class StrictTrackingDrawableSliderTail : DrawableSliderTail + private partial class StrictTrackingDrawableSliderTail : DrawableSliderTail { public override bool DisplayResult => true; } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs index 8c95da9be1..d588127cb9 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections /// /// A single follow point positioned between two adjacent s. /// - public class FollowPoint : PoolableDrawable, IAnimationTimeReference + public partial class FollowPoint : PoolableDrawable, IAnimationTimeReference { private const float width = 8; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs index 1a9d12e860..20c36b7804 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections /// /// Visualises the s between two s. /// - public class FollowPointConnection : PoolableDrawableWithLifetime + public partial class FollowPointConnection : PoolableDrawableWithLifetime { // Todo: These shouldn't be constants public const int SPACING = 32; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs index 306b034645..144eaffe82 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections /// /// Visualises connections between s. /// - public class FollowPointRenderer : PooledDrawableWithLifetimeContainer + public partial class FollowPointRenderer : PooledDrawableWithLifetimeContainer { public new IReadOnlyList Entries => lifetimeEntries; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index 6201199cc3..3458069dd1 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -24,7 +24,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableHitCircle : DrawableOsuHitObject, IHasApproachCircle + public partial class DrawableHitCircle : DrawableOsuHitObject, IHasApproachCircle { public OsuAction? HitAction => HitArea.HitAction; protected virtual OsuSkinComponents CirclePieceComponent => OsuSkinComponents.HitCircle; @@ -231,7 +231,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override JudgementResult CreateResult(Judgement judgement) => new OsuHitCircleJudgementResult(HitObject, judgement); - public class HitReceptor : CompositeDrawable, IKeyBindingHandler + public partial class HitReceptor : CompositeDrawable, IKeyBindingHandler { // IsHovered is used public override bool HandlePositionalInput => true; @@ -274,7 +274,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } } - private class ProxyableSkinnableDrawable : SkinnableDrawable + private partial class ProxyableSkinnableDrawable : SkinnableDrawable { public override bool RemoveWhenNotAlive => false; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index d9d0d28477..df0ba344d8 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public abstract class DrawableOsuHitObject : DrawableHitObject + public abstract partial class DrawableOsuHitObject : DrawableHitObject { public readonly IBindable PositionBindable = new Bindable(); public readonly IBindable StackHeightBindable = new Bindable(); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs index b4abdde911..b4004ff572 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableOsuJudgement : DrawableJudgement + public partial class DrawableOsuJudgement : DrawableJudgement { protected SkinnableLighting Lighting { get; private set; } @@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override Drawable CreateDefaultJudgement(HitResult result) => new OsuJudgementPiece(result); - private class OsuJudgementPiece : DefaultJudgementPiece + private partial class OsuJudgementPiece : DefaultJudgementPiece { public OsuJudgementPiece(HitResult result) : base(result) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index a4745b365b..4601af45d8 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableSlider : DrawableOsuHitObject + public partial class DrawableSlider : DrawableOsuHitObject { public new Slider HitObject => (Slider)base.HitObject; @@ -327,7 +327,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => SliderBody?.ReceivePositionalInputAt(screenSpacePos) ?? base.ReceivePositionalInputAt(screenSpacePos); - private class DefaultSliderBody : PlaySliderBody + private partial class DefaultSliderBody : PlaySliderBody { } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs index 35d5c1f478..e1766adc20 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableSliderBall : CircularContainer, ISliderProgress, IRequireHighFrequencyMousePosition + public partial class DrawableSliderBall : CircularContainer, ISliderProgress, IRequireHighFrequencyMousePosition { public const float FOLLOW_AREA = 2.4f; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs index d1d749d7e2..b8a1efabe0 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableSliderHead : DrawableHitCircle + public partial class DrawableSliderHead : DrawableHitCircle { public new SliderHeadCircle HitObject => (SliderHeadCircle)base.HitObject; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs index 08602e168c..3446d41fb4 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableSliderRepeat : DrawableOsuHitObject, ITrackSnaking + public partial class DrawableSliderRepeat : DrawableOsuHitObject, ITrackSnaking { public new SliderRepeat HitObject => (SliderRepeat)base.HitObject; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs index a59cd92d62..2c1b68e05a 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableSliderTail : DrawableOsuHitObject, IRequireTracking + public partial class DrawableSliderTail : DrawableOsuHitObject, IRequireTracking { public new SliderTailCircle HitObject => (SliderTailCircle)base.HitObject; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index 563c7e85aa..6d0ae93e62 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -14,7 +14,7 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableSliderTick : DrawableOsuHitObject, IRequireTracking + public partial class DrawableSliderTick : DrawableOsuHitObject, IRequireTracking { public const double ANIM_DURATION = 150; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 83a9408570..eed5c3e2e3 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -24,7 +24,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableSpinner : DrawableOsuHitObject + public partial class DrawableSpinner : DrawableOsuHitObject { public new Spinner HitObject => (Spinner)base.HitObject; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinnerBonusTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinnerBonusTick.cs index 841f74b751..f1f4ec983e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinnerBonusTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinnerBonusTick.cs @@ -5,7 +5,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableSpinnerBonusTick : DrawableSpinnerTick + public partial class DrawableSpinnerBonusTick : DrawableSpinnerTick { public DrawableSpinnerBonusTick() : base(null) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinnerTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinnerTick.cs index 4975ca1248..b9ce07363c 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinnerTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinnerTick.cs @@ -7,7 +7,7 @@ using osu.Framework.Graphics; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class DrawableSpinnerTick : DrawableOsuHitObject + public partial class DrawableSpinnerTick : DrawableOsuHitObject { public override bool DisplayResult => false; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/SkinnableLighting.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/SkinnableLighting.cs index 4af4767a3e..68b61f9b2b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/SkinnableLighting.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/SkinnableLighting.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Objects.Drawables { - public class SkinnableLighting : SkinnableSprite + public partial class SkinnableLighting : SkinnableSprite { private DrawableHitObject targetObject; private JudgementResult targetResult; diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index 1e59e19246..7dede9e283 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -15,7 +15,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu { - public class OsuInputManager : RulesetInputManager + public partial class OsuInputManager : RulesetInputManager { public IEnumerable PressedActions => KeyBindingContainer.PressedActions; @@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Osu return base.HandleMouseTouchStateChange(e); } - private class OsuKeyBindingContainer : RulesetKeyBindingContainer + private partial class OsuKeyBindingContainer : RulesetKeyBindingContainer { private bool allowGameplayInputs = true; diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 34a1bd40e9..50d4eb6258 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Osu.Scoring { - public class OsuScoreProcessor : ScoreProcessor + public partial class OsuScoreProcessor : ScoreProcessor { public OsuScoreProcessor() : base(new OsuRuleset()) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonCursor.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonCursor.cs index 446f3c83ae..4ca6abfdf7 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonCursor.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonCursor.cs @@ -13,7 +13,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Argon { - public class ArgonCursor : OsuCursorSprite + public partial class ArgonCursor : OsuCursorSprite { public ArgonCursor() { diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonCursorTrail.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonCursorTrail.cs index 9bb3122a3b..28991b4a62 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonCursorTrail.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonCursorTrail.cs @@ -9,7 +9,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Skinning.Argon { - public class ArgonCursorTrail : CursorTrail + public partial class ArgonCursorTrail : CursorTrail { protected override float IntervalMultiplier => 0.4f; diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonFollowCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonFollowCircle.cs index 83c5f6295a..95c75164aa 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonFollowCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonFollowCircle.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Skinning.Argon { - public class ArgonFollowCircle : FollowCircle + public partial class ArgonFollowCircle : FollowCircle { public ArgonFollowCircle() { diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonFollowPoint.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonFollowPoint.cs index 47dae3c30a..2f44264040 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonFollowPoint.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonFollowPoint.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Skinning.Argon { - public class ArgonFollowPoint : CompositeDrawable + public partial class ArgonFollowPoint : CompositeDrawable { public ArgonFollowPoint() { diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPiece.cs index bb68c7298f..f5f410210b 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPiece.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Skinning.Argon { - public class ArgonJudgementPiece : CompositeDrawable, IAnimatableJudgement + public partial class ArgonJudgementPiece : CompositeDrawable, IAnimatableJudgement { protected readonly HitResult Result; @@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon public Drawable? GetAboveHitObjectsProxiedContent() => JudgementText.CreateProxy(); - private class RingExplosion : CompositeDrawable + private partial class RingExplosion : CompositeDrawable { private readonly float travel = 52; diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs index 4ac71e4225..db458ec48a 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs @@ -21,7 +21,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Argon { - public class ArgonMainCirclePiece : CompositeDrawable + public partial class ArgonMainCirclePiece : CompositeDrawable { public const float BORDER_THICKNESS = (OsuHitObject.OBJECT_RADIUS * 2) * (2f / 58); @@ -198,7 +198,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon drawableObject.ApplyCustomUpdateState -= updateStateTransforms; } - private class FlashPiece : Circle + private partial class FlashPiece : Circle { public FlashPiece() { diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonReverseArrow.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonReverseArrow.cs index 9d44db3614..f93e26b2ca 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonReverseArrow.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonReverseArrow.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Argon { - public class ArgonReverseArrow : CompositeDrawable + public partial class ArgonReverseArrow : CompositeDrawable { private Bindable accentColour = null!; diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderBall.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderBall.cs index 3df9edd225..48b43f359d 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderBall.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderBall.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Argon { - public class ArgonSliderBall : CircularContainer + public partial class ArgonSliderBall : CircularContainer { private readonly Box fill; private readonly SpriteIcon icon; diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderBody.cs index e1642d126d..c3d08116ac 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderBody.cs @@ -7,7 +7,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Argon { - public class ArgonSliderBody : PlaySliderBody + public partial class ArgonSliderBody : PlaySliderBody { protected override void LoadComplete() { @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon protected override Default.DrawableSliderPath CreateSliderPath() => new DrawableSliderPath(); - private class DrawableSliderPath : Default.DrawableSliderPath + private partial class DrawableSliderPath : Default.DrawableSliderPath { protected override Color4 ColourAt(float position) { diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderScorePoint.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderScorePoint.cs index 4c6b9a2f17..7479c2aced 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderScorePoint.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderScorePoint.cs @@ -12,7 +12,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Argon { - public class ArgonSliderScorePoint : CircularContainer + public partial class ArgonSliderScorePoint : CircularContainer { private Bindable accentColour = null!; diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinner.cs index 95438e9588..d5a9cf46c5 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinner.cs @@ -15,7 +15,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Skinning.Argon { - public class ArgonSpinner : CompositeDrawable + public partial class ArgonSpinner : CompositeDrawable { private DrawableSpinner drawableSpinner = null!; diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs index f99d4275bd..bdc93eb63f 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Skinning.Argon { - public class ArgonSpinnerDisc : CompositeDrawable + public partial class ArgonSpinnerDisc : CompositeDrawable { private const float initial_scale = 1f; private const float idle_alpha = 0.2f; diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs index e998f55755..31cdc0dc0f 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Argon { - public class ArgonSpinnerProgressArc : CompositeDrawable + public partial class ArgonSpinnerProgressArc : CompositeDrawable { private const float arc_fill = 0.15f; private const float arc_radius = 0.12f; diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs index 57fb57a09e..702c5c2675 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Skinning.Argon { - public class ArgonSpinnerRingArc : CompositeDrawable + public partial class ArgonSpinnerRingArc : CompositeDrawable { private const float arc_fill = 0.31f; private const float arc_fill_complete = 0.50f; diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerTicks.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerTicks.cs index 0203432088..4f0e1256d4 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerTicks.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerTicks.cs @@ -12,7 +12,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Argon { - public class ArgonSpinnerTicks : CompositeDrawable + public partial class ArgonSpinnerTicks : CompositeDrawable { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/CirclePiece.cs index 4a679cda2c..f4761e0ea8 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/CirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/CirclePiece.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class CirclePiece : CompositeDrawable + public partial class CirclePiece : CompositeDrawable { [Resolved] private DrawableHitObject drawableObject { get; set; } = null!; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs index 3a67ad526e..b65f46c414 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs @@ -11,7 +11,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class DefaultApproachCircle : SkinnableSprite + public partial class DefaultApproachCircle : SkinnableSprite { private readonly IBindable accentColour = new Bindable(); diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultFollowCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultFollowCircle.cs index aaace89cd5..3c41d473f4 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultFollowCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultFollowCircle.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class DefaultFollowCircle : FollowCircle + public partial class DefaultFollowCircle : FollowCircle { public DefaultFollowCircle() { diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSliderBall.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSliderBall.cs index 97bb4a3697..c911943bfb 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSliderBall.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSliderBall.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class DefaultSliderBall : CompositeDrawable + public partial class DefaultSliderBall : CompositeDrawable { private Box box = null!; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSmokeSegment.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSmokeSegment.cs index 27a2dc3960..47c4bcc52c 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSmokeSegment.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSmokeSegment.cs @@ -6,7 +6,7 @@ using osu.Framework.Graphics.Textures; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class DefaultSmokeSegment : SmokeSegment + public partial class DefaultSmokeSegment : SmokeSegment { [BackgroundDependencyLoader] private void load(TextureStore textures) diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinner.cs index a975030630..071fbe6add 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinner.cs @@ -15,7 +15,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class DefaultSpinner : CompositeDrawable + public partial class DefaultSpinner : CompositeDrawable { private DrawableSpinner drawableSpinner = null!; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinnerDisc.cs index b58daf7174..75f3247448 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinnerDisc.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinnerDisc.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class DefaultSpinnerDisc : CompositeDrawable + public partial class DefaultSpinnerDisc : CompositeDrawable { private DrawableSpinner drawableSpinner = null!; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DrawableSliderPath.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DrawableSliderPath.cs index 883524f334..6f41d33c3d 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/DrawableSliderPath.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DrawableSliderPath.cs @@ -6,7 +6,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public abstract class DrawableSliderPath : SmoothPath + public abstract partial class DrawableSliderPath : SmoothPath { public const float BORDER_PORTION = 0.128f; public const float GRADIENT_PORTION = 1 - BORDER_PORTION; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/ExplodePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/ExplodePiece.cs index f8010a9971..91bf75617a 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/ExplodePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/ExplodePiece.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class ExplodePiece : Container + public partial class ExplodePiece : Container { [Resolved] private DrawableHitObject drawableObject { get; set; } = null!; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/FlashPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/FlashPiece.cs index 06ee64d8b3..789137117e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/FlashPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/FlashPiece.cs @@ -9,7 +9,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class FlashPiece : Container + public partial class FlashPiece : Container { public FlashPiece() { diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/GlowPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/GlowPiece.cs index f5e01b802e..65cbdc3d2f 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/GlowPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/GlowPiece.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics.Textures; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class GlowPiece : Container + public partial class GlowPiece : Container { public GlowPiece() { diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/KiaiFlash.cs b/osu.Game.Rulesets.Osu/Skinning/Default/KiaiFlash.cs index 506f679836..11c2fd97e8 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/KiaiFlash.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/KiaiFlash.cs @@ -11,7 +11,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class KiaiFlash : BeatSyncedContainer + public partial class KiaiFlash : BeatSyncedContainer { private const double fade_length = 80; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs index 6d56d21349..20fa4e5342 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class MainCirclePiece : CompositeDrawable + public partial class MainCirclePiece : CompositeDrawable { private readonly CirclePiece circle; private readonly RingPiece ring; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/ManualSliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/Default/ManualSliderBody.cs index d73c94eb9b..d171f56f40 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/ManualSliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/ManualSliderBody.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default /// /// A with the ability to set the drawn vertices manually. /// - public class ManualSliderBody : SliderBody + public partial class ManualSliderBody : SliderBody { public new void SetVertices(IReadOnlyList vertices) { diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs index 60cfecfb5a..eb49b7b852 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs @@ -12,7 +12,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class NumberPiece : Container + public partial class NumberPiece : Container { private readonly SkinnableSpriteText number; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/PlaySliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/Default/PlaySliderBody.cs index 96af59abe2..539777dd6b 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/PlaySliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/PlaySliderBody.cs @@ -12,7 +12,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public abstract class PlaySliderBody : SnakingSliderBody + public abstract partial class PlaySliderBody : SnakingSliderBody { protected IBindable ScaleBindable { get; private set; } = null!; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs index 222e8d4348..3fe7872ff7 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class ReverseArrowPiece : BeatSyncedContainer + public partial class ReverseArrowPiece : BeatSyncedContainer { [Resolved] private DrawableHitObject drawableRepeat { get; set; } = null!; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/RingPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/RingPiece.cs index e813a7e274..46d48f62e7 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/RingPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/RingPiece.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class RingPiece : CircularContainer + public partial class RingPiece : CircularContainer { public RingPiece(float thickness = 9) { diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs index a1184a15cd..039c4825fa 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs @@ -6,7 +6,7 @@ using osu.Framework.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class SpinnerBackgroundLayer : SpinnerFill + public partial class SpinnerBackgroundLayer : SpinnerFill { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerCentreLayer.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerCentreLayer.cs index 3dd5aed6ae..f5c90bafbf 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerCentreLayer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerCentreLayer.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class SpinnerCentreLayer : CompositeDrawable, IHasAccentColour + public partial class SpinnerCentreLayer : CompositeDrawable, IHasAccentColour { private DrawableSpinner spinner = null!; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerFill.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerFill.cs index f574ae589e..93f93b8521 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerFill.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerFill.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class SpinnerFill : CircularContainer, IHasAccentColour + public partial class SpinnerFill : CircularContainer, IHasAccentColour { public readonly Box Disc; diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerRotationTracker.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerRotationTracker.cs index 3a9f73404d..bf06f513b7 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerRotationTracker.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerRotationTracker.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class SpinnerRotationTracker : CircularContainer + public partial class SpinnerRotationTracker : CircularContainer { public override bool IsPresent => true; // handle input when hidden diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs index 9feaa0966a..0bd5fd4cac 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class SpinnerSpmCalculator : Component + public partial class SpinnerSpmCalculator : Component { private readonly Queue records = new Queue(); private const double spm_count_duration = 595; // not using hundreds to avoid frame rounding issues diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerTicks.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerTicks.cs index e518ae1da8..f5f8d456f3 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerTicks.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerTicks.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class SpinnerTicks : Container, IHasAccentColour + public partial class SpinnerTicks : Container, IHasAccentColour { public SpinnerTicks() { diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs index fa23c60d57..f1143cf14d 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs @@ -5,7 +5,7 @@ using osu.Game.Graphics.Backgrounds; namespace osu.Game.Rulesets.Osu.Skinning.Default { - public class TrianglesPiece : Triangles + public partial class TrianglesPiece : Triangles { protected override bool CreateNewTriangles => false; protected override float SpawnRatio => 0.5f; diff --git a/osu.Game.Rulesets.Osu/Skinning/FollowCircle.cs b/osu.Game.Rulesets.Osu/Skinning/FollowCircle.cs index 9eb8e66c83..355d3f9a2f 100644 --- a/osu.Game.Rulesets.Osu/Skinning/FollowCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/FollowCircle.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Skinning { - public abstract class FollowCircle : CompositeDrawable + public abstract partial class FollowCircle : CompositeDrawable { [Resolved] protected DrawableHitObject? ParentObject { get; private set; } diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs index 4dd4f9562a..e9342bbdbb 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs @@ -11,7 +11,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Legacy { - public class LegacyApproachCircle : SkinnableSprite + public partial class LegacyApproachCircle : SkinnableSprite { private readonly IBindable accentColour = new Bindable(); diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs index b2ffc171be..b0c01d2925 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs @@ -9,7 +9,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Skinning.Legacy { - public class LegacyCursor : OsuCursorSprite + public partial class LegacyCursor : OsuCursorSprite { private readonly ISkin skin; private bool spin; diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs index a28b480753..e022e5534d 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs @@ -23,7 +23,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Legacy { - public class LegacyCursorParticles : CompositeDrawable, IKeyBindingHandler + public partial class LegacyCursorParticles : CompositeDrawable, IKeyBindingHandler { public bool Active => breakSpewer.Active.Value || kiaiSpewer.Active.Value; @@ -140,7 +140,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy breakSpewer.Direction = SpewDirection.None; } - private class LegacyCursorParticleSpewer : ParticleSpewer, IRequireHighFrequencyMousePosition + private partial class LegacyCursorParticleSpewer : ParticleSpewer, IRequireHighFrequencyMousePosition { private const int particle_duration_min = 300; private const int particle_duration_max = 1000; diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs index 9a59fd73b2..af71e2a5d9 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Skinning.Legacy { - public class LegacyCursorTrail : CursorTrail + public partial class LegacyCursorTrail : CursorTrail { private readonly ISkin skin; private const double disjoint_trail_time_separation = 1000 / 60.0; diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyFollowCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyFollowCircle.cs index 0d12fb01f5..f8dcb9e8a2 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyFollowCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyFollowCircle.cs @@ -7,7 +7,7 @@ using osu.Framework.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Legacy { - public class LegacyFollowCircle : FollowCircle + public partial class LegacyFollowCircle : FollowCircle { public LegacyFollowCircle(Drawable animationContent) { diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs index e155c1b816..6547b058c2 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Legacy { - public class LegacyMainCirclePiece : CompositeDrawable + public partial class LegacyMainCirclePiece : CompositeDrawable { public override bool RemoveCompletedTransforms => false; diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyNewStyleSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyNewStyleSpinner.cs index f950d3e43e..67a6d5e41a 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyNewStyleSpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyNewStyleSpinner.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy /// Legacy skinned spinner with two main spinning layers, one fixed overlay and one final spinning overlay. /// No background layer. /// - public class LegacyNewStyleSpinner : LegacySpinner + public partial class LegacyNewStyleSpinner : LegacySpinner { private Sprite glow = null!; private Sprite discBottom = null!; diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs index e5efb668bc..c57487cf75 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy /// /// Legacy skinned spinner with one main spinning layer and a background layer. /// - public class LegacyOldStyleSpinner : LegacySpinner + public partial class LegacyOldStyleSpinner : LegacySpinner { private Sprite disc = null!; private Sprite metreSprite = null!; diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs index 773cc7ae3c..fbe094ef81 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs @@ -11,7 +11,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu.Skinning.Legacy { - public class LegacyReverseArrow : CompositeDrawable + public partial class LegacyReverseArrow : CompositeDrawable { [Resolved(canBeNull: true)] private DrawableHitObject? drawableHitObject { get; set; } diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBall.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBall.cs index 60d71ae843..2aa843581e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBall.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBall.cs @@ -13,7 +13,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Legacy { - public class LegacySliderBall : CompositeDrawable + public partial class LegacySliderBall : CompositeDrawable { private readonly Drawable animationContent; diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBody.cs index 29a0745193..b39092a467 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBody.cs @@ -11,7 +11,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Legacy { - public class LegacySliderBody : PlaySliderBody + public partial class LegacySliderBody : PlaySliderBody { protected override DrawableSliderPath CreateSliderPath() => new LegacyDrawableSliderPath(); @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy return base.GetBodyAccentColour(skin, hitObjectAccentColour).Opacity(0.7f); } - private class LegacyDrawableSliderPath : DrawableSliderPath + private partial class LegacyDrawableSliderPath : DrawableSliderPath { private const float shadow_portion = 1 - (OsuLegacySkinTransformer.LEGACY_CIRCLE_RADIUS / OsuHitObject.OBJECT_RADIUS); diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs index 08b579697c..bc69e66fb3 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Skinning.Legacy { - public class LegacySliderHeadHitCircle : LegacyMainCirclePiece + public partial class LegacySliderHeadHitCircle : LegacyMainCirclePiece { [Resolved(canBeNull: true)] private DrawableHitObject? drawableHitObject { get; set; } diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySmokeSegment.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySmokeSegment.cs index c9c7e86e86..0e93ef7ad5 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySmokeSegment.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySmokeSegment.cs @@ -6,7 +6,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu.Skinning.Legacy { - public class LegacySmokeSegment : SmokeSegment + public partial class LegacySmokeSegment : SmokeSegment { [BackgroundDependencyLoader] private void load(ISkinSource skin) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs index 66b195962b..d8f837ae5e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Skinning.Legacy { - public abstract class LegacySpinner : CompositeDrawable, IHasApproachCircle + public abstract partial class LegacySpinner : CompositeDrawable, IHasApproachCircle { public const float SPRITE_SCALE = 0.625f; diff --git a/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs b/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs index 2a13f07cdb..548a14f5eb 100644 --- a/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs +++ b/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs @@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Osu.Skinning /// A sprite which is displayed within the playfield, but historically was not considered part of the playfield. /// Performs scale adjustment to undo the scale applied by (osu! ruleset specifically). /// - public class NonPlayfieldSprite : Sprite + public partial class NonPlayfieldSprite : Sprite { public override Texture? Texture { diff --git a/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs index 1411b27c09..283687adfd 100644 --- a/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning { - public abstract class SliderBody : CompositeDrawable + public abstract partial class SliderBody : CompositeDrawable { private DrawableSliderPath path; @@ -107,7 +107,7 @@ namespace osu.Game.Rulesets.Osu.Skinning protected virtual DrawableSliderPath CreateSliderPath() => new DefaultDrawableSliderPath(); - private class DefaultDrawableSliderPath : DrawableSliderPath + private partial class DefaultDrawableSliderPath : DrawableSliderPath { private const float opacity_at_centre = 0.3f; private const float opacity_at_edge = 0.8f; diff --git a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs index 66d74ae13e..a824f202ec 100644 --- a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs @@ -21,7 +21,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning { - public abstract class SmokeSegment : Drawable, ITexturedShaderDrawable + public abstract partial class SmokeSegment : Drawable, ITexturedShaderDrawable { // fade anim values private const double initial_fade_out_duration = 4000; diff --git a/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs index 8ba9e75d19..f8ee465cd6 100644 --- a/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Skinning /// /// A which changes its curve depending on the snaking progress. /// - public abstract class SnakingSliderBody : SliderBody, ISliderProgress + public abstract partial class SnakingSliderBody : SliderBody, ISliderProgress { public readonly List CurrentCurve = new List(); diff --git a/osu.Game.Rulesets.Osu/Statistics/AccuracyHeatmap.cs b/osu.Game.Rulesets.Osu/Statistics/AccuracyHeatmap.cs index acf32da73f..0249b6d9b1 100644 --- a/osu.Game.Rulesets.Osu/Statistics/AccuracyHeatmap.cs +++ b/osu.Game.Rulesets.Osu/Statistics/AccuracyHeatmap.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Statistics { - public class AccuracyHeatmap : CompositeDrawable + public partial class AccuracyHeatmap : CompositeDrawable { /// /// Size of the inner circle containing the "hit" points, relative to the size of this . @@ -233,7 +233,7 @@ namespace osu.Game.Rulesets.Osu.Statistics bufferedGrid.ForceRedraw(); } - private class HitPoint : Circle + private partial class HitPoint : Circle { /// /// The base colour which will be lightened/darkened depending on the value of this . diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs b/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs index 1b2ef23674..9ecabd1d5e 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs @@ -24,7 +24,7 @@ using osuTK.Graphics.ES30; namespace osu.Game.Rulesets.Osu.UI.Cursor { - public class CursorTrail : Drawable, IRequireHighFrequencyMousePosition + public partial class CursorTrail : Drawable, IRequireHighFrequencyMousePosition { private const int max_sprites = 2048; diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs index 6d435f01b0..66c86ee09d 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.UI.Cursor { - public class OsuCursor : SkinReloadableDrawable + public partial class OsuCursor : SkinReloadableDrawable { private const float size = 28; @@ -66,7 +66,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor public void Contract() => expandTarget.ScaleTo(released_scale, 400, Easing.OutQuad); - private class DefaultCursor : OsuCursorSprite + private partial class DefaultCursor : OsuCursorSprite { public DefaultCursor() { diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs index 26fe08972e..5d7648b073 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.UI.Cursor { - public class OsuCursorContainer : GameplayCursorContainer, IKeyBindingHandler + public partial class OsuCursorContainer : GameplayCursorContainer, IKeyBindingHandler { protected override Drawable CreateCursor() => new OsuCursor(); @@ -165,7 +165,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor ActiveCursor.ScaleTo(CursorScale.Value * 0.8f, 450, Easing.OutQuint); } - private class DefaultCursorTrail : CursorTrail + private partial class DefaultCursorTrail : CursorTrail { [BackgroundDependencyLoader] private void load(TextureStore textures) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorSprite.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorSprite.cs index 03ef79a262..aaf8949084 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorSprite.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorSprite.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Rulesets.Osu.UI.Cursor { - public abstract class OsuCursorSprite : CompositeDrawable + public abstract partial class OsuCursorSprite : CompositeDrawable { /// /// The an optional piece of the cursor to expand when in a clicked state. diff --git a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs index 5f430dc921..d1fa0d09cc 100644 --- a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs @@ -22,7 +22,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.UI { - public class DrawableOsuRuleset : DrawableRuleset + public partial class DrawableOsuRuleset : DrawableRuleset { protected new OsuRulesetConfigManager Config => (OsuRulesetConfigManager)base.Config; diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index e9a6c84c0b..122330d09b 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -29,7 +29,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.UI { [Cached] - public class OsuPlayfield : Playfield + public partial class OsuPlayfield : Playfield { private readonly PlayfieldBorder playfieldBorder; private readonly ProxyContainer approachCircles; @@ -181,12 +181,12 @@ namespace osu.Game.Rulesets.Osu.UI public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => HitObjectContainer.ReceivePositionalInputAt(screenSpacePos); - private class ProxyContainer : LifetimeManagementContainer + private partial class ProxyContainer : LifetimeManagementContainer { public void Add(Drawable proxy) => AddInternal(proxy); } - private class DrawableJudgementPool : DrawablePool + private partial class DrawableJudgementPool : DrawablePool { private readonly HitResult result; private readonly Action onLoaded; diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs index 80f4eb3000..b45d552c7f 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfieldAdjustmentContainer.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.UI { - public class OsuPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer + public partial class OsuPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer { protected override Container Content => content; private readonly ScalingContainer content; @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Osu.UI /// /// A which scales its content relative to a target width. /// - private class ScalingContainer : Container + private partial class ScalingContainer : Container { internal bool PlayfieldShift { get; set; } diff --git a/osu.Game.Rulesets.Osu/UI/OsuReplayRecorder.cs b/osu.Game.Rulesets.Osu/UI/OsuReplayRecorder.cs index 5964a9b9b6..66a4f467a9 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuReplayRecorder.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuReplayRecorder.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.UI { - public class OsuReplayRecorder : ReplayRecorder + public partial class OsuReplayRecorder : ReplayRecorder { public OsuReplayRecorder(Score score) : base(score) diff --git a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs index 412505331b..e951197643 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.UI { - public class OsuResumeOverlay : ResumeOverlay + public partial class OsuResumeOverlay : ResumeOverlay { private Container cursorScaleContainer; private OsuClickToResumeCursor clickToResumeCursor; @@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Osu.UI protected override bool OnHover(HoverEvent e) => true; - public class OsuClickToResumeCursor : OsuCursor, IKeyBindingHandler + public partial class OsuClickToResumeCursor : OsuCursor, IKeyBindingHandler { public override bool HandlePositionalInput => true; diff --git a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs index eff4b30362..f711a0fc31 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.UI { - public class OsuSettingsSubsection : RulesetSettingsSubsection + public partial class OsuSettingsSubsection : RulesetSettingsSubsection { protected override LocalisableString Header => "osu!"; diff --git a/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs b/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs index bf5618dc90..389440ba2d 100644 --- a/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.UI /// /// Manages smoke trails generated from user input. /// - public class SmokeContainer : Container, IRequireHighFrequencyMousePosition, IKeyBindingHandler + public partial class SmokeContainer : Container, IRequireHighFrequencyMousePosition, IKeyBindingHandler { private SmokeSkinnableDrawable? currentSegmentSkinnable; @@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.Osu.UI private void addPosition() => (currentSegmentSkinnable?.Drawable as SmokeSegment)?.AddPosition(lastMousePosition, Time.Current); - private class SmokeSkinnableDrawable : SkinnableDrawable + private partial class SmokeSkinnableDrawable : SkinnableDrawable { public override bool RemoveWhenNotAlive => true; diff --git a/osu.Game.Rulesets.Taiko.Tests/DrawableTaikoRulesetTestScene.cs b/osu.Game.Rulesets.Taiko.Tests/DrawableTaikoRulesetTestScene.cs index 01719bfea6..a222fe8275 100644 --- a/osu.Game.Rulesets.Taiko.Tests/DrawableTaikoRulesetTestScene.cs +++ b/osu.Game.Rulesets.Taiko.Tests/DrawableTaikoRulesetTestScene.cs @@ -16,7 +16,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests { - public abstract class DrawableTaikoRulesetTestScene : OsuTestScene + public abstract partial class DrawableTaikoRulesetTestScene : OsuTestScene { protected const int DEFAULT_PLAYFIELD_CONTAINER_HEIGHT = 768; diff --git a/osu.Game.Rulesets.Taiko.Tests/DrawableTestHit.cs b/osu.Game.Rulesets.Taiko.Tests/DrawableTestHit.cs index 6a585b840d..157a96eec8 100644 --- a/osu.Game.Rulesets.Taiko.Tests/DrawableTestHit.cs +++ b/osu.Game.Rulesets.Taiko.Tests/DrawableTestHit.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables; namespace osu.Game.Rulesets.Taiko.Tests { - public class DrawableTestHit : DrawableHit + public partial class DrawableTestHit : DrawableHit { public readonly HitResult Type; diff --git a/osu.Game.Rulesets.Taiko.Tests/DrawableTestStrongHit.cs b/osu.Game.Rulesets.Taiko.Tests/DrawableTestStrongHit.cs index 7355e1dbca..747c599721 100644 --- a/osu.Game.Rulesets.Taiko.Tests/DrawableTestStrongHit.cs +++ b/osu.Game.Rulesets.Taiko.Tests/DrawableTestStrongHit.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables; namespace osu.Game.Rulesets.Taiko.Tests { - public class DrawableTestStrongHit : DrawableTestHit + public partial class DrawableTestStrongHit : DrawableTestHit { private readonly bool hitBoth; diff --git a/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneEditor.cs b/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneEditor.cs index 5915b9fdfa..3ee9171e7e 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneEditor.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneEditor.cs @@ -9,7 +9,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests.Editor { [TestFixture] - public class TestSceneEditor : EditorTestScene + public partial class TestSceneEditor : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new TaikoRuleset(); } diff --git a/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneTaikoEditorSaving.cs b/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneTaikoEditorSaving.cs index 06c06f6e28..93b26624de 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneTaikoEditorSaving.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneTaikoEditorSaving.cs @@ -10,7 +10,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests.Editor { - public class TestSceneTaikoEditorSaving : EditorSavingTestScene + public partial class TestSceneTaikoEditorSaving : EditorSavingTestScene { protected override Ruleset CreateRuleset() => new TaikoRuleset(); diff --git a/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneTaikoHitObjectComposer.cs b/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneTaikoHitObjectComposer.cs index 8d17918a92..ed73730c4a 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneTaikoHitObjectComposer.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneTaikoHitObjectComposer.cs @@ -16,7 +16,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests.Editor { - public class TestSceneTaikoHitObjectComposer : EditorClockTestScene + public partial class TestSceneTaikoHitObjectComposer : EditorClockTestScene { [SetUp] public void Setup() => Schedule(() => @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Editor { } - private class TestComposer : CompositeDrawable + private partial class TestComposer : CompositeDrawable { [Cached(typeof(EditorBeatmap))] [Cached(typeof(IBeatSnapProvider))] diff --git a/osu.Game.Rulesets.Taiko.Tests/HitObjectApplicationTestScene.cs b/osu.Game.Rulesets.Taiko.Tests/HitObjectApplicationTestScene.cs index 09a6a2f16c..e8688f36bc 100644 --- a/osu.Game.Rulesets.Taiko.Tests/HitObjectApplicationTestScene.cs +++ b/osu.Game.Rulesets.Taiko.Tests/HitObjectApplicationTestScene.cs @@ -16,7 +16,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests { - public abstract class HitObjectApplicationTestScene : OsuTestScene + public abstract partial class HitObjectApplicationTestScene : OsuTestScene { [Cached(typeof(IScrollingInfo))] private ScrollingTestContainer.TestScrollingInfo info = new ScrollingTestContainer.TestScrollingInfo diff --git a/osu.Game.Rulesets.Taiko.Tests/Judgements/JudgementTest.cs b/osu.Game.Rulesets.Taiko.Tests/Judgements/JudgementTest.cs index 7f2f27b2b8..eb2d96ec51 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Judgements/JudgementTest.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Judgements/JudgementTest.cs @@ -19,7 +19,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests.Judgements { - public class JudgementTest : RateAdjustedBeatmapTestScene + public partial class JudgementTest : RateAdjustedBeatmapTestScene { private ScoreAccessibleReplayPlayer currentPlayer = null!; protected List JudgementResults { get; private set; } = null!; @@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Judgements return beatmap; } - private class ScoreAccessibleReplayPlayer : ReplayPlayer + private partial class ScoreAccessibleReplayPlayer : ReplayPlayer { public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; diff --git a/osu.Game.Rulesets.Taiko.Tests/Judgements/TestSceneDrumRollJudgements.cs b/osu.Game.Rulesets.Taiko.Tests/Judgements/TestSceneDrumRollJudgements.cs index 2c28c3dad5..a9231b4783 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Judgements/TestSceneDrumRollJudgements.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Judgements/TestSceneDrumRollJudgements.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Taiko.Replays; namespace osu.Game.Rulesets.Taiko.Tests.Judgements { - public class TestSceneDrumRollJudgements : JudgementTest + public partial class TestSceneDrumRollJudgements : JudgementTest { [Test] public void TestHitAllDrumRoll() diff --git a/osu.Game.Rulesets.Taiko.Tests/Judgements/TestSceneHitJudgements.cs b/osu.Game.Rulesets.Taiko.Tests/Judgements/TestSceneHitJudgements.cs index d2d5cdb6ac..3bf94eb62e 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Judgements/TestSceneHitJudgements.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Judgements/TestSceneHitJudgements.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Taiko.Replays; namespace osu.Game.Rulesets.Taiko.Tests.Judgements { - public class TestSceneHitJudgements : JudgementTest + public partial class TestSceneHitJudgements : JudgementTest { [Test] public void TestHitCentreHit() diff --git a/osu.Game.Rulesets.Taiko.Tests/Judgements/TestSceneSwellJudgements.cs b/osu.Game.Rulesets.Taiko.Tests/Judgements/TestSceneSwellJudgements.cs index 7bdfcf0b07..ccc829f09e 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Judgements/TestSceneSwellJudgements.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Judgements/TestSceneSwellJudgements.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Taiko.Replays; namespace osu.Game.Rulesets.Taiko.Tests.Judgements { - public class TestSceneSwellJudgements : JudgementTest + public partial class TestSceneSwellJudgements : JudgementTest { [Test] public void TestHitAllSwell() diff --git a/osu.Game.Rulesets.Taiko.Tests/Mods/TaikoModTestScene.cs b/osu.Game.Rulesets.Taiko.Tests/Mods/TaikoModTestScene.cs index 3090facf8c..7760c5a30b 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Mods/TaikoModTestScene.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Mods/TaikoModTestScene.cs @@ -5,7 +5,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests.Mods { - public abstract class TaikoModTestScene : ModTestScene + public abstract partial class TaikoModTestScene : ModTestScene { protected sealed override Ruleset CreatePlayerRuleset() => new TaikoRuleset(); } diff --git a/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModFlashlight.cs b/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModFlashlight.cs index d55ce17e6c..05a408c621 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModFlashlight.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModFlashlight.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Tests.Mods { - public class TestSceneTaikoModFlashlight : TaikoModTestScene + public partial class TestSceneTaikoModFlashlight : TaikoModTestScene { [TestCase(1f)] [TestCase(0.5f)] @@ -38,11 +38,11 @@ namespace osu.Game.Rulesets.Taiko.Tests.Mods }); } - private class TestTaikoModFlashlight : TaikoModFlashlight + private partial class TestTaikoModFlashlight : TaikoModFlashlight { protected override Flashlight CreateFlashlight() => new TestTaikoFlashlight(this, Playfield); - public class TestTaikoFlashlight : TaikoFlashlight + public partial class TestTaikoFlashlight : TaikoFlashlight { public TestTaikoFlashlight(TaikoModFlashlight modFlashlight, TaikoPlayfield taikoPlayfield) : base(modFlashlight, taikoPlayfield) diff --git a/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModHidden.cs b/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModHidden.cs index 7abbb9d186..edc53429b1 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModHidden.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModHidden.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.Taiko.Mods; namespace osu.Game.Rulesets.Taiko.Tests.Mods { - public class TestSceneTaikoModHidden : TaikoModTestScene + public partial class TestSceneTaikoModHidden : TaikoModTestScene { [Test] public void TestDefaultBeatmapTest() => CreateModTest(new ModTestData diff --git a/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModPerfect.cs b/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModPerfect.cs index 92503a9f03..aed08f33e0 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModPerfect.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Mods/TestSceneTaikoModPerfect.cs @@ -10,7 +10,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests.Mods { - public class TestSceneTaikoModPerfect : ModPerfectTestScene + public partial class TestSceneTaikoModPerfect : ModPerfectTestScene { protected override Ruleset CreatePlayerRuleset() => new TestTaikoRuleset(); @@ -31,11 +31,11 @@ namespace osu.Game.Rulesets.Taiko.Tests.Mods [TestCase(true)] public void TestSwell(bool shouldMiss) => CreateHitObjectTest(new HitObjectTestData(new Swell { StartTime = 1000, EndTime = 3000 }, false), shouldMiss); - private class TestTaikoRuleset : TaikoRuleset + private partial class TestTaikoRuleset : TaikoRuleset { public override HealthProcessor CreateHealthProcessor(double drainStartTime) => new TestTaikoHealthProcessor(); - private class TestTaikoHealthProcessor : TaikoHealthProcessor + private partial class TestTaikoHealthProcessor : TaikoHealthProcessor { protected override void Reset(bool storeResults) { diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TaikoSkinnableTestScene.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TaikoSkinnableTestScene.cs index 82be26b422..38530282b7 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TaikoSkinnableTestScene.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TaikoSkinnableTestScene.cs @@ -7,7 +7,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests.Skinning { - public abstract class TaikoSkinnableTestScene : SkinnableTestScene + public abstract partial class TaikoSkinnableTestScene : SkinnableTestScene { protected override Ruleset CreateRulesetForSkinProvider() => new TaikoRuleset(); } diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableBarLine.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableBarLine.cs index a4aa0e1fad..7fd90685e3 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableBarLine.cs @@ -18,7 +18,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests.Skinning { [TestFixture] - public class TestSceneDrawableBarLine : TaikoSkinnableTestScene + public partial class TestSceneDrawableBarLine : TaikoSkinnableTestScene { [Cached(typeof(IScrollingInfo))] private ScrollingTestContainer.TestScrollingInfo info = new ScrollingTestContainer.TestScrollingInfo diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRoll.cs index 25cb3f7886..3b2f4f2fb2 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableDrumRoll.cs @@ -16,7 +16,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests.Skinning { [TestFixture] - public class TestSceneDrawableDrumRoll : TaikoSkinnableTestScene + public partial class TestSceneDrawableDrumRoll : TaikoSkinnableTestScene { [Cached(typeof(IScrollingInfo))] private ScrollingTestContainer.TestScrollingInfo info = new ScrollingTestContainer.TestScrollingInfo diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs index adfd27c5d6..9567eac80f 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs @@ -16,7 +16,7 @@ using osu.Game.Tests.Gameplay; namespace osu.Game.Rulesets.Taiko.Tests.Skinning { [TestFixture] - public class TestSceneDrawableHit : TaikoSkinnableTestScene + public partial class TestSceneDrawableHit : TaikoSkinnableTestScene { [Cached] private GameplayState gameplayState = TestGameplayState.Create(new TaikoRuleset()); diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableSwell.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableSwell.cs index b8c0f6f11e..c130b5f366 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableSwell.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables; namespace osu.Game.Rulesets.Taiko.Tests.Skinning { [TestFixture] - public class TestSceneDrawableSwell : TaikoSkinnableTestScene + public partial class TestSceneDrawableSwell : TaikoSkinnableTestScene { [Test] public void TestHits() diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs index 71ce4c08d0..e4e68c7207 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs @@ -25,7 +25,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests.Skinning { [TestFixture] - public class TestSceneDrawableTaikoMascot : TaikoSkinnableTestScene + public partial class TestSceneDrawableTaikoMascot : TaikoSkinnableTestScene { [Cached(typeof(IScrollingInfo))] private ScrollingTestContainer.TestScrollingInfo info = new ScrollingTestContainer.TestScrollingInfo diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneHitExplosion.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneHitExplosion.cs index 0ddc607336..924f903ce9 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneHitExplosion.cs @@ -18,7 +18,7 @@ using osu.Game.Screens.Ranking; namespace osu.Game.Rulesets.Taiko.Tests.Skinning { [TestFixture] - public class TestSceneHitExplosion : TaikoSkinnableTestScene + public partial class TestSceneHitExplosion : TaikoSkinnableTestScene { protected override double TimePerAction => 100; diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneInputDrum.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneInputDrum.cs index f342bfe78e..cb5d0d1f91 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneInputDrum.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneInputDrum.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Tests.Skinning { [TestFixture] - public class TestSceneInputDrum : TaikoSkinnableTestScene + public partial class TestSceneInputDrum : TaikoSkinnableTestScene { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneKiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneKiaiHitExplosion.cs index e1a3c736fe..5f98f2f27a 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneKiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneKiaiHitExplosion.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets.Taiko.UI; namespace osu.Game.Rulesets.Taiko.Tests.Skinning { [TestFixture] - public class TestSceneKiaiHitExplosion : TaikoSkinnableTestScene + public partial class TestSceneKiaiHitExplosion : TaikoSkinnableTestScene { [Test] public void TestKiaiHits() diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs index eff9f58751..eb2762cb2d 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoPlayfield.cs @@ -17,7 +17,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests.Skinning { - public class TestSceneTaikoPlayfield : TaikoSkinnableTestScene + public partial class TestSceneTaikoPlayfield : TaikoSkinnableTestScene { [Cached(typeof(IScrollingInfo))] private ScrollingTestContainer.TestScrollingInfo info = new ScrollingTestContainer.TestScrollingInfo diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs index a9304b01ad..826cf2acab 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs @@ -14,7 +14,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko.Tests.Skinning { - public class TestSceneTaikoScroller : TaikoSkinnableTestScene + public partial class TestSceneTaikoScroller : TaikoSkinnableTestScene { private readonly ManualClock clock = new ManualClock(); diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneBarLineApplication.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneBarLineApplication.cs index 867ee13bea..00292d5473 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneBarLineApplication.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneBarLineApplication.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables; namespace osu.Game.Rulesets.Taiko.Tests { - public class TestSceneBarLineApplication : HitObjectApplicationTestScene + public partial class TestSceneBarLineApplication : HitObjectApplicationTestScene { [Test] public void TestApplyNewBarLine() diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneBarLineGeneration.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneBarLineGeneration.cs index bd52af7615..7b8c8926f0 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneBarLineGeneration.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneBarLineGeneration.cs @@ -12,7 +12,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests { - public class TestSceneBarLineGeneration : OsuTestScene + public partial class TestSceneBarLineGeneration : OsuTestScene { [Test] public void TestCloseBarLineGeneration() diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumRollApplication.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumRollApplication.cs index eceeaf5083..b01bd11149 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumRollApplication.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumRollApplication.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables; namespace osu.Game.Rulesets.Taiko.Tests { - public class TestSceneDrumRollApplication : HitObjectApplicationTestScene + public partial class TestSceneDrumRollApplication : HitObjectApplicationTestScene { [Test] public void TestApplyNewDrumRoll() diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumTouchInputArea.cs index 7210419c0e..6514b760bb 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumTouchInputArea.cs @@ -10,7 +10,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests { [TestFixture] - public class TestSceneDrumTouchInputArea : OsuTestScene + public partial class TestSceneDrumTouchInputArea : OsuTestScene { private DrumTouchInputArea drumTouchInputArea = null!; diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneFlyingHits.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneFlyingHits.cs index c787683620..e0ff617b59 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneFlyingHits.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneFlyingHits.cs @@ -16,7 +16,7 @@ using osu.Game.Rulesets.Taiko.UI; namespace osu.Game.Rulesets.Taiko.Tests { [TestFixture] - public class TestSceneFlyingHits : DrawableTaikoRulesetTestScene + public partial class TestSceneFlyingHits : DrawableTaikoRulesetTestScene { [TestCase(HitType.Centre)] [TestCase(HitType.Rim)] diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneHitApplication.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneHitApplication.cs index b337519c85..301620edc9 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneHitApplication.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneHitApplication.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables; namespace osu.Game.Rulesets.Taiko.Tests { - public class TestSceneHitApplication : HitObjectApplicationTestScene + public partial class TestSceneHitApplication : HitObjectApplicationTestScene { [Test] public void TestApplyNewHit() diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneHits.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneHits.cs index 5350a81f55..91209e5ec5 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneHits.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneHits.cs @@ -23,7 +23,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Tests { [TestFixture] - public class TestSceneHits : DrawableTaikoRulesetTestScene + public partial class TestSceneHits : DrawableTaikoRulesetTestScene { private const double default_duration = 3000; private const float scroll_time = 1000; diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneSampleOutput.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneSampleOutput.cs index e6c28a532a..dcdda6014c 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneSampleOutput.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneSampleOutput.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Taiko.Tests /// Taiko has some interesting rules for legacy mappings. /// [HeadlessTest] - public class TestSceneSampleOutput : TestSceneTaikoPlayer + public partial class TestSceneSampleOutput : TestSceneTaikoPlayer { public override void SetUpSteps() { diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoHitObjectSamples.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoHitObjectSamples.cs index c674f87f80..1d1e82fb07 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoHitObjectSamples.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoHitObjectSamples.cs @@ -8,7 +8,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Taiko.Tests { - public class TestSceneTaikoHitObjectSamples : HitObjectSampleTest + public partial class TestSceneTaikoHitObjectSamples : HitObjectSampleTest { protected override Ruleset CreatePlayerRuleset() => new TaikoRuleset(); diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayer.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayer.cs index 5e984b19f8..8c903f748c 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayer.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayer.cs @@ -7,7 +7,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests { - public class TestSceneTaikoPlayer : PlayerTestScene + public partial class TestSceneTaikoPlayer : PlayerTestScene { protected override Ruleset CreatePlayerRuleset() => new TaikoRuleset(); } diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayerLegacySkin.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayerLegacySkin.cs index 13df24c988..39776229fa 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayerLegacySkin.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoPlayerLegacySkin.cs @@ -6,7 +6,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests { - public class TestSceneTaikoPlayerLegacySkin : LegacySkinPlayerTestScene + public partial class TestSceneTaikoPlayerLegacySkin : LegacySkinPlayerTestScene { protected override Ruleset CreatePlayerRuleset() => new TaikoRuleset(); diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs index 2169ac5581..08c06b08f2 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs @@ -13,7 +13,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Taiko.Tests { - public class TestSceneTaikoSuddenDeath : TestSceneTaikoPlayer + public partial class TestSceneTaikoSuddenDeath : TestSceneTaikoPlayer { protected override bool AllowFail => true; diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/DrumRollPlacementBlueprint.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/DrumRollPlacementBlueprint.cs index dfbcd1cce3..4b4e2b5847 100644 --- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/DrumRollPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/DrumRollPlacementBlueprint.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.Taiko.Objects; namespace osu.Game.Rulesets.Taiko.Edit.Blueprints { - public class DrumRollPlacementBlueprint : TaikoSpanPlacementBlueprint + public partial class DrumRollPlacementBlueprint : TaikoSpanPlacementBlueprint { public DrumRollPlacementBlueprint() : base(new DrumRoll()) diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPiece.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPiece.cs index 86f32ca17c..84bc547372 100644 --- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPiece.cs +++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPiece.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Edit.Blueprints { - public class HitPiece : CompositeDrawable + public partial class HitPiece : CompositeDrawable { public HitPiece() { diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs index 863a2c9eac..0a1f5380b5 100644 --- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs @@ -12,7 +12,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Taiko.Edit.Blueprints { - public class HitPlacementBlueprint : PlacementBlueprint + public partial class HitPlacementBlueprint : PlacementBlueprint { private readonly HitPiece piece; diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/LengthPiece.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/LengthPiece.cs index e201d58f7a..af02522a05 100644 --- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/LengthPiece.cs +++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/LengthPiece.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Edit.Blueprints { - public class LengthPiece : CompositeDrawable + public partial class LengthPiece : CompositeDrawable { public LengthPiece() { diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/SwellPlacementBlueprint.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/SwellPlacementBlueprint.cs index 1d08af47d3..2080293428 100644 --- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/SwellPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/SwellPlacementBlueprint.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.Taiko.Objects; namespace osu.Game.Rulesets.Taiko.Edit.Blueprints { - public class SwellPlacementBlueprint : TaikoSpanPlacementBlueprint + public partial class SwellPlacementBlueprint : TaikoSpanPlacementBlueprint { public SwellPlacementBlueprint() : base(new Swell()) diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSelectionBlueprint.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSelectionBlueprint.cs index 4c67a37417..34695cbdd6 100644 --- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSelectionBlueprint.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Edit.Blueprints { - public class TaikoSelectionBlueprint : HitObjectSelectionBlueprint + public partial class TaikoSelectionBlueprint : HitObjectSelectionBlueprint { public TaikoSelectionBlueprint(HitObject hitObject) : base(hitObject) diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs index 70364cabf1..fcf2573d64 100644 --- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs @@ -16,7 +16,7 @@ using osuTK.Input; namespace osu.Game.Rulesets.Taiko.Edit.Blueprints { - public class TaikoSpanPlacementBlueprint : PlacementBlueprint + public partial class TaikoSpanPlacementBlueprint : PlacementBlueprint { private readonly HitPiece headPiece; private readonly HitPiece tailPiece; diff --git a/osu.Game.Rulesets.Taiko/Edit/TaikoBlueprintContainer.cs b/osu.Game.Rulesets.Taiko/Edit/TaikoBlueprintContainer.cs index 6107c8009a..6be22f3af0 100644 --- a/osu.Game.Rulesets.Taiko/Edit/TaikoBlueprintContainer.cs +++ b/osu.Game.Rulesets.Taiko/Edit/TaikoBlueprintContainer.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Edit.Compose.Components; namespace osu.Game.Rulesets.Taiko.Edit { - public class TaikoBlueprintContainer : ComposeBlueprintContainer + public partial class TaikoBlueprintContainer : ComposeBlueprintContainer { public TaikoBlueprintContainer(HitObjectComposer composer) : base(composer) diff --git a/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs b/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs index 161799c980..cff5731181 100644 --- a/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs +++ b/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs @@ -9,7 +9,7 @@ using osu.Game.Screens.Edit.Compose.Components; namespace osu.Game.Rulesets.Taiko.Edit { - public class TaikoHitObjectComposer : HitObjectComposer + public partial class TaikoHitObjectComposer : HitObjectComposer { public TaikoHitObjectComposer(TaikoRuleset ruleset) : base(ruleset) diff --git a/osu.Game.Rulesets.Taiko/Edit/TaikoSelectionHandler.cs b/osu.Game.Rulesets.Taiko/Edit/TaikoSelectionHandler.cs index 80e4e8f406..b727c0a61b 100644 --- a/osu.Game.Rulesets.Taiko/Edit/TaikoSelectionHandler.cs +++ b/osu.Game.Rulesets.Taiko/Edit/TaikoSelectionHandler.cs @@ -16,7 +16,7 @@ using osu.Game.Screens.Edit.Compose.Components; namespace osu.Game.Rulesets.Taiko.Edit { - public class TaikoSelectionHandler : EditorSelectionHandler + public partial class TaikoSelectionHandler : EditorSelectionHandler { private readonly Bindable selectionRimState = new Bindable(); private readonly Bindable selectionStrongState = new Bindable(); diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs index 46569c2495..733772e21f 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Mods { - public class TaikoModFlashlight : ModFlashlight + public partial class TaikoModFlashlight : ModFlashlight { public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.12 : 1; @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Taiko.Mods base.ApplyToDrawableRuleset(drawableRuleset); } - public class TaikoFlashlight : Flashlight + public partial class TaikoFlashlight : Flashlight { private readonly LayoutValue flashlightProperties = new LayoutValue(Invalidation.RequiredParentSizeToFit | Invalidation.DrawInfo); private readonly TaikoPlayfield taikoPlayfield; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs index 2405d5b73f..65a6fd4499 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables /// /// A line that scrolls alongside hit objects in the playfield and visualises control points. /// - public class DrawableBarLine : DrawableHitObject + public partial class DrawableBarLine : DrawableHitObject { public new BarLine HitObject => (BarLine)base.HitObject; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index 0bb14c791e..005d2ab1ac 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -22,7 +22,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { - public class DrawableDrumRoll : DrawableTaikoStrongableHitObject + public partial class DrawableDrumRoll : DrawableTaikoStrongableHitObject { /// /// Number of rolling hits required to reach the dark/final colour. @@ -173,7 +173,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables (MainPiece.Drawable as IHasAccentColour)?.FadeAccent(newColour, fadeDuration); } - public class StrongNestedHit : DrawableStrongNestedHit + public partial class StrongNestedHit : DrawableStrongNestedHit { public new DrawableDrumRoll ParentHitObject => (DrawableDrumRoll)base.ParentHitObject; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index b01adc880a..45e25ee7dc 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -15,7 +15,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { - public class DrawableDrumRollTick : DrawableTaikoStrongableHitObject + public partial class DrawableDrumRollTick : DrawableTaikoStrongableHitObject { public BindableBool IsFirstTick = new BindableBool(); @@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables protected override DrawableStrongNestedHit CreateStrongNestedHit(DrumRollTick.StrongNestedHit hitObject) => new StrongNestedHit(hitObject); - public class StrongNestedHit : DrawableStrongNestedHit + public partial class StrongNestedHit : DrawableStrongNestedHit { public new DrawableDrumRollTick ParentHitObject => (DrawableDrumRollTick)base.ParentHitObject; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableFlyingHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableFlyingHit.cs index 5ce72028e0..0cd265ecab 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableFlyingHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableFlyingHit.cs @@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables /// /// A hit used specifically for drum rolls, where spawning flying hits is required. /// - public class DrawableFlyingHit : DrawableHit + public partial class DrawableFlyingHit : DrawableHit { public DrawableFlyingHit(DrawableDrumRollTick drumRollTick) : base(new IgnoreHit diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index 59c9640beb..ff4edf35fa 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -19,7 +19,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { - public class DrawableHit : DrawableTaikoStrongableHitObject + public partial class DrawableHit : DrawableTaikoStrongableHitObject { /// /// A list of keys which can result in hits for this HitObject. @@ -220,7 +220,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables protected override DrawableStrongNestedHit CreateStrongNestedHit(Hit.StrongNestedHit hitObject) => new StrongNestedHit(hitObject); - public class StrongNestedHit : DrawableStrongNestedHit + public partial class StrongNestedHit : DrawableStrongNestedHit { public new DrawableHit ParentHitObject => (DrawableHit)base.ParentHitObject; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableStrongNestedHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableStrongNestedHit.cs index 01ee91a5c7..4ea30453d1 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableStrongNestedHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableStrongNestedHit.cs @@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables /// /// Used as a nested hitobject to provide s for s. /// - public abstract class DrawableStrongNestedHit : DrawableTaikoHitObject + public abstract partial class DrawableStrongNestedHit : DrawableTaikoHitObject { public new DrawableTaikoHitObject ParentHitObject => (DrawableTaikoHitObject)base.ParentHitObject; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 753f85f23f..8441e3a749 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -21,7 +21,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { - public class DrawableSwell : DrawableTaikoHitObject + public partial class DrawableSwell : DrawableTaikoHitObject { private const float target_ring_thick_border = 1.4f; private const float target_ring_thin_border = 1f; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs index 5d44fce254..3a5c006962 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs @@ -11,7 +11,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { - public class DrawableSwellTick : DrawableTaikoHitObject + public partial class DrawableSwellTick : DrawableTaikoHitObject { public override bool DisplayResult => false; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index 400c2f40b1..6172b75d2c 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { - public abstract class DrawableTaikoHitObject : DrawableHitObject, IKeyBindingHandler + public abstract partial class DrawableTaikoHitObject : DrawableHitObject, IKeyBindingHandler { protected readonly Container Content; private readonly Container proxiedContent; @@ -105,13 +105,13 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } } - private class ProxiedContentContainer : Container + private partial class ProxiedContentContainer : Container { public override bool RemoveWhenNotAlive => false; } } - public abstract class DrawableTaikoHitObject : DrawableTaikoHitObject + public abstract partial class DrawableTaikoHitObject : DrawableTaikoHitObject where TObject : TaikoHitObject { public override Vector2 OriginPosition => new Vector2(DrawHeight / 2); diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoStrongableHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoStrongableHitObject.cs index 4b58cc60e6..4d7cdf3243 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoStrongableHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoStrongableHitObject.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { - public abstract class DrawableTaikoStrongableHitObject : DrawableTaikoHitObject + public abstract partial class DrawableTaikoStrongableHitObject : DrawableTaikoHitObject where TObject : TaikoStrongableHitObject where TStrongNestedObject : StrongNestedHitObject { diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoHealthProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoHealthProcessor.cs index a663817aa8..7c70beb0a4 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoHealthProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoHealthProcessor.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Taiko.Scoring /// A for the taiko ruleset. /// Taiko fails if the player has not half-filled their health by the end of the map. /// - public class TaikoHealthProcessor : AccumulatingHealthProcessor + public partial class TaikoHealthProcessor : AccumulatingHealthProcessor { /// /// A value used for calculating . diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs index 3b0bb952dd..4b60ee3ccb 100644 --- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs +++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Taiko.Scoring { - internal class TaikoScoreProcessor : ScoreProcessor + internal partial class TaikoScoreProcessor : ScoreProcessor { public TaikoScoreProcessor() : base(new TaikoRuleset()) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonBarLine.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonBarLine.cs index 402e88b64d..32afb8e6ac 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonBarLine.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Skinning.Argon { - public class ArgonBarLine : CompositeDrawable + public partial class ArgonBarLine : CompositeDrawable { private Container majorEdgeContainer = null!; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs index 551a5af078..dedb276d58 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCentreCirclePiece.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon { - public class ArgonCentreCirclePiece : ArgonCirclePiece + public partial class ArgonCentreCirclePiece : ArgonCirclePiece { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs index c22c0e9e79..d7e37899ce 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonCirclePiece.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon { - public abstract class ArgonCirclePiece : BeatSyncedContainer + public abstract partial class ArgonCirclePiece : BeatSyncedContainer { public const float ICON_SIZE = 20 / 70f; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonElongatedCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonElongatedCirclePiece.cs index f86f181b2e..17386cc659 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonElongatedCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonElongatedCirclePiece.cs @@ -8,7 +8,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon { - public class ArgonElongatedCirclePiece : ArgonCirclePiece + public partial class ArgonElongatedCirclePiece : ArgonCirclePiece { public ArgonElongatedCirclePiece() { diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitExplosion.cs index 05bb9bcb9a..a47fd7e62e 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitExplosion.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon { - public class ArgonHitExplosion : CompositeDrawable, IAnimatableHitExplosion + public partial class ArgonHitExplosion : CompositeDrawable, IAnimatableHitExplosion { private readonly TaikoSkinComponents component; private readonly Circle outer; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitTarget.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitTarget.cs index ec2eccd595..0ddcd6feb2 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitTarget.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonHitTarget.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon { - public class ArgonHitTarget : CompositeDrawable + public partial class ArgonHitTarget : CompositeDrawable { /// /// Thickness of all drawn line pieces. diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonInputDrum.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonInputDrum.cs index 528e75aabb..e7b0a5537a 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonInputDrum.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonInputDrum.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon { - public class ArgonInputDrum : AspectContainer + public partial class ArgonInputDrum : AspectContainer { private const float rim_size = 0.3f; @@ -91,7 +91,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon /// /// A half-drum. Contains one centre and one rim hit. /// - private class TaikoHalfDrum : CompositeDrawable, IKeyBindingHandler + private partial class TaikoHalfDrum : CompositeDrawable, IKeyBindingHandler { /// /// The key to be used for the rim of the half-drum. diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs index baaf9e41e2..6756001089 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon { - public class ArgonJudgementPiece : CompositeDrawable, IAnimatableJudgement + public partial class ArgonJudgementPiece : CompositeDrawable, IAnimatableJudgement { protected readonly HitResult Result; @@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon public Drawable? GetAboveHitObjectsProxiedContent() => null; - private class RingExplosion : CompositeDrawable + private partial class RingExplosion : CompositeDrawable { private readonly float travel = 58; @@ -174,7 +174,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon this.FadeOutFromOne(1000, Easing.OutQuint); } - public class RingPiece : CircularContainer + public partial class RingPiece : CircularContainer { public RingPiece(float thickness = 9) { diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundLeft.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundLeft.cs index ebde83b607..07ac37b04c 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundLeft.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundLeft.cs @@ -8,7 +8,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon { - public class ArgonPlayfieldBackgroundLeft : CompositeDrawable + public partial class ArgonPlayfieldBackgroundLeft : CompositeDrawable { public ArgonPlayfieldBackgroundLeft() { diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundRight.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundRight.cs index bd0f3ab276..41a3e3bb33 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundRight.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonPlayfieldBackgroundRight.cs @@ -8,7 +8,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon { - public class ArgonPlayfieldBackgroundRight : CompositeDrawable + public partial class ArgonPlayfieldBackgroundRight : CompositeDrawable { public ArgonPlayfieldBackgroundRight() { diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs index fd81221be3..b32326a90f 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonRimCirclePiece.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon { - public class ArgonRimCirclePiece : ArgonCirclePiece + public partial class ArgonRimCirclePiece : ArgonCirclePiece { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonSwellCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonSwellCirclePiece.cs index 82a6e34128..d93d8598f6 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonSwellCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonSwellCirclePiece.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon { - public class ArgonSwellCirclePiece : ArgonCirclePiece + public partial class ArgonSwellCirclePiece : ArgonCirclePiece { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonTickPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonTickPiece.cs index df63d4948e..5baa320201 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonTickPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonTickPiece.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Skinning.Argon { - public class ArgonTickPiece : CompositeDrawable + public partial class ArgonTickPiece : CompositeDrawable { private readonly Bindable isFirstTick = new Bindable(); diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs index 534a1c71a3..719c1c36fa 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/RingPiece.cs @@ -8,7 +8,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon { - public class RingPiece : CircularContainer + public partial class RingPiece : CircularContainer { private readonly float relativeBorderThickness; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs index 339ab35795..4ed5c3d0df 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Skinning.Default { - public class CentreHitCirclePiece : CirclePiece + public partial class CentreHitCirclePiece : CirclePiece { public CentreHitCirclePiece() { @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default /// /// The symbol used for centre hit pieces. /// - public class CentreHitSymbolPiece : Container + public partial class CentreHitSymbolPiece : Container { public CentreHitSymbolPiece() { diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs index 7ddc413d98..bde502bbed 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default /// for a usage example. /// /// - public abstract class CirclePiece : BeatSyncedContainer, IHasAccentColour + public abstract partial class CirclePiece : BeatSyncedContainer, IHasAccentColour { public const float SYMBOL_SIZE = TaikoHitObject.DEFAULT_SIZE; public const float SYMBOL_BORDER = 8; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultBarLine.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultBarLine.cs index 973e685bc7..09965054e0 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultBarLine.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Skinning.Default { - public class DefaultBarLine : CompositeDrawable + public partial class DefaultBarLine : CompositeDrawable { /// /// The vertical offset of the triangles from the line tracker. diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs index 2e76396a4d..8a70c4bde8 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Default { - internal class DefaultHitExplosion : CircularContainer, IAnimatableHitExplosion + internal partial class DefaultHitExplosion : CircularContainer, IAnimatableHitExplosion { private readonly HitResult result; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs index 3d0578dbc0..6d19db999c 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Skinning.Default { - public class DefaultInputDrum : AspectContainer + public partial class DefaultInputDrum : AspectContainer { public DefaultInputDrum() { @@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default /// /// A half-drum. Contains one centre and one rim hit. /// - private class TaikoHalfDrum : Container, IKeyBindingHandler + private partial class TaikoHalfDrum : Container, IKeyBindingHandler { /// /// The key to be used for the rim of the half-drum. diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs index c85a8db788..c78d7719d0 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs @@ -6,7 +6,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Taiko.Skinning.Default { - public class DefaultJudgementPiece : Rulesets.Judgements.DefaultJudgementPiece + public partial class DefaultJudgementPiece : Rulesets.Judgements.DefaultJudgementPiece { public DefaultJudgementPiece(HitResult result) : base(result) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultKiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultKiaiHitExplosion.cs index ae68d63d97..750fb505a0 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultKiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultKiaiHitExplosion.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Skinning.Default { - public class DefaultKiaiHitExplosion : CircularContainer + public partial class DefaultKiaiHitExplosion : CircularContainer { public override bool RemoveWhenNotAlive => true; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/ElongatedCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/ElongatedCirclePiece.cs index 210841bca0..11d82a3714 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/ElongatedCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/ElongatedCirclePiece.cs @@ -7,7 +7,7 @@ using osu.Game.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Default { - public class ElongatedCirclePiece : CirclePiece + public partial class ElongatedCirclePiece : CirclePiece { public ElongatedCirclePiece() { diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs index c6165495d8..0920d58a34 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs @@ -11,7 +11,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Default { - public class RimHitCirclePiece : CirclePiece + public partial class RimHitCirclePiece : CirclePiece { public RimHitCirclePiece() { @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default /// /// The symbol used for rim hit pieces. /// - public class RimHitSymbolPiece : CircularContainer + public partial class RimHitSymbolPiece : CircularContainer { public RimHitSymbolPiece() { diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/SwellSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/SwellSymbolPiece.cs index 2f59cac3ff..d40b518aa3 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/SwellSymbolPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/SwellSymbolPiece.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Skinning.Default { - public class SwellCirclePiece : CirclePiece + public partial class SwellCirclePiece : CirclePiece { public SwellCirclePiece() { @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default /// /// The symbol used for swell pieces. /// - public class SwellSymbolPiece : Container + public partial class SwellSymbolPiece : Container { public SwellSymbolPiece() { diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs index a1eaef53ba..8bd8d5f4b4 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs @@ -13,7 +13,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Default { - public class TickPiece : CompositeDrawable + public partial class TickPiece : CompositeDrawable { /// /// Any tick that is not the first for a drumroll is not filled, but is instead displayed diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyBarLine.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyBarLine.cs index 2b528ae8ce..01100bfd63 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyBarLine.cs @@ -9,7 +9,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { - public class LegacyBarLine : Sprite + public partial class LegacyBarLine : Sprite { [BackgroundDependencyLoader] private void load(ISkinSource skin) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs index a5867ff51c..37eb95b86f 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { - public class LegacyCirclePiece : CompositeDrawable, IHasAccentColour + public partial class LegacyCirclePiece : CompositeDrawable, IHasAccentColour { private Drawable backgroundLayer = null!; private Drawable? foregroundLayer; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyDrumRoll.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyDrumRoll.cs index 1249231d92..5543a31ec9 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyDrumRoll.cs @@ -13,7 +13,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { - public class LegacyDrumRoll : CompositeDrawable, IHasAccentColour + public partial class LegacyDrumRoll : CompositeDrawable, IHasAccentColour { public override Quad ScreenSpaceDrawQuad { diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHit.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHit.cs index d93317f0e2..87c9d72d22 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHit.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHit.cs @@ -7,7 +7,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { - public class LegacyHit : LegacyCirclePiece + public partial class LegacyHit : LegacyCirclePiece { private readonly TaikoSkinComponents component; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs index ff1546381b..b9a432f3bd 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Taiko.UI; namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { - public class LegacyHitExplosion : CompositeDrawable, IAnimatableHitExplosion + public partial class LegacyHitExplosion : CompositeDrawable, IAnimatableHitExplosion { private readonly Drawable sprite; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs index 0abb365750..8ad419f8bd 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy /// /// A component of the playfield that captures input and displays input as a drum. /// - internal class LegacyInputDrum : Container + internal partial class LegacyInputDrum : Container { private Container content = null!; private LegacyHalfDrum left = null!; @@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy /// /// A half-drum. Contains one centre and one rim hit. /// - private class LegacyHalfDrum : Container, IKeyBindingHandler + private partial class LegacyHalfDrum : Container, IKeyBindingHandler { /// /// The key to be used for the rim of the half-drum. diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyTaikoScroller.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyTaikoScroller.cs index 4a2426bff5..2964473f89 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyTaikoScroller.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyTaikoScroller.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { - public class LegacyTaikoScroller : CompositeDrawable + public partial class LegacyTaikoScroller : CompositeDrawable { public Bindable LastResult = new Bindable(); @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy } } - private class ScrollerSprite : CompositeDrawable + private partial class ScrollerSprite : CompositeDrawable { private Sprite passingSprite = null!; private Sprite failingSprite = null!; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs index 21102f6eec..492782f0d1 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { - public class TaikoLegacyHitTarget : CompositeDrawable + public partial class TaikoLegacyHitTarget : CompositeDrawable { private Container content = null!; diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs index 3186f615a7..86175d3bca 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { - public class TaikoLegacyPlayfieldBackgroundRight : BeatSyncedContainer + public partial class TaikoLegacyPlayfieldBackgroundRight : BeatSyncedContainer { private Sprite kiai = null!; diff --git a/osu.Game.Rulesets.Taiko/TaikoInputManager.cs b/osu.Game.Rulesets.Taiko/TaikoInputManager.cs index d36fe5d496..ca06a0a77e 100644 --- a/osu.Game.Rulesets.Taiko/TaikoInputManager.cs +++ b/osu.Game.Rulesets.Taiko/TaikoInputManager.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Taiko { [Cached] // Used for touch input, see DrumTouchInputArea. - public class TaikoInputManager : RulesetInputManager + public partial class TaikoInputManager : RulesetInputManager { public TaikoInputManager(RulesetInfo ruleset) : base(ruleset, 0, SimultaneousBindingMode.Unique) diff --git a/osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs b/osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs index cb878e8ea0..ebdf9ef191 100644 --- a/osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs @@ -8,7 +8,7 @@ using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Taiko.UI { - public class BarLinePlayfield : ScrollingPlayfield + public partial class BarLinePlayfield : ScrollingPlayfield { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs index 24d2fd7be7..f91fe586f2 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Taiko.UI /// /// Text that is shown as judgement when a hit object is hit or missed. /// - public class DrawableTaikoJudgement : DrawableJudgement + public partial class DrawableTaikoJudgement : DrawableJudgement { public DrawableTaikoJudgement() { diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs index c5cf09d449..0dfb796c74 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs @@ -16,7 +16,7 @@ using osu.Game.Screens.Play; namespace osu.Game.Rulesets.Taiko.UI { - public class DrawableTaikoMascot : BeatSyncedContainer + public partial class DrawableTaikoMascot : BeatSyncedContainer { public readonly Bindable State; public readonly Bindable LastResult; diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs index c3d93a344d..32a83d87b8 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs @@ -27,7 +27,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.UI { - public class DrawableTaikoRuleset : DrawableScrollingRuleset + public partial class DrawableTaikoRuleset : DrawableScrollingRuleset { public new BindableDouble TimeRange => base.TimeRange; diff --git a/osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs b/osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs index ae37840825..87ee852171 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs @@ -6,7 +6,7 @@ using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Taiko.UI { - internal class DrumRollHitContainer : ScrollingHitObjectContainer + internal partial class DrumRollHitContainer : ScrollingHitObjectContainer { // TODO: this usage is buggy. // Because `LifetimeStart` is set based on scrolling, lifetime is not same as the time when the object is created. diff --git a/osu.Game.Rulesets.Taiko/UI/DrumSamplePlayer.cs b/osu.Game.Rulesets.Taiko/UI/DrumSamplePlayer.cs index b65e2af3d8..6454fb5afa 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumSamplePlayer.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumSamplePlayer.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Taiko.UI { - internal class DrumSamplePlayer : CompositeDrawable, IKeyBindingHandler + internal partial class DrumSamplePlayer : CompositeDrawable, IKeyBindingHandler { private readonly DrumSampleTriggerSource leftRimSampleTriggerSource; private readonly DrumSampleTriggerSource leftCentreSampleTriggerSource; diff --git a/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs b/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs index 3279d128d3..4809791af8 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs @@ -8,7 +8,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Taiko.UI { - public class DrumSampleTriggerSource : GameplaySampleTriggerSource + public partial class DrumSampleTriggerSource : GameplaySampleTriggerSource { public DrumSampleTriggerSource(HitObjectContainer hitObjectContainer) : base(hitObjectContainer) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index a7d9bd18c5..ab8c0a484e 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Taiko.UI /// /// An overlay that captures and displays osu!taiko mouse and touch input. /// - public class DrumTouchInputArea : VisibilityContainer + public partial class DrumTouchInputArea : VisibilityContainer { // visibility state affects our child. we always want to handle input. public override bool PropagatePositionalInputSubTree => true; @@ -181,7 +181,7 @@ namespace osu.Game.Rulesets.Taiko.UI mainContent.FadeOut(300); } - private class QuarterCircle : CompositeDrawable, IKeyBindingHandler + private partial class QuarterCircle : CompositeDrawable, IKeyBindingHandler { private readonly Circle overlay; diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs index 8f2b702472..1a2652acf9 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Taiko.UI /// /// A circle explodes from the hit target to indicate a hitobject has been hit. /// - internal class HitExplosion : PoolableDrawable + internal partial class HitExplosion : PoolableDrawable { public override bool RemoveWhenNotAlive => true; public override bool RemoveCompletedTransforms => false; diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs index badf34554c..02a78b0f1c 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Taiko.UI /// /// Pool for hit explosions of a specific type. /// - internal class HitExplosionPool : DrawablePool + internal partial class HitExplosionPool : DrawablePool { private readonly HitResult hitResult; diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 2f42a5aaf6..725857ed34 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Taiko.UI /// /// A component of the playfield that captures input and displays input as a drum. /// - internal class InputDrum : Container + internal partial class InputDrum : Container { public InputDrum() { diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs index 627e06e186..6c1e981a97 100644 --- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.UI { - public class KiaiHitExplosion : Container + public partial class KiaiHitExplosion : Container { public override bool RemoveWhenNotAlive => true; diff --git a/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundLeft.cs b/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundLeft.cs index 2a8890a95d..f676d051eb 100644 --- a/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundLeft.cs +++ b/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundLeft.cs @@ -11,7 +11,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.UI { - internal class PlayfieldBackgroundLeft : CompositeDrawable + internal partial class PlayfieldBackgroundLeft : CompositeDrawable { [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundRight.cs b/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundRight.cs index 44bfdacf37..7b2dbc5f5a 100644 --- a/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundRight.cs +++ b/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundRight.cs @@ -12,7 +12,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.UI { - public class PlayfieldBackgroundRight : CompositeDrawable + public partial class PlayfieldBackgroundRight : CompositeDrawable { [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs b/osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs index 6401c6d09f..a2f8dc83db 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Taiko.UI /// /// A component that is displayed at the hit position in the taiko playfield. /// - internal class TaikoHitTarget : Container + internal partial class TaikoHitTarget : Container { /// /// Thickness of all drawn line pieces. diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs index 0f214b8436..7b1e31112e 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.UI { - public sealed class TaikoMascotAnimation : BeatSyncedContainer + public sealed partial class TaikoMascotAnimation : BeatSyncedContainer { private readonly TextureAnimation textureAnimation; @@ -73,7 +73,7 @@ namespace osu.Game.Rulesets.Taiko.UI } } - private class ManualMascotTextureAnimation : TextureAnimation + private partial class ManualMascotTextureAnimation : TextureAnimation { private readonly TaikoMascotAnimationState state; @@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Taiko.UI } } - private class ClearMascotTextureAnimation : TextureAnimation + private partial class ClearMascotTextureAnimation : TextureAnimation { private const float clear_animation_speed = 1000 / 10f; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 45a3b80931..6ce0be5868 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -28,7 +28,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.UI { - public class TaikoPlayfield : ScrollingPlayfield + public partial class TaikoPlayfield : ScrollingPlayfield { /// /// Default height of a when inside a . @@ -342,7 +342,7 @@ namespace osu.Game.Rulesets.Taiko.UI kiaiExplosionContainer.Add(new KiaiHitExplosion(drawableObject, type)); } - private class ProxyContainer : LifetimeManagementContainer + private partial class ProxyContainer : LifetimeManagementContainer { public void Add(Drawable proxy) => AddInternal(proxy); diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs index 9cf530e903..79c5c36e08 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs @@ -8,7 +8,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Taiko.UI { - public class TaikoPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer + public partial class TaikoPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer { private const float default_relative_height = TaikoPlayfield.DEFAULT_HEIGHT / 768; private const float default_aspect = 16f / 9f; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs b/osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs index e6391d1386..57ff3b59d5 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.UI { - public class TaikoReplayRecorder : ReplayRecorder + public partial class TaikoReplayRecorder : ReplayRecorder { public TaikoReplayRecorder(Score score) : base(score) diff --git a/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs b/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs index 6eb103316f..ab40092b3f 100644 --- a/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs +++ b/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs @@ -22,7 +22,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Beatmaps { [HeadlessTest] - public class TestSceneBeatmapDifficultyCache : OsuTestScene + public partial class TestSceneBeatmapDifficultyCache : OsuTestScene { public const double BASE_STARS = 5.55; @@ -162,7 +162,7 @@ namespace osu.Game.Tests.Beatmaps Assert.AreEqual(expectedBracket, actualBracket); } - private class TestBeatmapDifficultyCache : BeatmapDifficultyCache + private partial class TestBeatmapDifficultyCache : BeatmapDifficultyCache { public Func ComputeDifficulty { get; set; } diff --git a/osu.Game.Tests/Beatmaps/TestSceneEditorBeatmap.cs b/osu.Game.Tests/Beatmaps/TestSceneEditorBeatmap.cs index 81d0e6f3ef..bb24560a44 100644 --- a/osu.Game.Tests/Beatmaps/TestSceneEditorBeatmap.cs +++ b/osu.Game.Tests/Beatmaps/TestSceneEditorBeatmap.cs @@ -18,7 +18,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Beatmaps { [HeadlessTest] - public class TestSceneEditorBeatmap : EditorClockTestScene + public partial class TestSceneEditorBeatmap : EditorClockTestScene { /// /// Tests that the addition event is correctly invoked after a hitobject is added. diff --git a/osu.Game.Tests/Beatmaps/WorkingBeatmapManagerTest.cs b/osu.Game.Tests/Beatmaps/WorkingBeatmapManagerTest.cs index 4ef466efbf..89b8c8927d 100644 --- a/osu.Game.Tests/Beatmaps/WorkingBeatmapManagerTest.cs +++ b/osu.Game.Tests/Beatmaps/WorkingBeatmapManagerTest.cs @@ -19,7 +19,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Beatmaps { [HeadlessTest] - public class WorkingBeatmapManagerTest : OsuTestScene + public partial class WorkingBeatmapManagerTest : OsuTestScene { private BeatmapManager beatmaps = null!; diff --git a/osu.Game.Tests/Chat/TestSceneChannelManager.cs b/osu.Game.Tests/Chat/TestSceneChannelManager.cs index c9a78cbf59..cdd192cfe1 100644 --- a/osu.Game.Tests/Chat/TestSceneChannelManager.cs +++ b/osu.Game.Tests/Chat/TestSceneChannelManager.cs @@ -18,7 +18,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Chat { [HeadlessTest] - public class TestSceneChannelManager : OsuTestScene + public partial class TestSceneChannelManager : OsuTestScene { private ChannelManager channelManager; private int currentMessageId; @@ -183,7 +183,7 @@ namespace osu.Game.Tests.Chat LastMessageId = 0, }; - private class ChannelManagerContainer : CompositeDrawable + private partial class ChannelManagerContainer : CompositeDrawable { [Cached] public ChannelManager ChannelManager { get; } diff --git a/osu.Game.Tests/Database/BackgroundBeatmapProcessorTests.cs b/osu.Game.Tests/Database/BackgroundBeatmapProcessorTests.cs index 4012e3f851..ddb60606ec 100644 --- a/osu.Game.Tests/Database/BackgroundBeatmapProcessorTests.cs +++ b/osu.Game.Tests/Database/BackgroundBeatmapProcessorTests.cs @@ -15,7 +15,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Database { [HeadlessTest] - public class BackgroundBeatmapProcessorTests : OsuTestScene, ILocalUserPlayInfo + public partial class BackgroundBeatmapProcessorTests : OsuTestScene, ILocalUserPlayInfo { public IBindable IsPlaying => isPlaying; @@ -124,7 +124,7 @@ namespace osu.Game.Tests.Database }); } - public class TestBackgroundBeatmapProcessor : BackgroundBeatmapProcessor + public partial class TestBackgroundBeatmapProcessor : BackgroundBeatmapProcessor { protected override int TimeToSleepDuringGameplay => 10; } diff --git a/osu.Game.Tests/Database/RealmTest.cs b/osu.Game.Tests/Database/RealmTest.cs index 1b1878942b..d2779e3038 100644 --- a/osu.Game.Tests/Database/RealmTest.cs +++ b/osu.Game.Tests/Database/RealmTest.cs @@ -18,7 +18,7 @@ using osu.Game.Rulesets; namespace osu.Game.Tests.Database { [TestFixture] - public abstract class RealmTest + public abstract partial class RealmTest { protected void RunTestWithRealm([InstantHandle] Action testAction, [CallerMemberName] string caller = "") { @@ -107,7 +107,7 @@ namespace osu.Game.Tests.Database protected static RulesetInfo CreateRuleset() => new RulesetInfo("osu", "osu!", string.Empty, 0) { Available = true }; - private class RealmTestGame : Framework.Game + private partial class RealmTestGame : Framework.Game { public RealmTestGame([InstantHandle] Func work) { diff --git a/osu.Game.Tests/Database/TestRealmKeyBindingStore.cs b/osu.Game.Tests/Database/TestRealmKeyBindingStore.cs index 362b37124d..f4467867db 100644 --- a/osu.Game.Tests/Database/TestRealmKeyBindingStore.cs +++ b/osu.Game.Tests/Database/TestRealmKeyBindingStore.cs @@ -20,7 +20,7 @@ using Realms; namespace osu.Game.Tests.Database { [TestFixture] - public class TestRealmKeyBindingStore + public partial class TestRealmKeyBindingStore { private NativeStorage storage; @@ -123,7 +123,7 @@ namespace osu.Game.Tests.Database storage.DeleteDirectory(string.Empty); } - public class TestKeyBindingContainer : KeyBindingContainer + public partial class TestKeyBindingContainer : KeyBindingContainer { public override IEnumerable DefaultKeyBindings => new[] diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index 495a221159..f556f6e2fe 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -20,7 +20,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Editing { [HeadlessTest] - public class TestSceneHitObjectComposerDistanceSnapping : EditorClockTestScene + public partial class TestSceneHitObjectComposerDistanceSnapping : EditorClockTestScene { private TestHitObjectComposer composer = null!; @@ -251,7 +251,7 @@ namespace osu.Game.Tests.Editing private void assertSnappedDistance(float distance, float expectedDistance, HitObject? referenceObject = null) => AddAssert($"distance = {distance} -> distance = {expectedDistance} (snapped)", () => composer.FindSnappedDistance(referenceObject ?? new HitObject(), distance), () => Is.EqualTo(expectedDistance).Within(Precision.FLOAT_EPSILON)); - private class TestHitObjectComposer : OsuHitObjectComposer + private partial class TestHitObjectComposer : OsuHitObjectComposer { public new EditorBeatmap EditorBeatmap => base.EditorBeatmap; diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectContainerEventBuffer.cs b/osu.Game.Tests/Editing/TestSceneHitObjectContainerEventBuffer.cs index c3e171684c..745c636166 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectContainerEventBuffer.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectContainerEventBuffer.cs @@ -16,7 +16,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Editing { [HeadlessTest] - public class TestSceneHitObjectContainerEventBuffer : OsuTestScene + public partial class TestSceneHitObjectContainerEventBuffer : OsuTestScene { private readonly TestHitObject testObj = new TestHitObject(); @@ -139,7 +139,7 @@ namespace osu.Game.Tests.Editing => AddAssert($"began = {began}, finished = {finished}, transferred = {transferred}", () => (beganUsage == testObj) == began && (finishedUsage == testObj) == finished && (transferredUsage == testObj) == transferred); - private class TestPlayfield : Playfield + private partial class TestPlayfield : Playfield { public TestPlayfield() { @@ -165,11 +165,11 @@ namespace osu.Game.Tests.Editing public override string ToString() => "TestHitObject"; } - private class TestDrawableHitObject : DrawableHitObject + private partial class TestDrawableHitObject : DrawableHitObject { } - private class TestDrawable : Drawable + private partial class TestDrawable : Drawable { public new void Schedule(Action action) => base.Schedule(action); } diff --git a/osu.Game.Tests/Editing/TransactionalCommitComponentTest.cs b/osu.Game.Tests/Editing/TransactionalCommitComponentTest.cs index 3d7286c396..7280631e32 100644 --- a/osu.Game.Tests/Editing/TransactionalCommitComponentTest.cs +++ b/osu.Game.Tests/Editing/TransactionalCommitComponentTest.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Edit; namespace osu.Game.Tests.Editing { [TestFixture] - public class TransactionalCommitComponentTest + public partial class TransactionalCommitComponentTest { private TestHandler handler; @@ -89,7 +89,7 @@ namespace osu.Game.Tests.Editing Assert.That(() => handler.EndChange(), Throws.TypeOf()); } - private class TestHandler : TransactionalCommitComponent + private partial class TestHandler : TransactionalCommitComponent { public int StateUpdateCount { get; private set; } diff --git a/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs b/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs index c4e8bbfccf..fd0bff101f 100644 --- a/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs +++ b/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs @@ -21,7 +21,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Gameplay { [HeadlessTest] - public class TestSceneDrainingHealthProcessor : OsuTestScene + public partial class TestSceneDrainingHealthProcessor : OsuTestScene { private HealthProcessor processor; private ManualClock clock; diff --git a/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs b/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs index 91e33b759c..62863524fe 100644 --- a/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs +++ b/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs @@ -16,7 +16,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Gameplay { [HeadlessTest] - public class TestSceneDrawableHitObject : OsuTestScene + public partial class TestSceneDrawableHitObject : OsuTestScene { [Test] public void TestEntryLifetime() @@ -137,7 +137,7 @@ namespace osu.Game.Tests.Gameplay AddAssert("DHO state is correct", () => dho.State.Value == ArmedState.Miss); } - private class TestDrawableHitObject : DrawableHitObject + private partial class TestDrawableHitObject : DrawableHitObject { public const double INITIAL_LIFETIME_OFFSET = 100; public const double LIFETIME_ON_APPLY = 222; diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs index 255d6400c8..f38c2c9416 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs @@ -25,7 +25,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Gameplay { [HeadlessTest] - public class TestSceneHitObjectAccentColour : OsuTestScene + public partial class TestSceneHitObjectAccentColour : OsuTestScene { [Resolved] private OsuConfigManager config { get; set; } @@ -84,7 +84,7 @@ namespace osu.Game.Tests.Gameplay AddAssert("combo colour is green", () => hitObject.AccentColour.Value == Color4.Green); } - private class TestDrawableHitObject : DrawableHitObject + private partial class TestDrawableHitObject : DrawableHitObject { public TestDrawableHitObject() : base(new TestHitObjectWithCombo()) diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectContainer.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectContainer.cs index 79e64ba2a2..8322833187 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectContainer.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectContainer.cs @@ -14,7 +14,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Gameplay { [HeadlessTest] - public class TestSceneHitObjectContainer : OsuTestScene + public partial class TestSceneHitObjectContainer : OsuTestScene { private HitObjectContainer container; @@ -66,7 +66,7 @@ namespace osu.Game.Tests.Gameplay AddAssert("second object index is 0", () => container.IndexOf(secondObject) == 1); } - private class TestDrawableHitObject : DrawableHitObject + private partial class TestDrawableHitObject : DrawableHitObject { public TestDrawableHitObject([NotNull] HitObject hitObject) : base(hitObject) diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs index e25d08f98c..769ca1f9a9 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectSamples.cs @@ -13,7 +13,7 @@ using static osu.Game.Skinning.SkinConfiguration; namespace osu.Game.Tests.Gameplay { - public class TestSceneHitObjectSamples : HitObjectSampleTest + public partial class TestSceneHitObjectSamples : HitObjectSampleTest { protected override Ruleset CreatePlayerRuleset() => new OsuRuleset(); protected override IResourceStore RulesetResources => TestResources.GetStore(); diff --git a/osu.Game.Tests/Gameplay/TestSceneMasterGameplayClockContainer.cs b/osu.Game.Tests/Gameplay/TestSceneMasterGameplayClockContainer.cs index abd734b96c..3c6ec28da2 100644 --- a/osu.Game.Tests/Gameplay/TestSceneMasterGameplayClockContainer.cs +++ b/osu.Game.Tests/Gameplay/TestSceneMasterGameplayClockContainer.cs @@ -17,7 +17,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Gameplay { [HeadlessTest] - public class TestSceneMasterGameplayClockContainer : OsuTestScene + public partial class TestSceneMasterGameplayClockContainer : OsuTestScene { private OsuConfigManager localConfig; diff --git a/osu.Game.Tests/Gameplay/TestSceneProxyContainer.cs b/osu.Game.Tests/Gameplay/TestSceneProxyContainer.cs index 1893e43f43..be69b77e8b 100644 --- a/osu.Game.Tests/Gameplay/TestSceneProxyContainer.cs +++ b/osu.Game.Tests/Gameplay/TestSceneProxyContainer.cs @@ -17,7 +17,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Gameplay { [HeadlessTest] - public class TestSceneProxyContainer : OsuTestScene + public partial class TestSceneProxyContainer : OsuTestScene { private HitObjectContainer hitObjectContainer; private ProxyContainer proxyContainer; @@ -62,14 +62,14 @@ namespace osu.Game.Tests.Gameplay proxyContainer.AddProxy(drawableHitObject); } - private class ProxyContainer : LifetimeManagementContainer + private partial class ProxyContainer : LifetimeManagementContainer { public IReadOnlyList AliveChildren => AliveInternalChildren; public void AddProxy(Drawable d) => AddInternal(d.CreateProxy()); } - private class TestDrawableHitObject : DrawableHitObject + private partial class TestDrawableHitObject : DrawableHitObject { protected override double InitialLifetimeOffset => 100; diff --git a/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs b/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs index d5219f6391..3ce7aa72d9 100644 --- a/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs +++ b/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs @@ -22,7 +22,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Gameplay { [HeadlessTest] - public class TestSceneScoreProcessor : OsuTestScene + public partial class TestSceneScoreProcessor : OsuTestScene { [Test] public void TestNoScoreIncreaseFromMiss() diff --git a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs index 577933eae3..2cad7d33c2 100644 --- a/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs +++ b/osu.Game.Tests/Gameplay/TestSceneStoryboardSamples.cs @@ -33,7 +33,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Gameplay { [HeadlessTest] - public class TestSceneStoryboardSamples : OsuTestScene, IStorageResourceProvider + public partial class TestSceneStoryboardSamples : OsuTestScene, IStorageResourceProvider { [Resolved] private OsuConfigManager config { get; set; } @@ -199,7 +199,7 @@ namespace osu.Game.Tests.Gameplay protected internal override ISkin GetSkin() => new TestSkin("test-sample", resources); } - private class TestDrawableStoryboardSample : DrawableStoryboardSample + private partial class TestDrawableStoryboardSample : DrawableStoryboardSample { public TestDrawableStoryboardSample(StoryboardSampleInfo sampleInfo) : base(sampleInfo) diff --git a/osu.Game.Tests/ImportTest.cs b/osu.Game.Tests/ImportTest.cs index 23ca31ee42..9e2c9cd7e0 100644 --- a/osu.Game.Tests/ImportTest.cs +++ b/osu.Game.Tests/ImportTest.cs @@ -15,7 +15,7 @@ using osu.Game.Tests.Resources; namespace osu.Game.Tests { - public abstract class ImportTest + public abstract partial class ImportTest { protected virtual TestOsuGameBase LoadOsuIntoHost(GameHost host, bool withBeatmap = false) { @@ -45,7 +45,7 @@ namespace osu.Game.Tests Assert.IsTrue(task.Wait(timeout), failureMessage); } - public class TestOsuGameBase : OsuGameBase + public partial class TestOsuGameBase : OsuGameBase { public RealmAccess Realm => Dependencies.Get(); diff --git a/osu.Game.Tests/Input/ConfineMouseTrackerTest.cs b/osu.Game.Tests/Input/ConfineMouseTrackerTest.cs index a91d4553de..3c296b2ff5 100644 --- a/osu.Game.Tests/Input/ConfineMouseTrackerTest.cs +++ b/osu.Game.Tests/Input/ConfineMouseTrackerTest.cs @@ -15,7 +15,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Input { [HeadlessTest] - public class ConfineMouseTrackerTest : OsuGameTestScene + public partial class ConfineMouseTrackerTest : OsuGameTestScene { [Resolved] private FrameworkConfigManager frameworkConfigManager { get; set; } diff --git a/osu.Game.Tests/Mods/SettingsSourceAttributeTest.cs b/osu.Game.Tests/Mods/SettingsSourceAttributeTest.cs index dd105787fa..bf59862787 100644 --- a/osu.Game.Tests/Mods/SettingsSourceAttributeTest.cs +++ b/osu.Game.Tests/Mods/SettingsSourceAttributeTest.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays.Settings; namespace osu.Game.Tests.Mods { [TestFixture] - public class SettingsSourceAttributeTest + public partial class SettingsSourceAttributeTest { [Test] public void TestOrdering() @@ -60,11 +60,11 @@ namespace osu.Game.Tests.Mods public BindableInt UnorderedSetting { get; set; } = new BindableInt(); } - private class CustomSettingsControl : SettingsItem + private partial class CustomSettingsControl : SettingsItem { protected override Drawable CreateControl() => new CustomControl(); - private class CustomControl : Drawable, IHasCurrentValue + private partial class CustomControl : Drawable, IHasCurrentValue { public Bindable Current { get; set; } = new Bindable(); } diff --git a/osu.Game.Tests/NonVisual/FirstAvailableHitWindowsTest.cs b/osu.Game.Tests/NonVisual/FirstAvailableHitWindowsTest.cs index 14da07bc2d..9a32b8e894 100644 --- a/osu.Game.Tests/NonVisual/FirstAvailableHitWindowsTest.cs +++ b/osu.Game.Tests/NonVisual/FirstAvailableHitWindowsTest.cs @@ -18,7 +18,7 @@ using osu.Game.Scoring; namespace osu.Game.Tests.NonVisual { - public class FirstAvailableHitWindowsTest + public partial class FirstAvailableHitWindowsTest { private TestDrawableRuleset testDrawableRuleset; @@ -76,7 +76,7 @@ namespace osu.Game.Tests.NonVisual } [SuppressMessage("ReSharper", "UnassignedGetOnlyAutoProperty")] - private class TestDrawableRuleset : DrawableRuleset + private partial class TestDrawableRuleset : DrawableRuleset { public List HitObjects; public override IEnumerable Objects => HitObjects; diff --git a/osu.Game.Tests/NonVisual/GameplayClockContainerTest.cs b/osu.Game.Tests/NonVisual/GameplayClockContainerTest.cs index 363c7a459e..d67a3cb824 100644 --- a/osu.Game.Tests/NonVisual/GameplayClockContainerTest.cs +++ b/osu.Game.Tests/NonVisual/GameplayClockContainerTest.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Play; namespace osu.Game.Tests.NonVisual { [TestFixture] - public class GameplayClockContainerTest + public partial class GameplayClockContainerTest { [TestCase(0)] [TestCase(1)] @@ -22,7 +22,7 @@ namespace osu.Game.Tests.NonVisual Assert.That(gameplayClock.GetTrueGameplayRate(), Is.EqualTo(2)); } - private class TestGameplayClockContainer : GameplayClockContainer + private partial class TestGameplayClockContainer : GameplayClockContainer { public TestGameplayClockContainer(IFrameBasedClock underlyingClock) : base(underlyingClock) diff --git a/osu.Game.Tests/NonVisual/Multiplayer/StatefulMultiplayerClientTest.cs b/osu.Game.Tests/NonVisual/Multiplayer/StatefulMultiplayerClientTest.cs index d1c5e2d8b3..ae6a76f6cd 100644 --- a/osu.Game.Tests/NonVisual/Multiplayer/StatefulMultiplayerClientTest.cs +++ b/osu.Game.Tests/NonVisual/Multiplayer/StatefulMultiplayerClientTest.cs @@ -16,7 +16,7 @@ using osu.Game.Tests.Visual.Multiplayer; namespace osu.Game.Tests.NonVisual.Multiplayer { [HeadlessTest] - public class StatefulMultiplayerClientTest : MultiplayerTestScene + public partial class StatefulMultiplayerClientTest : MultiplayerTestScene { [Test] public void TestUserAddedOnJoin() diff --git a/osu.Game.Tests/NonVisual/OngoingOperationTrackerTest.cs b/osu.Game.Tests/NonVisual/OngoingOperationTrackerTest.cs index 03ca3a0a1a..0bcae05f44 100644 --- a/osu.Game.Tests/NonVisual/OngoingOperationTrackerTest.cs +++ b/osu.Game.Tests/NonVisual/OngoingOperationTrackerTest.cs @@ -17,7 +17,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.NonVisual { [HeadlessTest] - public class OngoingOperationTrackerTest : OsuTestScene + public partial class OngoingOperationTrackerTest : OsuTestScene { private OngoingOperationTracker tracker; private IBindable operationInProgress; @@ -94,7 +94,7 @@ namespace osu.Game.Tests.NonVisual AddAssert("operation ended", () => !screen.OngoingOperationTracker.InProgress.Value); } - private class TestScreenWithTracker : OsuScreen + private partial class TestScreenWithTracker : OsuScreen { public OngoingOperationTracker OngoingOperationTracker { get; private set; } diff --git a/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs b/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs index 5c247bace9..197e9404ff 100644 --- a/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs +++ b/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs @@ -22,7 +22,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.NonVisual.Skinning { [HeadlessTest] - public class LegacySkinAnimationTest : OsuTestScene + public partial class LegacySkinAnimationTest : OsuTestScene { private const string animation_name = "animation"; private const int frame_count = 6; diff --git a/osu.Game.Tests/Online/TestDummyAPIRequestHandling.cs b/osu.Game.Tests/Online/TestDummyAPIRequestHandling.cs index 61fdae0ca1..f41c3ad6af 100644 --- a/osu.Game.Tests/Online/TestDummyAPIRequestHandling.cs +++ b/osu.Game.Tests/Online/TestDummyAPIRequestHandling.cs @@ -14,7 +14,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Online { [HeadlessTest] - public class TestDummyAPIRequestHandling : OsuTestScene + public partial class TestDummyAPIRequestHandling : OsuTestScene { [Test] public void TestGenericRequestHandling() diff --git a/osu.Game.Tests/Online/TestSceneBeatmapDownloading.cs b/osu.Game.Tests/Online/TestSceneBeatmapDownloading.cs index 641c1ad523..c959132332 100644 --- a/osu.Game.Tests/Online/TestSceneBeatmapDownloading.cs +++ b/osu.Game.Tests/Online/TestSceneBeatmapDownloading.cs @@ -15,7 +15,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Online { [HeadlessTest] - public class TestSceneBeatmapDownloading : OsuTestScene + public partial class TestSceneBeatmapDownloading : OsuTestScene { private BeatmapModelDownloader beatmaps; private ProgressNotification recentNotification; diff --git a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs index e7590df3e0..e1d8e08c5e 100644 --- a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs +++ b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs @@ -34,7 +34,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Online { [HeadlessTest] - public class TestSceneOnlinePlayBeatmapAvailabilityTracker : OsuTestScene + public partial class TestSceneOnlinePlayBeatmapAvailabilityTracker : OsuTestScene { private RulesetStore rulesets; private TestBeatmapManager beatmaps; diff --git a/osu.Game.Tests/OnlinePlay/TestSceneCatchUpSyncManager.cs b/osu.Game.Tests/OnlinePlay/TestSceneCatchUpSyncManager.cs index 6015c92663..1d568a9dc2 100644 --- a/osu.Game.Tests/OnlinePlay/TestSceneCatchUpSyncManager.cs +++ b/osu.Game.Tests/OnlinePlay/TestSceneCatchUpSyncManager.cs @@ -16,7 +16,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.OnlinePlay { [HeadlessTest] - public class TestSceneCatchUpSyncManager : OsuTestScene + public partial class TestSceneCatchUpSyncManager : OsuTestScene { private GameplayClockContainer master; private SpectatorSyncManager syncManager; diff --git a/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs b/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs index 7a45d1e7cf..e9e94aa897 100644 --- a/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs +++ b/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs @@ -22,7 +22,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Tests.Rulesets.Scoring { - public class ScoreProcessorTest + public partial class ScoreProcessorTest { private ScoreProcessor scoreProcessor; private IBeatmap beatmap; @@ -394,7 +394,7 @@ namespace osu.Game.Tests.Rulesets.Scoring } } - private class TestScoreProcessor : ScoreProcessor + private partial class TestScoreProcessor : ScoreProcessor { protected override double DefaultAccuracyPortion => 0.5; protected override double DefaultComboPortion => 0.5; diff --git a/osu.Game.Tests/Rulesets/TestSceneBrokenRulesetHandling.cs b/osu.Game.Tests/Rulesets/TestSceneBrokenRulesetHandling.cs index ecc4b3ec63..c3a6b7c474 100644 --- a/osu.Game.Tests/Rulesets/TestSceneBrokenRulesetHandling.cs +++ b/osu.Game.Tests/Rulesets/TestSceneBrokenRulesetHandling.cs @@ -18,7 +18,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Rulesets { [HeadlessTest] - public class TestSceneBrokenRulesetHandling : OsuTestScene + public partial class TestSceneBrokenRulesetHandling : OsuTestScene { [Resolved] private OsuGameBase gameBase { get; set; } = null!; diff --git a/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs b/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs index 29534348dc..3fba21050e 100644 --- a/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs +++ b/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs @@ -29,7 +29,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Rulesets { [HeadlessTest] - public class TestSceneDrawableRulesetDependencies : OsuTestScene + public partial class TestSceneDrawableRulesetDependencies : OsuTestScene { [Test] public void TestDisposalDoesNotDisposeParentStores() @@ -63,7 +63,7 @@ namespace osu.Game.Tests.Rulesets AddAssert("parent shader manager not disposed", () => !shaderManager.IsDisposed); } - private class DrawableWithDependencies : CompositeDrawable + private partial class DrawableWithDependencies : CompositeDrawable { public TestTextureStore ParentTextureStore { get; private set; } public TestSampleStore ParentSampleStore { get; private set; } diff --git a/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs b/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs index a29fc9f1fb..11f3fe660d 100644 --- a/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs +++ b/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs @@ -21,7 +21,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Rulesets { [HeadlessTest] - public class TestSceneRulesetSkinProvidingContainer : OsuTestScene + public partial class TestSceneRulesetSkinProvidingContainer : OsuTestScene { private SkinRequester requester; @@ -64,7 +64,7 @@ namespace osu.Game.Tests.Rulesets }); } - private class SkinRequester : Drawable, ISkin + private partial class SkinRequester : Drawable, ISkin { private ISkinSource skin; diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs index a31c624f78..0bbf4406fb 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs @@ -23,7 +23,7 @@ namespace osu.Game.Tests.Skins { [TestFixture] [HeadlessTest] - public class TestSceneBeatmapSkinLookupDisables : OsuTestScene + public partial class TestSceneBeatmapSkinLookupDisables : OsuTestScene { private UserSkinSource userSource; private BeatmapSkinSource beatmapSource; @@ -88,7 +88,7 @@ namespace osu.Game.Tests.Skins } } - public class SkinRequester : Drawable, ISkin + public partial class SkinRequester : Drawable, ISkin { private ISkinSource skin; diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs index e82a5b57d9..5256bcb3af 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs @@ -17,7 +17,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Skins { [HeadlessTest] - public class TestSceneBeatmapSkinResources : OsuTestScene + public partial class TestSceneBeatmapSkinResources : OsuTestScene { [Resolved] private BeatmapManager beatmaps { get; set; } diff --git a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs index 8c6f137dc0..816834989c 100644 --- a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs +++ b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs @@ -27,7 +27,7 @@ namespace osu.Game.Tests.Skins { [TestFixture] [HeadlessTest] - public class TestSceneSkinConfigurationLookup : OsuTestScene + public partial class TestSceneSkinConfigurationLookup : OsuTestScene { private UserSkinSource userSource; private BeatmapSkinSource beatmapSource; @@ -211,7 +211,7 @@ namespace osu.Game.Tests.Skins } } - public class SkinRequester : Drawable, ISkin + public partial class SkinRequester : Drawable, ISkin { private ISkinSource skin; diff --git a/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs b/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs index ad71296a11..df314b56a9 100644 --- a/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs +++ b/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs @@ -20,7 +20,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Skins { [HeadlessTest] - public class TestSceneSkinProvidingContainer : OsuTestScene + public partial class TestSceneSkinProvidingContainer : OsuTestScene { [Resolved] private IRenderer renderer { get; set; } @@ -59,7 +59,7 @@ namespace osu.Game.Tests.Skins }); } - private class TestSkinProvidingContainer : SkinProvidingContainer + private partial class TestSkinProvidingContainer : SkinProvidingContainer { private readonly IEnumerable sources; diff --git a/osu.Game.Tests/Skins/TestSceneSkinResources.cs b/osu.Game.Tests/Skins/TestSceneSkinResources.cs index 22d6d08355..748668b6ca 100644 --- a/osu.Game.Tests/Skins/TestSceneSkinResources.cs +++ b/osu.Game.Tests/Skins/TestSceneSkinResources.cs @@ -26,7 +26,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Skins { [HeadlessTest] - public class TestSceneSkinResources : OsuTestScene + public partial class TestSceneSkinResources : OsuTestScene { [Resolved] private SkinManager skins { get; set; } = null!; diff --git a/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs b/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs index 79b44c109a..f1533a32b9 100644 --- a/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs +++ b/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs @@ -30,7 +30,7 @@ namespace osu.Game.Tests.Testing /// provided ruleset below are cached at the base implementation. /// [HeadlessTest] - public class TestSceneRulesetDependencies : OsuTestScene + public partial class TestSceneRulesetDependencies : OsuTestScene { protected override Ruleset CreateRuleset() => new TestRuleset(); diff --git a/osu.Game.Tests/Visual/Audio/TestSceneAudioFilter.cs b/osu.Game.Tests/Visual/Audio/TestSceneAudioFilter.cs index 15903b2074..cc72731493 100644 --- a/osu.Game.Tests/Visual/Audio/TestSceneAudioFilter.cs +++ b/osu.Game.Tests/Visual/Audio/TestSceneAudioFilter.cs @@ -19,7 +19,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Tests.Visual.Audio { - public class TestSceneAudioFilter : OsuTestScene + public partial class TestSceneAudioFilter : OsuTestScene { private OsuSpriteText lowPassText; private AudioFilter lowPassFilter; diff --git a/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs b/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs index d9dfa1d876..fbdaad1cd8 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs @@ -32,7 +32,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Tests.Visual.Background { [TestFixture] - public class TestSceneBackgroundScreenDefault : OsuTestScene + public partial class TestSceneBackgroundScreenDefault : OsuTestScene { private BackgroundScreenStack stack; private TestBackgroundScreenDefault screen; @@ -252,7 +252,7 @@ namespace osu.Game.Tests.Visual.Background private WorkingBeatmap createTestWorkingBeatmapWithUniqueBackground() => new UniqueBackgroundTestWorkingBeatmap(renderer, Audio); private WorkingBeatmap createTestWorkingBeatmapWithStoryboard() => new TestWorkingBeatmapWithStoryboard(Audio); - private class TestBackgroundScreenDefault : BackgroundScreenDefault + private partial class TestBackgroundScreenDefault : BackgroundScreenDefault { private bool? lastLoadTriggerCausedChange; @@ -289,7 +289,7 @@ namespace osu.Game.Tests.Visual.Background protected override Texture GetBackground() => renderer.CreateTexture(1, 1); } - private class TestWorkingBeatmapWithStoryboard : TestWorkingBeatmap + private partial class TestWorkingBeatmapWithStoryboard : TestWorkingBeatmap { public TestWorkingBeatmapWithStoryboard(AudioManager audioManager) : base(new Beatmap(), createStoryboard(), audioManager) @@ -315,7 +315,7 @@ namespace osu.Game.Tests.Visual.Background public Drawable CreateDrawable() => new DrawableTestStoryboardElement(); } - private class DrawableTestStoryboardElement : OsuSpriteText + private partial class DrawableTestStoryboardElement : OsuSpriteText { public override bool RemoveWhenNotAlive => false; diff --git a/osu.Game.Tests/Visual/Background/TestSceneSeasonalBackgroundLoader.cs b/osu.Game.Tests/Visual/Background/TestSceneSeasonalBackgroundLoader.cs index c9920cd01f..54a722cee0 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneSeasonalBackgroundLoader.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneSeasonalBackgroundLoader.cs @@ -20,7 +20,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Tests.Visual.Background { - public class TestSceneSeasonalBackgroundLoader : ScreenTestScene + public partial class TestSceneSeasonalBackgroundLoader : ScreenTestScene { [Resolved] private OsuConfigManager config { get; set; } diff --git a/osu.Game.Tests/Visual/Background/TestSceneTrianglesBackground.cs b/osu.Game.Tests/Visual/Background/TestSceneTrianglesBackground.cs index 81a3249efb..d3cdf928e8 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneTrianglesBackground.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneTrianglesBackground.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Shapes; namespace osu.Game.Tests.Visual.Background { - public class TestSceneTrianglesBackground : OsuTestScene + public partial class TestSceneTrianglesBackground : OsuTestScene { private readonly Triangles triangles; diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs index 917434ae22..5df5337a96 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs @@ -37,7 +37,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Background { [TestFixture] - public class TestSceneUserDimBackgrounds : ScreenTestScene + public partial class TestSceneUserDimBackgrounds : ScreenTestScene { private DummySongSelect songSelect; private TestPlayerLoader playerLoader; @@ -299,7 +299,7 @@ namespace osu.Game.Tests.Visual.Background rulesets?.Dispose(); } - private class DummySongSelect : PlaySongSelect + private partial class DummySongSelect : PlaySongSelect { private FadeAccessibleBackground background; @@ -346,7 +346,7 @@ namespace osu.Game.Tests.Visual.Background public bool IsBackgroundCurrent() => background?.IsCurrentScreen() == true; } - private class FadeAccessibleResults : ResultsScreen + private partial class FadeAccessibleResults : ResultsScreen { public FadeAccessibleResults(ScoreInfo score) : base(score, true) @@ -358,7 +358,7 @@ namespace osu.Game.Tests.Visual.Background public Vector2 ExpectedBackgroundBlur => new Vector2(BACKGROUND_BLUR); } - private class LoadBlockingTestPlayer : TestPlayer + private partial class LoadBlockingTestPlayer : TestPlayer { protected override BackgroundScreen CreateBackground() => new FadeAccessibleBackground(Beatmap.Value); @@ -400,7 +400,7 @@ namespace osu.Game.Tests.Visual.Background } } - private class TestPlayerLoader : PlayerLoader + private partial class TestPlayerLoader : PlayerLoader { private FadeAccessibleBackground background; @@ -419,7 +419,7 @@ namespace osu.Game.Tests.Visual.Background protected override BackgroundScreen CreateBackground() => background = new FadeAccessibleBackground(Beatmap.Value); } - private class FadeAccessibleBackground : BackgroundScreenBeatmap + private partial class FadeAccessibleBackground : BackgroundScreenBeatmap { protected override DimmableBackground CreateFadeContainer() => dimmable = new TestDimmableBackground { RelativeSizeAxes = Axes.Both }; @@ -439,7 +439,7 @@ namespace osu.Game.Tests.Visual.Background } } - private class TestDimmableBackground : BackgroundScreenBeatmap.DimmableBackground + private partial class TestDimmableBackground : BackgroundScreenBeatmap.DimmableBackground { public Color4 CurrentColour => Content.Colour; public float CurrentAlpha => Content.Alpha; diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs index 7cad6f504b..ff35f5e8a9 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimContainer.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Background { - public class TestSceneUserDimContainer : OsuTestScene + public partial class TestSceneUserDimContainer : OsuTestScene { private TestUserDimContainer userDimContainer; @@ -104,7 +104,7 @@ namespace osu.Game.Tests.Visual.Background AddAssert("no dim", () => userDimContainer.DimEqual(0)); } - private class TestUserDimContainer : UserDimContainer + private partial class TestUserDimContainer : UserDimContainer { public bool DimEqual(float expectedDimLevel) => Content.Colour == OsuColour.Gray(1f - expectedDimLevel); diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCard.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCard.cs index f95e3b9990..d4018be7fc 100644 --- a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCard.cs +++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCard.cs @@ -26,7 +26,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Beatmaps { - public class TestSceneBeatmapCard : OsuManualInputManagerTestScene + public partial class TestSceneBeatmapCard : OsuManualInputManagerTestScene { /// /// All cards on this scene use a common online ID to ensure that map download, preview tracks, etc. can be tested manually with online sources. diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDifficultyList.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDifficultyList.cs index b609b06921..9f3e36ad76 100644 --- a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDifficultyList.cs +++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDifficultyList.cs @@ -13,7 +13,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Beatmaps { - public class TestSceneBeatmapCardDifficultyList : OsuTestScene + public partial class TestSceneBeatmapCardDifficultyList : OsuTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDownloadButton.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDownloadButton.cs index 82e18e45bb..ed80def57d 100644 --- a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDownloadButton.cs +++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDownloadButton.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Beatmaps { - public class TestSceneBeatmapCardDownloadButton : OsuTestScene + public partial class TestSceneBeatmapCardDownloadButton : OsuTestScene { private DownloadButton downloadButton; diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs index 9540d9e4f7..c33033624a 100644 --- a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs +++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs @@ -19,7 +19,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Beatmaps { - public class TestSceneBeatmapCardFavouriteButton : OsuManualInputManagerTestScene + public partial class TestSceneBeatmapCardFavouriteButton : OsuManualInputManagerTestScene { private DummyAPIAccess dummyAPI => (DummyAPIAccess)API; diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardThumbnail.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardThumbnail.cs index 5afda0ad0c..f44fe2b90c 100644 --- a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardThumbnail.cs +++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardThumbnail.cs @@ -17,7 +17,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Beatmaps { - public class TestSceneBeatmapCardThumbnail : OsuManualInputManagerTestScene + public partial class TestSceneBeatmapCardThumbnail : OsuManualInputManagerTestScene { private PlayButton playButton => this.ChildrenOfType().Single(); diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapSetOnlineStatusPill.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapSetOnlineStatusPill.cs index ada521f7f6..8a11d60875 100644 --- a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapSetOnlineStatusPill.cs +++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapSetOnlineStatusPill.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Beatmaps { - public class TestSceneBeatmapSetOnlineStatusPill : ThemeComparisonTestScene + public partial class TestSceneBeatmapSetOnlineStatusPill : ThemeComparisonTestScene { protected override Drawable CreateContent() => new FillFlowContainer { diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultySpectrumDisplay.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultySpectrumDisplay.cs index 94b2d10fcf..11fa6ed92d 100644 --- a/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultySpectrumDisplay.cs +++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultySpectrumDisplay.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Beatmaps { - public class TestSceneDifficultySpectrumDisplay : OsuTestScene + public partial class TestSceneDifficultySpectrumDisplay : OsuTestScene { private DifficultySpectrumDisplay display; diff --git a/osu.Game.Tests/Visual/Collections/TestSceneManageCollectionsDialog.cs b/osu.Game.Tests/Visual/Collections/TestSceneManageCollectionsDialog.cs index 77e781bfe4..1e9982f8d4 100644 --- a/osu.Game.Tests/Visual/Collections/TestSceneManageCollectionsDialog.cs +++ b/osu.Game.Tests/Visual/Collections/TestSceneManageCollectionsDialog.cs @@ -21,7 +21,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Collections { - public class TestSceneManageCollectionsDialog : OsuManualInputManagerTestScene + public partial class TestSceneManageCollectionsDialog : OsuManualInputManagerTestScene { protected override Container Content { get; } = new Container { RelativeSizeAxes = Axes.Both }; diff --git a/osu.Game.Tests/Visual/Colours/TestSceneStarDifficultyColours.cs b/osu.Game.Tests/Visual/Colours/TestSceneStarDifficultyColours.cs index 13d7a33600..55a2efa89d 100644 --- a/osu.Game.Tests/Visual/Colours/TestSceneStarDifficultyColours.cs +++ b/osu.Game.Tests/Visual/Colours/TestSceneStarDifficultyColours.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Colours { - public class TestSceneStarDifficultyColours : OsuTestScene + public partial class TestSceneStarDifficultyColours : OsuTestScene { [Resolved] private OsuColour colours { get; set; } diff --git a/osu.Game.Tests/Visual/Components/TestSceneIdleTracker.cs b/osu.Game.Tests/Visual/Components/TestSceneIdleTracker.cs index 9dd75b6e5e..aad30ff450 100644 --- a/osu.Game.Tests/Visual/Components/TestSceneIdleTracker.cs +++ b/osu.Game.Tests/Visual/Components/TestSceneIdleTracker.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Components { [TestFixture] - public class TestSceneIdleTracker : OsuManualInputManagerTestScene + public partial class TestSceneIdleTracker : OsuManualInputManagerTestScene { private IdleTrackingBox box1; private IdleTrackingBox box2; @@ -154,7 +154,7 @@ namespace osu.Game.Tests.Visual.Components AddUntilStep("wait for all idle", () => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle); } - private class IdleTrackingBox : CompositeDrawable + private partial class IdleTrackingBox : CompositeDrawable { private readonly IdleTracker idleTracker; diff --git a/osu.Game.Tests/Visual/Components/TestScenePollingComponent.cs b/osu.Game.Tests/Visual/Components/TestScenePollingComponent.cs index 3c89267610..4bab8d0ccc 100644 --- a/osu.Game.Tests/Visual/Components/TestScenePollingComponent.cs +++ b/osu.Game.Tests/Visual/Components/TestScenePollingComponent.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Components { [HeadlessTest] - public class TestScenePollingComponent : OsuTestScene + public partial class TestScenePollingComponent : OsuTestScene { private Container pollBox; private TestPoller poller; @@ -132,7 +132,7 @@ namespace osu.Game.Tests.Visual.Components protected override double TimePerAction => 500; - public class TestPoller : PollingComponent + public partial class TestPoller : PollingComponent { public event Action OnPoll; @@ -143,7 +143,7 @@ namespace osu.Game.Tests.Visual.Components } } - public class TestSlowPoller : TestPoller + public partial class TestSlowPoller : TestPoller { protected override Task Poll() => Task.Delay((int)(TimeBetweenPolls.Value / 2f / Clock.Rate)).ContinueWith(_ => base.Poll()); } diff --git a/osu.Game.Tests/Visual/Components/TestScenePreviewTrackManager.cs b/osu.Game.Tests/Visual/Components/TestScenePreviewTrackManager.cs index 94a71ed50c..b334616125 100644 --- a/osu.Game.Tests/Visual/Components/TestScenePreviewTrackManager.cs +++ b/osu.Game.Tests/Visual/Components/TestScenePreviewTrackManager.cs @@ -13,7 +13,7 @@ using osu.Game.Beatmaps; namespace osu.Game.Tests.Visual.Components { - public class TestScenePreviewTrackManager : OsuTestScene, IPreviewTrackOwner + public partial class TestScenePreviewTrackManager : OsuTestScene, IPreviewTrackOwner { private readonly IAdjustableAudioComponent gameTrackAudio = new AudioAdjustments(); @@ -201,7 +201,7 @@ namespace osu.Game.Tests.Visual.Components return track; } - private class TestTrackOwner : CompositeDrawable, IPreviewTrackOwner + private partial class TestTrackOwner : CompositeDrawable, IPreviewTrackOwner { private readonly PreviewTrack track; private readonly bool registerAsOwner; @@ -227,7 +227,7 @@ namespace osu.Game.Tests.Visual.Components } } - public class TestPreviewTrackManager : PreviewTrackManager + public partial class TestPreviewTrackManager : PreviewTrackManager { public bool AllowUpdate = true; @@ -248,7 +248,7 @@ namespace osu.Game.Tests.Visual.Components return base.UpdateSubTree(); } - public class TestPreviewTrack : TrackManagerPreviewTrack + public partial class TestPreviewTrack : TrackManagerPreviewTrack { private readonly ITrackStore trackManager; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneBeatDivisorControl.cs b/osu.Game.Tests/Visual/Editing/TestSceneBeatDivisorControl.cs index f2d27b9117..56b16301be 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneBeatDivisorControl.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneBeatDivisorControl.cs @@ -21,7 +21,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneBeatDivisorControl : OsuManualInputManagerTestScene + public partial class TestSceneBeatDivisorControl : OsuManualInputManagerTestScene { private BeatDivisorControl beatDivisorControl; private BindableBeatDivisor bindableBeatDivisor; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneBlueprintOrdering.cs b/osu.Game.Tests/Visual/Editing/TestSceneBlueprintOrdering.cs index 796a3cf9fc..7728adecae 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneBlueprintOrdering.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneBlueprintOrdering.cs @@ -24,7 +24,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneBlueprintOrdering : EditorTestScene + public partial class TestSceneBlueprintOrdering : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneComposeScreen.cs b/osu.Game.Tests/Visual/Editing/TestSceneComposeScreen.cs index 0df44b9ac4..035092ecb7 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneComposeScreen.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneComposeScreen.cs @@ -21,7 +21,7 @@ using osu.Game.Skinning; namespace osu.Game.Tests.Visual.Editing { [TestFixture] - public class TestSceneComposeScreen : EditorClockTestScene + public partial class TestSceneComposeScreen : EditorClockTestScene { private EditorBeatmap editorBeatmap = null!; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneComposeSelectBox.cs b/osu.Game.Tests/Visual/Editing/TestSceneComposeSelectBox.cs index 52e44efb30..7a0b3d0c1a 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneComposeSelectBox.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneComposeSelectBox.cs @@ -15,7 +15,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneComposeSelectBox : OsuManualInputManagerTestScene + public partial class TestSceneComposeSelectBox : OsuManualInputManagerTestScene { private Container selectionArea; private SelectionBox selectionBox; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs b/osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs index 31fc107892..ffb8a67c68 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs @@ -26,7 +26,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneComposerSelection : EditorTestScene + public partial class TestSceneComposerSelection : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDesignSection.cs b/osu.Game.Tests/Visual/Editing/TestSceneDesignSection.cs index 1ecbc24d90..9a66e1676d 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDesignSection.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDesignSection.cs @@ -20,7 +20,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneDesignSection : OsuManualInputManagerTestScene + public partial class TestSceneDesignSection : OsuManualInputManagerTestScene { private TestDesignSection designSection; private EditorBeatmap editorBeatmap { get; set; } @@ -97,7 +97,7 @@ namespace osu.Game.Tests.Visual.Editing AddAssert($"beatmap value is {expectedFinalValue}", () => editorBeatmap.BeatmapInfo.CountdownOffset == expectedFinalValue); } - private class TestDesignSection : DesignSection + private partial class TestDesignSection : DesignSection { public new LabelledSwitchButton EnableCountdown => base.EnableCountdown; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDifficultyDelete.cs b/osu.Game.Tests/Visual/Editing/TestSceneDifficultyDelete.cs index 4366b1c0bb..280e6de97e 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDifficultyDelete.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDifficultyDelete.cs @@ -18,7 +18,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneDifficultyDelete : EditorTestScene + public partial class TestSceneDifficultyDelete : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); protected override bool IsolateSavingFromDatabase => false; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDifficultySwitching.cs b/osu.Game.Tests/Visual/Editing/TestSceneDifficultySwitching.cs index 1f88fa8f35..69070b0b64 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDifficultySwitching.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDifficultySwitching.cs @@ -20,7 +20,7 @@ using osu.Game.Tests.Beatmaps.IO; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneDifficultySwitching : EditorTestScene + public partial class TestSceneDifficultySwitching : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs index 01a49c7dea..21b925a257 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneDistanceSnapGrid : EditorClockTestScene + public partial class TestSceneDistanceSnapGrid : EditorClockTestScene { private const double beat_length = 100; private const int beat_snap_distance = 10; @@ -108,7 +108,7 @@ namespace osu.Game.Tests.Visual.Editing AddStep("check correct interval count", () => Assert.That((end_time / grid.DistanceBetweenTicks) * multiplier, Is.EqualTo(grid.MaxIntervals))); } - private class TestDistanceSnapGrid : DistanceSnapGrid + private partial class TestDistanceSnapGrid : DistanceSnapGrid { public new float DistanceBetweenTicks => base.DistanceBetweenTicks; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs index 80a5b4832b..a40c7814e1 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs @@ -31,7 +31,7 @@ using SharpCompress.Archives.Zip; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneEditorBeatmapCreation : EditorTestScene + public partial class TestSceneEditorBeatmapCreation : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorBindings.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorBindings.cs index 5771d64775..61723aab7e 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorBindings.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorBindings.cs @@ -11,7 +11,7 @@ namespace osu.Game.Tests.Visual.Editing /// /// Test editor hotkeys at a high level to ensure they all work well together. /// - public class TestSceneEditorBindings : EditorTestScene + public partial class TestSceneEditorBindings : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorChangeStates.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorChangeStates.cs index 109a49310a..278b6e9626 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorChangeStates.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorChangeStates.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Osu.Objects; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneEditorChangeStates : EditorTestScene + public partial class TestSceneEditorChangeStates : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs index 0a5a1febe4..d26bb6bb8a 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneEditorClipboard : EditorTestScene + public partial class TestSceneEditorClipboard : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorClock.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorClock.cs index 319f8ab9dc..82d2542190 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorClock.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorClock.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Editing { [TestFixture] - public class TestSceneEditorClock : EditorClockTestScene + public partial class TestSceneEditorClock : EditorClockTestScene { [Cached] private EditorBeatmap editorBeatmap = new EditorBeatmap(new TestBeatmap(new OsuRuleset().RulesetInfo)); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorComposeRadioButtons.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorComposeRadioButtons.cs index 6a69347651..e11d2e9dbf 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorComposeRadioButtons.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorComposeRadioButtons.cs @@ -13,7 +13,7 @@ using osu.Game.Screens.Edit.Components.RadioButtons; namespace osu.Game.Tests.Visual.Editing { [TestFixture] - public class TestSceneEditorComposeRadioButtons : OsuTestScene + public partial class TestSceneEditorComposeRadioButtons : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Aquamarine); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorMenuBar.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorMenuBar.cs index 913155aafb..699b99c57f 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorMenuBar.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorMenuBar.cs @@ -15,7 +15,7 @@ using osu.Game.Screens.Edit.Components.Menus; namespace osu.Game.Tests.Visual.Editing { [TestFixture] - public class TestSceneEditorMenuBar : OsuTestScene + public partial class TestSceneEditorMenuBar : OsuTestScene { [Cached] private readonly OverlayColourProvider overlayColour = new OverlayColourProvider(OverlayColourScheme.Aquamarine); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorNavigation.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorNavigation.cs index 327d581e37..5914290d40 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorNavigation.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorNavigation.cs @@ -17,7 +17,7 @@ using osu.Game.Tests.Resources; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneEditorNavigation : OsuGameTestScene + public partial class TestSceneEditorNavigation : OsuGameTestScene { [Test] public void TestEditorGameplayTestAlwaysUsesOriginalRuleset() diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorSamplePlayback.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorSamplePlayback.cs index 43a3cb1342..8b941d7597 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorSamplePlayback.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorSamplePlayback.cs @@ -13,7 +13,7 @@ using osu.Game.Skinning; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneEditorSamplePlayback : EditorTestScene + public partial class TestSceneEditorSamplePlayback : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs index d7e9cc1bc0..70118e0b67 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs @@ -20,7 +20,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneEditorSaving : EditorSavingTestScene + public partial class TestSceneEditorSaving : EditorSavingTestScene { [Test] public void TestCantExitWithoutSaving() diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorScreenModes.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorScreenModes.cs index 962260e1bd..a9d054881b 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorScreenModes.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorScreenModes.cs @@ -12,7 +12,7 @@ using osu.Game.Screens.Edit; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneEditorScreenModes : EditorTestScene + public partial class TestSceneEditorScreenModes : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorSeekSnapping.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorSeekSnapping.cs index aa4bccd728..9df5df6b39 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorSeekSnapping.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorSeekSnapping.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Editing { [TestFixture] - public class TestSceneEditorSeekSnapping : EditorClockTestScene + public partial class TestSceneEditorSeekSnapping : EditorClockTestScene { public TestSceneEditorSeekSnapping() { @@ -315,7 +315,7 @@ namespace osu.Game.Tests.Visual.Editing AddStep("Reset", () => EditorClock.Seek(0)); } - private class TimingPointVisualiser : CompositeDrawable + private partial class TimingPointVisualiser : CompositeDrawable { private readonly double length; @@ -386,7 +386,7 @@ namespace osu.Game.Tests.Visual.Editing tracker.X = (float)(Time.Current / length); } - private class TimingPointTimeline : CompositeDrawable + private partial class TimingPointTimeline : CompositeDrawable { public TimingPointTimeline(TimingControlPoint timingPoint, double endTime, double fullDuration) { diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorSeeking.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorSeeking.cs index 924396ce03..817e0f17f7 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorSeeking.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorSeeking.cs @@ -12,7 +12,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneEditorSeeking : EditorTestScene + public partial class TestSceneEditorSeeking : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorSummaryTimeline.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorSummaryTimeline.cs index 3657878075..ccd2feef9c 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorSummaryTimeline.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorSummaryTimeline.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Editing { [TestFixture] - public class TestSceneEditorSummaryTimeline : EditorClockTestScene + public partial class TestSceneEditorSummaryTimeline : EditorClockTestScene { [Cached(typeof(EditorBeatmap))] private readonly EditorBeatmap editorBeatmap; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs index ee6c322ee3..2250868a39 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs @@ -27,7 +27,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneEditorTestGameplay : EditorTestScene + public partial class TestSceneEditorTestGameplay : EditorTestScene { protected override bool IsolateSavingFromDatabase => false; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs index 1c87eb49c9..7ab0188114 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs @@ -29,7 +29,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { [TestFixture] - public class TestSceneHitObjectComposer : EditorClockTestScene + public partial class TestSceneHitObjectComposer : EditorClockTestScene { private OsuHitObjectComposer hitObjectComposer; private EditorBeatmapContainer editorBeatmapContainer; @@ -168,7 +168,7 @@ namespace osu.Game.Tests.Visual.Editing AddAssert("distance spacing increased by 0.5", () => editorBeatmap.BeatmapInfo.DistanceSpacing == originalSpacing + 0.5); } - public class EditorBeatmapContainer : Container + public partial class EditorBeatmapContainer : Container { private readonly IWorkingBeatmap working; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectDifficultyPointAdjustments.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectDifficultyPointAdjustments.cs index a429c6f58b..ab82678eb9 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectDifficultyPointAdjustments.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectDifficultyPointAdjustments.cs @@ -23,7 +23,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneHitObjectDifficultyPointAdjustments : EditorTestScene + public partial class TestSceneHitObjectDifficultyPointAdjustments : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs index 6313842dfd..e8dcc6f19b 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs @@ -23,7 +23,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneHitObjectSamplePointAdjustments : EditorTestScene + public partial class TestSceneHitObjectSamplePointAdjustments : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneLabelledTimeSignature.cs b/osu.Game.Tests/Visual/Editing/TestSceneLabelledTimeSignature.cs index 328e41ebea..e91596b872 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneLabelledTimeSignature.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneLabelledTimeSignature.cs @@ -13,7 +13,7 @@ using osu.Game.Screens.Edit.Timing; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneLabelledTimeSignature : OsuManualInputManagerTestScene + public partial class TestSceneLabelledTimeSignature : OsuManualInputManagerTestScene { private LabelledTimeSignature timeSignature; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneMetadataSection.cs b/osu.Game.Tests/Visual/Editing/TestSceneMetadataSection.cs index d87bbd8a10..a9f8e19e30 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneMetadataSection.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneMetadataSection.cs @@ -13,7 +13,7 @@ using osu.Game.Screens.Edit.Setup; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneMetadataSection : OsuTestScene + public partial class TestSceneMetadataSection : OsuTestScene { [Cached] private EditorBeatmap editorBeatmap = new EditorBeatmap(new Beatmap @@ -141,7 +141,7 @@ namespace osu.Game.Tests.Visual.Editing AddAssert($"romanised title is {(editable ? "" : "not ")}editable", () => metadataSection.RomanisedTitleTextBox.ReadOnly == !editable); } - private class TestMetadataSection : MetadataSection + private partial class TestMetadataSection : MetadataSection { public new LabelledTextBox ArtistTextBox => base.ArtistTextBox; public new LabelledTextBox RomanisedArtistTextBox => base.RomanisedArtistTextBox; diff --git a/osu.Game.Tests/Visual/Editing/TestScenePlaybackControl.cs b/osu.Game.Tests/Visual/Editing/TestScenePlaybackControl.cs index 674476d644..6fa52d5bbc 100644 --- a/osu.Game.Tests/Visual/Editing/TestScenePlaybackControl.cs +++ b/osu.Game.Tests/Visual/Editing/TestScenePlaybackControl.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Editing { [TestFixture] - public class TestScenePlaybackControl : EditorClockTestScene + public partial class TestScenePlaybackControl : EditorClockTestScene { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tests/Visual/Editing/TestSceneRectangularPositionSnapGrid.cs b/osu.Game.Tests/Visual/Editing/TestSceneRectangularPositionSnapGrid.cs index 7ad12c37bc..e73a45e154 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneRectangularPositionSnapGrid.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneRectangularPositionSnapGrid.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneRectangularPositionSnapGrid : OsuManualInputManagerTestScene + public partial class TestSceneRectangularPositionSnapGrid : OsuManualInputManagerTestScene { private Container content; protected override Container Content => content; @@ -64,7 +64,7 @@ namespace osu.Game.Tests.Visual.Editing })); } - private class SnappingCursorContainer : CompositeDrawable + private partial class SnappingCursorContainer : CompositeDrawable { public Func GetSnapPosition; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneSelectionBlueprintDeselection.cs b/osu.Game.Tests/Visual/Editing/TestSceneSelectionBlueprintDeselection.cs index 5c933468be..24f50d36a2 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneSelectionBlueprintDeselection.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneSelectionBlueprintDeselection.cs @@ -12,7 +12,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneSelectionBlueprintDeselection : EditorTestScene + public partial class TestSceneSelectionBlueprintDeselection : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneSetupScreen.cs b/osu.Game.Tests/Visual/Editing/TestSceneSetupScreen.cs index ddb458d570..c0e681b8b4 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneSetupScreen.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneSetupScreen.cs @@ -20,7 +20,7 @@ using osu.Game.Screens.Edit.Setup; namespace osu.Game.Tests.Visual.Editing { [TestFixture] - public class TestSceneSetupScreen : EditorClockTestScene + public partial class TestSceneSetupScreen : EditorClockTestScene { [Cached(typeof(EditorBeatmap))] [Cached(typeof(IBeatSnapProvider))] diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTapButton.cs b/osu.Game.Tests/Visual/Editing/TestSceneTapButton.cs index f36524290a..8562fb746a 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneTapButton.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneTapButton.cs @@ -13,7 +13,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneTapButton : OsuManualInputManagerTestScene + public partial class TestSceneTapButton : OsuManualInputManagerTestScene { private TapButton tapButton; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTapTimingControl.cs b/osu.Game.Tests/Visual/Editing/TestSceneTapTimingControl.cs index 6ed63515e9..f38df89e82 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneTapTimingControl.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneTapTimingControl.cs @@ -23,7 +23,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { [TestFixture] - public class TestSceneTapTimingControl : EditorClockTestScene + public partial class TestSceneTapTimingControl : EditorClockTestScene { private EditorBeatmap editorBeatmap => editorBeatmapContainer?.EditorBeatmap; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTimelineBlueprintContainer.cs b/osu.Game.Tests/Visual/Editing/TestSceneTimelineBlueprintContainer.cs index c098b683a6..b63296a48d 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneTimelineBlueprintContainer.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneTimelineBlueprintContainer.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Edit.Compose.Components.Timeline; namespace osu.Game.Tests.Visual.Editing { [TestFixture] - public class TestSceneTimelineBlueprintContainer : TimelineTestScene + public partial class TestSceneTimelineBlueprintContainer : TimelineTestScene { public override Drawable CreateTestComponent() => new TimelineBlueprintContainer(Composer); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTimelineHitObjectBlueprint.cs b/osu.Game.Tests/Visual/Editing/TestSceneTimelineHitObjectBlueprint.cs index 603dbf4c67..709d796e97 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneTimelineHitObjectBlueprint.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneTimelineHitObjectBlueprint.cs @@ -18,7 +18,7 @@ using static osu.Game.Screens.Edit.Compose.Components.Timeline.TimelineHitObject namespace osu.Game.Tests.Visual.Editing { - public class TestSceneTimelineHitObjectBlueprint : TimelineTestScene + public partial class TestSceneTimelineHitObjectBlueprint : TimelineTestScene { public override Drawable CreateTestComponent() => new TimelineBlueprintContainer(Composer); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTimelineSelection.cs b/osu.Game.Tests/Visual/Editing/TestSceneTimelineSelection.cs index 54ad4e25e4..50eeb9a54b 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneTimelineSelection.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneTimelineSelection.cs @@ -20,7 +20,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneTimelineSelection : EditorTestScene + public partial class TestSceneTimelineSelection : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTimelineTickDisplay.cs b/osu.Game.Tests/Visual/Editing/TestSceneTimelineTickDisplay.cs index b02f0b09b4..41fb3ed8b9 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneTimelineTickDisplay.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneTimelineTickDisplay.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Editing { [TestFixture] - public class TestSceneTimelineTickDisplay : TimelineTestScene + public partial class TestSceneTimelineTickDisplay : TimelineTestScene { public override Drawable CreateTestComponent() => Empty(); // tick display is implicitly inside the timeline. diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTimelineZoom.cs b/osu.Game.Tests/Visual/Editing/TestSceneTimelineZoom.cs index 11ac102814..19f4678c15 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneTimelineZoom.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneTimelineZoom.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneTimelineZoom : TimelineTestScene + public partial class TestSceneTimelineZoom : TimelineTestScene { public override Drawable CreateTestComponent() => Empty(); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs b/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs index e7805bf393..86a977fd3f 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs @@ -20,7 +20,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { [TestFixture] - public class TestSceneTimingScreen : EditorClockTestScene + public partial class TestSceneTimingScreen : EditorClockTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneWaveform.cs b/osu.Game.Tests/Visual/Editing/TestSceneWaveform.cs index 82b0d70cff..4c2b77bb1d 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneWaveform.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneWaveform.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Editing { [TestFixture] - public class TestSceneWaveform : OsuTestScene + public partial class TestSceneWaveform : OsuTestScene { private IWorkingBeatmap waveformBeatmap; @@ -104,7 +104,7 @@ namespace osu.Game.Tests.Visual.Editing AddUntilStep("wait for load", () => graph.Loaded.IsSet); } - public class TestWaveformGraph : WaveformGraph + public partial class TestWaveformGraph : WaveformGraph { public readonly ManualResetEventSlim Loaded = new ManualResetEventSlim(); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneZoomableScrollContainer.cs b/osu.Game.Tests/Visual/Editing/TestSceneZoomableScrollContainer.cs index 89c5b9b23b..6bc2922253 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneZoomableScrollContainer.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneZoomableScrollContainer.cs @@ -21,7 +21,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { - public class TestSceneZoomableScrollContainer : OsuManualInputManagerTestScene + public partial class TestSceneZoomableScrollContainer : OsuManualInputManagerTestScene { private ZoomableScrollContainer scrollContainer; private Drawable innerBox; diff --git a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs index c2b1ba3aba..cb45ad5a07 100644 --- a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs +++ b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs @@ -23,7 +23,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Editing { - public abstract class TimelineTestScene : EditorClockTestScene + public abstract partial class TimelineTestScene : EditorClockTestScene { protected TimelineArea TimelineArea { get; private set; } @@ -87,7 +87,7 @@ namespace osu.Game.Tests.Visual.Editing public abstract Drawable CreateTestComponent(); - private class AudioVisualiser : CompositeDrawable + private partial class AudioVisualiser : CompositeDrawable { private readonly Drawable marker; @@ -126,7 +126,7 @@ namespace osu.Game.Tests.Visual.Editing } } - private class StartStopButton : OsuButton + private partial class StartStopButton : OsuButton { [Resolved] private EditorClock editorClock { get; set; } diff --git a/osu.Game.Tests/Visual/Gameplay/OsuPlayerTestScene.cs b/osu.Game.Tests/Visual/Gameplay/OsuPlayerTestScene.cs index f173170da5..7ff059ff77 100644 --- a/osu.Game.Tests/Visual/Gameplay/OsuPlayerTestScene.cs +++ b/osu.Game.Tests/Visual/Gameplay/OsuPlayerTestScene.cs @@ -11,7 +11,7 @@ namespace osu.Game.Tests.Visual.Gameplay /// /// A with an arbitrary ruleset value to test with. /// - public abstract class OsuPlayerTestScene : PlayerTestScene + public abstract partial class OsuPlayerTestScene : PlayerTestScene { protected override Ruleset CreatePlayerRuleset() => new OsuRuleset(); } diff --git a/osu.Game.Tests/Visual/Gameplay/SkinnableHUDComponentTestScene.cs b/osu.Game.Tests/Visual/Gameplay/SkinnableHUDComponentTestScene.cs index ea4aa98f86..545b3c2cf4 100644 --- a/osu.Game.Tests/Visual/Gameplay/SkinnableHUDComponentTestScene.cs +++ b/osu.Game.Tests/Visual/Gameplay/SkinnableHUDComponentTestScene.cs @@ -9,7 +9,7 @@ using osu.Game.Skinning; namespace osu.Game.Tests.Visual.Gameplay { - public abstract class SkinnableHUDComponentTestScene : SkinnableTestScene + public abstract partial class SkinnableHUDComponentTestScene : SkinnableTestScene { protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset(); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAllRulesetPlayers.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAllRulesetPlayers.cs index a8d7148bd2..e86302bbd1 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneAllRulesetPlayers.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAllRulesetPlayers.cs @@ -20,7 +20,7 @@ namespace osu.Game.Tests.Visual.Gameplay /// A base class which runs test for all available rulesets. /// Steps to be run for each ruleset should be added via . /// - public abstract class TestSceneAllRulesetPlayers : RateAdjustedBeatmapTestScene + public abstract partial class TestSceneAllRulesetPlayers : RateAdjustedBeatmapTestScene { protected Player Player { get; private set; } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs index f2fe55d719..5442b3bfef 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs @@ -19,7 +19,7 @@ using osu.Game.Users.Drawables; namespace osu.Game.Tests.Visual.Gameplay { [Description("Player instantiated with an autoplay mod.")] - public class TestSceneAutoplay : TestSceneAllRulesetPlayers + public partial class TestSceneAutoplay : TestSceneAllRulesetPlayers { protected new TestReplayPlayer Player => (TestReplayPlayer)base.Player; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapOffsetControl.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapOffsetControl.cs index cfd282c404..6eae795630 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapOffsetControl.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapOffsetControl.cs @@ -14,7 +14,7 @@ using osu.Game.Tests.Visual.Ranking; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneBeatmapOffsetControl : OsuTestScene + public partial class TestSceneBeatmapOffsetControl : OsuTestScene { private BeatmapOffsetControl offsetControl; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs index 8ad97eb33c..5cd8c00935 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs @@ -26,7 +26,7 @@ using osu.Game.Storyboards; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneBeatmapSkinFallbacks : OsuPlayerTestScene + public partial class TestSceneBeatmapSkinFallbacks : OsuPlayerTestScene { private ISkin currentBeatmapSkin; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs index 28a9d17882..a40eab5948 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneBezierConverter : OsuTestScene + public partial class TestSceneBezierConverter : OsuTestScene { private readonly SmoothPath drawablePath; private readonly SmoothPath controlPointDrawablePath; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakTracker.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakTracker.cs index e31b325d54..c010b2c809 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBreakTracker.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBreakTracker.cs @@ -14,7 +14,7 @@ using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual.Gameplay { [TestFixture] - public class TestSceneBreakTracker : OsuTestScene + public partial class TestSceneBreakTracker : OsuTestScene { private readonly BreakOverlay breakOverlay; @@ -161,7 +161,7 @@ namespace osu.Game.Tests.Visual.Gameplay }); } - private class TestBreakTracker : BreakTracker + private partial class TestBreakTracker : BreakTracker { public readonly FramedClock FramedManualClock; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneClicksPerSecondCalculator.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneClicksPerSecondCalculator.cs index 2dad5e2c32..6b8e0e1088 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneClicksPerSecondCalculator.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneClicksPerSecondCalculator.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneClicksPerSecondCalculator : OsuTestScene + public partial class TestSceneClicksPerSecondCalculator : OsuTestScene { private ClicksPerSecondCalculator calculator = null!; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneColourHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneColourHitErrorMeter.cs index a953db4f19..0784aac298 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneColourHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneColourHitErrorMeter.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneColourHitErrorMeter : OsuTestScene + public partial class TestSceneColourHitErrorMeter : OsuTestScene { private DependencyProvidingContainer dependencyContainer = null!; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs index 13ceb05aff..434d853992 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneCompletionCancellation.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneCompletionCancellation : OsuPlayerTestScene + public partial class TestSceneCompletionCancellation : OsuPlayerTestScene { [Resolved] private AudioManager audio { get; set; } @@ -122,7 +122,7 @@ namespace osu.Game.Tests.Visual.Gameplay protected override TestPlayer CreatePlayer(Ruleset ruleset) => new FakeRankingPushPlayer(); - public class FakeRankingPushPlayer : TestPlayer + public partial class FakeRankingPushPlayer : TestPlayer { public bool ResultsCreated { get; private set; } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs index 334d8f1452..287b7d43b4 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs @@ -33,7 +33,7 @@ using JetBrains.Annotations; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneDrawableScrollingRuleset : OsuTestScene + public partial class TestSceneDrawableScrollingRuleset : OsuTestScene { /// /// The amount of time visible by the "view window" of the playfield. @@ -305,7 +305,7 @@ namespace osu.Game.Tests.Visual.Gameplay public override string ShortName { get; } = string.Empty; } - private class TestDrawableScrollingRuleset : DrawableScrollingRuleset + private partial class TestDrawableScrollingRuleset : DrawableScrollingRuleset { public bool RelativeScaleBeatLengthsOverride { get; set; } @@ -342,7 +342,7 @@ namespace osu.Game.Tests.Visual.Gameplay protected override Playfield CreatePlayfield() => new TestPlayfield(); } - private class TestPlayfield : ScrollingPlayfield + private partial class TestPlayfield : ScrollingPlayfield { public TestPlayfield() { @@ -427,7 +427,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - private class DrawableTestHitObject : DrawableHitObject + private partial class DrawableTestHitObject : DrawableHitObject { public DrawableTestHitObject([CanBeNull] TestHitObject hitObject) : base(hitObject) @@ -457,7 +457,7 @@ namespace osu.Game.Tests.Visual.Gameplay protected override void Update() => LifetimeEnd = HitObject.EndTime; } - private class DrawableTestPooledHitObject : DrawableTestHitObject + private partial class DrawableTestPooledHitObject : DrawableTestHitObject { public DrawableTestPooledHitObject() : base(null) @@ -467,7 +467,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - private class DrawableTestParentHitObject : DrawableTestHitObject + private partial class DrawableTestParentHitObject : DrawableTestHitObject { private readonly Container container; @@ -491,7 +491,7 @@ namespace osu.Game.Tests.Visual.Gameplay protected override void ClearNestedHitObjects() => container.Clear(false); } - private class DrawableTestPooledParentHitObject : DrawableTestParentHitObject + private partial class DrawableTestPooledParentHitObject : DrawableTestParentHitObject { public DrawableTestPooledParentHitObject() : base(null) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableStoryboardSprite.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableStoryboardSprite.cs index 3fc456c411..ec4bb1a86b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableStoryboardSprite.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableStoryboardSprite.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneDrawableStoryboardSprite : SkinnableTestScene + public partial class TestSceneDrawableStoryboardSprite : SkinnableTestScene { protected override Ruleset CreateRulesetForSkinProvider() => new OsuRuleset(); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneFailAnimation.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneFailAnimation.cs index ce01bf2fb5..6cb1101173 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneFailAnimation.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneFailAnimation.cs @@ -13,7 +13,7 @@ using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneFailAnimation : TestSceneAllRulesetPlayers + public partial class TestSceneFailAnimation : TestSceneAllRulesetPlayers { protected override Player CreatePlayer(Ruleset ruleset) { @@ -39,7 +39,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("frequency only ever decreased", () => !((FailPlayer)Player).FrequencyIncreased); } - private class FailPlayer : TestPlayer + private partial class FailPlayer : TestPlayer { public new FailOverlay FailOverlay => base.FailOverlay; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneFailJudgement.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneFailJudgement.cs index 5e87eff717..e779c6c1cb 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneFailJudgement.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneFailJudgement.cs @@ -13,7 +13,7 @@ using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneFailJudgement : TestSceneAllRulesetPlayers + public partial class TestSceneFailJudgement : TestSceneAllRulesetPlayers { protected override Player CreatePlayer(Ruleset ruleset) { @@ -37,7 +37,7 @@ namespace osu.Game.Tests.Visual.Gameplay }); } - private class FailPlayer : TestPlayer + private partial class FailPlayer : TestPlayer { public new HealthProcessor HealthProcessor => base.HealthProcessor; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs index 90e36ecae2..235ada2d63 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneFailingLayer.cs @@ -16,7 +16,7 @@ using osu.Game.Screens.Play.HUD; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneFailingLayer : OsuTestScene + public partial class TestSceneFailingLayer : OsuTestScene { private FailingLayer layer; @@ -111,7 +111,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("layer fade is visible", () => layer.IsPresent); } - private class HealthProcessorContainer : Container + private partial class HealthProcessorContainer : Container { [Cached(typeof(HealthProcessor))] private readonly HealthProcessor healthProcessor; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneFrameStabilityContainer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneFrameStabilityContainer.cs index ef74024b4b..534348bed3 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneFrameStabilityContainer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneFrameStabilityContainer.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneFrameStabilityContainer : OsuTestScene + public partial class TestSceneFrameStabilityContainer : OsuTestScene { private readonly ManualClock manualClock; @@ -145,7 +145,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void checkRate(double rate) => AddAssert($"clock rate is {rate}", () => consumer.Clock.Rate, () => Is.EqualTo(rate)); - public class ClockConsumingChild : CompositeDrawable + public partial class ClockConsumingChild : CompositeDrawable { private readonly OsuSpriteText text; private readonly OsuSpriteText text2; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs index 30d2cc6423..d4000c07e7 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayLeaderboard.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Gameplay { [TestFixture] - public class TestSceneGameplayLeaderboard : OsuTestScene + public partial class TestSceneGameplayLeaderboard : OsuTestScene { private TestGameplayLeaderboard leaderboard; @@ -169,7 +169,7 @@ namespace osu.Game.Tests.Visual.Gameplay leaderboardScore.TotalScore.BindTo(score); } - private class TestGameplayLeaderboard : GameplayLeaderboard + private partial class TestGameplayLeaderboard : GameplayLeaderboard { public float Spacing => Flow.Spacing.Y; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs index f3a6302da0..aa5e5985c3 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayMenuOverlay.cs @@ -19,7 +19,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { [Description("player pause/fail screens")] - public class TestSceneGameplayMenuOverlay : OsuManualInputManagerTestScene + public partial class TestSceneGameplayMenuOverlay : OsuManualInputManagerTestScene { private FailOverlay failOverlay; private PauseOverlay pauseOverlay; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs index bd55ed8bd6..1dffeed01b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneGameplayRewinding : OsuPlayerTestScene + public partial class TestSceneGameplayRewinding : OsuPlayerTestScene { [Resolved] private AudioManager audioManager { get; set; } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySamplePlayback.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySamplePlayback.cs index 1fe2dfd4df..3d35860fef 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySamplePlayback.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySamplePlayback.cs @@ -14,7 +14,7 @@ using osu.Game.Skinning; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneGameplaySamplePlayback : PlayerTestScene + public partial class TestSceneGameplaySamplePlayback : PlayerTestScene { [Test] public void TestAllSamplesStopDuringSeek() diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs index b6da562bd0..e184d50d7c 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs @@ -18,7 +18,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneGameplaySampleTriggerSource : PlayerTestScene + public partial class TestSceneGameplaySampleTriggerSource : PlayerTestScene { private TestGameplaySampleTriggerSource sampleTriggerSource; protected override Ruleset CreatePlayerRuleset() => new OsuRuleset(); @@ -124,7 +124,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddRepeatStep("trigger sample", () => sampleTriggerSource.Play(), 10); } - public class TestGameplaySampleTriggerSource : GameplaySampleTriggerSource + public partial class TestGameplaySampleTriggerSource : GameplaySampleTriggerSource { public TestGameplaySampleTriggerSource(HitObjectContainer hitObjectContainer) : base(hitObjectContainer) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 75510fa822..94f9b4262d 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -24,7 +24,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneHUDOverlay : OsuManualInputManagerTestScene + public partial class TestSceneHUDOverlay : OsuManualInputManagerTestScene { private OsuConfigManager localConfig = null!; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs index b90b9b437d..e2ff2780e0 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs @@ -31,7 +31,7 @@ using osu.Game.Screens.Play.HUD.HitErrorMeters; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneHitErrorMeter : OsuTestScene + public partial class TestSceneHitErrorMeter : OsuTestScene { [Cached(typeof(ScoreProcessor))] private TestScoreProcessor scoreProcessor = new TestScoreProcessor(); @@ -263,7 +263,7 @@ namespace osu.Game.Tests.Visual.Gameplay } [SuppressMessage("ReSharper", "UnassignedGetOnlyAutoProperty")] - private class TestDrawableRuleset : DrawableRuleset + private partial class TestDrawableRuleset : DrawableRuleset { public HitWindows HitWindows; @@ -305,7 +305,7 @@ namespace osu.Game.Tests.Visual.Gameplay public override void CancelResume() => throw new NotImplementedException(); } - private class TestScoreProcessor : ScoreProcessor + private partial class TestScoreProcessor : ScoreProcessor { public TestScoreProcessor() : base(new OsuRuleset()) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHoldForMenuButton.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHoldForMenuButton.cs index 50fd1b2a51..3c225d60e0 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHoldForMenuButton.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHoldForMenuButton.cs @@ -15,7 +15,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { [Description("'Hold to Quit' UI element")] - public class TestSceneHoldForMenuButton : OsuManualInputManagerTestScene + public partial class TestSceneHoldForMenuButton : OsuManualInputManagerTestScene { private bool exitAction; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyBindings.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyBindings.cs index c690203f82..53c07304cf 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyBindings.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyBindings.cs @@ -20,7 +20,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { [HeadlessTest] - public class TestSceneKeyBindings : OsuManualInputManagerTestScene + public partial class TestSceneKeyBindings : OsuManualInputManagerTestScene { private readonly ActionReceiver receiver; @@ -71,7 +71,7 @@ namespace osu.Game.Tests.Visual.Gameplay Down, } - private class TestKeyBindingContainer : DatabasedKeyBindingContainer + private partial class TestKeyBindingContainer : DatabasedKeyBindingContainer { public TestKeyBindingContainer() : base(new TestRuleset().RulesetInfo, 0) @@ -79,7 +79,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - private class ActionReceiver : CompositeDrawable, IKeyBindingHandler + private partial class ActionReceiver : CompositeDrawable, IKeyBindingHandler { public bool ReceivedAction; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs index bfda6f50cb..890ac21b40 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs @@ -13,7 +13,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { [TestFixture] - public class TestSceneKeyCounter : OsuManualInputManagerTestScene + public partial class TestSceneKeyCounter : OsuManualInputManagerTestScene { public TestSceneKeyCounter() { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneLeadIn.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneLeadIn.cs index c18a78fe3c..dadf3ca65f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneLeadIn.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneLeadIn.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneLeadIn : RateAdjustedBeatmapTestScene + public partial class TestSceneLeadIn : RateAdjustedBeatmapTestScene { private LeadInPlayer player = null!; @@ -106,7 +106,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("player loaded", () => player.IsLoaded && player.Alpha == 1); } - private class LeadInPlayer : TestPlayer + private partial class LeadInPlayer : TestPlayer { public LeadInPlayer() : base(false, false) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneMedalOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneMedalOverlay.cs index 3fd36d509d..626406e4d2 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneMedalOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneMedalOverlay.cs @@ -10,7 +10,7 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual.Gameplay { [TestFixture] - public class TestSceneMedalOverlay : OsuTestScene + public partial class TestSceneMedalOverlay : OsuTestScene { public TestSceneMedalOverlay() { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneModValidity.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneModValidity.cs index 0c6b656ab6..b26f48d028 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneModValidity.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneModValidity.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Tests.Visual.Gameplay { [HeadlessTest] - public class TestSceneModValidity : TestSceneAllRulesetPlayers + public partial class TestSceneModValidity : TestSceneAllRulesetPlayers { protected override void AddCheckSteps() { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs index 966138c0b3..84334ba0a9 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneNightcoreBeatContainer.cs @@ -13,7 +13,7 @@ using osu.Game.Tests.Visual.UserInterface; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneNightcoreBeatContainer : TestSceneBeatSyncedContainer + public partial class TestSceneNightcoreBeatContainer : TestSceneBeatSyncedContainer { protected override void LoadComplete() { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs index 789e7e770f..269d104fa3 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneOverlayActivation.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneOverlayActivation : OsuPlayerTestScene + public partial class TestSceneOverlayActivation : OsuPlayerTestScene { protected new OverlayTestPlayer Player => base.Player as OverlayTestPlayer; @@ -64,7 +64,7 @@ namespace osu.Game.Tests.Visual.Gameplay protected override TestPlayer CreatePlayer(Ruleset ruleset) => new OverlayTestPlayer(); - protected class OverlayTestPlayer : TestPlayer + protected partial class OverlayTestPlayer : TestPlayer { public new OverlayActivation OverlayActivationMode => base.OverlayActivationMode.Value; } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneParticleExplosion.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneParticleExplosion.cs index bddf051871..2d48ac81e2 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneParticleExplosion.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneParticleExplosion.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Gameplay { [TestFixture] - public class TestSceneParticleExplosion : OsuTestScene + public partial class TestSceneParticleExplosion : OsuTestScene { private ParticleExplosion explosion; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneParticleSpewer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneParticleSpewer.cs index 66441c8bad..c73d57dc2b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneParticleSpewer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneParticleSpewer.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Gameplay { [TestFixture] - public class TestSceneParticleSpewer : OsuTestScene + public partial class TestSceneParticleSpewer : OsuTestScene { private TestParticleSpewer spewer; @@ -88,7 +88,7 @@ namespace osu.Game.Tests.Visual.Gameplay Size = new Vector2(0.5f), }; - private class TestParticleSpewer : ParticleSpewer + private partial class TestParticleSpewer : ParticleSpewer { public const int MAX_DURATION = 1500; private const int rate = 250; diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs index d0371acce7..7880a849a2 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs @@ -21,7 +21,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { - public class TestScenePause : OsuPlayerTestScene + public partial class TestScenePause : OsuPlayerTestScene { protected new PausePlayer Player => (PausePlayer)base.Player; @@ -396,7 +396,7 @@ namespace osu.Game.Tests.Visual.Gameplay protected override TestPlayer CreatePlayer(Ruleset ruleset) => new PausePlayer(); - protected class PausePlayer : TestPlayer + protected partial class PausePlayer : TestPlayer { public double LastPauseTime { get; private set; } public double LastResumeTime { get; private set; } diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePauseWhenInactive.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePauseWhenInactive.cs index e1c755b90c..b770f72f19 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePauseWhenInactive.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePauseWhenInactive.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Gameplay { [HeadlessTest] // we alter unsafe properties on the game host to test inactive window state. - public class TestScenePauseWhenInactive : OsuPlayerTestScene + public partial class TestScenePauseWhenInactive : OsuPlayerTestScene { [Resolved] private GameHost host { get; set; } diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePerformancePointsCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePerformancePointsCounter.cs index a86e707400..9622caabf5 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePerformancePointsCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePerformancePointsCounter.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Gameplay { - public class TestScenePerformancePointsCounter : OsuTestScene + public partial class TestScenePerformancePointsCounter : OsuTestScene { private DependencyProvidingContainer dependencyContainer; diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index 6b24ac7384..2ea27c2fef 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -32,7 +32,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { - public class TestScenePlayerLoader : ScreenTestScene + public partial class TestScenePlayerLoader : ScreenTestScene { private TestPlayerLoader loader; private TestPlayer player; @@ -451,7 +451,7 @@ namespace osu.Game.Tests.Visual.Gameplay private EpilepsyWarning getWarning() => loader.ChildrenOfType().SingleOrDefault(); - private class TestPlayerLoader : PlayerLoader + private partial class TestPlayerLoader : PlayerLoader { public new VisualSettings VisualSettings => base.VisualSettings; @@ -482,7 +482,7 @@ namespace osu.Game.Tests.Visual.Gameplay public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank; } - protected class SlowLoadPlayer : TestPlayer + protected partial class SlowLoadPlayer : TestPlayer { public readonly ManualResetEventSlim AllowLoad = new ManualResetEventSlim(false); diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLocalScoreImport.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLocalScoreImport.cs index 38a091dd85..80c4e4bce9 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLocalScoreImport.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLocalScoreImport.cs @@ -27,7 +27,7 @@ using osu.Game.Tests.Resources; namespace osu.Game.Tests.Visual.Gameplay { - public class TestScenePlayerLocalScoreImport : PlayerTestScene + public partial class TestScenePlayerLocalScoreImport : PlayerTestScene { private BeatmapManager beatmaps = null!; private RulesetStore rulesets = null!; diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerReferenceLeaking.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerReferenceLeaking.cs index ec0eea62d9..b1209e3a4f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerReferenceLeaking.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerReferenceLeaking.cs @@ -12,7 +12,7 @@ using osu.Game.Storyboards; namespace osu.Game.Tests.Visual.Gameplay { - public class TestScenePlayerReferenceLeaking : TestSceneAllRulesetPlayers + public partial class TestScenePlayerReferenceLeaking : TestSceneAllRulesetPlayers { private readonly WeakList workingWeakReferences = new WeakList(); diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerScoreSubmission.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerScoreSubmission.cs index d1bdfb1dfa..2fbdfbc198 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerScoreSubmission.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerScoreSubmission.cs @@ -26,7 +26,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Tests.Visual.Gameplay { - public class TestScenePlayerScoreSubmission : PlayerTestScene + public partial class TestScenePlayerScoreSubmission : PlayerTestScene { protected override bool AllowFail => allowFail; @@ -345,7 +345,7 @@ namespace osu.Game.Tests.Visual.Gameplay }); } - protected class FakeImportingPlayer : TestPlayer + protected partial class FakeImportingPlayer : TestPlayer { public bool ScoreImportStarted { get; set; } public SemaphoreSlim AllowImportCompletion { get; } diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePoolingRuleset.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePoolingRuleset.cs index 618ffbcb0e..55ee6c9fc9 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePoolingRuleset.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePoolingRuleset.cs @@ -31,7 +31,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Gameplay { - public class TestScenePoolingRuleset : OsuTestScene + public partial class TestScenePoolingRuleset : OsuTestScene { private const double time_between_objects = 1000; @@ -194,7 +194,7 @@ namespace osu.Game.Tests.Visual.Gameplay public override string ShortName { get; } = string.Empty; } - private class TestDrawablePoolingRuleset : DrawableRuleset + private partial class TestDrawablePoolingRuleset : DrawableRuleset { public int PoolSize; @@ -210,7 +210,7 @@ namespace osu.Game.Tests.Visual.Gameplay protected override Playfield CreatePlayfield() => new TestPlayfield(PoolSize); } - private class TestPlayfield : Playfield + private partial class TestPlayfield : Playfield { private readonly int poolSize; @@ -283,7 +283,7 @@ namespace osu.Game.Tests.Visual.Gameplay public double Duration { get; set; } } - private class DrawableTestHitObject : DrawableHitObject + private partial class DrawableTestHitObject : DrawableHitObject { public DrawableTestHitObject() : base(null) @@ -335,7 +335,7 @@ namespace osu.Game.Tests.Visual.Gameplay { } - private class DrawableTestKilledHitObject : DrawableHitObject + private partial class DrawableTestKilledHitObject : DrawableHitObject { public DrawableTestKilledHitObject() : base(null) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplay.cs index faa6a429c5..c476aae202 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplay.cs @@ -15,7 +15,7 @@ using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual.Gameplay { [Description("Player instantiated with a replay.")] - public class TestSceneReplay : TestSceneAllRulesetPlayers + public partial class TestSceneReplay : TestSceneAllRulesetPlayers { protected override Player CreatePlayer(Ruleset ruleset) { @@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("cannot fail", () => !((ScoreAccessibleReplayPlayer)Player).AllowFail); } - private class ScoreAccessibleReplayPlayer : ReplayPlayer + private partial class ScoreAccessibleReplayPlayer : ReplayPlayer { public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; public new HUDOverlay HUDOverlay => base.HUDOverlay; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs index cd227630c1..c473278fdc 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs @@ -24,7 +24,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Tests.Visual.Gameplay { [TestFixture] - public class TestSceneReplayDownloadButton : OsuManualInputManagerTestScene + public partial class TestSceneReplayDownloadButton : OsuManualInputManagerTestScene { private const long online_score_id = 2553163309; @@ -219,7 +219,7 @@ namespace osu.Game.Tests.Visual.Gameplay } }; - private class TestReplayDownloadButton : ReplayDownloadButton + private partial class TestReplayDownloadButton : ReplayDownloadButton { public void SetDownloadState(DownloadState state) => State.Value = state; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs index 6319b91a38..e0a6a60ff2 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs @@ -10,7 +10,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneReplayPlayer : RateAdjustedBeatmapTestScene + public partial class TestSceneReplayPlayer : RateAdjustedBeatmapTestScene { protected TestReplayPlayer Player; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs index b3401c916b..65b409a6f7 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs @@ -31,7 +31,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneReplayRecorder : OsuManualInputManagerTestScene + public partial class TestSceneReplayRecorder : OsuManualInputManagerTestScene { private TestRulesetInputManager playbackManager; private TestRulesetInputManager recordingManager; @@ -218,7 +218,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - public class TestInputConsumer : CompositeDrawable, IKeyBindingHandler + public partial class TestInputConsumer : CompositeDrawable, IKeyBindingHandler { public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Parent.ReceivePositionalInputAt(screenSpacePos); @@ -261,7 +261,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - public class TestRulesetInputManager : RulesetInputManager + public partial class TestRulesetInputManager : RulesetInputManager { public TestRulesetInputManager(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) : base(ruleset, variant, unique) @@ -271,7 +271,7 @@ namespace osu.Game.Tests.Visual.Gameplay protected override KeyBindingContainer CreateKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) => new TestKeyBindingContainer(); - internal class TestKeyBindingContainer : KeyBindingContainer + internal partial class TestKeyBindingContainer : KeyBindingContainer { public override IEnumerable DefaultKeyBindings => new[] { @@ -299,7 +299,7 @@ namespace osu.Game.Tests.Visual.Gameplay Down, } - internal class TestReplayRecorder : ReplayRecorder + internal partial class TestReplayRecorder : ReplayRecorder { public TestReplayRecorder(Score target) : base(target) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs index f8b5085a70..8fff07e6d8 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs @@ -28,7 +28,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneScoring : OsuTestScene + public partial class TestSceneScoring : OsuTestScene { private GraphContainer graphs = null!; private SettingsSlider sliderMaxCombo = null!; @@ -279,7 +279,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - public class GraphContainer : Container, IHasCustomTooltip> + public partial class GraphContainer : Container, IHasCustomTooltip> { public readonly BindableList MissLocations = new BindableList(); public readonly BindableList NonPerfectLocations = new BindableList(); @@ -439,7 +439,7 @@ namespace osu.Game.Tests.Visual.Gameplay public IEnumerable TooltipContent => Content.OfType(); - public class GraphTooltip : CompositeDrawable, ITooltip> + public partial class GraphTooltip : CompositeDrawable, ITooltip> { private readonly GraphContainer graphContainer; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs index 6d036f8e9b..317d01553a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs @@ -29,7 +29,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Gameplay { [TestFixture] - public class TestSceneScrollingHitObjects : OsuTestScene + public partial class TestSceneScrollingHitObjects : OsuTestScene { [Cached(typeof(IReadOnlyList))] private IReadOnlyList mods { get; set; } = Array.Empty(); @@ -252,7 +252,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void setScrollAlgorithm(ScrollVisualisationMethod algorithm) => scrollContainers.ForEach(c => c.ScrollAlgorithm = algorithm); - private class TestPlayfield : ScrollingPlayfield + private partial class TestPlayfield : ScrollingPlayfield { public new ScrollingDirection Direction => base.Direction.Value; @@ -279,7 +279,7 @@ namespace osu.Game.Tests.Visual.Gameplay protected override ScrollingHitObjectContainer CreateScrollingHitObjectContainer() => new TestScrollingHitObjectContainer(); } - private class TestDrawableControlPoint : DrawableHitObject + private partial class TestDrawableControlPoint : DrawableHitObject { public TestDrawableControlPoint(ScrollingDirection direction, double time) : base(new HitObject { StartTime = time, HitWindows = HitWindows.Empty }) @@ -320,7 +320,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - private class TestDrawableHitObject : DrawableHitObject + private partial class TestDrawableHitObject : DrawableHitObject { public TestDrawableHitObject(TestHitObject hitObject) : base(hitObject) @@ -336,7 +336,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - private class TestScrollingHitObjectContainer : ScrollingHitObjectContainer + private partial class TestScrollingHitObjectContainer : ScrollingHitObjectContainer { protected override RectangleF GetConservativeBoundingBox(HitObjectLifetimeEntry entry) { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs index 578718b7c9..48dbda9da6 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs @@ -18,7 +18,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneSkinEditor : PlayerTestScene + public partial class TestSceneSkinEditor : PlayerTestScene { private SkinEditor? skinEditor; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorComponentsList.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorComponentsList.cs index f88b4be3d8..05a550a24d 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorComponentsList.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorComponentsList.cs @@ -13,7 +13,7 @@ using osu.Game.Skinning.Editor; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneSkinEditorComponentsList : SkinnableTestScene + public partial class TestSceneSkinEditorComponentsList : SkinnableTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs index 6c02ddab14..ad3911f50b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs @@ -18,7 +18,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneSkinEditorMultipleSkins : SkinnableTestScene + public partial class TestSceneSkinEditorMultipleSkins : SkinnableTestScene { [Cached] private readonly ScoreProcessor scoreProcessor = new ScoreProcessor(new OsuRuleset()); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableAccuracyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableAccuracyCounter.cs index 1288f2a9f1..6f079778c5 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableAccuracyCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableAccuracyCounter.cs @@ -14,7 +14,7 @@ using osu.Game.Skinning; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneSkinnableAccuracyCounter : SkinnableHUDComponentTestScene + public partial class TestSceneSkinnableAccuracyCounter : SkinnableHUDComponentTestScene { [Cached] private ScoreProcessor scoreProcessor = new ScoreProcessor(new OsuRuleset()); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableComboCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableComboCounter.cs index ef56f456ea..93fa953ef4 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableComboCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableComboCounter.cs @@ -14,7 +14,7 @@ using osu.Game.Skinning; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneSkinnableComboCounter : SkinnableHUDComponentTestScene + public partial class TestSceneSkinnableComboCounter : SkinnableHUDComponentTestScene { [Cached] private ScoreProcessor scoreProcessor = new ScoreProcessor(new OsuRuleset()); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs index 97974d2368..c02cec8c75 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs @@ -24,7 +24,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneSkinnableDrawable : OsuTestScene + public partial class TestSceneSkinnableDrawable : OsuTestScene { [Test] public void TestConfineScaleDown() @@ -160,7 +160,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("consumer using base source", () => consumer.Drawable is BaseSourceBox); } - private class SwitchableSkinProvidingContainer : SkinProvidingContainer + private partial class SwitchableSkinProvidingContainer : SkinProvidingContainer { private bool allow = true; @@ -178,7 +178,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - private class ExposedSkinnableDrawable : SkinnableDrawable + private partial class ExposedSkinnableDrawable : SkinnableDrawable { public new Drawable Drawable => base.Drawable; @@ -188,7 +188,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - private class DefaultBox : DrawWidthBox + private partial class DefaultBox : DrawWidthBox { public DefaultBox() { @@ -196,7 +196,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - private class DrawWidthBox : Container + private partial class DrawWidthBox : Container { private readonly OsuSpriteText text; @@ -224,7 +224,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - private class NamedBox : Container + private partial class NamedBox : Container { public NamedBox(string name) { @@ -246,7 +246,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - private class SkinConsumer : SkinnableDrawable + private partial class SkinConsumer : SkinnableDrawable { public new Drawable Drawable => base.Drawable; public int SkinChangedCount { get; private set; } @@ -263,7 +263,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - private class BaseSourceBox : NamedBox + private partial class BaseSourceBox : NamedBox { public BaseSourceBox() : base("Base Source") @@ -271,7 +271,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - private class SecondarySourceBox : NamedBox + private partial class SecondarySourceBox : NamedBox { public SecondarySourceBox() : base("Secondary Source") @@ -316,7 +316,7 @@ namespace osu.Game.Tests.Visual.Gameplay } [Cached(typeof(ISkinSource))] - private class SkinSourceContainer : Container, ISkinSource + private partial class SkinSourceContainer : Container, ISkinSource { public Drawable GetDrawableComponent(ISkinComponentLookup componentLookupName) => new BaseSourceBox(); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs index 485c76ac5c..1f2329af4a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs @@ -23,7 +23,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneSkinnableHUDOverlay : SkinnableTestScene + public partial class TestSceneSkinnableHUDOverlay : SkinnableTestScene { private HUDOverlay hudOverlay; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs index 2d6ad28b90..7f6c9d7804 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHealthDisplay.cs @@ -16,7 +16,7 @@ using osu.Game.Skinning; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneSkinnableHealthDisplay : SkinnableHUDComponentTestScene + public partial class TestSceneSkinnableHealthDisplay : SkinnableHUDComponentTestScene { [Cached(typeof(HealthProcessor))] private HealthProcessor healthProcessor = new DrainingHealthProcessor(0); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableScoreCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableScoreCounter.cs index 1b3538cc21..c95e8ee5b2 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableScoreCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableScoreCounter.cs @@ -13,7 +13,7 @@ using osu.Game.Skinning; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneSkinnableScoreCounter : SkinnableHUDComponentTestScene + public partial class TestSceneSkinnableScoreCounter : SkinnableHUDComponentTestScene { [Cached] private ScoreProcessor scoreProcessor = new ScoreProcessor(new OsuRuleset()); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs index 8122d8defb..5c69062e67 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs @@ -20,7 +20,7 @@ using osu.Game.Skinning; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneSkinnableSound : OsuTestScene + public partial class TestSceneSkinnableSound : OsuTestScene { private TestSkinSourceContainer skinSource; private PausableSkinnableSound skinnableSound; @@ -131,7 +131,7 @@ namespace osu.Game.Tests.Visual.Gameplay } [Cached(typeof(ISkinSource))] - private class TestSkinSourceContainer : Container, ISkinSource, ISamplePlaybackDisabler + private partial class TestSkinSourceContainer : Container, ISkinSource, ISamplePlaybackDisabler { [Resolved] private ISkinSource source { get; set; } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs index 1bba62a5cf..8b1a8307ca 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs @@ -15,7 +15,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { [TestFixture] - public class TestSceneSkipOverlay : OsuManualInputManagerTestScene + public partial class TestSceneSkipOverlay : OsuManualInputManagerTestScene { private TestSkipOverlay skip; private int requestCount; @@ -162,7 +162,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert($"request count is {expected}", () => requestCount, () => Is.EqualTo(expected)); } - private class TestSkipOverlay : SkipOverlay + private partial class TestSkipOverlay : SkipOverlay { public TestSkipOverlay(double startTime) : base(startTime) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSliderPath.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSliderPath.cs index 7044ddad37..dfa9fdf03b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSliderPath.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSliderPath.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneSliderPath : OsuTestScene + public partial class TestSceneSliderPath : OsuTestScene { private readonly SmoothPath drawablePath; private SliderPath path; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs index 881870921c..8ae6a2a5fc 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSoloGameplayLeaderboard.cs @@ -19,7 +19,7 @@ using osu.Game.Screens.Select; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneSoloGameplayLeaderboard : OsuTestScene + public partial class TestSceneSoloGameplayLeaderboard : OsuTestScene { [Cached] private readonly ScoreProcessor scoreProcessor = new ScoreProcessor(new OsuRuleset()); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index 6127aa304c..2e579cc522 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs @@ -17,7 +17,7 @@ using osu.Game.Skinning; namespace osu.Game.Tests.Visual.Gameplay { [TestFixture] - public class TestSceneSongProgress : SkinnableHUDComponentTestScene + public partial class TestSceneSongProgress : SkinnableHUDComponentTestScene { private GameplayClockContainer gameplayClockContainer = null!; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgressGraph.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgressGraph.cs index 2fa3c0c7ec..5a61502978 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgressGraph.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgressGraph.cs @@ -14,7 +14,7 @@ using osu.Game.Screens.Play.HUD; namespace osu.Game.Tests.Visual.Gameplay { [TestFixture] - public class TestSceneSongProgressGraph : OsuTestScene + public partial class TestSceneSongProgressGraph : OsuTestScene { private TestSongProgressGraph graph; @@ -59,7 +59,7 @@ namespace osu.Game.Tests.Visual.Gameplay graph.Objects = objects; } - private class TestSongProgressGraph : SongProgressGraph + private partial class TestSongProgressGraph : SongProgressGraph { public int CreationCount { get; private set; } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs index 929af7f84d..8f1eb98c79 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs @@ -28,7 +28,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneSpectator : ScreenTestScene + public partial class TestSceneSpectator : ScreenTestScene { private readonly APIUser streamingUser = new APIUser { Id = MultiplayerTestScene.PLAYER_1_ID, Username = "Test user" }; @@ -388,7 +388,7 @@ namespace osu.Game.Tests.Visual.Gameplay /// /// Used for the sole purpose of adding as a resolvable dependency. /// - private class DependenciesScreen : OsuScreen + private partial class DependenciesScreen : OsuScreen { [Cached(typeof(SpectatorClient))] public readonly TestSpectatorClient SpectatorClient = new TestSpectatorClient(); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorHost.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorHost.cs index 083be3539d..1c09c29748 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorHost.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorHost.cs @@ -15,7 +15,7 @@ using osu.Game.Tests.Visual.Spectator; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneSpectatorHost : PlayerTestScene + public partial class TestSceneSpectatorHost : PlayerTestScene { protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset(); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs index 9c41c70a0e..1ad1da0994 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs @@ -35,7 +35,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneSpectatorPlayback : OsuManualInputManagerTestScene + public partial class TestSceneSpectatorPlayback : OsuManualInputManagerTestScene { private TestRulesetInputManager playbackManager; private TestRulesetInputManager recordingManager; @@ -257,7 +257,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - public class TestInputConsumer : CompositeDrawable, IKeyBindingHandler + public partial class TestInputConsumer : CompositeDrawable, IKeyBindingHandler { public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Parent.ReceivePositionalInputAt(screenSpacePos); @@ -300,7 +300,7 @@ namespace osu.Game.Tests.Visual.Gameplay } } - public class TestRulesetInputManager : RulesetInputManager + public partial class TestRulesetInputManager : RulesetInputManager { public TestRulesetInputManager(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) : base(ruleset, variant, unique) @@ -310,7 +310,7 @@ namespace osu.Game.Tests.Visual.Gameplay protected override KeyBindingContainer CreateKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) => new TestKeyBindingContainer(); - internal class TestKeyBindingContainer : KeyBindingContainer + internal partial class TestKeyBindingContainer : KeyBindingContainer { public override IEnumerable DefaultKeyBindings => new[] { @@ -360,7 +360,7 @@ namespace osu.Game.Tests.Visual.Gameplay Down, } - internal class TestReplayRecorder : ReplayRecorder + internal partial class TestReplayRecorder : ReplayRecorder { public List SentFrames = new List(); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStarCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStarCounter.cs index 708a5e94de..699c8ea20a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStarCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStarCounter.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Gameplay { [TestFixture] - public class TestSceneStarCounter : OsuTestScene + public partial class TestSceneStarCounter : OsuTestScene { private readonly StarCounter starCounter; private readonly OsuSpriteText starsLabel; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs index eaf22ba9cc..dbce62cbef 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Gameplay { [TestFixture] - public class TestSceneStoryboard : OsuTestScene + public partial class TestSceneStoryboard : OsuTestScene { private Container storyboardContainer = null!; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs index f0e184d727..a9d4508f70 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardSamplePlayback.cs @@ -23,7 +23,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneStoryboardSamplePlayback : PlayerTestScene + public partial class TestSceneStoryboardSamplePlayback : PlayerTestScene { private Storyboard storyboard; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs index a26a7e97be..0d88fb01a8 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs @@ -26,7 +26,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneStoryboardWithOutro : PlayerTestScene + public partial class TestSceneStoryboardWithOutro : PlayerTestScene { protected override bool HasCustomSteps => true; @@ -198,7 +198,7 @@ namespace osu.Game.Tests.Visual.Gameplay return storyboard; } - protected class OutroPlayer : TestPlayer + protected partial class OutroPlayer : TestPlayer { public void ExitViaPause() => PerformExit(true); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneUnknownMod.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneUnknownMod.cs index a31347589b..cb5631e599 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneUnknownMod.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneUnknownMod.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Osu; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneUnknownMod : ModTestScene + public partial class TestSceneUnknownMod : ModTestScene { protected override Ruleset CreatePlayerRuleset() => new OsuRuleset(); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneUnstableRateCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneUnstableRateCounter.cs index 60b8691bfb..2f572b46c9 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneUnstableRateCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneUnstableRateCounter.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneUnstableRateCounter : OsuTestScene + public partial class TestSceneUnstableRateCounter : OsuTestScene { [Cached(typeof(ScoreProcessor))] private TestScoreProcessor scoreProcessor = new TestScoreProcessor(); @@ -103,7 +103,7 @@ namespace osu.Game.Tests.Visual.Gameplay }); } - private class TestScoreProcessor : ScoreProcessor + private partial class TestScoreProcessor : ScoreProcessor { public TestScoreProcessor() : base(new OsuRuleset()) diff --git a/osu.Game.Tests/Visual/Menus/IntroTestScene.cs b/osu.Game.Tests/Visual/Menus/IntroTestScene.cs index e0f0df0554..b09dbc1a91 100644 --- a/osu.Game.Tests/Visual/Menus/IntroTestScene.cs +++ b/osu.Game.Tests/Visual/Menus/IntroTestScene.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Menus { [TestFixture] - public abstract class IntroTestScene : OsuTestScene + public abstract partial class IntroTestScene : OsuTestScene { [Cached] private OsuLogo logo; diff --git a/osu.Game.Tests/Visual/Menus/TestSceneDisclaimer.cs b/osu.Game.Tests/Visual/Menus/TestSceneDisclaimer.cs index 57f16bbcce..45e5a7c270 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneDisclaimer.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneDisclaimer.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Menu; namespace osu.Game.Tests.Visual.Menus { - public class TestSceneDisclaimer : ScreenTestScene + public partial class TestSceneDisclaimer : ScreenTestScene { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tests/Visual/Menus/TestSceneIntroCircles.cs b/osu.Game.Tests/Visual/Menus/TestSceneIntroCircles.cs index 85a3a51ddb..0c024248ea 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneIntroCircles.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneIntroCircles.cs @@ -9,7 +9,7 @@ using osu.Game.Screens.Menu; namespace osu.Game.Tests.Visual.Menus { [TestFixture] - public class TestSceneIntroCircles : IntroTestScene + public partial class TestSceneIntroCircles : IntroTestScene { protected override bool IntroReliesOnTrack => false; protected override IntroScreen CreateScreen() => new IntroCircles(); diff --git a/osu.Game.Tests/Visual/Menus/TestSceneIntroTriangles.cs b/osu.Game.Tests/Visual/Menus/TestSceneIntroTriangles.cs index 7ab04a22e5..23373892d1 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneIntroTriangles.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneIntroTriangles.cs @@ -9,7 +9,7 @@ using osu.Game.Screens.Menu; namespace osu.Game.Tests.Visual.Menus { [TestFixture] - public class TestSceneIntroTriangles : IntroTestScene + public partial class TestSceneIntroTriangles : IntroTestScene { protected override bool IntroReliesOnTrack => true; protected override IntroScreen CreateScreen() => new IntroTriangles(); diff --git a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs index ae63022823..2ccf184525 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneIntroWelcome.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Menu; namespace osu.Game.Tests.Visual.Menus { [TestFixture] - public class TestSceneIntroWelcome : IntroTestScene + public partial class TestSceneIntroWelcome : IntroTestScene { protected override bool IntroReliesOnTrack => false; protected override IntroScreen CreateScreen() => new IntroWelcome(); diff --git a/osu.Game.Tests/Visual/Menus/TestSceneLoader.cs b/osu.Game.Tests/Visual/Menus/TestSceneLoader.cs index 1f2eb57b79..aac9614ddb 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneLoader.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneLoader.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Menus { [TestFixture] - public class TestSceneLoader : ScreenTestScene + public partial class TestSceneLoader : ScreenTestScene { private TestLoader loader; @@ -68,7 +68,7 @@ namespace osu.Game.Tests.Visual.Menus AddUntilStep("not current", () => !loader.IsCurrentScreen()); } - private class TestLoader : Loader + private partial class TestLoader : Loader { public readonly ManualResetEventSlim AllowLoad = new ManualResetEventSlim(); @@ -80,7 +80,7 @@ namespace osu.Game.Tests.Visual.Menus protected override OsuScreen CreateLoadableScreen() => screen = new TestScreen(); protected override ShaderPrecompiler CreateShaderPrecompiler() => new TestShaderPrecompiler(AllowLoad); - private class TestShaderPrecompiler : ShaderPrecompiler + private partial class TestShaderPrecompiler : ShaderPrecompiler { private readonly ManualResetEventSlim allowLoad; @@ -92,7 +92,7 @@ namespace osu.Game.Tests.Visual.Menus protected override bool AllLoaded => allowLoad.IsSet; } - private class TestScreen : OsuScreen + private partial class TestScreen : OsuScreen { public TestScreen() { diff --git a/osu.Game.Tests/Visual/Menus/TestSceneLoginPanel.cs b/osu.Game.Tests/Visual/Menus/TestSceneLoginPanel.cs index dbe7b9cc74..738220f5ce 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneLoginPanel.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneLoginPanel.cs @@ -16,7 +16,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Menus { [TestFixture] - public class TestSceneLoginPanel : OsuManualInputManagerTestScene + public partial class TestSceneLoginPanel : OsuManualInputManagerTestScene { private LoginPanel loginPanel; private int hideCount; diff --git a/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs index 720e32a242..f17433244b 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneMusicActionHandling.cs @@ -16,7 +16,7 @@ using osu.Game.Tests.Resources; namespace osu.Game.Tests.Visual.Menus { - public class TestSceneMusicActionHandling : OsuGameTestScene + public partial class TestSceneMusicActionHandling : OsuGameTestScene { private GlobalActionContainer globalActionContainer => Game.ChildrenOfType().First(); diff --git a/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs index 7a2b4d5ca5..e5e092b382 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs @@ -13,7 +13,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Menus { - public class TestSceneSideOverlays : OsuGameTestScene + public partial class TestSceneSideOverlays : OsuGameTestScene { [SetUpSteps] public override void SetUpSteps() diff --git a/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs b/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs index ba73361566..c54c66df7e 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneSongTicker.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Menu; namespace osu.Game.Tests.Visual.Menus { - public class TestSceneSongTicker : OsuTestScene + public partial class TestSceneSongTicker : OsuTestScene { public TestSceneSongTicker() { diff --git a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs index 4473f315b9..0bc42b06dd 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs @@ -26,7 +26,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Menus { [TestFixture] - public class TestSceneToolbar : OsuManualInputManagerTestScene + public partial class TestSceneToolbar : OsuManualInputManagerTestScene { private TestToolbar toolbar; @@ -201,7 +201,7 @@ namespace osu.Game.Tests.Visual.Menus AddAssert("volume not changed", () => Audio.Volume.Value == 0.5); } - public class TestToolbar : Toolbar + public partial class TestToolbar : Toolbar { public new Bindable OverlayActivationMode => base.OverlayActivationMode as Bindable; } diff --git a/osu.Game.Tests/Visual/Menus/TestSceneToolbarClock.cs b/osu.Game.Tests/Visual/Menus/TestSceneToolbarClock.cs index d96f80df40..f38ad5af15 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneToolbarClock.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneToolbarClock.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Menus { [TestFixture] - public class TestSceneToolbarClock : OsuManualInputManagerTestScene + public partial class TestSceneToolbarClock : OsuManualInputManagerTestScene { private Bindable clockDisplayMode; diff --git a/osu.Game.Tests/Visual/Menus/TestSceneToolbarUserButton.cs b/osu.Game.Tests/Visual/Menus/TestSceneToolbarUserButton.cs index 2901501b30..2bdfc8959d 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneToolbarUserButton.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneToolbarUserButton.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Menus { [TestFixture] - public class TestSceneToolbarUserButton : OsuManualInputManagerTestScene + public partial class TestSceneToolbarUserButton : OsuManualInputManagerTestScene { public TestSceneToolbarUserButton() { diff --git a/osu.Game.Tests/Visual/Mods/TestSceneModFailCondition.cs b/osu.Game.Tests/Visual/Mods/TestSceneModFailCondition.cs index 23c1eda7f7..49256c7a01 100644 --- a/osu.Game.Tests/Visual/Mods/TestSceneModFailCondition.cs +++ b/osu.Game.Tests/Visual/Mods/TestSceneModFailCondition.cs @@ -14,7 +14,7 @@ using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual.Mods { - public class TestSceneModFailCondition : ModTestScene + public partial class TestSceneModFailCondition : ModTestScene { private bool restartRequested; diff --git a/osu.Game.Tests/Visual/Multiplayer/MultiplayerGameplayLeaderboardTestScene.cs b/osu.Game.Tests/Visual/Multiplayer/MultiplayerGameplayLeaderboardTestScene.cs index 631f2e707a..fa7d2c04f4 100644 --- a/osu.Game.Tests/Visual/Multiplayer/MultiplayerGameplayLeaderboardTestScene.cs +++ b/osu.Game.Tests/Visual/Multiplayer/MultiplayerGameplayLeaderboardTestScene.cs @@ -26,7 +26,7 @@ using osu.Game.Screens.Play.HUD; namespace osu.Game.Tests.Visual.Multiplayer { - public abstract class MultiplayerGameplayLeaderboardTestScene : OsuTestScene + public abstract partial class MultiplayerGameplayLeaderboardTestScene : OsuTestScene { protected const int TOTAL_USERS = 16; diff --git a/osu.Game.Tests/Visual/Multiplayer/QueueModeTestScene.cs b/osu.Game.Tests/Visual/Multiplayer/QueueModeTestScene.cs index ca4d926866..0e9863a9f5 100644 --- a/osu.Game.Tests/Visual/Multiplayer/QueueModeTestScene.cs +++ b/osu.Game.Tests/Visual/Multiplayer/QueueModeTestScene.cs @@ -24,7 +24,7 @@ using osu.Game.Tests.Resources; namespace osu.Game.Tests.Visual.Multiplayer { - public abstract class QueueModeTestScene : ScreenTestScene + public abstract partial class QueueModeTestScene : ScreenTestScene { protected abstract QueueMode Mode { get; } diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneAllPlayersQueueMode.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneAllPlayersQueueMode.cs index 5947cabf7f..7b1abd104f 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneAllPlayersQueueMode.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneAllPlayersQueueMode.cs @@ -23,7 +23,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneAllPlayersQueueMode : QueueModeTestScene + public partial class TestSceneAllPlayersQueueMode : QueueModeTestScene { protected override QueueMode Mode => QueueMode.AllPlayers; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneCreateMultiplayerMatchButton.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneCreateMultiplayerMatchButton.cs index 317e410f37..11b0f8b91c 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneCreateMultiplayerMatchButton.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneCreateMultiplayerMatchButton.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.OnlinePlay.Multiplayer; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneCreateMultiplayerMatchButton : MultiplayerTestScene + public partial class TestSceneCreateMultiplayerMatchButton : MultiplayerTestScene { private CreateMultiplayerMatchButton button; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs index be1f21a7b2..4de911b6b6 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableLoungeRoom.cs @@ -21,7 +21,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneDrawableLoungeRoom : OsuManualInputManagerTestScene + public partial class TestSceneDrawableLoungeRoom : OsuManualInputManagerTestScene { private readonly Room room = new Room { diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs index 23ef440a4d..4ffccdbf0e 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs @@ -27,7 +27,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneDrawableRoom : OsuTestScene + public partial class TestSceneDrawableRoom : OsuTestScene { [Cached] protected readonly OverlayColourProvider ColourProvider = new OverlayColourProvider(OverlayColourScheme.Plum); diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomParticipantsList.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomParticipantsList.cs index b26481387d..98abc93994 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomParticipantsList.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomParticipantsList.cs @@ -15,7 +15,7 @@ using osu.Game.Users.Drawables; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneDrawableRoomParticipantsList : OnlinePlayTestScene + public partial class TestSceneDrawableRoomParticipantsList : OnlinePlayTestScene { private DrawableRoomParticipantsList list; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs index 73d1222156..312135402f 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs @@ -33,7 +33,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneDrawableRoomPlaylist : MultiplayerTestScene + public partial class TestSceneDrawableRoomPlaylist : MultiplayerTestScene { private TestPlaylist playlist; @@ -390,7 +390,7 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("wait for items to load", () => playlist.ItemMap.Values.All(i => i.IsLoaded)); } - private class TestPlaylist : DrawableRoomPlaylist + private partial class TestPlaylist : DrawableRoomPlaylist { public new IReadOnlyDictionary> ItemMap => base.ItemMap; } diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneFreeModSelectOverlay.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneFreeModSelectOverlay.cs index 457af3e4af..45f671618e 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneFreeModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneFreeModSelectOverlay.cs @@ -19,7 +19,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneFreeModSelectOverlay : MultiplayerTestScene + public partial class TestSceneFreeModSelectOverlay : MultiplayerTestScene { private FreeModSelectOverlay freeModSelectOverlay; private readonly Bindable>> availableMods = new Bindable>>(); diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneGameplayChatDisplay.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneGameplayChatDisplay.cs index a08791ecff..979cb4424e 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneGameplayChatDisplay.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneGameplayChatDisplay.cs @@ -18,7 +18,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneGameplayChatDisplay : OsuManualInputManagerTestScene + public partial class TestSceneGameplayChatDisplay : OsuManualInputManagerTestScene { private GameplayChatDisplay chatDisplay; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneHostOnlyQueueMode.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneHostOnlyQueueMode.cs index 800b523a9d..145c655c0a 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneHostOnlyQueueMode.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneHostOnlyQueueMode.cs @@ -17,7 +17,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneHostOnlyQueueMode : QueueModeTestScene + public partial class TestSceneHostOnlyQueueMode : QueueModeTestScene { protected override QueueMode Mode => QueueMode.HostOnly; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs index 3d6d4f0a90..d99d764449 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs @@ -19,7 +19,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneLoungeRoomsContainer : OnlinePlayTestScene + public partial class TestSceneLoungeRoomsContainer : OnlinePlayTestScene { protected new TestRoomManager RoomManager => (TestRoomManager)base.RoomManager; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapDetailArea.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapDetailArea.cs index b113352117..63a0ada3dc 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapDetailArea.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapDetailArea.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMatchBeatmapDetailArea : OnlinePlayTestScene + public partial class TestSceneMatchBeatmapDetailArea : OnlinePlayTestScene { public override void SetUpSteps() { diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchLeaderboard.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchLeaderboard.cs index d2468ae005..defb3006cc 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchLeaderboard.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchLeaderboard.cs @@ -15,7 +15,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMatchLeaderboard : OnlinePlayTestScene + public partial class TestSceneMatchLeaderboard : OnlinePlayTestScene { public override void SetUpSteps() { diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchStartControl.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchStartControl.cs index 12e7394c93..3efc7fbd30 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchStartControl.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchStartControl.cs @@ -28,7 +28,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMatchStartControl : OsuManualInputManagerTestScene + public partial class TestSceneMatchStartControl : OsuManualInputManagerTestScene { private readonly Mock multiplayerClient = new Mock(); private readonly Mock availabilityTracker = new Mock(); diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiHeader.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiHeader.cs index 70c6271d24..3d85a47ca9 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiHeader.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiHeader.cs @@ -12,7 +12,7 @@ using osu.Game.Screens.OnlinePlay; namespace osu.Game.Tests.Visual.Multiplayer { [TestFixture] - public class TestSceneMultiHeader : OsuTestScene + public partial class TestSceneMultiHeader : OsuTestScene { public TestSceneMultiHeader() { @@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual.Multiplayer AddStep("push multi screen", () => screenStack.CurrentScreen.Push(new TestOnlinePlaySubScreen(++index))); } - private class TestOnlinePlaySubScreen : OsuScreen, IOnlinePlaySubScreen + private partial class TestOnlinePlaySubScreen : OsuScreen, IOnlinePlaySubScreen { private readonly int index; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorLeaderboard.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorLeaderboard.cs index 4fda4c1c50..049c02ffde 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorLeaderboard.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorLeaderboard.cs @@ -16,7 +16,7 @@ using osu.Game.Screens.Play.HUD; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiSpectatorLeaderboard : MultiplayerTestScene + public partial class TestSceneMultiSpectatorLeaderboard : MultiplayerTestScene { private Dictionary clocks; private MultiSpectatorLeaderboard leaderboard; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs index 13fde4fd72..c2036984c1 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs @@ -30,7 +30,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiSpectatorScreen : MultiplayerTestScene + public partial class TestSceneMultiSpectatorScreen : MultiplayerTestScene { [Resolved] private OsuGameBase game { get; set; } = null!; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs index 6098a3e794..5033347b15 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs @@ -46,7 +46,7 @@ using ReadyButton = osu.Game.Screens.OnlinePlay.Components.ReadyButton; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiplayer : ScreenTestScene + public partial class TestSceneMultiplayer : ScreenTestScene { private BeatmapManager beatmaps = null!; private BeatmapSetInfo importedSet = null!; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboard.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboard.cs index 95fd449dd3..a612167d57 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboard.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboard.cs @@ -15,7 +15,7 @@ using osu.Game.Screens.Play.HUD; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiplayerGameplayLeaderboard : MultiplayerGameplayLeaderboardTestScene + public partial class TestSceneMultiplayerGameplayLeaderboard : MultiplayerGameplayLeaderboardTestScene { protected override MultiplayerRoomUser CreateUser(int userId) { @@ -47,7 +47,7 @@ namespace osu.Game.Tests.Visual.Multiplayer }); } - private class TestLeaderboard : MultiplayerGameplayLeaderboard + private partial class TestLeaderboard : MultiplayerGameplayLeaderboard { public Dictionary> UserMods => UserScores.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.ScoreProcessor.Mods); diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboardTeams.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboardTeams.cs index 93ccf3977b..48f74cf308 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboardTeams.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerGameplayLeaderboardTeams.cs @@ -12,7 +12,7 @@ using osu.Game.Screens.Play.HUD; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiplayerGameplayLeaderboardTeams : MultiplayerGameplayLeaderboardTestScene + public partial class TestSceneMultiplayerGameplayLeaderboardTeams : MultiplayerGameplayLeaderboardTestScene { private int team; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerLoungeSubScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerLoungeSubScreen.cs index 1a3fefa603..cf25e06799 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerLoungeSubScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerLoungeSubScreen.cs @@ -18,7 +18,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiplayerLoungeSubScreen : OnlinePlayTestScene + public partial class TestSceneMultiplayerLoungeSubScreen : OnlinePlayTestScene { protected new TestRoomManager RoomManager => (TestRoomManager)base.RoomManager; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchFooter.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchFooter.cs index 83e7ef6a81..d636373fbd 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchFooter.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchFooter.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.OnlinePlay.Multiplayer.Match; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiplayerMatchFooter : MultiplayerTestScene + public partial class TestSceneMultiplayerMatchFooter : MultiplayerTestScene { public override void SetUpSteps() { diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs index b87321c047..c0b6a0beab 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs @@ -31,7 +31,7 @@ using osu.Game.Tests.Resources; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiplayerMatchSongSelect : MultiplayerTestScene + public partial class TestSceneMultiplayerMatchSongSelect : MultiplayerTestScene { private BeatmapManager manager; private RulesetStore rulesets; @@ -112,7 +112,7 @@ namespace osu.Game.Tests.Visual.Multiplayer .All(b => b.Mod.GetType() != type)); } - private class TestMultiplayerMatchSongSelect : MultiplayerMatchSongSelect + private partial class TestMultiplayerMatchSongSelect : MultiplayerMatchSongSelect { public new Bindable> Mods => base.Mods; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSubScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSubScreen.cs index 9fc42dc68b..8816787ceb 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSubScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSubScreen.cs @@ -39,7 +39,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiplayerMatchSubScreen : MultiplayerTestScene + public partial class TestSceneMultiplayerMatchSubScreen : MultiplayerTestScene { private MultiplayerMatchSubScreen screen; @@ -286,7 +286,7 @@ namespace osu.Game.Tests.Visual.Multiplayer }); } - private class TestMultiplayerMatchSubScreen : MultiplayerMatchSubScreen + private partial class TestMultiplayerMatchSubScreen : MultiplayerMatchSubScreen { [Resolved(canBeNull: true)] [CanBeNull] diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs index edd1491865..2da29ccc95 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerParticipantsList.cs @@ -23,7 +23,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiplayerParticipantsList : MultiplayerTestScene + public partial class TestSceneMultiplayerParticipantsList : MultiplayerTestScene { [SetUpSteps] public void SetupSteps() diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerPlayer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerPlayer.cs index f6a6b3c667..45c5c67fff 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerPlayer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerPlayer.cs @@ -14,7 +14,7 @@ using osu.Game.Screens.OnlinePlay.Multiplayer; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiplayerPlayer : MultiplayerTestScene + public partial class TestSceneMultiplayerPlayer : MultiplayerTestScene { private MultiplayerPlayer player; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerPlaylist.cs index 8dbad4e330..d7578b4114 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerPlaylist.cs @@ -27,7 +27,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiplayerPlaylist : MultiplayerTestScene + public partial class TestSceneMultiplayerPlaylist : MultiplayerTestScene { private MultiplayerPlaylist list; private BeatmapManager beatmaps; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerQueueList.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerQueueList.cs index 63677ce378..bb37f1a5a7 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerQueueList.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerQueueList.cs @@ -25,7 +25,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiplayerQueueList : MultiplayerTestScene + public partial class TestSceneMultiplayerQueueList : MultiplayerTestScene { private MultiplayerQueueList playlist; private BeatmapManager beatmaps; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerResults.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerResults.cs index a638702ceb..f030466fff 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerResults.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerResults.cs @@ -11,7 +11,7 @@ using osu.Game.Tests.Resources; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiplayerResults : ScreenTestScene + public partial class TestSceneMultiplayerResults : ScreenTestScene { [Test] public void TestDisplayResults() diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerSpectateButton.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerSpectateButton.cs index 9b4cb722f3..816ba4ca32 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerSpectateButton.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerSpectateButton.cs @@ -26,7 +26,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiplayerSpectateButton : MultiplayerTestScene + public partial class TestSceneMultiplayerSpectateButton : MultiplayerTestScene { private MultiplayerSpectateButton spectateButton; private MatchStartControl startControl; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerSpectatorPlayerGrid.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerSpectatorPlayerGrid.cs index 089b4a020d..8fd05dcaa9 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerSpectatorPlayerGrid.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerSpectatorPlayerGrid.cs @@ -14,7 +14,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiplayerSpectatorPlayerGrid : OsuManualInputManagerTestScene + public partial class TestSceneMultiplayerSpectatorPlayerGrid : OsuManualInputManagerTestScene { private PlayerGrid grid; @@ -105,7 +105,7 @@ namespace osu.Game.Tests.Visual.Multiplayer bool checkAction() => Precision.AlmostEquals(grid.MaximisedFacade.DrawSize, grid.Content.ElementAt(index).DrawSize, 10) == shouldBeMaximised; } - private class GridContent : Box + private partial class GridContent : Box { public GridContent() { diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerTeamResults.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerTeamResults.cs index 56260941a8..68fd39a066 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerTeamResults.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerTeamResults.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMultiplayerTeamResults : ScreenTestScene + public partial class TestSceneMultiplayerTeamResults : ScreenTestScene { [Test] public void TestScaling() diff --git a/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsRoomSettingsPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsRoomSettingsPlaylist.cs index bbccdb0d17..91e9ce5ea2 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsRoomSettingsPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsRoomSettingsPlaylist.cs @@ -25,7 +25,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestScenePlaylistsRoomSettingsPlaylist : OnlinePlayTestScene + public partial class TestScenePlaylistsRoomSettingsPlaylist : OnlinePlayTestScene { private TestPlaylist playlist; @@ -159,7 +159,7 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("wait for items to load", () => playlist.ItemMap.Values.All(i => i.IsLoaded)); } - private class TestPlaylist : PlaylistsRoomSettingsPlaylist + private partial class TestPlaylist : PlaylistsRoomSettingsPlaylist { public new IReadOnlyDictionary> ItemMap => base.ItemMap; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsSongSelect.cs b/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsSongSelect.cs index 2eddf1a17e..b0b753fc22 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsSongSelect.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsSongSelect.cs @@ -24,7 +24,7 @@ using osu.Game.Tests.Visual.OnlinePlay; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestScenePlaylistsSongSelect : OnlinePlayTestScene + public partial class TestScenePlaylistsSongSelect : OnlinePlayTestScene { private BeatmapManager manager; @@ -154,7 +154,7 @@ namespace osu.Game.Tests.Visual.Multiplayer }); } - private class TestPlaylistsSongSelect : PlaylistsSongSelect + private partial class TestPlaylistsSongSelect : PlaylistsSongSelect { public new MatchBeatmapDetailArea BeatmapDetails => (MatchBeatmapDetailArea)base.BeatmapDetails; diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneRankRangePill.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneRankRangePill.cs index cb80fb56df..aaf1a850af 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneRankRangePill.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneRankRangePill.cs @@ -16,7 +16,7 @@ using osu.Game.Screens.OnlinePlay.Lounge.Components; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneRankRangePill : OsuTestScene + public partial class TestSceneRankRangePill : OsuTestScene { private readonly Mock multiplayerClient = new Mock(); diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneStarRatingRangeDisplay.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneStarRatingRangeDisplay.cs index 5bccabcf2f..e46ae978d7 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneStarRatingRangeDisplay.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneStarRatingRangeDisplay.cs @@ -12,7 +12,7 @@ using osu.Game.Tests.Visual.OnlinePlay; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneStarRatingRangeDisplay : OnlinePlayTestScene + public partial class TestSceneStarRatingRangeDisplay : OnlinePlayTestScene { public override void SetUpSteps() { diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneTeamVersus.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneTeamVersus.cs index ef2a431b8f..32e90153d8 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneTeamVersus.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneTeamVersus.cs @@ -27,7 +27,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneTeamVersus : ScreenTestScene + public partial class TestSceneTeamVersus : ScreenTestScene { private BeatmapManager beatmaps; private BeatmapSetInfo importedSet; diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneButtonSystemNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneButtonSystemNavigation.cs index bff30b83f9..64ea6003bc 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneButtonSystemNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneButtonSystemNavigation.cs @@ -12,7 +12,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Navigation { - public class TestSceneButtonSystemNavigation : OsuGameTestScene + public partial class TestSceneButtonSystemNavigation : OsuGameTestScene { private ButtonSystem buttons => ((MainMenu)Game.ScreenStack.CurrentScreen).ChildrenOfType().Single(); diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs b/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs index c3d7bde68f..d937b9e6d7 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs @@ -20,7 +20,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Navigation { - public class TestSceneChangeAndUseGameplayBindings : OsuGameTestScene + public partial class TestSceneChangeAndUseGameplayBindings : OsuGameTestScene { [Test] public void TestGameplayKeyBindings() diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneEditDefaultSkin.cs b/osu.Game.Tests/Visual/Navigation/TestSceneEditDefaultSkin.cs index 010ed23c9b..7d39d48378 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneEditDefaultSkin.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneEditDefaultSkin.cs @@ -13,7 +13,7 @@ using osu.Game.Skinning.Editor; namespace osu.Game.Tests.Visual.Navigation { - public class TestSceneEditDefaultSkin : OsuGameTestScene + public partial class TestSceneEditDefaultSkin : OsuGameTestScene { private SkinManager skinManager => Game.Dependencies.Get(); private SkinEditorOverlay skinEditor => Game.Dependencies.Get(); diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneFirstRunGame.cs b/osu.Game.Tests/Visual/Navigation/TestSceneFirstRunGame.cs index fe26d59812..7f7a81d787 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneFirstRunGame.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneFirstRunGame.cs @@ -13,7 +13,7 @@ using osu.Game.Overlays.Notifications; namespace osu.Game.Tests.Visual.Navigation { [System.ComponentModel.Description("game with first-run setup overlay")] - public class TestSceneFirstRunGame : OsuGameTestScene + public partial class TestSceneFirstRunGame : OsuGameTestScene { public override void SetUpSteps() { @@ -32,7 +32,7 @@ namespace osu.Game.Tests.Visual.Navigation protected override TestOsuGame CreateTestGame() => new FirstRunGame(LocalStorage, API); - private class FirstRunGame : TestOsuGame + private partial class FirstRunGame : TestOsuGame { public FirstRunGame(Storage storage, IAPIProvider api, string[] args = null) : base(storage, api, args) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneInterProcessCommunication.cs b/osu.Game.Tests/Visual/Navigation/TestSceneInterProcessCommunication.cs index 1c2b1fe37d..346f1d9f90 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneInterProcessCommunication.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneInterProcessCommunication.cs @@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual.Navigation { [TestFixture] [Ignore("This test cannot be run headless, as it requires the game host running the nested game to have IPC bound.")] - public class TestSceneInterProcessCommunication : OsuGameTestScene + public partial class TestSceneInterProcessCommunication : OsuGameTestScene { private HeadlessGameHost ipcSenderHost = null!; diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneMouseWheelVolumeAdjust.cs b/osu.Game.Tests/Visual/Navigation/TestSceneMouseWheelVolumeAdjust.cs index 2592936ab6..a89f5fb647 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneMouseWheelVolumeAdjust.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneMouseWheelVolumeAdjust.cs @@ -12,7 +12,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Navigation { - public class TestSceneMouseWheelVolumeAdjust : OsuGameTestScene + public partial class TestSceneMouseWheelVolumeAdjust : OsuGameTestScene { public override void SetUpSteps() { diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneOsuGame.cs b/osu.Game.Tests/Visual/Navigation/TestSceneOsuGame.cs index 6070b1456f..de303fe074 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneOsuGame.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneOsuGame.cs @@ -30,7 +30,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Navigation { [TestFixture] - public class TestSceneOsuGame : OsuGameTestScene + public partial class TestSceneOsuGame : OsuGameTestScene { private IReadOnlyList requiredGameDependencies => new[] { diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs b/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs index ce0543875b..1c8fa775b9 100644 --- a/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs +++ b/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs @@ -22,7 +22,7 @@ using static osu.Game.Tests.Visual.Navigation.TestSceneScreenNavigation; namespace osu.Game.Tests.Visual.Navigation { - public class TestScenePerformFromScreen : OsuGameTestScene + public partial class TestScenePerformFromScreen : OsuGameTestScene { private bool actionPerformed; @@ -237,7 +237,7 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("beatmap updated", () => Game.Beatmap.Value.BeatmapSetInfo.OnlineID == 241526); } - public class DialogBlockingScreen : OsuScreen + public partial class DialogBlockingScreen : OsuScreen { [Resolved] private IDialogOverlay dialogOverlay { get; set; } @@ -260,7 +260,7 @@ namespace osu.Game.Tests.Visual.Navigation } } - public class TestScreenWithNestedStack : OsuScreen, IHasSubScreenStack + public partial class TestScreenWithNestedStack : OsuScreen, IHasSubScreenStack { public DialogBlockingScreen Blocker { get; private set; } @@ -285,7 +285,7 @@ namespace osu.Game.Tests.Visual.Navigation } } - public class TestLoadBlockingScreen : OsuScreen + public partial class TestLoadBlockingScreen : OsuScreen { public readonly ManualResetEventSlim LoadEvent = new ManualResetEventSlim(); diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs index 02b348b439..8a09e7ac6f 100644 --- a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs +++ b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs @@ -18,7 +18,7 @@ using osu.Game.Screens.Select; namespace osu.Game.Tests.Visual.Navigation { - public class TestScenePresentBeatmap : OsuGameTestScene + public partial class TestScenePresentBeatmap : OsuGameTestScene { [Test] public void TestFromMainMenu() diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePresentScore.cs b/osu.Game.Tests/Visual/Navigation/TestScenePresentScore.cs index 003cec0d07..4bcd6b100a 100644 --- a/osu.Game.Tests/Visual/Navigation/TestScenePresentScore.cs +++ b/osu.Game.Tests/Visual/Navigation/TestScenePresentScore.cs @@ -24,7 +24,7 @@ using osu.Game.Screens.Select; namespace osu.Game.Tests.Visual.Navigation { - public class TestScenePresentScore : OsuGameTestScene + public partial class TestScenePresentScore : OsuGameTestScene { private BeatmapSetInfo beatmap; diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index e500efede3..d8fda5b21f 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -38,7 +38,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Navigation { - public class TestSceneScreenNavigation : OsuGameTestScene + public partial class TestSceneScreenNavigation : OsuGameTestScene { private const float click_padding = 25; @@ -694,7 +694,7 @@ namespace osu.Game.Tests.Visual.Navigation ConfirmAtMainMenu(); } - public class TestPlaySongSelect : PlaySongSelect + public partial class TestPlaySongSelect : PlaySongSelect { public ModSelectOverlay ModSelectOverlay => ModSelect; diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs index 2f0f2f68a5..e0b61794e4 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs @@ -24,7 +24,7 @@ using static osu.Game.Tests.Visual.Navigation.TestSceneScreenNavigation; namespace osu.Game.Tests.Visual.Navigation { - public class TestSceneSkinEditorNavigation : OsuGameTestScene + public partial class TestSceneSkinEditorNavigation : OsuGameTestScene { private TestPlaySongSelect songSelect; private SkinEditor skinEditor => Game.ChildrenOfType().FirstOrDefault(); diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneStartupBeatmapDisplay.cs b/osu.Game.Tests/Visual/Navigation/TestSceneStartupBeatmapDisplay.cs index bd3dcb8597..0c165bc40e 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneStartupBeatmapDisplay.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneStartupBeatmapDisplay.cs @@ -15,7 +15,7 @@ using osu.Game.Overlays.BeatmapSet; namespace osu.Game.Tests.Visual.Navigation { - public class TestSceneStartupBeatmapDisplay : OsuGameTestScene + public partial class TestSceneStartupBeatmapDisplay : OsuGameTestScene { private const int requested_beatmap_id = 75; private const int requested_beatmap_set_id = 1; diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneStartupBeatmapSetDisplay.cs b/osu.Game.Tests/Visual/Navigation/TestSceneStartupBeatmapSetDisplay.cs index 1072508e33..f885c2f44c 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneStartupBeatmapSetDisplay.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneStartupBeatmapSetDisplay.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Navigation { - public class TestSceneStartupBeatmapSetDisplay : OsuGameTestScene + public partial class TestSceneStartupBeatmapSetDisplay : OsuGameTestScene { private const int requested_beatmap_set_id = 1; diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneStartupImport.cs b/osu.Game.Tests/Visual/Navigation/TestSceneStartupImport.cs index 552eb82419..e795166d3e 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneStartupImport.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneStartupImport.cs @@ -9,7 +9,7 @@ using osu.Game.Tests.Resources; namespace osu.Game.Tests.Visual.Navigation { - public class TestSceneStartupImport : OsuGameTestScene + public partial class TestSceneStartupImport : OsuGameTestScene { private string? importFilename; diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneStartupRuleset.cs b/osu.Game.Tests/Visual/Navigation/TestSceneStartupRuleset.cs index 1aadff7a20..621dabe869 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneStartupRuleset.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneStartupRuleset.cs @@ -10,7 +10,7 @@ using osu.Game.Configuration; namespace osu.Game.Tests.Visual.Navigation { [TestFixture] - public class TestSceneStartupRuleset : OsuGameTestScene + public partial class TestSceneStartupRuleset : OsuGameTestScene { protected override TestOsuGame CreateTestGame() { diff --git a/osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs b/osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs index 2879536034..c32aa7f5f9 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs @@ -9,7 +9,7 @@ using osu.Game.Configuration; namespace osu.Game.Tests.Visual.Navigation { - public class TestSettingsMigration : OsuGameTestScene + public partial class TestSettingsMigration : OsuGameTestScene { public override void RecycleLocalStorage(bool isDisposing) { diff --git a/osu.Game.Tests/Visual/Online/TestSceneAccountCreationOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneAccountCreationOverlay.cs index b9d800e6fd..0f920643f0 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneAccountCreationOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneAccountCreationOverlay.cs @@ -18,7 +18,7 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual.Online { - public class TestSceneAccountCreationOverlay : OsuTestScene + public partial class TestSceneAccountCreationOverlay : OsuTestScene { private readonly Container userPanelArea; private readonly AccountCreationOverlay accountCreation; diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapAvailability.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapAvailability.cs index c78a36d2bd..36f8d2d9bd 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapAvailability.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapAvailability.cs @@ -11,7 +11,7 @@ using osu.Game.Overlays.BeatmapSet; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneBeatmapAvailability : OsuTestScene + public partial class TestSceneBeatmapAvailability : OsuTestScene { private readonly BeatmapAvailability container; diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapDownloadButton.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapDownloadButton.cs index ba600332bb..40e34a52b6 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapDownloadButton.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapDownloadButton.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Online { - public class TestSceneBeatmapDownloadButton : OsuTestScene + public partial class TestSceneBeatmapDownloadButton : OsuTestScene { private TestDownloadButton downloadButton; @@ -139,7 +139,7 @@ namespace osu.Game.Tests.Visual.Online return apiBeatmapSet; } - private class TestDownloadButton : BeatmapDownloadButton + private partial class TestDownloadButton : BeatmapDownloadButton { public new bool DownloadEnabled => base.DownloadEnabled; diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs index 1e0a09d37a..c64343b47b 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs @@ -25,7 +25,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Tests.Visual.Online { - public class TestSceneBeatmapListingOverlay : OsuManualInputManagerTestScene + public partial class TestSceneBeatmapListingOverlay : OsuManualInputManagerTestScene { private readonly List setsForResponse = new List(); diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapRulesetSelector.cs index b73028be5b..36c3576da6 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapRulesetSelector.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays.BeatmapSet; namespace osu.Game.Tests.Visual.Online { - public class TestSceneBeatmapRulesetSelector : OsuTestScene + public partial class TestSceneBeatmapRulesetSelector : OsuTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index bb4823fb1d..3335f69dbb 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -24,7 +24,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Tests.Visual.Online { - public class TestSceneBeatmapSetOverlay : OsuTestScene + public partial class TestSceneBeatmapSetOverlay : OsuTestScene { private readonly TestBeatmapSetOverlay overlay; @@ -283,7 +283,7 @@ namespace osu.Game.Tests.Visual.Online AddAssert($"is download button {(shown ? "shown" : "hidden")}", () => overlay.Header.HeaderContent.DownloadButtonsVisible == shown); } - private class TestBeatmapSetOverlay : BeatmapSetOverlay + private partial class TestBeatmapSetOverlay : BeatmapSetOverlay { public new BeatmapSetHeader Header => base.Header; } diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlayDetails.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlayDetails.cs index 31cebc2f0b..69c9faa9d3 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlayDetails.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlayDetails.cs @@ -16,7 +16,7 @@ using osu.Game.Screens.Select.Details; namespace osu.Game.Tests.Visual.Online { - public class TestSceneBeatmapSetOverlayDetails : OsuTestScene + public partial class TestSceneBeatmapSetOverlayDetails : OsuTestScene { private RatingsExposingDetails details; @@ -63,7 +63,7 @@ namespace osu.Game.Tests.Visual.Online }; } - private class RatingsExposingDetails : Details + private partial class RatingsExposingDetails : Details { public new UserRatings Ratings => base.Ratings; } diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs index 26e1e49ca3..59c96ec719 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs @@ -22,7 +22,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Online { - public class TestSceneBeatmapSetOverlaySuccessRate : OsuTestScene + public partial class TestSceneBeatmapSetOverlaySuccessRate : OsuTestScene { private GraphExposingSuccessRate successRate; @@ -104,7 +104,7 @@ namespace osu.Game.Tests.Visual.Online AddAssert("graph max values correct", () => successRate.ChildrenOfType().All(graph => graph.MaxValue == 0)); } - private class GraphExposingSuccessRate : SuccessRate + private partial class GraphExposingSuccessRate : SuccessRate { public new FailRetryGraph Graph => base.Graph; } diff --git a/osu.Game.Tests/Visual/Online/TestSceneBundledBeatmapDownloader.cs b/osu.Game.Tests/Visual/Online/TestSceneBundledBeatmapDownloader.cs index 08c6914f83..0f2786f9ef 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBundledBeatmapDownloader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBundledBeatmapDownloader.cs @@ -9,7 +9,7 @@ using osu.Game.Beatmaps.Drawables; namespace osu.Game.Tests.Visual.Online { [Ignore("Only for visual testing")] - public class TestSceneBundledBeatmapDownloader : OsuTestScene + public partial class TestSceneBundledBeatmapDownloader : OsuTestScene { private BundledBeatmapDownloader downloader; diff --git a/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs index c5ac3dd442..8d61c5df9f 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs @@ -18,7 +18,7 @@ using osu.Game.Overlays.Changelog; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneChangelogOverlay : OsuTestScene + public partial class TestSceneChangelogOverlay : OsuTestScene { private DummyAPIAccess dummyAPI => (DummyAPIAccess)API; @@ -201,7 +201,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("show build", () => changelog.ShowBuild(requestedBuild)); } - private class TestChangelogOverlay : ChangelogOverlay + private partial class TestChangelogOverlay : ChangelogOverlay { public new List Streams => base.Streams; diff --git a/osu.Game.Tests/Visual/Online/TestSceneChangelogSupporterPromo.cs b/osu.Game.Tests/Visual/Online/TestSceneChangelogSupporterPromo.cs index 018d40d1bc..96996db940 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChangelogSupporterPromo.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChangelogSupporterPromo.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays.Changelog; namespace osu.Game.Tests.Visual.Online { - public class TestSceneChangelogSupporterPromo : OsuTestScene + public partial class TestSceneChangelogSupporterPromo : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); diff --git a/osu.Game.Tests/Visual/Online/TestSceneChannelList.cs b/osu.Game.Tests/Visual/Online/TestSceneChannelList.cs index 8e17c490b1..a0cca5f53d 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChannelList.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChannelList.cs @@ -20,7 +20,7 @@ using osu.Game.Overlays.Chat.Listing; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneChannelList : OsuTestScene + public partial class TestSceneChannelList : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink); diff --git a/osu.Game.Tests/Visual/Online/TestSceneChannelListing.cs b/osu.Game.Tests/Visual/Online/TestSceneChannelListing.cs index 214c05e64d..2d2d7fc0ff 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChannelListing.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChannelListing.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneChannelListing : OsuTestScene + public partial class TestSceneChannelListing : OsuTestScene { [Cached] private readonly OverlayColourProvider overlayColours = new OverlayColourProvider(OverlayColourScheme.Pink); diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatLineTruncation.cs b/osu.Game.Tests/Visual/Online/TestSceneChatLineTruncation.cs index 79dc17cfa6..32d95ec8dc 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatLineTruncation.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatLineTruncation.cs @@ -15,7 +15,7 @@ using osu.Game.Overlays.Chat; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneChatLineTruncation : OsuTestScene + public partial class TestSceneChatLineTruncation : OsuTestScene { private readonly TestChatLineContainer textContainer; @@ -86,7 +86,7 @@ namespace osu.Game.Tests.Visual.Online } } - private class TestChatLineContainer : FillFlowContainer + private partial class TestChatLineContainer : FillFlowContainer { protected override int Compare(Drawable x, Drawable y) { diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs index de44986001..aa33866fa4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneChatLink : OsuTestScene + public partial class TestSceneChatLink : OsuTestScene { private readonly TestChatLineContainer textContainer; private Color4 linkColour; @@ -207,7 +207,7 @@ namespace osu.Game.Tests.Visual.Online } } - private class TestChatLineContainer : FillFlowContainer + private partial class TestChatLineContainer : FillFlowContainer { protected override int Compare(Drawable x, Drawable y) { diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 0b75a2aa05..8cc4eabcd7 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -34,7 +34,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneChatOverlay : OsuManualInputManagerTestScene + public partial class TestSceneChatOverlay : OsuManualInputManagerTestScene { private TestChatOverlay chatOverlay; private ChannelManager channelManager; @@ -621,7 +621,7 @@ namespace osu.Game.Tests.Visual.Online }; } - private class TestChatOverlay : ChatOverlay + private partial class TestChatOverlay : ChatOverlay { public bool SlowLoading { get; set; } @@ -635,7 +635,7 @@ namespace osu.Game.Tests.Visual.Online } } - private class SlowLoadingDrawableChannel : DrawableChannel + private partial class SlowLoadingDrawableChannel : DrawableChannel { public readonly ManualResetEventSlim LoadEvent = new ManualResetEventSlim(); diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatTextBox.cs b/osu.Game.Tests/Visual/Online/TestSceneChatTextBox.cs index 5d28d553a0..1e80acd56b 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatTextBox.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatTextBox.cs @@ -18,7 +18,7 @@ using osu.Game.Overlays.Chat; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneChatTextBox : OsuTestScene + public partial class TestSceneChatTextBox : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink); diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs index b4ffcd42b5..7981e212d4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs @@ -25,7 +25,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Online { - public class TestSceneCommentActions : OsuManualInputManagerTestScene + public partial class TestSceneCommentActions : OsuManualInputManagerTestScene { private Container content = null!; protected override Container Content => content; diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentReportButton.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentReportButton.cs index fb56a41507..d2e73b8673 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentReportButton.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentReportButton.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Online { - public class TestSceneCommentReportButton : ThemeComparisonTestScene + public partial class TestSceneCommentReportButton : ThemeComparisonTestScene { [SetUpSteps] public void SetUpSteps() diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index a94b9e61c0..291ccd634d 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -20,7 +20,7 @@ using osu.Game.Overlays.Comments; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneCommentsContainer : OsuTestScene + public partial class TestSceneCommentsContainer : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs index 95b718041e..43d80ee0ac 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays.Comments; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneCommentsHeader : OsuTestScene + public partial class TestSceneCommentsHeader : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); diff --git a/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs b/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs index 62f8f72929..4f825e1191 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs @@ -20,7 +20,7 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual.Online { - public class TestSceneCurrentlyPlayingDisplay : OsuTestScene + public partial class TestSceneCurrentlyPlayingDisplay : OsuTestScene { private readonly APIUser streamingUser = new APIUser { Id = 2, Username = "Test user" }; @@ -66,7 +66,7 @@ namespace osu.Game.Tests.Visual.Online AddUntilStep("Panel no longer present", () => !currentlyPlaying.ChildrenOfType().Any()); } - internal class TestUserLookupCache : UserLookupCache + internal partial class TestUserLookupCache : UserLookupCache { private static readonly string[] usernames = { diff --git a/osu.Game.Tests/Visual/Online/TestSceneDashboardOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneDashboardOverlay.cs index 074fea0604..504be45b44 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneDashboardOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneDashboardOverlay.cs @@ -8,7 +8,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Online { - public class TestSceneDashboardOverlay : OsuTestScene + public partial class TestSceneDashboardOverlay : OsuTestScene { protected override bool UseOnlineAPI => true; diff --git a/osu.Game.Tests/Visual/Online/TestSceneDrawableComment.cs b/osu.Game.Tests/Visual/Online/TestSceneDrawableComment.cs index cab0ffa3ba..ac80463d3a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneDrawableComment.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneDrawableComment.cs @@ -15,7 +15,7 @@ using osu.Game.Overlays.Comments; namespace osu.Game.Tests.Visual.Online { - public class TestSceneDrawableComment : OsuTestScene + public partial class TestSceneDrawableComment : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); diff --git a/osu.Game.Tests/Visual/Online/TestSceneExternalLinkButton.cs b/osu.Game.Tests/Visual/Online/TestSceneExternalLinkButton.cs index 4185d56833..90ec3160d8 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneExternalLinkButton.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneExternalLinkButton.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Online { - public class TestSceneExternalLinkButton : OsuTestScene + public partial class TestSceneExternalLinkButton : OsuTestScene { public TestSceneExternalLinkButton() { diff --git a/osu.Game.Tests/Visual/Online/TestSceneFavouriteButton.cs b/osu.Game.Tests/Visual/Online/TestSceneFavouriteButton.cs index 3206640f9a..3954fd5cff 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneFavouriteButton.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneFavouriteButton.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Online { - public class TestSceneFavouriteButton : OsuTestScene + public partial class TestSceneFavouriteButton : OsuTestScene { private FavouriteButton favourite; diff --git a/osu.Game.Tests/Visual/Online/TestSceneFriendDisplay.cs b/osu.Game.Tests/Visual/Online/TestSceneFriendDisplay.cs index 5454c87dff..7925b252b6 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneFriendDisplay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneFriendDisplay.cs @@ -16,7 +16,7 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual.Online { - public class TestSceneFriendDisplay : OsuTestScene + public partial class TestSceneFriendDisplay : OsuTestScene { protected override bool UseOnlineAPI => true; diff --git a/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs index b7e918207f..16d31c916e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneFullscreenOverlay.cs @@ -12,7 +12,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneFullscreenOverlay : OsuTestScene + public partial class TestSceneFullscreenOverlay : OsuTestScene { private FullscreenOverlay overlay; @@ -40,7 +40,7 @@ namespace osu.Game.Tests.Visual.Online AddAssert("fire count 3", () => fireCount == 3); } - private class TestFullscreenOverlay : FullscreenOverlay + private partial class TestFullscreenOverlay : FullscreenOverlay { public TestFullscreenOverlay() : base(OverlayColourScheme.Pink) @@ -57,11 +57,11 @@ namespace osu.Game.Tests.Visual.Online protected override OverlayHeader CreateHeader() => new TestHeader(); - internal class TestHeader : OverlayHeader + internal partial class TestHeader : OverlayHeader { protected override OverlayTitle CreateTitle() => new TestTitle(); - internal class TestTitle : OverlayTitle + internal partial class TestTitle : OverlayTitle { } } diff --git a/osu.Game.Tests/Visual/Online/TestSceneGraph.cs b/osu.Game.Tests/Visual/Online/TestSceneGraph.cs index 8b0536651d..357ed7548c 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneGraph.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneGraph.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneGraph : OsuTestScene + public partial class TestSceneGraph : OsuTestScene { public TestSceneGraph() { diff --git a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs index afc20dedff..d884c0cf14 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs @@ -16,7 +16,7 @@ using osu.Game.Overlays.Profile.Sections; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneHistoricalSection : OsuTestScene + public partial class TestSceneHistoricalSection : OsuTestScene { protected override bool UseOnlineAPI => true; diff --git a/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs index 181b086b00..a58845ca7e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHomeNewsPanel.cs @@ -15,7 +15,7 @@ using System.Collections.Generic; namespace osu.Game.Tests.Visual.Online { - public class TestSceneHomeNewsPanel : OsuTestScene + public partial class TestSceneHomeNewsPanel : OsuTestScene { [Cached] private readonly OverlayColourProvider overlayColour = new OverlayColourProvider(OverlayColourScheme.Purple); diff --git a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs index 7f0a00c474..e753632474 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs @@ -16,7 +16,7 @@ using osu.Framework.Extensions.IEnumerableExtensions; namespace osu.Game.Tests.Visual.Online { - public class TestSceneKudosuHistory : OsuTestScene + public partial class TestSceneKudosuHistory : OsuTestScene { private readonly Box background; diff --git a/osu.Game.Tests/Visual/Online/TestSceneLeaderboardModSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneLeaderboardModSelector.cs index 5579ecedbd..0a6bab468a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneLeaderboardModSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneLeaderboardModSelector.cs @@ -20,7 +20,7 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Tests.Visual.Online { - public class TestSceneLeaderboardModSelector : OsuTestScene + public partial class TestSceneLeaderboardModSelector : OsuTestScene { public TestSceneLeaderboardModSelector() { diff --git a/osu.Game.Tests/Visual/Online/TestSceneLeaderboardScopeSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneLeaderboardScopeSelector.cs index 8c38027df3..0231775189 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneLeaderboardScopeSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneLeaderboardScopeSelector.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Online { - public class TestSceneLeaderboardScopeSelector : OsuTestScene + public partial class TestSceneLeaderboardScopeSelector : OsuTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); diff --git a/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs b/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs index 57514cdf37..ba2b160fd1 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneMessageNotifier.cs @@ -23,7 +23,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Tests.Visual.Online { - public class TestSceneMessageNotifier : OsuManualInputManagerTestScene + public partial class TestSceneMessageNotifier : OsuManualInputManagerTestScene { private APIUser friend; private Channel publicChannel; @@ -228,7 +228,7 @@ namespace osu.Game.Tests.Visual.Online InputManager.Click(MouseButton.Left); } - private class TestContainer : Container + private partial class TestContainer : Container { [Cached] public ChannelManager ChannelManager { get; } diff --git a/osu.Game.Tests/Visual/Online/TestSceneNewsCard.cs b/osu.Game.Tests/Visual/Online/TestSceneNewsCard.cs index 8d73165d99..001e6d925e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNewsCard.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNewsCard.cs @@ -14,7 +14,7 @@ using System; namespace osu.Game.Tests.Visual.Online { - public class TestSceneNewsCard : OsuTestScene + public partial class TestSceneNewsCard : OsuTestScene { [Cached] private readonly OverlayColourProvider overlayColour = new OverlayColourProvider(OverlayColourScheme.Purple); diff --git a/osu.Game.Tests/Visual/Online/TestSceneNewsHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneNewsHeader.cs index cad045623b..2413c32d61 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNewsHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNewsHeader.cs @@ -11,7 +11,7 @@ using osu.Framework.Allocation; namespace osu.Game.Tests.Visual.Online { - public class TestSceneNewsHeader : OsuTestScene + public partial class TestSceneNewsHeader : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); @@ -47,7 +47,7 @@ namespace osu.Game.Tests.Visual.Online AddAssert("1 tab total", () => header.TabCount == 1); } - private class TestHeader : NewsHeader + private partial class TestHeader : NewsHeader { public int TabCount => TabControl.Items.Count; } diff --git a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs index 3e5dd91b2c..0e272c9cc8 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNewsOverlay.cs @@ -15,7 +15,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Online { - public class TestSceneNewsOverlay : OsuTestScene + public partial class TestSceneNewsOverlay : OsuTestScene { private DummyAPIAccess dummyAPI => (DummyAPIAccess)API; diff --git a/osu.Game.Tests/Visual/Online/TestSceneNewsSidebar.cs b/osu.Game.Tests/Visual/Online/TestSceneNewsSidebar.cs index 266e98db15..ce5fc888aa 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNewsSidebar.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNewsSidebar.cs @@ -16,7 +16,7 @@ using static osu.Game.Overlays.News.Sidebar.YearsPanel; namespace osu.Game.Tests.Visual.Online { - public class TestSceneNewsSidebar : OsuTestScene + public partial class TestSceneNewsSidebar : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); @@ -211,7 +211,7 @@ namespace osu.Game.Tests.Visual.Online } }; - private class TestNewsSidebar : NewsSidebar + private partial class TestNewsSidebar : NewsSidebar { public Action YearChanged; diff --git a/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs b/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs index 2df9089a8a..c017227243 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs @@ -16,7 +16,7 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual.Online { [HeadlessTest] - public class TestSceneNowPlayingCommand : OsuTestScene + public partial class TestSceneNowPlayingCommand : OsuTestScene { [Cached(typeof(IChannelPostTarget))] private PostTarget postTarget { get; set; } @@ -77,7 +77,7 @@ namespace osu.Game.Tests.Visual.Online AddAssert("Check link not present", () => !postTarget.LastMessage.Contains("https://")); } - public class PostTarget : Component, IChannelPostTarget + public partial class PostTarget : Component, IChannelPostTarget { public void PostMessage(string text, bool isAction = false, Channel target = null) { diff --git a/osu.Game.Tests/Visual/Online/TestSceneOfflineCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneOfflineCommentsContainer.cs index 07ccfcec88..4016fa7b68 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneOfflineCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneOfflineCommentsContainer.cs @@ -19,7 +19,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Tests.Visual.Online { - public class TestSceneOfflineCommentsContainer : OsuTestScene + public partial class TestSceneOfflineCommentsContainer : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); @@ -184,7 +184,7 @@ namespace osu.Game.Tests.Visual.Online PinnedComments = new List(), }; - private class TestCommentsContainer : CommentsContainer + private partial class TestCommentsContainer : CommentsContainer { public new void AppendComments([NotNull] CommentBundle bundle) => base.AppendComments(bundle); diff --git a/osu.Game.Tests/Visual/Online/TestSceneOnlineBeatmapListingOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneOnlineBeatmapListingOverlay.cs index 388c0a9d60..ecfa76f395 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneOnlineBeatmapListingOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneOnlineBeatmapListingOverlay.cs @@ -9,7 +9,7 @@ using NUnit.Framework; namespace osu.Game.Tests.Visual.Online { [Description("uses online API")] - public class TestSceneOnlineBeatmapListingOverlay : OsuTestScene + public partial class TestSceneOnlineBeatmapListingOverlay : OsuTestScene { protected override bool UseOnlineAPI => true; diff --git a/osu.Game.Tests/Visual/Online/TestSceneOnlineBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneOnlineBeatmapSetOverlay.cs index 0d9c47db7b..01b0b39661 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneOnlineBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneOnlineBeatmapSetOverlay.cs @@ -8,7 +8,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Online { - public class TestSceneOnlineBeatmapSetOverlay : OsuTestScene + public partial class TestSceneOnlineBeatmapSetOverlay : OsuTestScene { private readonly BeatmapSetOverlay overlay; diff --git a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs index b4bac5ee7e..6c8430e955 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneOnlineViewContainer : OsuTestScene + public partial class TestSceneOnlineViewContainer : OsuTestScene { private readonly TestOnlineViewContainer onlineView; @@ -67,7 +67,7 @@ namespace osu.Game.Tests.Visual.Online AddUntilStep("loading animation is visible", () => onlineView.LoadingSpinner.IsPresent); } - private class TestOnlineViewContainer : OnlineViewContainer + private partial class TestOnlineViewContainer : OnlineViewContainer { public new LoadingSpinner LoadingSpinner => base.LoadingSpinner; diff --git a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs index 118da682a7..15e411b9d8 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs @@ -17,7 +17,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Tests.Visual.Online { - public class TestScenePlayHistorySubsection : OsuTestScene + public partial class TestScenePlayHistorySubsection : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Red); diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs index 3068ba0185..e81b7a2ac8 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs @@ -16,7 +16,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Tests.Visual.Online { - public class TestSceneProfileRulesetSelector : OsuTestScene + public partial class TestSceneProfileRulesetSelector : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink); diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs b/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs index d05f1f02f7..55817e38a6 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneRankGraph : OsuTestScene + public partial class TestSceneRankGraph : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink); diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs index 6a39db4870..dfefcd735e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs @@ -16,7 +16,7 @@ using osu.Framework.Allocation; namespace osu.Game.Tests.Visual.Online { - public class TestSceneRankingsCountryFilter : OsuTestScene + public partial class TestSceneRankingsCountryFilter : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs index c776cfe377..5aef91bef1 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs @@ -12,7 +12,7 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual.Online { - public class TestSceneRankingsHeader : OsuTestScene + public partial class TestSceneRankingsHeader : OsuTestScene { [Cached] private readonly OverlayColourProvider overlayColour = new OverlayColourProvider(OverlayColourScheme.Green); diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs index 5476049882..d1c1164768 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs @@ -15,7 +15,7 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual.Online { - public class TestSceneRankingsOverlay : OsuTestScene + public partial class TestSceneRankingsOverlay : OsuTestScene { protected override bool UseOnlineAPI => true; @@ -69,7 +69,7 @@ namespace osu.Game.Tests.Visual.Online }; } - private class TestRankingsOverlay : RankingsOverlay + private partial class TestRankingsOverlay : RankingsOverlay { public new Bindable Country => base.Country; } diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs index 5aafcf3f6b..119d79e2a9 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs @@ -15,7 +15,7 @@ using osu.Game.Overlays.Rankings; namespace osu.Game.Tests.Visual.Online { - public class TestSceneRankingsSpotlightSelector : OsuTestScene + public partial class TestSceneRankingsSpotlightSelector : OsuTestScene { protected override bool UseOnlineAPI => true; diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsTables.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsTables.cs index 81b76d19ac..cd5e1cef08 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsTables.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsTables.cs @@ -16,7 +16,7 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual.Online { - public class TestSceneRankingsTables : OsuTestScene + public partial class TestSceneRankingsTables : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); diff --git a/osu.Game.Tests/Visual/Online/TestSceneScoreboardTime.cs b/osu.Game.Tests/Visual/Online/TestSceneScoreboardTime.cs index 8f03f240f7..ab85cd4a15 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneScoreboardTime.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneScoreboardTime.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays.BeatmapSet.Scores; namespace osu.Game.Tests.Visual.Online { - public class TestSceneScoreboardTime : OsuTestScene + public partial class TestSceneScoreboardTime : OsuTestScene { private StopwatchClock stopwatch; diff --git a/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs index a0f76c4e14..2bfbf76c10 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs @@ -26,7 +26,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Tests.Visual.Online { - public class TestSceneScoresContainer : OsuTestScene + public partial class TestSceneScoresContainer : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); @@ -313,7 +313,7 @@ namespace osu.Game.Tests.Visual.Online Position = 1337, }; - private class TestScoresContainer : ScoresContainer + private partial class TestScoresContainer : ScoresContainer { public new APIScoresCollection Scores { diff --git a/osu.Game.Tests/Visual/Online/TestSceneShowMoreButton.cs b/osu.Game.Tests/Visual/Online/TestSceneShowMoreButton.cs index 32262c18a8..905a085386 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneShowMoreButton.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneShowMoreButton.cs @@ -10,7 +10,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Online { - public class TestSceneShowMoreButton : OsuTestScene + public partial class TestSceneShowMoreButton : OsuTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); diff --git a/osu.Game.Tests/Visual/Online/TestSceneSpotlightsLayout.cs b/osu.Game.Tests/Visual/Online/TestSceneSpotlightsLayout.cs index d7feade128..4cbcaaac85 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneSpotlightsLayout.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneSpotlightsLayout.cs @@ -17,7 +17,7 @@ using osu.Game.Rulesets.Taiko; namespace osu.Game.Tests.Visual.Online { - public class TestSceneSpotlightsLayout : OsuTestScene + public partial class TestSceneSpotlightsLayout : OsuTestScene { protected override bool UseOnlineAPI => true; diff --git a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs index 34ecad7dc1..7d2ac90939 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs @@ -20,7 +20,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Online { - public class TestSceneStandAloneChatDisplay : OsuManualInputManagerTestScene + public partial class TestSceneStandAloneChatDisplay : OsuManualInputManagerTestScene { private readonly APIUser admin = new APIUser { @@ -401,7 +401,7 @@ namespace osu.Game.Tests.Visual.Online private void checkNotScrolledToBottom() => AddUntilStep("not scrolled to bottom", () => !chatDisplay.ScrolledToBottom); - private class TestStandAloneChatDisplay : StandAloneChatDisplay + private partial class TestStandAloneChatDisplay : StandAloneChatDisplay { public TestStandAloneChatDisplay(bool textBox = false) : base(textBox) diff --git a/osu.Game.Tests/Visual/Online/TestSceneTotalCommentsCounter.cs b/osu.Game.Tests/Visual/Online/TestSceneTotalCommentsCounter.cs index d4355d2f11..8af87dd597 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneTotalCommentsCounter.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneTotalCommentsCounter.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Online { - public class TestSceneTotalCommentsCounter : OsuTestScene + public partial class TestSceneTotalCommentsCounter : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserHistoryGraph.cs b/osu.Game.Tests/Visual/Online/TestSceneUserHistoryGraph.cs index 42a8462604..d93bf059dd 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserHistoryGraph.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserHistoryGraph.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays.Profile.Sections.Historical; namespace osu.Game.Tests.Visual.Online { - public class TestSceneUserHistoryGraph : OsuTestScene + public partial class TestSceneUserHistoryGraph : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink); diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneUserPanel.cs index 2a70fd7df3..4c1df850b2 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserPanel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserPanel.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneUserPanel : OsuTestScene + public partial class TestSceneUserPanel : OsuTestScene { private readonly Bindable activity = new Bindable(); private readonly Bindable status = new Bindable(); @@ -132,7 +132,7 @@ namespace osu.Game.Tests.Visual.Online private UserActivity soloGameStatusForRuleset(int rulesetId) => new UserActivity.InSoloGame(null, rulesetStore.GetRuleset(rulesetId)); - private class TestUserListPanel : UserListPanel + private partial class TestUserListPanel : UserListPanel { public TestUserListPanel(APIUser user) : base(user) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index 1abe06ed76..75743d788a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -15,7 +15,7 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual.Online { - public class TestSceneUserProfileHeader : OsuTestScene + public partial class TestSceneUserProfileHeader : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs index 7064a08151..02d01b4a46 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs @@ -14,7 +14,7 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneUserProfileOverlay : OsuTestScene + public partial class TestSceneUserProfileOverlay : OsuTestScene { protected override bool UseOnlineAPI => true; @@ -117,7 +117,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("Show without reload", profile.Show); } - private class TestUserProfileOverlay : UserProfileOverlay + private partial class TestUserProfileOverlay : UserProfileOverlay { public new ProfileHeader Header => base.Header; } diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.cs index 4260fff02d..fcefb31716 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays.Profile.Header.Components; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneUserProfilePreviousUsernames : OsuTestScene + public partial class TestSceneUserProfilePreviousUsernames : OsuTestScene { private PreviousUsernames container; diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs index 7875a9dfbc..f8432118d4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs @@ -20,7 +20,7 @@ using osu.Game.Overlays.Profile.Sections.Recent; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneUserProfileRecentSection : OsuTestScene + public partial class TestSceneUserProfileRecentSection : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs index 4bbb72c862..6f0ef10911 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Online { - public class TestSceneUserProfileScores : OsuTestScene + public partial class TestSceneUserProfileScores : OsuTestScene { public TestSceneUserProfileScores() { @@ -138,7 +138,7 @@ namespace osu.Game.Tests.Visual.Online }); } - private class ColourProvidedContainer : Container + private partial class ColourProvidedContainer : Container { [Cached] private readonly OverlayColourProvider colourProvider; diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs index d517aaa105..ef3a677efc 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs @@ -17,7 +17,7 @@ using osu.Game.Overlays.Profile.Sections; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneUserRanks : OsuTestScene + public partial class TestSceneUserRanks : OsuTestScene { protected override bool UseOnlineAPI => true; diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRequest.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRequest.cs index 32d427ba6d..1ffb438355 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserRequest.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserRequest.cs @@ -20,7 +20,7 @@ using osu.Game.Rulesets.Taiko; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneUserRequest : OsuTestScene + public partial class TestSceneUserRequest : OsuTestScene { [Resolved] private IAPIProvider api { get; set; } @@ -71,7 +71,7 @@ namespace osu.Game.Tests.Visual.Online api.Queue(request); } - private class UserTestContainer : FillFlowContainer + private partial class UserTestContainer : FillFlowContainer { public readonly Bindable User = new Bindable(); diff --git a/osu.Game.Tests/Visual/Online/TestSceneVotePill.cs b/osu.Game.Tests/Visual/Online/TestSceneVotePill.cs index fdc15af73d..ce1a9ac6a7 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneVotePill.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneVotePill.cs @@ -15,7 +15,7 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneVotePill : OsuTestScene + public partial class TestSceneVotePill : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); @@ -98,7 +98,7 @@ namespace osu.Game.Tests.Visual.Online }; } - private class TestPill : VotePill + private partial class TestPill : VotePill { public new Box Background => base.Background; diff --git a/osu.Game.Tests/Visual/Online/TestSceneWikiHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneWikiHeader.cs index 99e301f3ba..4e71c5977e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneWikiHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneWikiHeader.cs @@ -16,7 +16,7 @@ using osu.Game.Overlays.Wiki; namespace osu.Game.Tests.Visual.Online { - public class TestSceneWikiHeader : OsuTestScene + public partial class TestSceneWikiHeader : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Orange); @@ -97,7 +97,7 @@ namespace osu.Game.Tests.Visual.Online }; } - private class TestHeader : WikiHeader + private partial class TestHeader : WikiHeader { public IReadOnlyList TabControlItems => TabControl.Items; } diff --git a/osu.Game.Tests/Visual/Online/TestSceneWikiMainPage.cs b/osu.Game.Tests/Visual/Online/TestSceneWikiMainPage.cs index 03b94aded7..8876f0fd3b 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneWikiMainPage.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneWikiMainPage.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays.Wiki; namespace osu.Game.Tests.Visual.Online { - public class TestSceneWikiMainPage : OsuTestScene + public partial class TestSceneWikiMainPage : OsuTestScene { [Cached] private readonly OverlayColourProvider overlayColour = new OverlayColourProvider(OverlayColourScheme.Orange); diff --git a/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs index 863b352618..b486f800c6 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs @@ -21,7 +21,7 @@ using osu.Game.Overlays.Wiki.Markdown; namespace osu.Game.Tests.Visual.Online { - public class TestSceneWikiMarkdownContainer : OsuTestScene + public partial class TestSceneWikiMarkdownContainer : OsuTestScene { private TestMarkdownContainer markdownContainer; @@ -199,7 +199,7 @@ Line after image"; }); } - private class TestMarkdownContainer : WikiMarkdownContainer + private partial class TestMarkdownContainer : WikiMarkdownContainer { public LinkInline Link; @@ -208,7 +208,7 @@ Line after image"; UrlAdded = link => Link = link, }; - private class TestMarkdownTextFlowContainer : OsuMarkdownTextFlowContainer + private partial class TestMarkdownTextFlowContainer : OsuMarkdownTextFlowContainer { public Action UrlAdded; diff --git a/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs index 27cd74bb1f..620fd710e3 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs @@ -13,7 +13,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Online { - public class TestSceneWikiOverlay : OsuTestScene + public partial class TestSceneWikiOverlay : OsuTestScene { private DummyAPIAccess dummyAPI => (DummyAPIAccess)API; diff --git a/osu.Game.Tests/Visual/Online/TestSceneWikiSidebar.cs b/osu.Game.Tests/Visual/Online/TestSceneWikiSidebar.cs index 33e3ee7023..89944b3a8a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneWikiSidebar.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneWikiSidebar.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays.Wiki; namespace osu.Game.Tests.Visual.Online { - public class TestSceneWikiSidebar : OsuTestScene + public partial class TestSceneWikiSidebar : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Orange); diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsLoungeSubScreen.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsLoungeSubScreen.cs index 8ca37a241b..0c536cb1d4 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsLoungeSubScreen.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsLoungeSubScreen.cs @@ -17,7 +17,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Playlists { - public class TestScenePlaylistsLoungeSubScreen : OnlinePlayTestScene + public partial class TestScenePlaylistsLoungeSubScreen : OnlinePlayTestScene { protected new TestRoomManager RoomManager => (TestRoomManager)base.RoomManager; @@ -95,7 +95,7 @@ namespace osu.Game.Tests.Visual.Playlists loungeScreen.ChildrenOfType().First().ScreenSpaceDrawQuad .Contains(room.ScreenSpaceDrawQuad.Centre); - private class TestLoungeSubScreen : PlaylistsLoungeSubScreen + private partial class TestLoungeSubScreen : PlaylistsLoungeSubScreen { public new Bindable SelectedRoom => base.SelectedRoom; } diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs index c71bdb3a06..901c541026 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs @@ -17,7 +17,7 @@ using osu.Game.Tests.Visual.OnlinePlay; namespace osu.Game.Tests.Visual.Playlists { - public class TestScenePlaylistsMatchSettingsOverlay : OnlinePlayTestScene + public partial class TestScenePlaylistsMatchSettingsOverlay : OnlinePlayTestScene { protected new TestRoomManager RoomManager => (TestRoomManager)base.RoomManager; @@ -146,7 +146,7 @@ namespace osu.Game.Tests.Visual.Playlists AddUntilStep("error not displayed", () => !settings.ErrorText.IsPresent); } - private class TestRoomSettings : PlaylistsRoomSettingsOverlay + private partial class TestRoomSettings : PlaylistsRoomSettingsOverlay { public TriangleButton ApplyButton => ((MatchSettings)Settings).ApplyButton; diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsParticipantsList.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsParticipantsList.cs index 9a0dda056a..c4a1200cb1 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsParticipantsList.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsParticipantsList.cs @@ -13,7 +13,7 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual.Playlists { - public class TestScenePlaylistsParticipantsList : OnlinePlayTestScene + public partial class TestScenePlaylistsParticipantsList : OnlinePlayTestScene { public override void SetUpSteps() { diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsResultsScreen.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsResultsScreen.cs index 26fa740159..cb422d8c06 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsResultsScreen.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsResultsScreen.cs @@ -28,7 +28,7 @@ using osu.Game.Tests.Resources; namespace osu.Game.Tests.Visual.Playlists { - public class TestScenePlaylistsResultsScreen : ScreenTestScene + public partial class TestScenePlaylistsResultsScreen : ScreenTestScene { private const int scores_per_result = 10; private const int real_user_position = 200; @@ -365,7 +365,7 @@ namespace osu.Game.Tests.Visual.Playlists }; } - private class TestResultsScreen : PlaylistsResultsScreen + private partial class TestResultsScreen : PlaylistsResultsScreen { public new LoadingSpinner LeftSpinner => base.LeftSpinner; public new LoadingSpinner CentreSpinner => base.CentreSpinner; diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomCreation.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomCreation.cs index b304b34275..bdae91de59 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomCreation.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomCreation.cs @@ -33,7 +33,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Playlists { - public class TestScenePlaylistsRoomCreation : OnlinePlayTestScene + public partial class TestScenePlaylistsRoomCreation : OnlinePlayTestScene { private BeatmapManager manager; @@ -219,7 +219,7 @@ namespace osu.Game.Tests.Visual.Playlists importedBeatmap = manager.Import(beatmap.BeatmapInfo.BeatmapSet)?.Value.Detach(); }); - private class TestPlaylistsRoomSubScreen : PlaylistsRoomSubScreen + private partial class TestPlaylistsRoomSubScreen : PlaylistsRoomSubScreen { public new Bindable SelectedItem => base.SelectedItem; diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsScreen.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsScreen.cs index af3d2d9d9a..71e284ecfe 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsScreen.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsScreen.cs @@ -8,7 +8,7 @@ using NUnit.Framework; namespace osu.Game.Tests.Visual.Playlists { [TestFixture] - public class TestScenePlaylistsScreen : ScreenTestScene + public partial class TestScenePlaylistsScreen : ScreenTestScene { protected override bool UseOnlineAPI => true; diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneAccuracyCircle.cs b/osu.Game.Tests/Visual/Ranking/TestSceneAccuracyCircle.cs index 3e2043cea5..0145a1dfef 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneAccuracyCircle.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneAccuracyCircle.cs @@ -22,7 +22,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Ranking { - public class TestSceneAccuracyCircle : OsuTestScene + public partial class TestSceneAccuracyCircle : OsuTestScene { [TestCase(0.2, ScoreRank.D)] [TestCase(0.5, ScoreRank.D)] diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneContractedPanelMiddleContent.cs b/osu.Game.Tests/Visual/Ranking/TestSceneContractedPanelMiddleContent.cs index 83242fe363..e92e74598d 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneContractedPanelMiddleContent.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneContractedPanelMiddleContent.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Ranking { - public class TestSceneContractedPanelMiddleContent : OsuTestScene + public partial class TestSceneContractedPanelMiddleContent : OsuTestScene { [Test] public void TestShowPanel() @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Ranking Child = new ContractedPanelMiddleContentContainer(workingBeatmap, score); } - private class ContractedPanelMiddleContentContainer : Container + private partial class ContractedPanelMiddleContentContainer : Container { [Cached] private Bindable workingBeatmap { get; set; } diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneExpandedPanelMiddleContent.cs b/osu.Game.Tests/Visual/Ranking/TestSceneExpandedPanelMiddleContent.cs index 62e9adcf25..bd7a11b4bb 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneExpandedPanelMiddleContent.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneExpandedPanelMiddleContent.cs @@ -27,7 +27,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Ranking { - public class TestSceneExpandedPanelMiddleContent : OsuTestScene + public partial class TestSceneExpandedPanelMiddleContent : OsuTestScene { [Resolved] private RulesetStore rulesetStore { get; set; } @@ -105,7 +105,7 @@ namespace osu.Game.Tests.Visual.Ranking private bool containsAny(string text, params string[] stringsToMatch) => stringsToMatch.Any(text.Contains); - private class ExpandedPanelMiddleContentContainer : Container + private partial class ExpandedPanelMiddleContentContainer : Container { public ExpandedPanelMiddleContentContainer(ScoreInfo score) { diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneExpandedPanelTopContent.cs b/osu.Game.Tests/Visual/Ranking/TestSceneExpandedPanelTopContent.cs index 94f6fa8839..be7be6d4f1 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneExpandedPanelTopContent.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneExpandedPanelTopContent.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Ranking { - public class TestSceneExpandedPanelTopContent : OsuTestScene + public partial class TestSceneExpandedPanelTopContent : OsuTestScene { public TestSceneExpandedPanelTopContent() { diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneHitEventTimingDistributionGraph.cs b/osu.Game.Tests/Visual/Ranking/TestSceneHitEventTimingDistributionGraph.cs index e014d79402..a40cb41e2c 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneHitEventTimingDistributionGraph.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneHitEventTimingDistributionGraph.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Ranking { - public class TestSceneHitEventTimingDistributionGraph : OsuTestScene + public partial class TestSceneHitEventTimingDistributionGraph : OsuTestScene { private HitEventTimingDistributionGraph graph = null!; private readonly BindableFloat width = new BindableFloat(600); diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs index 89d6206fd7..42068ff117 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs @@ -35,7 +35,7 @@ using Realms; namespace osu.Game.Tests.Visual.Ranking { [TestFixture] - public class TestSceneResultsScreen : OsuManualInputManagerTestScene + public partial class TestSceneResultsScreen : OsuManualInputManagerTestScene { [Resolved] private BeatmapManager beatmaps { get; set; } @@ -309,7 +309,7 @@ namespace osu.Game.Tests.Visual.Ranking private UnrankedSoloResultsScreen createUnrankedSoloResultsScreen() => new UnrankedSoloResultsScreen(TestResources.CreateTestScoreInfo()); - private class TestResultsContainer : Container + private partial class TestResultsContainer : Container { [Cached(typeof(Player))] private readonly Player player = new TestPlayer(); @@ -328,7 +328,7 @@ namespace osu.Game.Tests.Visual.Ranking } } - private class TestResultsScreen : ResultsScreen + private partial class TestResultsScreen : ResultsScreen { public HotkeyRetryOverlay RetryOverlay; @@ -362,7 +362,7 @@ namespace osu.Game.Tests.Visual.Ranking } } - private class DelayedFetchResultsScreen : TestResultsScreen + private partial class DelayedFetchResultsScreen : TestResultsScreen { private readonly Task fetchWaitTask; @@ -398,7 +398,7 @@ namespace osu.Game.Tests.Visual.Ranking } } - private class UnrankedSoloResultsScreen : SoloResultsScreen + private partial class UnrankedSoloResultsScreen : SoloResultsScreen { public HotkeyRetryOverlay RetryOverlay; diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneScorePanel.cs b/osu.Game.Tests/Visual/Ranking/TestSceneScorePanel.cs index 77fcd04fbd..b87e5adfb1 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneScorePanel.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneScorePanel.cs @@ -12,7 +12,7 @@ using osu.Game.Tests.Resources; namespace osu.Game.Tests.Visual.Ranking { - public class TestSceneScorePanel : OsuTestScene + public partial class TestSceneScorePanel : OsuTestScene { private ScorePanel panel; diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneScorePanelList.cs b/osu.Game.Tests/Visual/Ranking/TestSceneScorePanelList.cs index 871224f3e4..f08a6c9eca 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneScorePanelList.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneScorePanelList.cs @@ -19,7 +19,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Ranking { - public class TestSceneScorePanelList : OsuManualInputManagerTestScene + public partial class TestSceneScorePanelList : OsuManualInputManagerTestScene { private ScorePanelList list; diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticTable.cs b/osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticTable.cs index 57a3907b6e..81d146614a 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticTable.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneSimpleStatisticTable.cs @@ -15,7 +15,7 @@ using osu.Game.Screens.Ranking.Statistics; namespace osu.Game.Tests.Visual.Ranking { - public class TestSceneSimpleStatisticTable : OsuTestScene + public partial class TestSceneSimpleStatisticTable : OsuTestScene { private Container container; diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneStatisticsPanel.cs b/osu.Game.Tests/Visual/Ranking/TestSceneStatisticsPanel.cs index 8214c52edc..fcd5f97fcc 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneStatisticsPanel.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneStatisticsPanel.cs @@ -27,7 +27,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Ranking { - public class TestSceneStatisticsPanel : OsuTestScene + public partial class TestSceneStatisticsPanel : OsuTestScene { [Test] public void TestScoreWithTimeStatistics() diff --git a/osu.Game.Tests/Visual/Settings/TestSceneDirectorySelector.cs b/osu.Game.Tests/Visual/Settings/TestSceneDirectorySelector.cs index 16110e5595..ce6973aacf 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneDirectorySelector.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneDirectorySelector.cs @@ -9,7 +9,7 @@ using osu.Game.Tests.Visual.UserInterface; namespace osu.Game.Tests.Visual.Settings { - public class TestSceneDirectorySelector : ThemeComparisonTestScene + public partial class TestSceneDirectorySelector : ThemeComparisonTestScene { protected override Drawable CreateContent() => new OsuDirectorySelector { diff --git a/osu.Game.Tests/Visual/Settings/TestSceneFileSelector.cs b/osu.Game.Tests/Visual/Settings/TestSceneFileSelector.cs index 97bf0d212a..f61e3ca557 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneFileSelector.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneFileSelector.cs @@ -13,7 +13,7 @@ using osu.Game.Tests.Visual.UserInterface; namespace osu.Game.Tests.Visual.Settings { - public class TestSceneFileSelector : ThemeComparisonTestScene + public partial class TestSceneFileSelector : ThemeComparisonTestScene { [Resolved] private OsuColour colours { get; set; } diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index bd54591b9b..da48086717 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -17,7 +17,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Settings { [TestFixture] - public class TestSceneKeyBindingPanel : OsuManualInputManagerTestScene + public partial class TestSceneKeyBindingPanel : OsuManualInputManagerTestScene { private readonly KeyBindingPanel panel; diff --git a/osu.Game.Tests/Visual/Settings/TestSceneLatencyCertifierScreen.cs b/osu.Game.Tests/Visual/Settings/TestSceneLatencyCertifierScreen.cs index caffc54d47..84c153c15b 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneLatencyCertifierScreen.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneLatencyCertifierScreen.cs @@ -10,7 +10,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Settings { - public class TestSceneLatencyCertifierScreen : ScreenTestScene + public partial class TestSceneLatencyCertifierScreen : ScreenTestScene { private LatencyCertifierScreen latencyCertifier = null!; diff --git a/osu.Game.Tests/Visual/Settings/TestSceneMigrationScreens.cs b/osu.Game.Tests/Visual/Settings/TestSceneMigrationScreens.cs index e32757c6f6..91320fdb1c 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneMigrationScreens.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneMigrationScreens.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays.Settings.Sections.Maintenance; namespace osu.Game.Tests.Visual.Settings { - public class TestSceneMigrationScreens : ScreenTestScene + public partial class TestSceneMigrationScreens : ScreenTestScene { [Cached(typeof(INotificationOverlay))] private readonly NotificationOverlay notifications; @@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual.Settings AddStep("Push screen", () => Stack.Push(new TestMigrationSelectScreen(false))); } - private class TestMigrationSelectScreen : MigrationSelectScreen + private partial class TestMigrationSelectScreen : MigrationSelectScreen { private readonly bool deleteSuccess; @@ -54,7 +54,7 @@ namespace osu.Game.Tests.Visual.Settings protected override void BeginMigration(DirectoryInfo target) => this.Push(new TestMigrationRunScreen(deleteSuccess)); - private class TestMigrationRunScreen : MigrationRunScreen + private partial class TestMigrationRunScreen : MigrationRunScreen { private readonly bool success; diff --git a/osu.Game.Tests/Visual/Settings/TestSceneRestoreDefaultValueButton.cs b/osu.Game.Tests/Visual/Settings/TestSceneRestoreDefaultValueButton.cs index 289969af3e..6e52881f5e 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneRestoreDefaultValueButton.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneRestoreDefaultValueButton.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Settings { - public class TestSceneRestoreDefaultValueButton : OsuTestScene + public partial class TestSceneRestoreDefaultValueButton : OsuTestScene { [Resolved] private OsuColour colours { get; set; } diff --git a/osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs b/osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs index 6ff53663ba..384508f375 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs @@ -17,7 +17,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Settings { [TestFixture] - public class TestSceneSettingsItem : OsuTestScene + public partial class TestSceneSettingsItem : OsuTestScene { [Test] public void TestRestoreDefaultValueButtonVisibility() diff --git a/osu.Game.Tests/Visual/Settings/TestSceneSettingsNumberBox.cs b/osu.Game.Tests/Visual/Settings/TestSceneSettingsNumberBox.cs index 53e1f0e0bf..fc261611db 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneSettingsNumberBox.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneSettingsNumberBox.cs @@ -11,7 +11,7 @@ using osu.Game.Overlays.Settings; namespace osu.Game.Tests.Visual.Settings { - public class TestSceneSettingsNumberBox : OsuTestScene + public partial class TestSceneSettingsNumberBox : OsuTestScene { private SettingsNumberBox numberBox; private OsuTextBox textBox; diff --git a/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs index ad60c98e05..4e295ba665 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs @@ -18,7 +18,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Settings { [TestFixture] - public class TestSceneSettingsPanel : OsuManualInputManagerTestScene + public partial class TestSceneSettingsPanel : OsuManualInputManagerTestScene { private SettingsPanel settings; private DialogOverlay dialogOverlay; diff --git a/osu.Game.Tests/Visual/Settings/TestSceneSettingsSource.cs b/osu.Game.Tests/Visual/Settings/TestSceneSettingsSource.cs index 3cf6f7febf..30811bab32 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneSettingsSource.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneSettingsSource.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Settings { [TestFixture] - public class TestSceneSettingsSource : OsuTestScene + public partial class TestSceneSettingsSource : OsuTestScene { public TestSceneSettingsSource() { diff --git a/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs b/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs index 5e75bd7bc1..5ca08e0bba 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Settings { [TestFixture] - public class TestSceneTabletSettings : OsuTestScene + public partial class TestSceneTabletSettings : OsuTestScene { private TestTabletHandler tabletHandler; private TabletSettings settings; diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs index 1042341337..8650119dd4 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs @@ -22,7 +22,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.SongSelect { [System.ComponentModel.Description("Advanced beatmap statistics display")] - public class TestSceneAdvancedStats : OsuTestScene + public partial class TestSceneAdvancedStats : OsuTestScene { private TestAdvancedStats advancedStats; @@ -164,7 +164,7 @@ namespace osu.Game.Tests.Visual.SongSelect private bool barIsBlue(AdvancedStats.StatisticRow row) => row.ModBar.AccentColour == colours.BlueDark; private bool barIsRed(AdvancedStats.StatisticRow row) => row.ModBar.AccentColour == colours.Red; - private class TestAdvancedStats : AdvancedStats + private partial class TestAdvancedStats : AdvancedStats { public new StatisticRow FirstValue => base.FirstValue; public new StatisticRow HpDrain => base.HpDrain; diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index d4d9f89c6a..2d1c5ef120 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -26,7 +26,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.SongSelect { [TestFixture] - public class TestSceneBeatmapCarousel : OsuManualInputManagerTestScene + public partial class TestSceneBeatmapCarousel : OsuManualInputManagerTestScene { private TestBeatmapCarousel carousel; private RulesetStore rulesets; @@ -1112,7 +1112,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("Selection is visible", selectedBeatmapVisible); } - private class TestBeatmapCarousel : BeatmapCarousel + private partial class TestBeatmapCarousel : BeatmapCarousel { public bool PendingFilterTask => PendingFilter != null; diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetails.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetails.cs index e33cfe280e..20cc1e544e 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetails.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetails.cs @@ -14,7 +14,7 @@ using osu.Game.Screens.Select; namespace osu.Game.Tests.Visual.SongSelect { [System.ComponentModel.Description("PlaySongSelect beatmap details")] - public class TestSceneBeatmapDetails : OsuTestScene + public partial class TestSceneBeatmapDetails : OsuTestScene { private BeatmapDetails details; diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs index a144111fd3..a470ed47d4 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs @@ -30,7 +30,7 @@ using osuTK; namespace osu.Game.Tests.Visual.SongSelect { [TestFixture] - public class TestSceneBeatmapInfoWedge : OsuTestScene + public partial class TestSceneBeatmapInfoWedge : OsuTestScene { private RulesetStore rulesets; private TestBeatmapInfoWedge infoWedge; @@ -267,7 +267,7 @@ namespace osu.Game.Tests.Visual.SongSelect }; } - private class TestBeatmapInfoWedge : BeatmapInfoWedge + private partial class TestBeatmapInfoWedge : BeatmapInfoWedge { public new Container DisplayedContent => base.DisplayedContent; diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs index 1839821bb5..ef0ad6c25c 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs @@ -27,7 +27,7 @@ using osuTK; namespace osu.Game.Tests.Visual.SongSelect { - public class TestSceneBeatmapLeaderboard : OsuTestScene + public partial class TestSceneBeatmapLeaderboard : OsuTestScene { private readonly FailableLeaderboard leaderboard; @@ -381,7 +381,7 @@ namespace osu.Game.Tests.Visual.SongSelect }; } - private class FailableLeaderboard : BeatmapLeaderboard + private partial class FailableLeaderboard : BeatmapLeaderboard { public new void SetErrorState(LeaderboardState state) => base.SetErrorState(state); public new void SetScores(IEnumerable? scores, ScoreInfo? userScore = null) => base.SetScores(scores, userScore); diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapMetadataDisplay.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapMetadataDisplay.cs index c42b51c1a6..c2537cff79 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapMetadataDisplay.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapMetadataDisplay.cs @@ -22,7 +22,7 @@ using osuTK; namespace osu.Game.Tests.Visual.SongSelect { - public class TestSceneBeatmapMetadataDisplay : OsuTestScene + public partial class TestSceneBeatmapMetadataDisplay : OsuTestScene { private BeatmapMetadataDisplay display; @@ -119,7 +119,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep("finish loading", () => display.Loading = false); } - private class TestBeatmapDifficultyCache : BeatmapDifficultyCache + private partial class TestBeatmapDifficultyCache : BeatmapDifficultyCache { private TaskCompletionSource calculationBlocker; diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapOptionsOverlay.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapOptionsOverlay.cs index 5ad82f1ffd..46a26d2e98 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapOptionsOverlay.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapOptionsOverlay.cs @@ -11,7 +11,7 @@ using osu.Game.Screens.Select.Options; namespace osu.Game.Tests.Visual.SongSelect { [Description("bottom beatmap details")] - public class TestSceneBeatmapOptionsOverlay : OsuTestScene + public partial class TestSceneBeatmapOptionsOverlay : OsuTestScene { public TestSceneBeatmapOptionsOverlay() { diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs index 504ded5406..a368e901f5 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapRecommendations.cs @@ -23,7 +23,7 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual.SongSelect { - public class TestSceneBeatmapRecommendations : OsuGameTestScene + public partial class TestSceneBeatmapRecommendations : OsuGameTestScene { [Resolved] private IRulesetStore rulesetStore { get; set; } diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneDifficultyRangeFilterControl.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneDifficultyRangeFilterControl.cs index 7ae2c6e5e2..275e6ca753 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneDifficultyRangeFilterControl.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneDifficultyRangeFilterControl.cs @@ -8,7 +8,7 @@ using osuTK; namespace osu.Game.Tests.Visual.SongSelect { - public class TestSceneDifficultyRangeFilterControl : OsuTestScene + public partial class TestSceneDifficultyRangeFilterControl : OsuTestScene { [Test] public void TestBasic() diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneFilterControl.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneFilterControl.cs index dadcd43db5..64e2447cca 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneFilterControl.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneFilterControl.cs @@ -24,7 +24,7 @@ using Realms; namespace osu.Game.Tests.Visual.SongSelect { - public class TestSceneFilterControl : OsuManualInputManagerTestScene + public partial class TestSceneFilterControl : OsuManualInputManagerTestScene { protected override Container Content { get; } = new Container { RelativeSizeAxes = Axes.Both }; diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index b6b9e8926b..01c5ad8358 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -42,7 +42,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.SongSelect { [TestFixture] - public class TestScenePlaySongSelect : ScreenTestScene + public partial class TestScenePlaySongSelect : ScreenTestScene { private BeatmapManager manager = null!; private RulesetStore rulesets = null!; @@ -1141,7 +1141,7 @@ namespace osu.Game.Tests.Visual.SongSelect rulesets.Dispose(); } - private class TestSongSelect : PlaySongSelect + private partial class TestSongSelect : PlaySongSelect { public Action? StartRequested; diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooter.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooter.cs index 0a88abface..646dedc2be 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooter.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooter.cs @@ -13,7 +13,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.SongSelect { - public class TestSceneSongSelectFooter : OsuManualInputManagerTestScene + public partial class TestSceneSongSelectFooter : OsuManualInputManagerTestScene { private FooterButtonRandom randomButton; diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneTopLocalRank.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneTopLocalRank.cs index cced9b8b89..cf0de14541 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneTopLocalRank.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneTopLocalRank.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Tests.Visual.SongSelect { - public class TestSceneTopLocalRank : OsuTestScene + public partial class TestSceneTopLocalRank : OsuTestScene { private RulesetStore rulesets = null!; private BeatmapManager beatmapManager = null!; diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneUpdateBeatmapSetButton.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneUpdateBeatmapSetButton.cs index 96cfbe4dd1..e47b7e25a8 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneUpdateBeatmapSetButton.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneUpdateBeatmapSetButton.cs @@ -22,7 +22,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.SongSelect { [TestFixture] - public class TestSceneUpdateBeatmapSetButton : OsuManualInputManagerTestScene + public partial class TestSceneUpdateBeatmapSetButton : OsuManualInputManagerTestScene { private BeatmapCarousel carousel = null!; diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs index 39fd9fda2b..0476198e41 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneUserTopScoreContainer.cs @@ -19,7 +19,7 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual.SongSelect { - public class TestSceneUserTopScoreContainer : OsuTestScene + public partial class TestSceneUserTopScoreContainer : OsuTestScene { [Cached(typeof(IDialogOverlay))] private readonly DialogOverlay dialogOverlay; diff --git a/osu.Game.Tests/Visual/TestMultiplayerComponents.cs b/osu.Game.Tests/Visual/TestMultiplayerComponents.cs index 0458f41358..1814fb70c8 100644 --- a/osu.Game.Tests/Visual/TestMultiplayerComponents.cs +++ b/osu.Game.Tests/Visual/TestMultiplayerComponents.cs @@ -30,7 +30,7 @@ namespace osu.Game.Tests.Visual /// ///

///
- public class TestMultiplayerComponents : OsuScreen + public partial class TestMultiplayerComponents : OsuScreen { public Screens.OnlinePlay.Multiplayer.Multiplayer MultiplayerScreen => multiplayerScreen; @@ -91,7 +91,7 @@ namespace osu.Game.Tests.Visual return true; } - private class TestMultiplayer : Screens.OnlinePlay.Multiplayer.Multiplayer + private partial class TestMultiplayer : Screens.OnlinePlay.Multiplayer.Multiplayer { public new TestMultiplayerRoomManager RoomManager { get; private set; } public TestRoomRequestsHandler RequestsHandler { get; private set; } diff --git a/osu.Game.Tests/Visual/TestSceneOsuScreenStack.cs b/osu.Game.Tests/Visual/TestSceneOsuScreenStack.cs index 7588546f42..7f01a67903 100644 --- a/osu.Game.Tests/Visual/TestSceneOsuScreenStack.cs +++ b/osu.Game.Tests/Visual/TestSceneOsuScreenStack.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual { [TestFixture] - public class TestSceneOsuScreenStack : OsuTestScene + public partial class TestSceneOsuScreenStack : OsuTestScene { private TestOsuScreenStack stack; @@ -90,7 +90,7 @@ namespace osu.Game.Tests.Visual AddAssert("allows adjustments 11", () => musicController.AllowTrackAdjustments); } - public class TestScreen : ScreenWithBeatmapBackground + public partial class TestScreen : ScreenWithBeatmapBackground { private readonly string screenText; @@ -112,7 +112,7 @@ namespace osu.Game.Tests.Visual } } - private class NoParallaxTestScreen : TestScreen + private partial class NoParallaxTestScreen : TestScreen { public NoParallaxTestScreen(string screenText) : base(screenText) @@ -122,22 +122,22 @@ namespace osu.Game.Tests.Visual public override float BackgroundParallaxAmount => 0.0f; } - private class TestOsuScreenStack : OsuScreenStack + private partial class TestOsuScreenStack : OsuScreenStack { public new float ParallaxAmount => base.ParallaxAmount; } - private class AllowScreen : OsuScreen + private partial class AllowScreen : OsuScreen { public override bool? AllowTrackAdjustments => true; } - public class DisallowScreen : OsuScreen + public partial class DisallowScreen : OsuScreen { public override bool? AllowTrackAdjustments => false; } - private class InheritScreen : OsuScreen + private partial class InheritScreen : OsuScreen { } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBackButton.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBackButton.cs index 9b84cf2a9e..837de60053 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBackButton.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBackButton.cs @@ -12,7 +12,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneBackButton : OsuTestScene + public partial class TestSceneBackButton : OsuTestScene { public TestSceneBackButton() { diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs index 368babc9b5..5d97714ab5 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatSyncedContainer.cs @@ -26,7 +26,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneBeatSyncedContainer : OsuTestScene + public partial class TestSceneBeatSyncedContainer : OsuTestScene { private TestBeatSyncedContainer beatContainer; @@ -171,7 +171,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("effect has kiai", () => actualEffectPoint != null && ((EffectControlPoint)actualEffectPoint).KiaiMode); } - private class TestBeatSyncedContainer : BeatSyncedContainer + private partial class TestBeatSyncedContainer : BeatSyncedContainer { private const int flash_layer_height = 150; @@ -321,7 +321,7 @@ namespace osu.Game.Tests.Visual.UserInterface } } - private class InfoString : FillFlowContainer + private partial class InfoString : FillFlowContainer { private const int text_size = 20; private const int margin = 7; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingCardSizeTabControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingCardSizeTabControl.cs index bc846d8bcb..f93c9a3d5d 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingCardSizeTabControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingCardSizeTabControl.cs @@ -16,7 +16,7 @@ using osu.Game.Overlays.BeatmapListing; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneBeatmapListingCardSizeTabControl : OsuTestScene + public partial class TestSceneBeatmapListingCardSizeTabControl : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchControl.cs index e8454e8d0f..0aae182db4 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchControl.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneBeatmapListingSearchControl : OsuTestScene + public partial class TestSceneBeatmapListingSearchControl : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSortTabControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSortTabControl.cs index 0ef13385ec..316035275f 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSortTabControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSortTabControl.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneBeatmapListingSortTabControl : OsuTestScene + public partial class TestSceneBeatmapListingSortTabControl : OsuTestScene { private readonly BeatmapListingSortTabControl control; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs index ff1dce1a4e..7f7ba6966b 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneBeatmapSearchFilter : OsuTestScene + public partial class TestSceneBeatmapSearchFilter : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs index a387148c2c..eeb2d1e70f 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs @@ -14,7 +14,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneBreadcrumbControl : OsuTestScene + public partial class TestSceneBreadcrumbControl : OsuTestScene { private readonly TestBreadcrumbControl breadcrumbs; @@ -62,7 +62,7 @@ namespace osu.Game.Tests.Visual.UserInterface Circles, } - private class TestBreadcrumbControl : BreadcrumbControl + private partial class TestBreadcrumbControl : BreadcrumbControl { public BreadcrumbTabItem GetDrawable(BreadcrumbTab tab) => (BreadcrumbTabItem)TabContainer.First(t => t.Value == tab); } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControlHeader.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControlHeader.cs index 8e2502dad1..cc203b3043 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControlHeader.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControlHeader.cs @@ -11,7 +11,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneBreadcrumbControlHeader : OsuTestScene + public partial class TestSceneBreadcrumbControlHeader : OsuTestScene { private static readonly string[] items = { "first", "second", "third", "fourth", "fifth" }; @@ -48,7 +48,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep($"Remove {item} item", () => header.RemoveItem(item)); } - private class TestHeader : BreadcrumbControlOverlayHeader + private partial class TestHeader : BreadcrumbControlOverlayHeader { public TestHeader() { @@ -77,7 +77,7 @@ namespace osu.Game.Tests.Visual.UserInterface protected override OverlayTitle CreateTitle() => new TestTitle(); } - private class TestTitle : OverlayTitle + private partial class TestTitle : OverlayTitle { public TestTitle() { diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneButtonSystem.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneButtonSystem.cs index cbd4c69180..ac811aeb65 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneButtonSystem.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneButtonSystem.cs @@ -17,7 +17,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneButtonSystem : OsuManualInputManagerTestScene + public partial class TestSceneButtonSystem : OsuManualInputManagerTestScene { private OsuLogo logo; private ButtonSystem buttons; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneColourPicker.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneColourPicker.cs index eba0e8cfed..d2acf89dc8 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneColourPicker.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneColourPicker.cs @@ -15,7 +15,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneColourPicker : OsuTestScene + public partial class TestSceneColourPicker : OsuTestScene { private readonly Bindable colour = new Bindable(Colour4.Aquamarine); @@ -79,7 +79,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("set red", () => colour.Value = Colour4.Red); } - private class ColourProvidingContainer : Container + private partial class ColourProvidingContainer : Container { [Cached] private OverlayColourProvider provider { get; } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index fd4ec2f3dc..99e1702870 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -15,7 +15,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneCommentEditor : OsuManualInputManagerTestScene + public partial class TestSceneCommentEditor : OsuManualInputManagerTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); @@ -103,7 +103,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("cancel action fired", () => cancellableCommentEditor.Cancelled); } - private class TestCommentEditor : CommentEditor + private partial class TestCommentEditor : CommentEditor { public new Bindable Current => base.Current; public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; @@ -126,7 +126,7 @@ namespace osu.Game.Tests.Visual.UserInterface protected override string TextBoxPlaceholder => @"This text box is empty"; } - private class TestCancellableCommentEditor : CancellableCommentEditor + private partial class TestCancellableCommentEditor : CancellableCommentEditor { public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; protected override string FooterText => @"Wow, another one. Sicc"; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentRepliesButton.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentRepliesButton.cs index 115833b034..1bfa389a25 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentRepliesButton.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentRepliesButton.cs @@ -16,7 +16,7 @@ using osu.Framework.Testing; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneCommentRepliesButton : OsuTestScene + public partial class TestSceneCommentRepliesButton : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); @@ -54,7 +54,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("Icon facing downwards", () => button.Icon.Scale.Y == 1); } - private class TestButton : CommentRepliesButton + private partial class TestButton : CommentRepliesButton { public SpriteIcon Icon => this.ChildrenOfType().First(); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneContextMenu.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneContextMenu.cs index bd77c4725c..3491b7dbc1 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneContextMenu.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneContextMenu.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneContextMenu : OsuTestScene + public partial class TestSceneContextMenu : OsuTestScene { private const int start_time = 0; private const int duration = 1000; @@ -113,12 +113,12 @@ namespace osu.Game.Tests.Visual.UserInterface }; } - private class MyContextMenuContainer : Container, IHasContextMenu + private partial class MyContextMenuContainer : Container, IHasContextMenu { public MenuItem[] ContextMenuItems => makeMenu(); } - private class AnotherContextMenuContainer : Container, IHasContextMenu + private partial class AnotherContextMenuContainer : Container, IHasContextMenu { public MenuItem[] ContextMenuItems { diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs index 75c47f0b1b..01d4eb83f3 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCursors.cs @@ -20,7 +20,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneCursors : OsuManualInputManagerTestScene + public partial class TestSceneCursors : OsuManualInputManagerTestScene { private readonly GlobalCursorDisplay globalCursorDisplay; private readonly CustomCursorBox[] cursorBoxes = new CustomCursorBox[6]; @@ -239,7 +239,7 @@ namespace osu.Game.Tests.Visual.UserInterface private bool checkAtMouse(CursorContainer cursorContainer) => Precision.AlmostEquals(InputManager.CurrentState.Mouse.Position, cursorContainer.ToScreenSpace(cursorContainer.ActiveCursor.DrawPosition)); - private class CustomCursorBox : Container, IProvideCursor + private partial class CustomCursorBox : Container, IProvideCursor { public bool SmoothTransition; @@ -290,11 +290,11 @@ namespace osu.Game.Tests.Visual.UserInterface } } - private class TestCursorContainer : CursorContainer + private partial class TestCursorContainer : CursorContainer { protected override Drawable CreateCursor() => new TestCursor(); - private class TestCursor : CircularContainer + private partial class TestCursor : CircularContainer { public TestCursor() { diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs index 2b6a93143f..6092f35050 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDashboardBeatmapListing.cs @@ -17,7 +17,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneDashboardBeatmapListing : OsuTestScene + public partial class TestSceneDashboardBeatmapListing : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs index c1a9768cf0..7635c61867 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDeleteLocalScore.cs @@ -32,7 +32,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneDeleteLocalScore : OsuManualInputManagerTestScene + public partial class TestSceneDeleteLocalScore : OsuManualInputManagerTestScene { private readonly ContextMenuContainer contextMenuContainer; private readonly BeatmapLeaderboard leaderboard; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDialogOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDialogOverlay.cs index a8e6142bab..81b692004b 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneDialogOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDialogOverlay.cs @@ -15,7 +15,7 @@ using osu.Game.Overlays.Dialog; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneDialogOverlay : OsuTestScene + public partial class TestSceneDialogOverlay : OsuTestScene { private DialogOverlay overlay; @@ -114,7 +114,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("dialog displayed", () => overlay.CurrentDialog == dialog); } - public class SlowLoadingDialogOverlay : DialogOverlay + public partial class SlowLoadingDialogOverlay : DialogOverlay { public ManualResetEventSlim LoadEvent = new ManualResetEventSlim(); @@ -166,7 +166,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("dialog is not part of hierarchy", () => testDialog.Parent == null); } - private class TestPopupDialog : PopupDialog + private partial class TestPopupDialog : PopupDialog { } } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDifficultyMultiplierDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDifficultyMultiplierDisplay.cs index 984276b27e..890c7295b4 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneDifficultyMultiplierDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDifficultyMultiplierDisplay.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays.Mods; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneDifficultyMultiplierDisplay : OsuTestScene + public partial class TestSceneDifficultyMultiplierDisplay : OsuTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneDrawableDate.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneDrawableDate.cs index 59e85ae085..108ad8b7c1 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneDrawableDate.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneDrawableDate.cs @@ -13,7 +13,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneDrawableDate : OsuTestScene + public partial class TestSceneDrawableDate : OsuTestScene { public TestSceneDrawableDate() { @@ -36,7 +36,7 @@ namespace osu.Game.Tests.Visual.UserInterface }; } - private class PokeyDrawableDate : CompositeDrawable + private partial class PokeyDrawableDate : CompositeDrawable { public PokeyDrawableDate(DateTimeOffset date) { diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneEditorSidebar.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneEditorSidebar.cs index ee07acef52..72dacb7558 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneEditorSidebar.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneEditorSidebar.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneEditorSidebar : OsuTestScene + public partial class TestSceneEditorSidebar : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingBar.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingBar.cs index 2d97513206..9d850c0fc5 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingBar.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingBar.cs @@ -11,7 +11,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneExpandingBar : OsuTestScene + public partial class TestSceneExpandingBar : OsuTestScene { public TestSceneExpandingBar() { diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingContainer.cs index 704185b117..3f4f86e424 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneExpandingContainer.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneExpandingContainer : OsuManualInputManagerTestScene + public partial class TestSceneExpandingContainer : OsuManualInputManagerTestScene { private TestExpandingContainer container; private SettingsToolboxGroup toolboxGroup; @@ -149,7 +149,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("container still expanded", () => container.Expanded.Value); } - private class TestExpandingContainer : ExpandingContainer + private partial class TestExpandingContainer : ExpandingContainer { public TestExpandingContainer() : base(120, 250) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFPSCounter.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFPSCounter.cs index d78707045b..a91e6e3350 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFPSCounter.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFPSCounter.cs @@ -12,7 +12,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneFPSCounter : OsuTestScene + public partial class TestSceneFPSCounter : OsuTestScene { [SetUpSteps] public void SetUpSteps() diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenBehaviour.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenBehaviour.cs index 8fa4f7ec0e..ec8ef0ad50 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenBehaviour.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenBehaviour.cs @@ -10,7 +10,7 @@ using osu.Game.Overlays.FirstRunSetup; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneFirstRunScreenBehaviour : OsuManualInputManagerTestScene + public partial class TestSceneFirstRunScreenBehaviour : OsuManualInputManagerTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenBundledBeatmaps.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenBundledBeatmaps.cs index 6cc4ac709b..e9460e45d3 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenBundledBeatmaps.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenBundledBeatmaps.cs @@ -10,7 +10,7 @@ using osu.Game.Overlays.FirstRunSetup; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneFirstRunScreenBundledBeatmaps : OsuManualInputManagerTestScene + public partial class TestSceneFirstRunScreenBundledBeatmaps : OsuManualInputManagerTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenImportFromStable.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenImportFromStable.cs index 3c3d5933e4..e6fc889a70 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenImportFromStable.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenImportFromStable.cs @@ -17,7 +17,7 @@ using osu.Game.Overlays.FirstRunSetup; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneFirstRunScreenImportFromStable : OsuManualInputManagerTestScene + public partial class TestSceneFirstRunScreenImportFromStable : OsuManualInputManagerTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenUIScale.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenUIScale.cs index 98ad77fbae..8ba94cf9ae 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenUIScale.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunScreenUIScale.cs @@ -10,7 +10,7 @@ using osu.Game.Overlays.FirstRunSetup; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneFirstRunScreenUIScale : OsuManualInputManagerTestScene + public partial class TestSceneFirstRunScreenUIScale : OsuManualInputManagerTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunSetupOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunSetupOverlay.cs index 16d564f0ee..77ed97e3ed 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunSetupOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFirstRunSetupOverlay.cs @@ -25,7 +25,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneFirstRunSetupOverlay : OsuManualInputManagerTestScene + public partial class TestSceneFirstRunSetupOverlay : OsuManualInputManagerTestScene { private FirstRunSetupOverlay overlay; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs index a4b5faae26..24b4060a42 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs @@ -14,7 +14,7 @@ using osu.Game.Screens.Select; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneFooterButtonMods : OsuTestScene + public partial class TestSceneFooterButtonMods : OsuTestScene { private readonly TestFooterButtonMods footerButtonMods; @@ -81,7 +81,7 @@ namespace osu.Game.Tests.Visual.UserInterface return expectedValue == footerButtonMods.MultiplierText.Current.Value; } - private class TestFooterButtonMods : FooterButtonMods + private partial class TestFooterButtonMods : FooterButtonMods { public new OsuSpriteText MultiplierText => base.MultiplierText; } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs index ad5e498c8b..c75c2a7877 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFriendsOnlineStatusControl.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays.Dashboard.Friends; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneFriendsOnlineStatusControl : OsuTestScene + public partial class TestSceneFriendsOnlineStatusControl : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs index 8ed5dd43cc..ed59572cab 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneHistoryTextBox.cs @@ -11,7 +11,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneHistoryTextBox : OsuManualInputManagerTestScene + public partial class TestSceneHistoryTextBox : OsuManualInputManagerTestScene { private const string temp = "Temp message"; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs index 235dbc1fcb..801bef62c8 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneHoldToConfirmOverlay.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Menu; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneHoldToConfirmOverlay : OsuTestScene + public partial class TestSceneHoldToConfirmOverlay : OsuTestScene { protected override double TimePerAction => 100; // required for the early exit test, since hold-to-confirm delay is 200ms @@ -59,7 +59,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddUntilStep("wait until fired again", () => overlay.Fired); } - private class TestHoldToConfirmOverlay : ExitConfirmOverlay + private partial class TestHoldToConfirmOverlay : ExitConfirmOverlay { public void Begin() => BeginConfirm(); } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneIconButton.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneIconButton.cs index 35d250c7ac..454fa7cd05 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneIconButton.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneIconButton.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneIconButton : OsuTestScene + public partial class TestSceneIconButton : OsuTestScene { public TestSceneIconButton() { @@ -38,7 +38,7 @@ namespace osu.Game.Tests.Visual.UserInterface }; } - private class ColouredIconButton : IconButton + private partial class ColouredIconButton : IconButton { public ColouredIconButton() { @@ -47,7 +47,7 @@ namespace osu.Game.Tests.Visual.UserInterface } } - private class NamedIconButton : Container + private partial class NamedIconButton : Container { public NamedIconButton(string name, IconButton button) { diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledColourPalette.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledColourPalette.cs index d7a69616f3..91a60009dc 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledColourPalette.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledColourPalette.cs @@ -18,7 +18,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneLabelledColourPalette : OsuManualInputManagerTestScene + public partial class TestSceneLabelledColourPalette : OsuManualInputManagerTestScene { private LabelledColourPalette component; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledDrawable.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledDrawable.cs index 7ce0fceff9..0dffc9da51 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledDrawable.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledDrawable.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneLabelledDrawable : OsuTestScene + public partial class TestSceneLabelledDrawable : OsuTestScene { [TestCase(false)] [TestCase(true)] @@ -88,7 +88,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert($"description {(hasDescription ? "visible" : "hidden")}", () => component.ChildrenOfType().ElementAt(1).IsPresent == hasDescription); } - private class PaddedLabelledDrawable : LabelledDrawable + private partial class PaddedLabelledDrawable : LabelledDrawable { public PaddedLabelledDrawable() : base(true) @@ -104,7 +104,7 @@ namespace osu.Game.Tests.Visual.UserInterface }; } - private class NonPaddedLabelledDrawable : LabelledDrawable + private partial class NonPaddedLabelledDrawable : LabelledDrawable { public NonPaddedLabelledDrawable() : base(false) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledDropdown.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledDropdown.cs index cd14d6bde3..a2cfae3c7f 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledDropdown.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledDropdown.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneLabelledDropdown : OsuTestScene + public partial class TestSceneLabelledDropdown : OsuTestScene { [Test] public void TestLabelledDropdown() diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs index 5548375af2..6181891e13 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs @@ -17,7 +17,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneLabelledSliderBar : OsuTestScene + public partial class TestSceneLabelledSliderBar : OsuTestScene { [Test] public void TestBasic() => createSliderBar(); @@ -101,7 +101,7 @@ namespace osu.Game.Tests.Visual.UserInterface }); } - private class OverlayColourContainer : Container + private partial class OverlayColourContainer : Container { [Cached] private OverlayColourProvider colourProvider; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSwitchButton.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSwitchButton.cs index 03434ff0a1..c4af47bd0f 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSwitchButton.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSwitchButton.cs @@ -10,7 +10,7 @@ using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneLabelledSwitchButton : OsuTestScene + public partial class TestSceneLabelledSwitchButton : OsuTestScene { [TestCase(false)] [TestCase(true)] diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledTextBox.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledTextBox.cs index 3f93e60773..8046554819 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledTextBox.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledTextBox.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneLabelledTextBox : OsuTestScene + public partial class TestSceneLabelledTextBox : OsuTestScene { [TestCase(false)] [TestCase(true)] diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLoadingLayer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLoadingLayer.cs index 2fc6405b88..cc5304a961 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneLoadingLayer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLoadingLayer.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneLoadingLayer : OsuTestScene + public partial class TestSceneLoadingLayer : OsuTestScene { private TestLoadingLayer overlay; @@ -87,7 +87,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("hide", () => overlay.Hide()); } - private class TestLoadingLayer : LoadingLayer + private partial class TestLoadingLayer : LoadingLayer { public new Box BackgroundDimLayer => base.BackgroundDimLayer; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLoadingSpinner.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLoadingSpinner.cs index 8c9b9186b1..40e786592a 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneLoadingSpinner.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLoadingSpinner.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneLoadingSpinner : OsuGridTestScene + public partial class TestSceneLoadingSpinner : OsuGridTestScene { public TestSceneLoadingSpinner() : base(2, 2) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLogoAnimation.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLogoAnimation.cs index b565cb359b..f9d92aabc6 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneLogoAnimation.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLogoAnimation.cs @@ -13,7 +13,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneLogoAnimation : OsuTestScene + public partial class TestSceneLogoAnimation : OsuTestScene { [BackgroundDependencyLoader] private void load(LargeTextureStore textures) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs index d069e742dd..5926f07a11 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneLogoTrackingContainer : OsuTestScene + public partial class TestSceneLogoTrackingContainer : OsuTestScene { private OsuLogo logo; private TestLogoTrackingContainer trackingContainer; @@ -277,7 +277,7 @@ namespace osu.Game.Tests.Visual.UserInterface Schedule(moveLogoFacade); } - private class TestLogoTrackingContainer : LogoTrackingContainer + private partial class TestLogoTrackingContainer : LogoTrackingContainer { /// /// Check that the logo is tracking the position of the facade, with an acceptable precision lenience. diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModColumn.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModColumn.cs index 72cddc0ad2..a11000214c 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModColumn.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModColumn.cs @@ -22,7 +22,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneModColumn : OsuManualInputManagerTestScene + public partial class TestSceneModColumn : OsuManualInputManagerTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); @@ -294,7 +294,7 @@ namespace osu.Game.Tests.Visual.UserInterface modState.Filtered.Value = filter?.Invoke(modState.Mod) == false; } - private class TestModColumn : ModColumn + private partial class TestModColumn : ModColumn { public new bool SelectionAnimationRunning => base.SelectionAnimationRunning; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModDifficultyAdjustSettings.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModDifficultyAdjustSettings.cs index 181f46a996..0d02a72d87 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModDifficultyAdjustSettings.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModDifficultyAdjustSettings.cs @@ -21,7 +21,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneModDifficultyAdjustSettings : OsuManualInputManagerTestScene + public partial class TestSceneModDifficultyAdjustSettings : OsuManualInputManagerTestScene { private OsuModDifficultyAdjust modDifficultyAdjust; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModDisplay.cs index c65d1f8c5e..bd5a0d8645 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModDisplay.cs @@ -11,7 +11,7 @@ using osu.Game.Screens.Play.HUD; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneModDisplay : OsuTestScene + public partial class TestSceneModDisplay : OsuTestScene { [Test] public void TestMode([Values] ExpansionMode mode) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModFlowDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModFlowDisplay.cs index c45ea3a40c..f0efabe2f7 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModFlowDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModFlowDisplay.cs @@ -11,7 +11,7 @@ using osu.Game.Screens.Play.HUD; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneModFlowDisplay : OsuTestScene + public partial class TestSceneModFlowDisplay : OsuTestScene { private ModFlowDisplay modFlow; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModIcon.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModIcon.cs index ce9aa682d1..897d5fd9f5 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModIcon.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModIcon.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneModIcon : OsuTestScene + public partial class TestSceneModIcon : OsuTestScene { [Test] public void TestShowAllMods() diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModPanel.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModPanel.cs index 9c0b36073b..64bdc167c2 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModPanel.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModPanel.cs @@ -18,7 +18,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneModPanel : OsuManualInputManagerTestScene + public partial class TestSceneModPanel : OsuManualInputManagerTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs index 901f234db6..1090764788 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs @@ -25,7 +25,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneModPresetColumn : OsuManualInputManagerTestScene + public partial class TestSceneModPresetColumn : OsuManualInputManagerTestScene { protected override bool UseFreshStoragePerRun => true; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetPanel.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetPanel.cs index bcd5579f03..35e352534b 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetPanel.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetPanel.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneModPresetPanel : OsuTestScene + public partial class TestSceneModPresetPanel : OsuTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs index 0292ce5905..eff320a575 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs @@ -28,7 +28,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneModSelectOverlay : OsuManualInputManagerTestScene + public partial class TestSceneModSelectOverlay : OsuManualInputManagerTestScene { protected override bool UseFreshStoragePerRun => true; @@ -584,7 +584,7 @@ namespace osu.Game.Tests.Visual.UserInterface private ModPanel getPanelForMod(Type modType) => modSelectOverlay.ChildrenOfType().Single(panel => panel.Mod.GetType() == modType); - private class TestModSelectOverlay : UserModSelectOverlay + private partial class TestModSelectOverlay : UserModSelectOverlay { protected override bool ShowPresets => true; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettingsArea.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettingsArea.cs index a9c3872643..dac1f94c28 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettingsArea.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettingsArea.cs @@ -16,7 +16,7 @@ using osu.Game.Rulesets.Osu.Mods; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneModSettingsArea : OsuTestScene + public partial class TestSceneModSettingsArea : OsuTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSwitchSmall.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSwitchSmall.cs index ff9cc09806..07312379b3 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSwitchSmall.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSwitchSmall.cs @@ -22,7 +22,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneModSwitchSmall : OsuTestScene + public partial class TestSceneModSwitchSmall : OsuTestScene { [Test] public void TestOsu() => createSwitchTestFor(new OsuRuleset()); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSwitchTiny.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSwitchTiny.cs index ddb5845df8..34dd139428 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSwitchTiny.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSwitchTiny.cs @@ -22,7 +22,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneModSwitchTiny : OsuTestScene + public partial class TestSceneModSwitchTiny : OsuTestScene { [Test] public void TestOsu() => createSwitchTestFor(new OsuRuleset()); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModsEffectDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModsEffectDisplay.cs index 42eceb3242..a1c8bef1de 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModsEffectDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModsEffectDisplay.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneModsEffectDisplay : OsuTestScene + public partial class TestSceneModsEffectDisplay : OsuTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddUntilStep("colours are correct", () => testDisplay.Container.Colour == colourProvider.Background5 && background.Colour == colours.ForModType(ModType.DifficultyIncrease)); } - private class TestDisplay : ModsEffectDisplay + private partial class TestDisplay : ModsEffectDisplay { public Container Container => Content; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneNotificationOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneNotificationOverlay.cs index 7ed08d8dff..3cd5daf7a1 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneNotificationOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneNotificationOverlay.cs @@ -21,7 +21,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneNotificationOverlay : OsuManualInputManagerTestScene + public partial class TestSceneNotificationOverlay : OsuManualInputManagerTestScene { private NotificationOverlay notificationOverlay = null!; @@ -617,12 +617,12 @@ namespace osu.Game.Tests.Visual.UserInterface notificationOverlay.Post(new SimpleNotification { Text = @"Spam incoming!!" }); } - private class BackgroundNotification : SimpleNotification + private partial class BackgroundNotification : SimpleNotification { public override bool IsImportant => false; } - private class BackgroundProgressNotification : ProgressNotification + private partial class BackgroundProgressNotification : ProgressNotification { public override bool IsImportant => false; } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs index f7f35b8361..d07b90025f 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneNowPlayingOverlay.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets.Osu; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneNowPlayingOverlay : OsuTestScene + public partial class TestSceneNowPlayingOverlay : OsuTestScene { [Cached] private MusicController musicController = new MusicController(); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs index 2d8d7a5de3..f2123061e5 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOnScreenDisplay.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays.OSD; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneOnScreenDisplay : OsuTestScene + public partial class TestSceneOnScreenDisplay : OsuTestScene { [BackgroundDependencyLoader] private void load() @@ -95,7 +95,7 @@ namespace osu.Game.Tests.Visual.UserInterface Setting4 } - private class EmptyToast : Toast + private partial class EmptyToast : Toast { public EmptyToast() : base("", "", "") @@ -103,7 +103,7 @@ namespace osu.Game.Tests.Visual.UserInterface } } - private class LengthyToast : Toast + private partial class LengthyToast : Toast { public LengthyToast() : base("Toast with a very very very long text", "A very very very very very very long text also", "A very very very very very long shortcut") @@ -111,7 +111,7 @@ namespace osu.Game.Tests.Visual.UserInterface } } - private class TestOnScreenDisplay : OnScreenDisplay + private partial class TestOnScreenDisplay : OnScreenDisplay { protected override void DisplayTemporarily(Drawable toDisplay) => toDisplay.FadeIn().ResizeHeightTo(110); } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuAnimatedButton.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuAnimatedButton.cs index bab2121d70..eba3885a2b 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuAnimatedButton.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuAnimatedButton.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneOsuAnimatedButton : OsuTestScene + public partial class TestSceneOsuAnimatedButton : OsuTestScene { [Test] public void TestRelativeSized() @@ -104,7 +104,7 @@ namespace osu.Game.Tests.Visual.UserInterface }); } - public class BaseContainer : OsuAnimatedButton + public partial class BaseContainer : OsuAnimatedButton { public BaseContainer(string text) { diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuButton.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuButton.cs index d4c2bfd422..41e5d47093 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuButton.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuButton.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneOsuButton : OsuTestScene + public partial class TestSceneOsuButton : OsuTestScene { [Test] public void TestToggleEnabled() diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuDropdown.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuDropdown.cs index 2cda95bda4..770b9dece1 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuDropdown.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuDropdown.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneOsuDropdown : ThemeComparisonTestScene + public partial class TestSceneOsuDropdown : ThemeComparisonTestScene { protected override Drawable CreateContent() => new OsuEnumDropdown diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuFont.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuFont.cs index f534fc0fac..7b3f97a16e 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuFont.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuFont.cs @@ -13,7 +13,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneOsuFont : OsuTestScene + public partial class TestSceneOsuFont : OsuTestScene { private OsuSpriteText spriteText; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuHoverContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuHoverContainer.cs index d4b15c06c5..ab5a70f448 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuHoverContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuHoverContainer.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneOsuHoverContainer : OsuManualInputManagerTestScene + public partial class TestSceneOsuHoverContainer : OsuManualInputManagerTestScene { private OsuHoverTestContainer hoverContainer; private Box colourContainer; @@ -181,7 +181,7 @@ namespace osu.Game.Tests.Visual.UserInterface private void doMoveOut() => InputManager.MoveMouseTo(new Vector2(InputManager.ScreenSpaceDrawQuad.TopLeft.X, InputManager.ScreenSpaceDrawQuad.TopLeft.Y)); - private sealed class OsuHoverTestContainer : OsuHoverContainer + private sealed partial class OsuHoverTestContainer : OsuHoverContainer { public static readonly Color4 HOVER_COLOUR = Color4.Red; public static readonly Color4 IDLE_COLOUR = Color4.Green; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuIcon.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuIcon.cs index 1e1c3b3282..a1254678b7 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuIcon.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuIcon.cs @@ -21,7 +21,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneOsuIcon : OsuTestScene + public partial class TestSceneOsuIcon : OsuTestScene { public TestSceneOsuIcon() { @@ -60,7 +60,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("change icons", () => flow.Children.ForEach(i => i.SpriteIcon.Icon = new IconUsage((char)(i.SpriteIcon.Icon.Icon + 1)))); } - private class Icon : Container, IHasTooltip + private partial class Icon : Container, IHasTooltip { public LocalisableString TooltipText { get; } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuLogo.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuLogo.cs index e23a960a7e..24a27f71e8 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuLogo.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuLogo.cs @@ -9,7 +9,7 @@ using osu.Game.Screens.Menu; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneOsuLogo : OsuTestScene + public partial class TestSceneOsuLogo : OsuTestScene { [Test] public void TestBasic() diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuMarkdownContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuMarkdownContainer.cs index cdccb817b9..1e2485c6e2 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuMarkdownContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuMarkdownContainer.cs @@ -13,7 +13,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneOsuMarkdownContainer : OsuTestScene + public partial class TestSceneOsuMarkdownContainer : OsuTestScene { private OsuMarkdownContainer markdownContainer; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuMenu.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuMenu.cs index 5349a1b8a0..addaab5d35 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuMenu.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuMenu.cs @@ -12,7 +12,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneOsuMenu : OsuManualInputManagerTestScene + public partial class TestSceneOsuMenu : OsuManualInputManagerTestScene { private OsuMenu menu; private bool actionPerformed; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuPopover.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuPopover.cs index 6cc89a6df8..ca26c26b0a 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuPopover.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuPopover.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneOsuPopover : OsuGridTestScene + public partial class TestSceneOsuPopover : OsuGridTestScene { public TestSceneOsuPopover() : base(1, 2) @@ -56,7 +56,7 @@ namespace osu.Game.Tests.Visual.UserInterface }; } - private class TriangleButtonWithPopover : TriangleButton, IHasPopover + private partial class TriangleButtonWithPopover : TriangleButton, IHasPopover { public TriangleButtonWithPopover() { @@ -91,7 +91,7 @@ namespace osu.Game.Tests.Visual.UserInterface }; } - private class ColourProvidingContainer : Container + private partial class ColourProvidingContainer : Container { [Cached] private OverlayColourProvider provider { get; } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuTextBox.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuTextBox.cs index cc510f007b..929537e675 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuTextBox.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuTextBox.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneOsuTextBox : ThemeComparisonTestScene + public partial class TestSceneOsuTextBox : ThemeComparisonTestScene { private IEnumerable numberBoxes => this.ChildrenOfType(); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs index a5493559d6..8f10065d17 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs @@ -13,7 +13,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneOverlayHeader : OsuTestScene + public partial class TestSceneOverlayHeader : OsuTestScene { private readonly FillFlowContainer flow; @@ -70,7 +70,7 @@ namespace osu.Game.Tests.Visual.UserInterface }); } - private class ColourProvidedContainer : Container + private partial class ColourProvidedContainer : Container { [Cached] private readonly OverlayColourProvider colourProvider; @@ -85,7 +85,7 @@ namespace osu.Game.Tests.Visual.UserInterface } } - private class TestNoBackgroundHeader : OverlayHeader + private partial class TestNoBackgroundHeader : OverlayHeader { protected override OverlayTitle CreateTitle() => new TestTitle(); @@ -95,14 +95,14 @@ namespace osu.Game.Tests.Visual.UserInterface } } - private class TestNoControlHeader : OverlayHeader + private partial class TestNoControlHeader : OverlayHeader { protected override Drawable CreateBackground() => new OverlayHeaderBackground(@"Headers/changelog"); protected override OverlayTitle CreateTitle() => new TestTitle(); } - private class TestStringTabControlHeader : TabControlOverlayHeader + private partial class TestStringTabControlHeader : TabControlOverlayHeader { protected override Drawable CreateBackground() => new OverlayHeaderBackground(@"Headers/news"); @@ -117,7 +117,7 @@ namespace osu.Game.Tests.Visual.UserInterface } } - private class TestEnumTabControlHeader : TabControlOverlayHeader + private partial class TestEnumTabControlHeader : TabControlOverlayHeader { public TestEnumTabControlHeader() { @@ -136,7 +136,7 @@ namespace osu.Game.Tests.Visual.UserInterface Tabs } - private class TestBreadcrumbControlHeader : BreadcrumbControlOverlayHeader + private partial class TestBreadcrumbControlHeader : BreadcrumbControlOverlayHeader { protected override OverlayTitle CreateTitle() => new TestTitle(); @@ -150,7 +150,7 @@ namespace osu.Game.Tests.Visual.UserInterface } } - private class TestTitle : OverlayTitle + private partial class TestTitle : OverlayTitle { public TestTitle() { diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaderBackground.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaderBackground.cs index 11507e561f..7a445427f5 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaderBackground.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaderBackground.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneOverlayHeaderBackground : OsuTestScene + public partial class TestSceneOverlayHeaderBackground : OsuTestScene { public TestSceneOverlayHeaderBackground() { diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs index 5a1ce9e791..432e448038 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs @@ -18,7 +18,7 @@ using osu.Framework.Allocation; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneOverlayRulesetSelector : OsuTestScene + public partial class TestSceneOverlayRulesetSelector : OsuTestScene { private readonly OverlayRulesetSelector selector; private readonly Bindable ruleset = new Bindable(); @@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual.UserInterface }); } - private class ColourProvidedContainer : Container + private partial class ColourProvidedContainer : Container { [Cached] private readonly OverlayColourProvider colourProvider; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayScrollContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayScrollContainer.cs index 7b3e82ff6d..926bc01aea 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayScrollContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayScrollContainer.cs @@ -15,7 +15,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneOverlayScrollContainer : OsuManualInputManagerTestScene + public partial class TestSceneOverlayScrollContainer : OsuManualInputManagerTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); @@ -100,7 +100,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("invocation count is 1", () => invocationCount == 1); } - private class TestScrollContainer : OverlayScrollContainer + private partial class TestScrollContainer : OverlayScrollContainer { public new ScrollToTopButton Button => base.Button; } diff --git a/osu.Game.Tests/Visual/UserInterface/TestScenePageSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestScenePageSelector.cs index 1907a56735..b9e3592389 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestScenePageSelector.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestScenePageSelector.cs @@ -13,7 +13,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.UserInterface { - public class TestScenePageSelector : OsuTestScene + public partial class TestScenePageSelector : OsuTestScene { [Cached] private OverlayColourProvider provider { get; } = new OverlayColourProvider(OverlayColourScheme.Green); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneParallaxContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneParallaxContainer.cs index 6ab69f32ef..92d4981d4a 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneParallaxContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneParallaxContainer.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Backgrounds; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneParallaxContainer : OsuTestScene + public partial class TestSceneParallaxContainer : OsuTestScene { public TestSceneParallaxContainer() { diff --git a/osu.Game.Tests/Visual/UserInterface/TestScenePlaylistOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestScenePlaylistOverlay.cs index d87bcfa5dd..c723988d6a 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestScenePlaylistOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestScenePlaylistOverlay.cs @@ -20,7 +20,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { - public class TestScenePlaylistOverlay : OsuManualInputManagerTestScene + public partial class TestScenePlaylistOverlay : OsuManualInputManagerTestScene { protected override bool UseFreshStoragePerRun => true; diff --git a/osu.Game.Tests/Visual/UserInterface/TestScenePopupDialog.cs b/osu.Game.Tests/Visual/UserInterface/TestScenePopupDialog.cs index 218677fd03..9537ab63be 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestScenePopupDialog.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestScenePopupDialog.cs @@ -13,7 +13,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { - public class TestScenePopupDialog : OsuManualInputManagerTestScene + public partial class TestScenePopupDialog : OsuManualInputManagerTestScene { private TestPopupDialog dialog; @@ -52,7 +52,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("release button", () => InputManager.ReleaseButton(MouseButton.Left)); } - private class TestPopupDialog : PopupDialog + private partial class TestPopupDialog : PopupDialog { public PopupDialogDangerousButton DangerousButton { get; } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneProfileSubsectionHeader.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneProfileSubsectionHeader.cs index 9738ff33c3..b4b45da133 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneProfileSubsectionHeader.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneProfileSubsectionHeader.cs @@ -13,7 +13,7 @@ using osu.Framework.Allocation; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneProfileSubsectionHeader : OsuTestScene + public partial class TestSceneProfileSubsectionHeader : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneRankingsSortTabControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneRankingsSortTabControl.cs index a95ae190dd..f364a48616 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneRankingsSortTabControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneRankingsSortTabControl.cs @@ -10,7 +10,7 @@ using osu.Game.Overlays.Rankings; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneRankingsSortTabControl : OsuTestScene + public partial class TestSceneRankingsSortTabControl : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneRoundedButton.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneRoundedButton.cs index 2587960275..1dc9845916 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneRoundedButton.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneRoundedButton.cs @@ -16,7 +16,7 @@ using osu.Game.Overlays.Settings; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneRoundedButton : ThemeComparisonTestScene + public partial class TestSceneRoundedButton : ThemeComparisonTestScene { private readonly BindableBool enabled = new BindableBool(true); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSafeAreaHandling.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSafeAreaHandling.cs index 90365ec939..453cdd1357 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSafeAreaHandling.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSafeAreaHandling.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneSafeAreaHandling : OsuGameTestScene + public partial class TestSceneSafeAreaHandling : OsuGameTestScene { private SafeAreaDefiningContainer safeAreaContainer; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneScalingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneScalingContainer.cs index 67c47492b0..26fa26a0b8 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneScalingContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneScalingContainer.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneScalingContainer : OsuTestScene + public partial class TestSceneScalingContainer : OsuTestScene { private OsuConfigManager osuConfigManager { get; set; } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneScreenBreadcrumbControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneScreenBreadcrumbControl.cs index b3ee0af78b..e0ae23e1c8 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneScreenBreadcrumbControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneScreenBreadcrumbControl.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneScreenBreadcrumbControl : OsuTestScene + public partial class TestSceneScreenBreadcrumbControl : OsuTestScene { private readonly ScreenBreadcrumbControl breadcrumbs; private readonly OsuScreenStack screenStack; @@ -79,7 +79,7 @@ namespace osu.Game.Tests.Visual.UserInterface private void pushNext() => AddStep(@"push next screen", () => ((TestScreen)screenStack.CurrentScreen).PushNext()); private void waitForCurrent() => AddUntilStep("current screen", () => screenStack.CurrentScreen.IsCurrentScreen()); - private abstract class TestScreen : OsuScreen + private abstract partial class TestScreen : OsuScreen { protected abstract string NextTitle { get; } protected abstract TestScreen CreateNextScreen(); @@ -122,14 +122,14 @@ namespace osu.Game.Tests.Visual.UserInterface } } - private class TestScreenOne : TestScreen + private partial class TestScreenOne : TestScreen { public override string Title => @"Screen One"; protected override string NextTitle => @"Two"; protected override TestScreen CreateNextScreen() => new TestScreenTwo(); } - private class TestScreenTwo : TestScreen + private partial class TestScreenTwo : TestScreen { public override string Title => @"Screen Two"; protected override string NextTitle => @"One"; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSectionsContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSectionsContainer.cs index f71d797363..05fffc903d 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSectionsContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSectionsContainer.cs @@ -20,7 +20,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneSectionsContainer : OsuManualInputManagerTestScene + public partial class TestSceneSectionsContainer : OsuManualInputManagerTestScene { private SectionsContainer container; private float custom; @@ -196,7 +196,7 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.ScrollVerticalBy(direction); } - private class TestSection : TestBox + private partial class TestSection : TestBox { public bool Selected { @@ -210,7 +210,7 @@ namespace osu.Game.Tests.Visual.UserInterface } } - private class TestBox : Container + private partial class TestBox : Container { private readonly Box background; private readonly OsuSpriteText text; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsCheckbox.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsCheckbox.cs index 466c83b1ac..a0fe5fce32 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsCheckbox.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsCheckbox.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneSettingsCheckbox : OsuTestScene + public partial class TestSceneSettingsCheckbox : OsuTestScene { [TestCase] public void TestCheckbox() @@ -56,7 +56,7 @@ namespace osu.Game.Tests.Visual.UserInterface }); } - private class OverlayColourContainer : Container + private partial class OverlayColourContainer : Container { [Cached] private OverlayColourProvider colourProvider; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsToolboxGroup.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsToolboxGroup.cs index 9fb0905a4f..71b98ed9af 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsToolboxGroup.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsToolboxGroup.cs @@ -18,7 +18,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneSettingsToolboxGroup : OsuManualInputManagerTestScene + public partial class TestSceneSettingsToolboxGroup : OsuManualInputManagerTestScene { private SettingsToolboxGroup group; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneShearedButtons.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneShearedButtons.cs index 6c485aff34..118d32ee70 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneShearedButtons.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneShearedButtons.cs @@ -17,7 +17,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneShearedButtons : OsuManualInputManagerTestScene + public partial class TestSceneShearedButtons : OsuManualInputManagerTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneShearedOverlayContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneShearedOverlayContainer.cs index c0fb315e03..fb06760568 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneShearedOverlayContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneShearedOverlayContainer.cs @@ -22,7 +22,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneShearedOverlayContainer : OsuManualInputManagerTestScene + public partial class TestSceneShearedOverlayContainer : OsuManualInputManagerTestScene { private TestShearedOverlayContainer overlay; @@ -66,7 +66,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("overlay dismissed", () => overlay.State.Value == Visibility.Hidden); } - public class TestShearedOverlayContainer : ShearedOverlayContainer + public partial class TestShearedOverlayContainer : ShearedOverlayContainer { public TestShearedOverlayContainer() : base(OverlayColourScheme.Green) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneShearedOverlayHeader.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneShearedOverlayHeader.cs index 09292ee92b..aeea0681eb 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneShearedOverlayHeader.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneShearedOverlayHeader.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneShearedOverlayHeader : OsuTestScene + public partial class TestSceneShearedOverlayHeader : OsuTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneShearedSearchTextBox.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneShearedSearchTextBox.cs index 78e06f7e32..0072864335 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneShearedSearchTextBox.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneShearedSearchTextBox.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneShearedSearchTextBox : OsuTestScene + public partial class TestSceneShearedSearchTextBox : OsuTestScene { [Test] public void TestAllColourSchemes() diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSizePreservingSpriteText.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSizePreservingSpriteText.cs index c4568d9aeb..7339ea7b23 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSizePreservingSpriteText.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSizePreservingSpriteText.cs @@ -13,7 +13,7 @@ using osu.Game.Graphics; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneSizePreservingSpriteText : OsuGridTestScene + public partial class TestSceneSizePreservingSpriteText : OsuGridTestScene { private readonly List parentContainers = new List(); private readonly List childContainers = new List(); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs index 72929a4555..6988bac2ee 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneStarRatingDisplay : OsuTestScene + public partial class TestSceneStarRatingDisplay : OsuTestScene { [TestCase(StarRatingDisplaySize.Regular)] [TestCase(StarRatingDisplaySize.Small)] diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneStatefulMenuItem.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneStatefulMenuItem.cs index 11acb31fef..88187f1808 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneStatefulMenuItem.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneStatefulMenuItem.cs @@ -13,7 +13,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneStatefulMenuItem : OsuManualInputManagerTestScene + public partial class TestSceneStatefulMenuItem : OsuManualInputManagerTestScene { [Test] public void TestTernaryRadioMenuItem() diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSwitchButton.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSwitchButton.cs index 4d90a11405..f3ab5dbff8 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSwitchButton.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSwitchButton.cs @@ -11,7 +11,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneSwitchButton : OsuManualInputManagerTestScene + public partial class TestSceneSwitchButton : OsuManualInputManagerTestScene { private SwitchButton switchButton; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneTabControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneTabControl.cs index b868abcc45..24c4ed79b1 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneTabControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneTabControl.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { [Description("SongSelect filter control")] - public class TestSceneTabControl : OsuTestScene + public partial class TestSceneTabControl : OsuTestScene { public TestSceneTabControl() { diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneToggleMenuItem.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneToggleMenuItem.cs index 92cfeef369..41a6f35624 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneToggleMenuItem.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneToggleMenuItem.cs @@ -8,7 +8,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneToggleMenuItem : OsuTestScene + public partial class TestSceneToggleMenuItem : OsuTestScene { public TestSceneToggleMenuItem() { diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs index de67b85c7d..651c5376b5 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneToolbarRulesetSelector.cs @@ -14,7 +14,7 @@ using osu.Game.Rulesets; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneToolbarRulesetSelector : OsuTestScene + public partial class TestSceneToolbarRulesetSelector : OsuTestScene { [Resolved] private RulesetStore rulesets { get; set; } @@ -65,7 +65,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("mode line has moved", () => selector.ModeButtonLine.DrawPosition.X > 0); } - private class TestSelector : ToolbarRulesetSelector + private partial class TestSelector : ToolbarRulesetSelector { public new Drawable ModeButtonLine => base.ModeButtonLine; } diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneTwoLayerButton.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneTwoLayerButton.cs index a11efb69bd..20b0ab5801 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneTwoLayerButton.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneTwoLayerButton.cs @@ -11,7 +11,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneTwoLayerButton : OsuTestScene + public partial class TestSceneTwoLayerButton : OsuTestScene { public TestSceneTwoLayerButton() { diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneUpdateableBeatmapBackgroundSprite.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneUpdateableBeatmapBackgroundSprite.cs index 32f47d77e1..48fe517f8a 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneUpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneUpdateableBeatmapBackgroundSprite.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneUpdateableBeatmapBackgroundSprite : OsuTestScene + public partial class TestSceneUpdateableBeatmapBackgroundSprite : OsuTestScene { protected override bool UseOnlineAPI => true; @@ -138,7 +138,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddUntilStep("all unloaded", () => !loadedBackgrounds.Any()); } - private class TestUpdateableBeatmapBackgroundSprite : UpdateableBeatmapBackgroundSprite + private partial class TestUpdateableBeatmapBackgroundSprite : UpdateableBeatmapBackgroundSprite { protected override double UnloadDelay => 2000; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneUpdateableBeatmapSetCover.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneUpdateableBeatmapSetCover.cs index 8176871481..a1a546d4a7 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneUpdateableBeatmapSetCover.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneUpdateableBeatmapSetCover.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneUpdateableBeatmapSetCover : OsuTestScene + public partial class TestSceneUpdateableBeatmapSetCover : OsuTestScene { [Test] public void TestLocal([Values] BeatmapSetCoverType coverType) @@ -139,7 +139,7 @@ namespace osu.Game.Tests.Visual.UserInterface Covers = new BeatmapSetOnlineCovers { Cover = coverUrl } }; - private class TestUpdateableOnlineBeatmapSetCover : UpdateableOnlineBeatmapSetCover + private partial class TestUpdateableOnlineBeatmapSetCover : UpdateableOnlineBeatmapSetCover { private readonly int loadDelay; @@ -163,7 +163,7 @@ namespace osu.Game.Tests.Visual.UserInterface } } - private class TestOnlineBeatmapSetCover : OnlineBeatmapSetCover + private partial class TestOnlineBeatmapSetCover : OnlineBeatmapSetCover { private readonly int loadDelay; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneUprightAspectMaintainingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneUprightAspectMaintainingContainer.cs index 67c26829df..15570b7927 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneUprightAspectMaintainingContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneUprightAspectMaintainingContainer.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneUprightAspectMaintainingContainer : OsuGridTestScene + public partial class TestSceneUprightAspectMaintainingContainer : OsuGridTestScene { private const int rows = 3; private const int columns = 4; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneUserListToolbar.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneUserListToolbar.cs index 5e2e2ccff6..8737f7312e 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneUserListToolbar.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneUserListToolbar.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneUserListToolbar : OsuTestScene + public partial class TestSceneUserListToolbar : OsuTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneVolumeOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneVolumeOverlay.cs index b5b4542eac..52543c68ce 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneVolumeOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneVolumeOverlay.cs @@ -9,7 +9,7 @@ using osu.Game.Overlays.Volume; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneVolumeOverlay : OsuTestScene + public partial class TestSceneVolumeOverlay : OsuTestScene { private VolumeOverlay volume; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneVolumePieces.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneVolumePieces.cs index 9ce71a5347..7cedef96e3 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneVolumePieces.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneVolumePieces.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneVolumePieces : OsuTestScene + public partial class TestSceneVolumePieces : OsuTestScene { protected override void LoadComplete() { diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneWaveContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneWaveContainer.cs index 6a4934cf47..7851571b36 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneWaveContainer.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneWaveContainer.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] - public class TestSceneWaveContainer : OsuTestScene + public partial class TestSceneWaveContainer : OsuTestScene { [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game.Tests/Visual/UserInterface/ThemeComparisonTestScene.cs b/osu.Game.Tests/Visual/UserInterface/ThemeComparisonTestScene.cs index 8fb0fd84a1..05ffd1fbef 100644 --- a/osu.Game.Tests/Visual/UserInterface/ThemeComparisonTestScene.cs +++ b/osu.Game.Tests/Visual/UserInterface/ThemeComparisonTestScene.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays; namespace osu.Game.Tests.Visual.UserInterface { - public abstract class ThemeComparisonTestScene : OsuGridTestScene + public abstract partial class ThemeComparisonTestScene : OsuGridTestScene { protected ThemeComparisonTestScene() : base(1, 2) diff --git a/osu.Game.Tournament.Tests/Components/TestSceneDateTextBox.cs b/osu.Game.Tournament.Tests/Components/TestSceneDateTextBox.cs index 0e6e8f54bd..f547acd635 100644 --- a/osu.Game.Tournament.Tests/Components/TestSceneDateTextBox.cs +++ b/osu.Game.Tournament.Tests/Components/TestSceneDateTextBox.cs @@ -11,7 +11,7 @@ using osuTK.Input; namespace osu.Game.Tournament.Tests.Components { - public class TestSceneDateTextBox : OsuManualInputManagerTestScene + public partial class TestSceneDateTextBox : OsuManualInputManagerTestScene { private DateTextBox textBox; diff --git a/osu.Game.Tournament.Tests/Components/TestSceneDrawableTournamentMatch.cs b/osu.Game.Tournament.Tests/Components/TestSceneDrawableTournamentMatch.cs index 66093b80a1..cb923a1f9a 100644 --- a/osu.Game.Tournament.Tests/Components/TestSceneDrawableTournamentMatch.cs +++ b/osu.Game.Tournament.Tests/Components/TestSceneDrawableTournamentMatch.cs @@ -10,7 +10,7 @@ using osu.Game.Tournament.Screens.Ladder.Components; namespace osu.Game.Tournament.Tests.Components { - public class TestSceneDrawableTournamentMatch : TournamentTestScene + public partial class TestSceneDrawableTournamentMatch : TournamentTestScene { public TestSceneDrawableTournamentMatch() { diff --git a/osu.Game.Tournament.Tests/Components/TestSceneDrawableTournamentTeam.cs b/osu.Game.Tournament.Tests/Components/TestSceneDrawableTournamentTeam.cs index 4ea7e8008a..dd7c613c6c 100644 --- a/osu.Game.Tournament.Tests/Components/TestSceneDrawableTournamentTeam.cs +++ b/osu.Game.Tournament.Tests/Components/TestSceneDrawableTournamentTeam.cs @@ -14,7 +14,7 @@ using osu.Game.Tournament.Screens.Ladder.Components; namespace osu.Game.Tournament.Tests.Components { - public class TestSceneDrawableTournamentTeam : OsuGridTestScene + public partial class TestSceneDrawableTournamentTeam : OsuGridTestScene { public TestSceneDrawableTournamentTeam() : base(4, 3) diff --git a/osu.Game.Tournament.Tests/Components/TestSceneMatchHeader.cs b/osu.Game.Tournament.Tests/Components/TestSceneMatchHeader.cs index 55d58fef6e..2347c84ba8 100644 --- a/osu.Game.Tournament.Tests/Components/TestSceneMatchHeader.cs +++ b/osu.Game.Tournament.Tests/Components/TestSceneMatchHeader.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Tournament.Tests.Components { - public class TestSceneMatchHeader : TournamentTestScene + public partial class TestSceneMatchHeader : TournamentTestScene { public TestSceneMatchHeader() { diff --git a/osu.Game.Tournament.Tests/Components/TestSceneMatchScoreDisplay.cs b/osu.Game.Tournament.Tests/Components/TestSceneMatchScoreDisplay.cs index 53301c34d4..9b1fc17591 100644 --- a/osu.Game.Tournament.Tests/Components/TestSceneMatchScoreDisplay.cs +++ b/osu.Game.Tournament.Tests/Components/TestSceneMatchScoreDisplay.cs @@ -11,7 +11,7 @@ using osu.Game.Tournament.Screens.Gameplay.Components; namespace osu.Game.Tournament.Tests.Components { - public class TestSceneMatchScoreDisplay : TournamentTestScene + public partial class TestSceneMatchScoreDisplay : TournamentTestScene { [Cached(Type = typeof(MatchIPCInfo))] private MatchIPCInfo matchInfo = new MatchIPCInfo(); diff --git a/osu.Game.Tournament.Tests/Components/TestSceneRoundDisplay.cs b/osu.Game.Tournament.Tests/Components/TestSceneRoundDisplay.cs index 514a797068..cb22e7e7c7 100644 --- a/osu.Game.Tournament.Tests/Components/TestSceneRoundDisplay.cs +++ b/osu.Game.Tournament.Tests/Components/TestSceneRoundDisplay.cs @@ -9,7 +9,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Tests.Components { - public class TestSceneRoundDisplay : TournamentTestScene + public partial class TestSceneRoundDisplay : TournamentTestScene { public TestSceneRoundDisplay() { diff --git a/osu.Game.Tournament.Tests/Components/TestSceneSongBar.cs b/osu.Game.Tournament.Tests/Components/TestSceneSongBar.cs index 992baa48a3..f793c33878 100644 --- a/osu.Game.Tournament.Tests/Components/TestSceneSongBar.cs +++ b/osu.Game.Tournament.Tests/Components/TestSceneSongBar.cs @@ -14,7 +14,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Tests.Components { [TestFixture] - public class TestSceneSongBar : OsuTestScene + public partial class TestSceneSongBar : OsuTestScene { [Cached] private readonly LadderInfo ladder = new LadderInfo(); diff --git a/osu.Game.Tournament.Tests/Components/TestSceneTournamentBeatmapPanel.cs b/osu.Game.Tournament.Tests/Components/TestSceneTournamentBeatmapPanel.cs index adfe048ce4..057566d426 100644 --- a/osu.Game.Tournament.Tests/Components/TestSceneTournamentBeatmapPanel.cs +++ b/osu.Game.Tournament.Tests/Components/TestSceneTournamentBeatmapPanel.cs @@ -14,7 +14,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Tests.Components { - public class TestSceneTournamentBeatmapPanel : TournamentTestScene + public partial class TestSceneTournamentBeatmapPanel : TournamentTestScene { /// /// Warning: the below API instance is actually the online API, rather than the dummy API provided by the test. diff --git a/osu.Game.Tournament.Tests/Components/TestSceneTournamentMatchChatDisplay.cs b/osu.Game.Tournament.Tests/Components/TestSceneTournamentMatchChatDisplay.cs index eb8b0dfbe6..d9ae8df651 100644 --- a/osu.Game.Tournament.Tests/Components/TestSceneTournamentMatchChatDisplay.cs +++ b/osu.Game.Tournament.Tests/Components/TestSceneTournamentMatchChatDisplay.cs @@ -15,7 +15,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Tests.Components { - public class TestSceneTournamentMatchChatDisplay : OsuTestScene + public partial class TestSceneTournamentMatchChatDisplay : OsuTestScene { private readonly Channel testChannel = new Channel(); private readonly Channel testChannel2 = new Channel(); diff --git a/osu.Game.Tournament.Tests/Components/TestSceneTournamentModDisplay.cs b/osu.Game.Tournament.Tests/Components/TestSceneTournamentModDisplay.cs index 263617ddf7..cea4306ff8 100644 --- a/osu.Game.Tournament.Tests/Components/TestSceneTournamentModDisplay.cs +++ b/osu.Game.Tournament.Tests/Components/TestSceneTournamentModDisplay.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Tournament.Tests.Components { - public class TestSceneTournamentModDisplay : TournamentTestScene + public partial class TestSceneTournamentModDisplay : TournamentTestScene { [Resolved] private IAPIProvider api { get; set; } diff --git a/osu.Game.Tournament.Tests/NonVisual/DataLoadTest.cs b/osu.Game.Tournament.Tests/NonVisual/DataLoadTest.cs index df77b31191..256a984a7c 100644 --- a/osu.Game.Tournament.Tests/NonVisual/DataLoadTest.cs +++ b/osu.Game.Tournament.Tests/NonVisual/DataLoadTest.cs @@ -17,7 +17,7 @@ using osu.Game.Tests; namespace osu.Game.Tournament.Tests.NonVisual { - public class DataLoadTest : TournamentHostTest + public partial class DataLoadTest : TournamentHostTest { [Test] public void TestRulesetGetsValidOnlineID() @@ -78,7 +78,7 @@ namespace osu.Game.Tournament.Tests.NonVisual } } - public class TestTournament : TournamentGameBase + public partial class TestTournament : TournamentGameBase { private readonly bool resetRuleset; private readonly Action runOnLoadComplete; diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneDrawingsScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneDrawingsScreen.cs index e0c6aaf834..10ed850002 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneDrawingsScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneDrawingsScreen.cs @@ -12,7 +12,7 @@ using osu.Game.Tournament.Screens.Drawings; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneDrawingsScreen : TournamentTestScene + public partial class TestSceneDrawingsScreen : TournamentTestScene { [BackgroundDependencyLoader] private void load(Storage storage) diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneGameplayScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneGameplayScreen.cs index 4fc15c365f..f127a930a6 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneGameplayScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneGameplayScreen.cs @@ -15,7 +15,7 @@ using osu.Game.Tournament.Screens.Gameplay.Components; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneGameplayScreen : TournamentTestScene + public partial class TestSceneGameplayScreen : TournamentTestScene { [Cached] private TournamentMatchChatDisplay chat = new TournamentMatchChatDisplay { Width = 0.5f }; diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneLadderEditorScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneLadderEditorScreen.cs index 7aade4fb82..5c4e1b2a5a 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneLadderEditorScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneLadderEditorScreen.cs @@ -10,7 +10,7 @@ using osu.Game.Tournament.Screens.Editors; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneLadderEditorScreen : TournamentTestScene + public partial class TestSceneLadderEditorScreen : TournamentTestScene { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneLadderScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneLadderScreen.cs index 1f817a1b22..20f729bb8d 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneLadderScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneLadderScreen.cs @@ -10,7 +10,7 @@ using osu.Game.Tournament.Screens.Ladder; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneLadderScreen : TournamentTestScene + public partial class TestSceneLadderScreen : TournamentTestScene { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneMapPoolScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneMapPoolScreen.cs index e0f91cc359..5695cb5574 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneMapPoolScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneMapPoolScreen.cs @@ -14,7 +14,7 @@ using osu.Game.Tournament.Screens.MapPool; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneMapPoolScreen : TournamentTestScene + public partial class TestSceneMapPoolScreen : TournamentTestScene { private MapPoolScreen screen; diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneRoundEditorScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneRoundEditorScreen.cs index 656663ece7..ebeb69012d 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneRoundEditorScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneRoundEditorScreen.cs @@ -7,7 +7,7 @@ using osu.Game.Tournament.Screens.Editors; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneRoundEditorScreen : TournamentTestScene + public partial class TestSceneRoundEditorScreen : TournamentTestScene { public TestSceneRoundEditorScreen() { diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneScheduleScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneScheduleScreen.cs index 6061314796..fd0de3d63a 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneScheduleScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneScheduleScreen.cs @@ -12,7 +12,7 @@ using osu.Game.Tournament.Screens.Schedule; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneScheduleScreen : TournamentTestScene + public partial class TestSceneScheduleScreen : TournamentTestScene { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneSeedingEditorScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneSeedingEditorScreen.cs index 94321e708f..cfb533149d 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneSeedingEditorScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneSeedingEditorScreen.cs @@ -9,7 +9,7 @@ using osu.Game.Tournament.Screens.Editors; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneSeedingEditorScreen : TournamentTestScene + public partial class TestSceneSeedingEditorScreen : TournamentTestScene { [Cached] private readonly LadderInfo ladder = new LadderInfo(); diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneSeedingScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneSeedingScreen.cs index 2581ed4b7e..c9620bc0b9 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneSeedingScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneSeedingScreen.cs @@ -14,7 +14,7 @@ using osu.Game.Tournament.Screens.TeamIntro; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneSeedingScreen : TournamentTestScene + public partial class TestSceneSeedingScreen : TournamentTestScene { [Cached] private readonly LadderInfo ladder = new LadderInfo diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneSetupScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneSetupScreen.cs index 9070590b15..84c8b9a141 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneSetupScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneSetupScreen.cs @@ -8,7 +8,7 @@ using osu.Game.Tournament.Screens.Setup; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneSetupScreen : TournamentTestScene + public partial class TestSceneSetupScreen : TournamentTestScene { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneShowcaseScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneShowcaseScreen.cs index 44e7c48887..6287679c27 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneShowcaseScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneShowcaseScreen.cs @@ -8,7 +8,7 @@ using osu.Game.Tournament.Screens.Showcase; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneShowcaseScreen : TournamentTestScene + public partial class TestSceneShowcaseScreen : TournamentTestScene { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneStablePathSelectScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneStablePathSelectScreen.cs index 27e5c59600..dbd9cb2817 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneStablePathSelectScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneStablePathSelectScreen.cs @@ -7,14 +7,14 @@ using osu.Game.Tournament.Screens.Setup; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneStablePathSelectScreen : TournamentTestScene + public partial class TestSceneStablePathSelectScreen : TournamentTestScene { public TestSceneStablePathSelectScreen() { AddStep("Add screen", () => Add(new StablePathSelectTestScreen())); } - private class StablePathSelectTestScreen : StablePathSelectScreen + private partial class StablePathSelectTestScreen : StablePathSelectScreen { protected override void ChangePath() { diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneTeamEditorScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneTeamEditorScreen.cs index b38430ece5..63c08800ad 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneTeamEditorScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneTeamEditorScreen.cs @@ -7,7 +7,7 @@ using osu.Game.Tournament.Screens.Editors; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneTeamEditorScreen : TournamentTestScene + public partial class TestSceneTeamEditorScreen : TournamentTestScene { public TestSceneTeamEditorScreen() { diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneTeamIntroScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneTeamIntroScreen.cs index fccc09c14e..5c26bc203c 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneTeamIntroScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneTeamIntroScreen.cs @@ -11,7 +11,7 @@ using osu.Game.Tournament.Screens.TeamIntro; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneTeamIntroScreen : TournamentTestScene + public partial class TestSceneTeamIntroScreen : TournamentTestScene { [Cached] private readonly LadderInfo ladder = new LadderInfo(); diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneTeamWinScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneTeamWinScreen.cs index 3b48c2eee5..43e16873c6 100644 --- a/osu.Game.Tournament.Tests/Screens/TestSceneTeamWinScreen.cs +++ b/osu.Game.Tournament.Tests/Screens/TestSceneTeamWinScreen.cs @@ -10,7 +10,7 @@ using osu.Game.Tournament.Screens.TeamWin; namespace osu.Game.Tournament.Tests.Screens { - public class TestSceneTeamWinScreen : TournamentTestScene + public partial class TestSceneTeamWinScreen : TournamentTestScene { [Test] public void TestBasic() diff --git a/osu.Game.Tournament.Tests/TestSceneTournamentSceneManager.cs b/osu.Game.Tournament.Tests/TestSceneTournamentSceneManager.cs index e961a3c670..859d0591c3 100644 --- a/osu.Game.Tournament.Tests/TestSceneTournamentSceneManager.cs +++ b/osu.Game.Tournament.Tests/TestSceneTournamentSceneManager.cs @@ -7,7 +7,7 @@ using osu.Framework.Allocation; namespace osu.Game.Tournament.Tests { - public class TestSceneTournamentSceneManager : TournamentTestScene + public partial class TestSceneTournamentSceneManager : TournamentTestScene { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tournament.Tests/TournamentTestBrowser.cs b/osu.Game.Tournament.Tests/TournamentTestBrowser.cs index 1adbe07709..1a9122c117 100644 --- a/osu.Game.Tournament.Tests/TournamentTestBrowser.cs +++ b/osu.Game.Tournament.Tests/TournamentTestBrowser.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics.Backgrounds; namespace osu.Game.Tournament.Tests { - public class TournamentTestBrowser : TournamentGameBase + public partial class TournamentTestBrowser : TournamentGameBase { protected override void LoadComplete() { diff --git a/osu.Game.Tournament.Tests/TournamentTestScene.cs b/osu.Game.Tournament.Tests/TournamentTestScene.cs index b440034f34..cab78422a2 100644 --- a/osu.Game.Tournament.Tests/TournamentTestScene.cs +++ b/osu.Game.Tournament.Tests/TournamentTestScene.cs @@ -18,7 +18,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Tests { - public abstract class TournamentTestScene : OsuTestScene + public abstract partial class TournamentTestScene : OsuTestScene { private TournamentMatch match; @@ -165,7 +165,7 @@ namespace osu.Game.Tournament.Tests protected override ITestSceneTestRunner CreateRunner() => new TournamentTestSceneTestRunner(); - public class TournamentTestSceneTestRunner : TournamentGameBase, ITestSceneTestRunner + public partial class TournamentTestSceneTestRunner : TournamentGameBase, ITestSceneTestRunner { private TestSceneTestRunner.TestRunner runner; diff --git a/osu.Game.Tournament/Components/ControlPanel.cs b/osu.Game.Tournament/Components/ControlPanel.cs index f43d494d5a..c3e66e80eb 100644 --- a/osu.Game.Tournament/Components/ControlPanel.cs +++ b/osu.Game.Tournament/Components/ControlPanel.cs @@ -16,7 +16,7 @@ namespace osu.Game.Tournament.Components /// An element anchored to the right-hand area of a screen that provides streamer level controls. /// Should be off-screen. /// - public class ControlPanel : Container + public partial class ControlPanel : Container { private readonly FillFlowContainer buttons; @@ -57,7 +57,7 @@ namespace osu.Game.Tournament.Components }; } - public class Spacer : CompositeDrawable + public partial class Spacer : CompositeDrawable { public Spacer(float height = 20) { diff --git a/osu.Game.Tournament/Components/DateTextBox.cs b/osu.Game.Tournament/Components/DateTextBox.cs index 76d12a6b03..192d8c9fd1 100644 --- a/osu.Game.Tournament/Components/DateTextBox.cs +++ b/osu.Game.Tournament/Components/DateTextBox.cs @@ -10,7 +10,7 @@ using osu.Game.Overlays.Settings; namespace osu.Game.Tournament.Components { - public class DateTextBox : SettingsTextBox + public partial class DateTextBox : SettingsTextBox { public new Bindable Current { diff --git a/osu.Game.Tournament/Components/DrawableTeamFlag.cs b/osu.Game.Tournament/Components/DrawableTeamFlag.cs index 348fd8cd76..317d685ee7 100644 --- a/osu.Game.Tournament/Components/DrawableTeamFlag.cs +++ b/osu.Game.Tournament/Components/DrawableTeamFlag.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Tournament.Components { - public class DrawableTeamFlag : Container + public partial class DrawableTeamFlag : Container { private readonly TournamentTeam team; diff --git a/osu.Game.Tournament/Components/DrawableTeamHeader.cs b/osu.Game.Tournament/Components/DrawableTeamHeader.cs index ceaf8d5e6e..1648e7373b 100644 --- a/osu.Game.Tournament/Components/DrawableTeamHeader.cs +++ b/osu.Game.Tournament/Components/DrawableTeamHeader.cs @@ -8,7 +8,7 @@ using osuTK; namespace osu.Game.Tournament.Components { - public class DrawableTeamHeader : TournamentSpriteTextWithBackground + public partial class DrawableTeamHeader : TournamentSpriteTextWithBackground { public DrawableTeamHeader(TeamColour colour) { diff --git a/osu.Game.Tournament/Components/DrawableTeamTitle.cs b/osu.Game.Tournament/Components/DrawableTeamTitle.cs index e64e08a921..68cc46be19 100644 --- a/osu.Game.Tournament/Components/DrawableTeamTitle.cs +++ b/osu.Game.Tournament/Components/DrawableTeamTitle.cs @@ -10,7 +10,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Components { - public class DrawableTeamTitle : TournamentSpriteTextWithBackground + public partial class DrawableTeamTitle : TournamentSpriteTextWithBackground { private readonly TournamentTeam team; diff --git a/osu.Game.Tournament/Components/DrawableTeamTitleWithHeader.cs b/osu.Game.Tournament/Components/DrawableTeamTitleWithHeader.cs index dbc9fa7f16..27113b0d21 100644 --- a/osu.Game.Tournament/Components/DrawableTeamTitleWithHeader.cs +++ b/osu.Game.Tournament/Components/DrawableTeamTitleWithHeader.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Tournament.Components { - public class DrawableTeamTitleWithHeader : CompositeDrawable + public partial class DrawableTeamTitleWithHeader : CompositeDrawable { public DrawableTeamTitleWithHeader(TournamentTeam team, TeamColour colour) { diff --git a/osu.Game.Tournament/Components/DrawableTeamWithPlayers.cs b/osu.Game.Tournament/Components/DrawableTeamWithPlayers.cs index 0bb35d534c..9606670ad8 100644 --- a/osu.Game.Tournament/Components/DrawableTeamWithPlayers.cs +++ b/osu.Game.Tournament/Components/DrawableTeamWithPlayers.cs @@ -13,7 +13,7 @@ using osuTK.Graphics; namespace osu.Game.Tournament.Components { - public class DrawableTeamWithPlayers : CompositeDrawable + public partial class DrawableTeamWithPlayers : CompositeDrawable { public DrawableTeamWithPlayers(TournamentTeam team, TeamColour colour) { diff --git a/osu.Game.Tournament/Components/DrawableTournamentHeaderLogo.cs b/osu.Game.Tournament/Components/DrawableTournamentHeaderLogo.cs index 9f5b825e30..c83fceb01d 100644 --- a/osu.Game.Tournament/Components/DrawableTournamentHeaderLogo.cs +++ b/osu.Game.Tournament/Components/DrawableTournamentHeaderLogo.cs @@ -11,7 +11,7 @@ using osu.Framework.Graphics.Textures; namespace osu.Game.Tournament.Components { - public class DrawableTournamentHeaderLogo : CompositeDrawable + public partial class DrawableTournamentHeaderLogo : CompositeDrawable { public DrawableTournamentHeaderLogo() { @@ -21,7 +21,7 @@ namespace osu.Game.Tournament.Components RelativeSizeAxes = Axes.X; } - private class LogoSprite : Sprite + private partial class LogoSprite : Sprite { [BackgroundDependencyLoader] private void load(TextureStore textures) diff --git a/osu.Game.Tournament/Components/DrawableTournamentHeaderText.cs b/osu.Game.Tournament/Components/DrawableTournamentHeaderText.cs index 67eeee7de4..7a1f448cb4 100644 --- a/osu.Game.Tournament/Components/DrawableTournamentHeaderText.cs +++ b/osu.Game.Tournament/Components/DrawableTournamentHeaderText.cs @@ -11,7 +11,7 @@ using osu.Framework.Graphics.Textures; namespace osu.Game.Tournament.Components { - public class DrawableTournamentHeaderText : CompositeDrawable + public partial class DrawableTournamentHeaderText : CompositeDrawable { public DrawableTournamentHeaderText(bool center = true) { @@ -25,7 +25,7 @@ namespace osu.Game.Tournament.Components RelativeSizeAxes = Axes.X; } - private class TextSprite : Sprite + private partial class TextSprite : Sprite { [BackgroundDependencyLoader] private void load(TextureStore textures) diff --git a/osu.Game.Tournament/Components/DrawableTournamentTeam.cs b/osu.Game.Tournament/Components/DrawableTournamentTeam.cs index eb1dde21e7..0036f5f115 100644 --- a/osu.Game.Tournament/Components/DrawableTournamentTeam.cs +++ b/osu.Game.Tournament/Components/DrawableTournamentTeam.cs @@ -12,7 +12,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Components { - public abstract class DrawableTournamentTeam : CompositeDrawable + public abstract partial class DrawableTournamentTeam : CompositeDrawable { public readonly TournamentTeam Team; diff --git a/osu.Game.Tournament/Components/IPCErrorDialog.cs b/osu.Game.Tournament/Components/IPCErrorDialog.cs index a32e01fb48..995bbffffc 100644 --- a/osu.Game.Tournament/Components/IPCErrorDialog.cs +++ b/osu.Game.Tournament/Components/IPCErrorDialog.cs @@ -8,7 +8,7 @@ using osu.Game.Overlays.Dialog; namespace osu.Game.Tournament.Components { - public class IPCErrorDialog : PopupDialog + public partial class IPCErrorDialog : PopupDialog { public IPCErrorDialog(string headerText, string bodyText) { diff --git a/osu.Game.Tournament/Components/RoundDisplay.cs b/osu.Game.Tournament/Components/RoundDisplay.cs index 98ef09aa58..6018cc6ffb 100644 --- a/osu.Game.Tournament/Components/RoundDisplay.cs +++ b/osu.Game.Tournament/Components/RoundDisplay.cs @@ -10,7 +10,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Components { - public class RoundDisplay : CompositeDrawable + public partial class RoundDisplay : CompositeDrawable { public RoundDisplay(TournamentMatch match) { diff --git a/osu.Game.Tournament/Components/SongBar.cs b/osu.Game.Tournament/Components/SongBar.cs index a9056166be..aeceece160 100644 --- a/osu.Game.Tournament/Components/SongBar.cs +++ b/osu.Game.Tournament/Components/SongBar.cs @@ -22,7 +22,7 @@ using osuTK.Graphics; namespace osu.Game.Tournament.Components { - public class SongBar : CompositeDrawable + public partial class SongBar : CompositeDrawable { private TournamentBeatmap beatmap; @@ -242,7 +242,7 @@ namespace osu.Game.Tournament.Components }; } - public class DiffPiece : TextFlowContainer + public partial class DiffPiece : TextFlowContainer { public DiffPiece(params (string heading, string content)[] tuples) { diff --git a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs index 462743cc3d..52769321a9 100644 --- a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs +++ b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Tournament.Components { - public class TournamentBeatmapPanel : CompositeDrawable + public partial class TournamentBeatmapPanel : CompositeDrawable { public readonly TournamentBeatmap Beatmap; diff --git a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs index ca2b400e8b..8a0dd6e336 100644 --- a/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs +++ b/osu.Game.Tournament/Components/TournamentMatchChatDisplay.cs @@ -15,7 +15,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Components { - public class TournamentMatchChatDisplay : StandAloneChatDisplay + public partial class TournamentMatchChatDisplay : StandAloneChatDisplay { private readonly Bindable chatChannel = new Bindable(); @@ -75,7 +75,7 @@ namespace osu.Game.Tournament.Components protected override StandAloneDrawableChannel CreateDrawableChannel(Channel channel) => new MatchChannel(channel); - public class MatchChannel : StandAloneDrawableChannel + public partial class MatchChannel : StandAloneDrawableChannel { public MatchChannel(Channel channel) : base(channel) @@ -84,7 +84,7 @@ namespace osu.Game.Tournament.Components } } - protected class MatchMessage : StandAloneMessage + protected partial class MatchMessage : StandAloneMessage { public MatchMessage(Message message) : base(message) diff --git a/osu.Game.Tournament/Components/TournamentModIcon.cs b/osu.Game.Tournament/Components/TournamentModIcon.cs index 6697a993c3..76b6151519 100644 --- a/osu.Game.Tournament/Components/TournamentModIcon.cs +++ b/osu.Game.Tournament/Components/TournamentModIcon.cs @@ -18,7 +18,7 @@ namespace osu.Game.Tournament.Components /// /// Mod icon displayed in tournament usages, allowing user overridden graphics. /// - public class TournamentModIcon : CompositeDrawable + public partial class TournamentModIcon : CompositeDrawable { private readonly string modAcronym; diff --git a/osu.Game.Tournament/Components/TournamentSpriteTextWithBackground.cs b/osu.Game.Tournament/Components/TournamentSpriteTextWithBackground.cs index b088670caa..3a16662463 100644 --- a/osu.Game.Tournament/Components/TournamentSpriteTextWithBackground.cs +++ b/osu.Game.Tournament/Components/TournamentSpriteTextWithBackground.cs @@ -10,7 +10,7 @@ using osu.Game.Graphics; namespace osu.Game.Tournament.Components { - public class TournamentSpriteTextWithBackground : CompositeDrawable + public partial class TournamentSpriteTextWithBackground : CompositeDrawable { public readonly TournamentSpriteText Text; diff --git a/osu.Game.Tournament/Components/TourneyVideo.cs b/osu.Game.Tournament/Components/TourneyVideo.cs index 2e79998e66..b9ce84b735 100644 --- a/osu.Game.Tournament/Components/TourneyVideo.cs +++ b/osu.Game.Tournament/Components/TourneyVideo.cs @@ -15,7 +15,7 @@ using osu.Game.Tournament.IO; namespace osu.Game.Tournament.Components { - public class TourneyVideo : CompositeDrawable + public partial class TourneyVideo : CompositeDrawable { private readonly string filename; private readonly bool drawFallbackGradient; diff --git a/osu.Game.Tournament/IPC/FileBasedIPC.cs b/osu.Game.Tournament/IPC/FileBasedIPC.cs index ad564c58c3..f940571ffe 100644 --- a/osu.Game.Tournament/IPC/FileBasedIPC.cs +++ b/osu.Game.Tournament/IPC/FileBasedIPC.cs @@ -22,7 +22,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.IPC { - public class FileBasedIPC : MatchIPCInfo + public partial class FileBasedIPC : MatchIPCInfo { public Storage IPCStorage { get; private set; } diff --git a/osu.Game.Tournament/IPC/MatchIPCInfo.cs b/osu.Game.Tournament/IPC/MatchIPCInfo.cs index f438923803..3bf790d58e 100644 --- a/osu.Game.Tournament/IPC/MatchIPCInfo.cs +++ b/osu.Game.Tournament/IPC/MatchIPCInfo.cs @@ -10,7 +10,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.IPC { - public class MatchIPCInfo : Component + public partial class MatchIPCInfo : Component { public Bindable Beatmap { get; } = new Bindable(); public Bindable Mods { get; } = new Bindable(); diff --git a/osu.Game.Tournament/SaveChangesOverlay.cs b/osu.Game.Tournament/SaveChangesOverlay.cs index b5e08fc005..a81f11cbe1 100644 --- a/osu.Game.Tournament/SaveChangesOverlay.cs +++ b/osu.Game.Tournament/SaveChangesOverlay.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Tournament { - internal class SaveChangesOverlay : CompositeDrawable + internal partial class SaveChangesOverlay : CompositeDrawable { [Resolved] private TournamentGame tournamentGame { get; set; } = null!; diff --git a/osu.Game.Tournament/Screens/BeatmapInfoScreen.cs b/osu.Game.Tournament/Screens/BeatmapInfoScreen.cs index 763f576afe..6f7234b8c3 100644 --- a/osu.Game.Tournament/Screens/BeatmapInfoScreen.cs +++ b/osu.Game.Tournament/Screens/BeatmapInfoScreen.cs @@ -13,7 +13,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Screens { - public abstract class BeatmapInfoScreen : TournamentMatchScreen + public abstract partial class BeatmapInfoScreen : TournamentMatchScreen { protected readonly SongBar SongBar; diff --git a/osu.Game.Tournament/Screens/Drawings/Components/Group.cs b/osu.Game.Tournament/Screens/Drawings/Components/Group.cs index 0b1a5328ab..b397f807f0 100644 --- a/osu.Game.Tournament/Screens/Drawings/Components/Group.cs +++ b/osu.Game.Tournament/Screens/Drawings/Components/Group.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Tournament.Screens.Drawings.Components { - public class Group : Container + public partial class Group : Container { public readonly string GroupName; diff --git a/osu.Game.Tournament/Screens/Drawings/Components/GroupContainer.cs b/osu.Game.Tournament/Screens/Drawings/Components/GroupContainer.cs index 62b3c4e8ff..37e15b7e45 100644 --- a/osu.Game.Tournament/Screens/Drawings/Components/GroupContainer.cs +++ b/osu.Game.Tournament/Screens/Drawings/Components/GroupContainer.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Tournament.Screens.Drawings.Components { - public class GroupContainer : Container + public partial class GroupContainer : Container { private readonly List groups = new List(); diff --git a/osu.Game.Tournament/Screens/Drawings/Components/GroupTeam.cs b/osu.Game.Tournament/Screens/Drawings/Components/GroupTeam.cs index 80bdad8b7b..167a576424 100644 --- a/osu.Game.Tournament/Screens/Drawings/Components/GroupTeam.cs +++ b/osu.Game.Tournament/Screens/Drawings/Components/GroupTeam.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Tournament.Screens.Drawings.Components { - public class GroupTeam : DrawableTournamentTeam + public partial class GroupTeam : DrawableTournamentTeam { private readonly FillFlowContainer innerContainer; diff --git a/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs b/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs index 8092c24ccb..c2b15dd3e9 100644 --- a/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs +++ b/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Tournament.Screens.Drawings.Components { - public class ScrollingTeamContainer : Container + public partial class ScrollingTeamContainer : Container { public event Action OnScrollStarted; public event Action OnSelected; @@ -309,7 +309,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components Scrolling } - public class ScrollingTeam : DrawableTournamentTeam + public partial class ScrollingTeam : DrawableTournamentTeam { public const float WIDTH = 58; public const float HEIGHT = 44; diff --git a/osu.Game.Tournament/Screens/Drawings/Components/VisualiserContainer.cs b/osu.Game.Tournament/Screens/Drawings/Components/VisualiserContainer.cs index 663162d1ca..676eec14cd 100644 --- a/osu.Game.Tournament/Screens/Drawings/Components/VisualiserContainer.cs +++ b/osu.Game.Tournament/Screens/Drawings/Components/VisualiserContainer.cs @@ -14,7 +14,7 @@ using osu.Framework.Utils; namespace osu.Game.Tournament.Screens.Drawings.Components { - public class VisualiserContainer : Container + public partial class VisualiserContainer : Container { /// /// Number of lines in the visualiser. @@ -61,7 +61,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components allLines.Remove(allLines.First()); } - private class VisualiserLine : Container + private partial class VisualiserLine : Container { /// /// Time offset. diff --git a/osu.Game.Tournament/Screens/Drawings/DrawingsScreen.cs b/osu.Game.Tournament/Screens/Drawings/DrawingsScreen.cs index 5ac25f97b5..23d0edf26e 100644 --- a/osu.Game.Tournament/Screens/Drawings/DrawingsScreen.cs +++ b/osu.Game.Tournament/Screens/Drawings/DrawingsScreen.cs @@ -24,7 +24,7 @@ using osuTK.Graphics; namespace osu.Game.Tournament.Screens.Drawings { - public class DrawingsScreen : TournamentScreen + public partial class DrawingsScreen : TournamentScreen { private const string results_filename = "drawings_results.txt"; diff --git a/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs index 4261828df2..4ee3108034 100644 --- a/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/LadderEditorScreen.cs @@ -23,7 +23,7 @@ using osuTK.Graphics; namespace osu.Game.Tournament.Screens.Editors { [Cached] - public class LadderEditorScreen : LadderScreen, IHasContextMenu + public partial class LadderEditorScreen : LadderScreen, IHasContextMenu { [Cached] private LadderEditorInfo editorInfo = new LadderEditorInfo(); @@ -86,7 +86,7 @@ namespace osu.Game.Tournament.Screens.Editors MatchesContainer.FirstOrDefault(p => p.Match == match)?.Remove(); } - private class JoinVisualiser : CompositeDrawable + private partial class JoinVisualiser : CompositeDrawable { private readonly Container matchesContainer; public readonly TournamentMatch Source; diff --git a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs index 0bd5ddb257..75131c282d 100644 --- a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs @@ -20,11 +20,11 @@ using osuTK; namespace osu.Game.Tournament.Screens.Editors { - public class RoundEditorScreen : TournamentEditorScreen + public partial class RoundEditorScreen : TournamentEditorScreen { protected override BindableList Storage => LadderInfo.Rounds; - public class RoundRow : CompositeDrawable, IModelBacked + public partial class RoundRow : CompositeDrawable, IModelBacked { public TournamentRound Model { get; } @@ -113,7 +113,7 @@ namespace osu.Game.Tournament.Screens.Editors AutoSizeAxes = Axes.Y; } - public class RoundBeatmapEditor : CompositeDrawable + public partial class RoundBeatmapEditor : CompositeDrawable { private readonly TournamentRound round; private readonly FillFlowContainer flow; @@ -141,7 +141,7 @@ namespace osu.Game.Tournament.Screens.Editors flow.Add(new RoundBeatmapRow(round, user)); } - public class RoundBeatmapRow : CompositeDrawable + public partial class RoundBeatmapRow : CompositeDrawable { public RoundBeatmap Model { get; } diff --git a/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs index 348661e2a3..a4358b4396 100644 --- a/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Tournament.Screens.Editors { - public class SeedingEditorScreen : TournamentEditorScreen + public partial class SeedingEditorScreen : TournamentEditorScreen { private readonly TournamentTeam team; @@ -32,7 +32,7 @@ namespace osu.Game.Tournament.Screens.Editors this.team = team; } - public class SeedingResultRow : CompositeDrawable, IModelBacked + public partial class SeedingResultRow : CompositeDrawable, IModelBacked { public SeedingResult Model { get; } @@ -106,7 +106,7 @@ namespace osu.Game.Tournament.Screens.Editors AutoSizeAxes = Axes.Y; } - public class SeedingBeatmapEditor : CompositeDrawable + public partial class SeedingBeatmapEditor : CompositeDrawable { private readonly SeedingResult round; private readonly FillFlowContainer flow; @@ -134,7 +134,7 @@ namespace osu.Game.Tournament.Screens.Editors flow.Add(new SeedingBeatmapRow(round, user)); } - public class SeedingBeatmapRow : CompositeDrawable + public partial class SeedingBeatmapRow : CompositeDrawable { private readonly SeedingResult result; public SeedingBeatmap Model { get; } diff --git a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs index da27c09e01..988f0a02f0 100644 --- a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs @@ -23,7 +23,7 @@ using osuTK; namespace osu.Game.Tournament.Screens.Editors { - public class TeamEditorScreen : TournamentEditorScreen + public partial class TeamEditorScreen : TournamentEditorScreen { protected override BindableList Storage => LadderInfo.Teams; @@ -60,7 +60,7 @@ namespace osu.Game.Tournament.Screens.Editors Storage.Add(c); } - public class TeamRow : CompositeDrawable, IModelBacked + public partial class TeamRow : CompositeDrawable, IModelBacked { public TournamentTeam Model { get; } @@ -181,7 +181,7 @@ namespace osu.Game.Tournament.Screens.Editors drawableContainer.Child = new DrawableTeamFlag(Model); } - public class PlayerEditor : CompositeDrawable + public partial class PlayerEditor : CompositeDrawable { private readonly TournamentTeam team; private readonly FillFlowContainer flow; @@ -209,7 +209,7 @@ namespace osu.Game.Tournament.Screens.Editors flow.Add(new PlayerRow(team, player)); } - public class PlayerRow : CompositeDrawable + public partial class PlayerRow : CompositeDrawable { private readonly TournamentUser user; diff --git a/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs index 8c55026c67..8f0d1de0cb 100644 --- a/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Tournament.Screens.Editors { - public abstract class TournamentEditorScreen : TournamentScreen + public abstract partial class TournamentEditorScreen : TournamentScreen where TDrawable : Drawable, IModelBacked where TModel : class, new() { diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs b/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs index 91a75bf86f..8f7484980d 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/MatchHeader.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Tournament.Screens.Gameplay.Components { - public class MatchHeader : Container + public partial class MatchHeader : Container { private TeamScoreDisplay teamDisplay1; private TeamScoreDisplay teamDisplay2; diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/MatchRoundDisplay.cs b/osu.Game.Tournament/Screens/Gameplay/Components/MatchRoundDisplay.cs index 78206c6d47..d2b61220f0 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/MatchRoundDisplay.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/MatchRoundDisplay.cs @@ -10,7 +10,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Screens.Gameplay.Components { - public class MatchRoundDisplay : TournamentSpriteTextWithBackground + public partial class MatchRoundDisplay : TournamentSpriteTextWithBackground { private readonly Bindable currentMatch = new Bindable(); diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/TeamDisplay.cs b/osu.Game.Tournament/Screens/Gameplay/Components/TeamDisplay.cs index 1eceddd871..60d1678326 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/TeamDisplay.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/TeamDisplay.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Tournament.Screens.Gameplay.Components { - public class TeamDisplay : DrawableTournamentTeam + public partial class TeamDisplay : DrawableTournamentTeam { private readonly TeamScore score; diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/TeamScore.cs b/osu.Game.Tournament/Screens/Gameplay/Components/TeamScore.cs index 3fa06c16b4..8b3786fa1f 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/TeamScore.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/TeamScore.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Tournament.Screens.Gameplay.Components { - public class TeamScore : CompositeDrawable + public partial class TeamScore : CompositeDrawable { private readonly Bindable currentTeamScore = new Bindable(); private readonly StarCounter counter; @@ -41,7 +41,7 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components private void scoreChanged(ValueChangedEvent score) => counter.Current = score.NewValue ?? 0; - public class TeamScoreStarCounter : StarCounter + public partial class TeamScoreStarCounter : StarCounter { public TeamScoreStarCounter(int count) : base(count) @@ -50,7 +50,7 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components public override Star CreateStar() => new LightSquare(); - public class LightSquare : Star + public partial class LightSquare : Star { private readonly Box box; diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/TeamScoreDisplay.cs b/osu.Game.Tournament/Screens/Gameplay/Components/TeamScoreDisplay.cs index 0fa5884603..57fe1c7312 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/TeamScoreDisplay.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/TeamScoreDisplay.cs @@ -13,7 +13,7 @@ using osuTK.Input; namespace osu.Game.Tournament.Screens.Gameplay.Components { - public class TeamScoreDisplay : CompositeDrawable + public partial class TeamScoreDisplay : CompositeDrawable { private readonly TeamColour teamColour; diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/TournamentMatchScoreDisplay.cs b/osu.Game.Tournament/Screens/Gameplay/Components/TournamentMatchScoreDisplay.cs index 7454d22aa2..bd1f3a2dd0 100644 --- a/osu.Game.Tournament/Screens/Gameplay/Components/TournamentMatchScoreDisplay.cs +++ b/osu.Game.Tournament/Screens/Gameplay/Components/TournamentMatchScoreDisplay.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Tournament.Screens.Gameplay.Components { // TODO: Update to derive from osu-side class? - public class TournamentMatchScoreDisplay : CompositeDrawable + public partial class TournamentMatchScoreDisplay : CompositeDrawable { private const float bar_height = 18; @@ -128,7 +128,7 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components score2Text.X = Math.Max(5 + score2Text.DrawWidth / 2, score2Bar.DrawWidth); } - private class MatchScoreCounter : CommaSeparatedScoreCounter + private partial class MatchScoreCounter : CommaSeparatedScoreCounter { private OsuSpriteText displayedSpriteText; diff --git a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs index 8a23ee65da..f2a2e97bcc 100644 --- a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs +++ b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs @@ -21,7 +21,7 @@ using osuTK.Graphics; namespace osu.Game.Tournament.Screens.Gameplay { - public class GameplayScreen : BeatmapInfoScreen + public partial class GameplayScreen : BeatmapInfoScreen { private readonly BindableBool warmup = new BindableBool(); @@ -232,7 +232,7 @@ namespace osu.Game.Tournament.Screens.Gameplay } } - private class ChromaArea : CompositeDrawable + private partial class ChromaArea : CompositeDrawable { [Resolved] private LadderInfo ladder { get; set; } diff --git a/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs b/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs index c005e11efe..2b66df1a31 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs @@ -24,7 +24,7 @@ using osuTK.Input; namespace osu.Game.Tournament.Screens.Ladder.Components { - public class DrawableMatchTeam : DrawableTournamentTeam, IHasContextMenu + public partial class DrawableMatchTeam : DrawableTournamentTeam, IHasContextMenu { private readonly TournamentMatch match; private readonly bool losers; diff --git a/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs b/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs index ed8b789387..33e383482f 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentMatch.cs @@ -19,7 +19,7 @@ using osuTK.Input; namespace osu.Game.Tournament.Screens.Ladder.Components { - public class DrawableTournamentMatch : CompositeDrawable + public partial class DrawableTournamentMatch : CompositeDrawable { public readonly TournamentMatch Match; private readonly bool editor; diff --git a/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentRound.cs b/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentRound.cs index 466b9ed482..4b2a29247b 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentRound.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/DrawableTournamentRound.cs @@ -12,7 +12,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Screens.Ladder.Components { - public class DrawableTournamentRound : CompositeDrawable + public partial class DrawableTournamentRound : CompositeDrawable { [UsedImplicitly] private readonly Bindable name; diff --git a/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs b/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs index 1fdf616e34..603a7830c7 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs @@ -18,7 +18,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Screens.Ladder.Components { - public class LadderEditorSettings : PlayerSettingsGroup + public partial class LadderEditorSettings : PlayerSettingsGroup { private const int padding = 10; @@ -89,7 +89,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components { } - private class SettingsRoundDropdown : SettingsDropdown + private partial class SettingsRoundDropdown : SettingsDropdown { public SettingsRoundDropdown(BindableList rounds) { diff --git a/osu.Game.Tournament/Screens/Ladder/Components/ProgressionPath.cs b/osu.Game.Tournament/Screens/Ladder/Components/ProgressionPath.cs index c5f8c3bb51..c79dbc26be 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/ProgressionPath.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/ProgressionPath.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Tournament.Screens.Ladder.Components { - public class ProgressionPath : Path + public partial class ProgressionPath : Path { public DrawableTournamentMatch Source { get; } public DrawableTournamentMatch Destination { get; } diff --git a/osu.Game.Tournament/Screens/Ladder/Components/SettingsTeamDropdown.cs b/osu.Game.Tournament/Screens/Ladder/Components/SettingsTeamDropdown.cs index 74424783c6..c90cdb7775 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/SettingsTeamDropdown.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/SettingsTeamDropdown.cs @@ -13,7 +13,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Screens.Ladder.Components { - public class SettingsTeamDropdown : SettingsDropdown + public partial class SettingsTeamDropdown : SettingsDropdown { public SettingsTeamDropdown(BindableList teams) { diff --git a/osu.Game.Tournament/Screens/Ladder/LadderDragContainer.cs b/osu.Game.Tournament/Screens/Ladder/LadderDragContainer.cs index 6fae44de35..10d58612f4 100644 --- a/osu.Game.Tournament/Screens/Ladder/LadderDragContainer.cs +++ b/osu.Game.Tournament/Screens/Ladder/LadderDragContainer.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Tournament.Screens.Ladder { - public class LadderDragContainer : Container + public partial class LadderDragContainer : Container { protected override bool OnDragStart(DragStartEvent e) => true; diff --git a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs index 7ad7e76a1f..595f08ed36 100644 --- a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs +++ b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Tournament.Screens.Ladder { - public class LadderScreen : TournamentScreen + public partial class LadderScreen : TournamentScreen { protected Container MatchesContainer; private Container paths; diff --git a/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs b/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs index decd723814..f0e34d78c3 100644 --- a/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs +++ b/osu.Game.Tournament/Screens/MapPool/MapPoolScreen.cs @@ -22,7 +22,7 @@ using osuTK.Input; namespace osu.Game.Tournament.Screens.MapPool { - public class MapPoolScreen : TournamentMatchScreen + public partial class MapPoolScreen : TournamentMatchScreen { private readonly FillFlowContainer> mapFlows; diff --git a/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs b/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs index 0827cbae69..8d5547c749 100644 --- a/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs +++ b/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Tournament.Screens.Schedule { - public class ScheduleScreen : TournamentScreen + public partial class ScheduleScreen : TournamentScreen { private readonly Bindable currentMatch = new Bindable(); private Container mainContainer; @@ -209,7 +209,7 @@ namespace osu.Game.Tournament.Screens.Schedule } } - public class ScheduleMatch : DrawableTournamentMatch + public partial class ScheduleMatch : DrawableTournamentMatch { public ScheduleMatch(TournamentMatch match, bool showTimestamp = true) : base(match) @@ -249,7 +249,7 @@ namespace osu.Game.Tournament.Screens.Schedule } } - public class ScheduleMatchDate : DrawableDate + public partial class ScheduleMatchDate : DrawableDate { public ScheduleMatchDate(DateTimeOffset date, float textSize = OsuFont.DEFAULT_FONT_SIZE, bool italic = true) : base(date, textSize, italic) @@ -261,7 +261,7 @@ namespace osu.Game.Tournament.Screens.Schedule : $"Starting {base.Format()}"; } - public class ScheduleContainer : Container + public partial class ScheduleContainer : Container { protected override Container Content => content; diff --git a/osu.Game.Tournament/Screens/Setup/ActionableInfo.cs b/osu.Game.Tournament/Screens/Setup/ActionableInfo.cs index a9ac21284e..639cca23b1 100644 --- a/osu.Game.Tournament/Screens/Setup/ActionableInfo.cs +++ b/osu.Game.Tournament/Screens/Setup/ActionableInfo.cs @@ -13,7 +13,7 @@ using osuTK.Graphics; namespace osu.Game.Tournament.Screens.Setup { - internal class ActionableInfo : LabelledDrawable + internal partial class ActionableInfo : LabelledDrawable { protected OsuButton Button; diff --git a/osu.Game.Tournament/Screens/Setup/ResolutionSelector.cs b/osu.Game.Tournament/Screens/Setup/ResolutionSelector.cs index a387341d66..e6ab6f143a 100644 --- a/osu.Game.Tournament/Screens/Setup/ResolutionSelector.cs +++ b/osu.Game.Tournament/Screens/Setup/ResolutionSelector.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Tournament.Screens.Setup { - internal class ResolutionSelector : ActionableInfo + internal partial class ResolutionSelector : ActionableInfo { private const int minimum_window_height = 480; private const int maximum_window_height = 2160; diff --git a/osu.Game.Tournament/Screens/Setup/SetupScreen.cs b/osu.Game.Tournament/Screens/Setup/SetupScreen.cs index ff781dec80..b86513eb49 100644 --- a/osu.Game.Tournament/Screens/Setup/SetupScreen.cs +++ b/osu.Game.Tournament/Screens/Setup/SetupScreen.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Tournament.Screens.Setup { - public class SetupScreen : TournamentScreen + public partial class SetupScreen : TournamentScreen { private FillFlowContainer fillFlow; diff --git a/osu.Game.Tournament/Screens/Setup/StablePathSelectScreen.cs b/osu.Game.Tournament/Screens/Setup/StablePathSelectScreen.cs index fac488fcf5..49f60156b6 100644 --- a/osu.Game.Tournament/Screens/Setup/StablePathSelectScreen.cs +++ b/osu.Game.Tournament/Screens/Setup/StablePathSelectScreen.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Tournament.Screens.Setup { - public class StablePathSelectScreen : TournamentScreen + public partial class StablePathSelectScreen : TournamentScreen { [Resolved(canBeNull: true)] private TournamentSceneManager sceneManager { get; set; } diff --git a/osu.Game.Tournament/Screens/Setup/TournamentSwitcher.cs b/osu.Game.Tournament/Screens/Setup/TournamentSwitcher.cs index 447d6f44ce..ff98d044f8 100644 --- a/osu.Game.Tournament/Screens/Setup/TournamentSwitcher.cs +++ b/osu.Game.Tournament/Screens/Setup/TournamentSwitcher.cs @@ -10,7 +10,7 @@ using osu.Game.Tournament.IO; namespace osu.Game.Tournament.Screens.Setup { - internal class TournamentSwitcher : ActionableInfo + internal partial class TournamentSwitcher : ActionableInfo { private OsuDropdown dropdown; private OsuButton folderButton; diff --git a/osu.Game.Tournament/Screens/Showcase/ShowcaseScreen.cs b/osu.Game.Tournament/Screens/Showcase/ShowcaseScreen.cs index a7a175ceba..35d63f4fcf 100644 --- a/osu.Game.Tournament/Screens/Showcase/ShowcaseScreen.cs +++ b/osu.Game.Tournament/Screens/Showcase/ShowcaseScreen.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Tournament.Screens.Showcase { - public class ShowcaseScreen : BeatmapInfoScreen + public partial class ShowcaseScreen : BeatmapInfoScreen { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tournament/Screens/Showcase/TournamentLogo.cs b/osu.Game.Tournament/Screens/Showcase/TournamentLogo.cs index 07a632ec72..d04059118f 100644 --- a/osu.Game.Tournament/Screens/Showcase/TournamentLogo.cs +++ b/osu.Game.Tournament/Screens/Showcase/TournamentLogo.cs @@ -11,7 +11,7 @@ using osu.Framework.Graphics.Textures; namespace osu.Game.Tournament.Screens.Showcase { - public class TournamentLogo : CompositeDrawable + public partial class TournamentLogo : CompositeDrawable { public TournamentLogo() { diff --git a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs index ba75b6a2ed..b07a0a65dd 100644 --- a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs +++ b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Tournament.Screens.TeamIntro { - public class SeedingScreen : TournamentMatchScreen + public partial class SeedingScreen : TournamentMatchScreen { private Container mainContainer; @@ -116,7 +116,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro }; }); - private class RightInfo : CompositeDrawable + private partial class RightInfo : CompositeDrawable { public RightInfo(TournamentTeam team) { @@ -148,7 +148,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro } } - private class BeatmapScoreRow : CompositeDrawable + private partial class BeatmapScoreRow : CompositeDrawable { public BeatmapScoreRow(SeedingBeatmap beatmap) { @@ -190,7 +190,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro } } - private class ModRow : CompositeDrawable + private partial class ModRow : CompositeDrawable { private readonly string mods; private readonly int seeding; @@ -254,7 +254,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro } } - private class LeftInfo : CompositeDrawable + private partial class LeftInfo : CompositeDrawable { public LeftInfo(TournamentTeam team) { @@ -286,7 +286,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro fill.Add(new RowDisplay(p.Username, p.Rank?.ToString("\\##,0") ?? "-")); } - internal class RowDisplay : CompositeDrawable + internal partial class RowDisplay : CompositeDrawable { public RowDisplay(string left, string right) { @@ -313,7 +313,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro } } - private class TeamDisplay : DrawableTournamentTeam + private partial class TeamDisplay : DrawableTournamentTeam { public TeamDisplay(TournamentTeam team) : base(team) diff --git a/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs index 08c9a7a897..950a63808c 100644 --- a/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs +++ b/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Tournament.Screens.TeamIntro { - public class TeamIntroScreen : TournamentMatchScreen + public partial class TeamIntroScreen : TournamentMatchScreen { private Container mainContainer; diff --git a/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs b/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs index ac54ff58f5..9206de1dc2 100644 --- a/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs +++ b/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Tournament.Screens.TeamWin { - public class TeamWinScreen : TournamentMatchScreen + public partial class TeamWinScreen : TournamentMatchScreen { private Container mainContainer; diff --git a/osu.Game.Tournament/Screens/TournamentMatchScreen.cs b/osu.Game.Tournament/Screens/TournamentMatchScreen.cs index 585cdd09c1..58444d0c1b 100644 --- a/osu.Game.Tournament/Screens/TournamentMatchScreen.cs +++ b/osu.Game.Tournament/Screens/TournamentMatchScreen.cs @@ -8,7 +8,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Screens { - public abstract class TournamentMatchScreen : TournamentScreen + public abstract partial class TournamentMatchScreen : TournamentScreen { protected readonly Bindable CurrentMatch = new Bindable(); private WarningBox noMatchWarning; diff --git a/osu.Game.Tournament/Screens/TournamentScreen.cs b/osu.Game.Tournament/Screens/TournamentScreen.cs index b4641fa45d..02903a637c 100644 --- a/osu.Game.Tournament/Screens/TournamentScreen.cs +++ b/osu.Game.Tournament/Screens/TournamentScreen.cs @@ -10,7 +10,7 @@ using osu.Game.Tournament.Models; namespace osu.Game.Tournament.Screens { - public abstract class TournamentScreen : CompositeDrawable + public abstract partial class TournamentScreen : CompositeDrawable { public const double FADE_DELAY = 200; diff --git a/osu.Game.Tournament/TournamentGame.cs b/osu.Game.Tournament/TournamentGame.cs index 7d67bfa759..beef1e197d 100644 --- a/osu.Game.Tournament/TournamentGame.cs +++ b/osu.Game.Tournament/TournamentGame.cs @@ -23,7 +23,7 @@ using osuTK.Graphics; namespace osu.Game.Tournament { [Cached] - public class TournamentGame : TournamentGameBase + public partial class TournamentGame : TournamentGameBase { public static ColourInfo GetTeamColour(TeamColour teamColour) => teamColour == TeamColour.Red ? COLOUR_RED : COLOUR_BLUE; diff --git a/osu.Game.Tournament/TournamentGameBase.cs b/osu.Game.Tournament/TournamentGameBase.cs index 98ba3ca60f..08f21cb556 100644 --- a/osu.Game.Tournament/TournamentGameBase.cs +++ b/osu.Game.Tournament/TournamentGameBase.cs @@ -27,7 +27,7 @@ using osuTK.Input; namespace osu.Game.Tournament { [Cached(typeof(TournamentGameBase))] - public class TournamentGameBase : OsuGameBase + public partial class TournamentGameBase : OsuGameBase { public const string BRACKET_FILENAME = @"bracket.json"; private LadderInfo ladder; @@ -335,7 +335,7 @@ namespace osu.Game.Tournament protected override UserInputManager CreateUserInputManager() => new TournamentInputManager(); - private class TournamentInputManager : UserInputManager + private partial class TournamentInputManager : UserInputManager { protected override MouseButtonEventManager CreateButtonEventManagerFor(MouseButton button) { diff --git a/osu.Game.Tournament/TournamentSceneManager.cs b/osu.Game.Tournament/TournamentSceneManager.cs index a12dbb4740..abfe69b97b 100644 --- a/osu.Game.Tournament/TournamentSceneManager.cs +++ b/osu.Game.Tournament/TournamentSceneManager.cs @@ -33,7 +33,7 @@ using osuTK.Input; namespace osu.Game.Tournament { [Cached] - public class TournamentSceneManager : CompositeDrawable + public partial class TournamentSceneManager : CompositeDrawable { private Container screens; private TourneyVideo video; @@ -224,7 +224,7 @@ namespace osu.Game.Tournament s.IsSelected = screenType == s.Type; } - private class Separator : CompositeDrawable + private partial class Separator : CompositeDrawable { public Separator() { @@ -233,7 +233,7 @@ namespace osu.Game.Tournament } } - private class ScreenButton : TourneyButton + private partial class ScreenButton : TourneyButton { public readonly Type Type; diff --git a/osu.Game.Tournament/TournamentSpriteText.cs b/osu.Game.Tournament/TournamentSpriteText.cs index 166a8dfaf0..7ecb31ff15 100644 --- a/osu.Game.Tournament/TournamentSpriteText.cs +++ b/osu.Game.Tournament/TournamentSpriteText.cs @@ -8,7 +8,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Tournament { - public class TournamentSpriteText : OsuSpriteText + public partial class TournamentSpriteText : OsuSpriteText { public TournamentSpriteText() { diff --git a/osu.Game.Tournament/TourneyButton.cs b/osu.Game.Tournament/TourneyButton.cs index f1b14df783..558bd476c3 100644 --- a/osu.Game.Tournament/TourneyButton.cs +++ b/osu.Game.Tournament/TourneyButton.cs @@ -8,7 +8,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Tournament { - public class TourneyButton : OsuButton + public partial class TourneyButton : OsuButton { public new Box Background => base.Background; diff --git a/osu.Game.Tournament/WarningBox.cs b/osu.Game.Tournament/WarningBox.cs index 123e78113a..4a196446f6 100644 --- a/osu.Game.Tournament/WarningBox.cs +++ b/osu.Game.Tournament/WarningBox.cs @@ -11,7 +11,7 @@ using osuTK.Graphics; namespace osu.Game.Tournament { - internal class WarningBox : Container + internal partial class WarningBox : Container { public WarningBox(string text) { diff --git a/osu.Game/Audio/Effects/AudioFilter.cs b/osu.Game/Audio/Effects/AudioFilter.cs index 9446967173..682ca4ca7b 100644 --- a/osu.Game/Audio/Effects/AudioFilter.cs +++ b/osu.Game/Audio/Effects/AudioFilter.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics; namespace osu.Game.Audio.Effects { - public class AudioFilter : Component, ITransformableFilter + public partial class AudioFilter : Component, ITransformableFilter { /// /// The maximum cutoff frequency that can be used with a low-pass filter. diff --git a/osu.Game/Audio/PreviewTrack.cs b/osu.Game/Audio/PreviewTrack.cs index 2409ca6eb6..ea226ab650 100644 --- a/osu.Game/Audio/PreviewTrack.cs +++ b/osu.Game/Audio/PreviewTrack.cs @@ -10,7 +10,7 @@ using osu.Framework.Threading; namespace osu.Game.Audio { [LongRunningLoad] - public abstract class PreviewTrack : Component + public abstract partial class PreviewTrack : Component { /// /// Invoked when this has stopped playing. diff --git a/osu.Game/Audio/PreviewTrackManager.cs b/osu.Game/Audio/PreviewTrackManager.cs index b8662b6a4b..1d710e6395 100644 --- a/osu.Game/Audio/PreviewTrackManager.cs +++ b/osu.Game/Audio/PreviewTrackManager.cs @@ -12,7 +12,7 @@ using osu.Game.Beatmaps; namespace osu.Game.Audio { - public class PreviewTrackManager : Component + public partial class PreviewTrackManager : Component { private readonly IAdjustableAudioComponent mainTrackAdjustments; @@ -85,7 +85,7 @@ namespace osu.Game.Audio protected virtual TrackManagerPreviewTrack CreatePreviewTrack(IBeatmapSetInfo beatmapSetInfo, ITrackStore trackStore) => new TrackManagerPreviewTrack(beatmapSetInfo, trackStore); - public class TrackManagerPreviewTrack : PreviewTrack + public partial class TrackManagerPreviewTrack : PreviewTrack { [Resolved] public IPreviewTrackOwner? Owner { get; private set; } diff --git a/osu.Game/BackgroundBeatmapProcessor.cs b/osu.Game/BackgroundBeatmapProcessor.cs index ea5904a8d3..b8c89d8822 100644 --- a/osu.Game/BackgroundBeatmapProcessor.cs +++ b/osu.Game/BackgroundBeatmapProcessor.cs @@ -20,7 +20,7 @@ using osu.Game.Screens.Play; namespace osu.Game { - public class BackgroundBeatmapProcessor : Component + public partial class BackgroundBeatmapProcessor : Component { [Resolved] private RulesetStore rulesetStore { get; set; } = null!; diff --git a/osu.Game/Beatmaps/BeatmapDifficultyCache.cs b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs index bf7b980e75..871faf5906 100644 --- a/osu.Game/Beatmaps/BeatmapDifficultyCache.cs +++ b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs @@ -26,7 +26,7 @@ namespace osu.Game.Beatmaps /// A component which performs and acts as a central cache for difficulty calculations of beatmap/ruleset/mod combinations. /// Currently not persisted between game sessions. /// - public class BeatmapDifficultyCache : MemoryCachingComponent + public partial class BeatmapDifficultyCache : MemoryCachingComponent { // Too many simultaneous updates can lead to stutters. One thread seems to work fine for song select display purposes. private readonly ThreadedTaskScheduler updateScheduler = new ThreadedTaskScheduler(1, nameof(BeatmapDifficultyCache)); diff --git a/osu.Game/Beatmaps/BeatmapOnlineChangeIngest.cs b/osu.Game/Beatmaps/BeatmapOnlineChangeIngest.cs index 5d0765641b..98aefd75d3 100644 --- a/osu.Game/Beatmaps/BeatmapOnlineChangeIngest.cs +++ b/osu.Game/Beatmaps/BeatmapOnlineChangeIngest.cs @@ -11,7 +11,7 @@ namespace osu.Game.Beatmaps /// /// Ingests any changes that happen externally to the client, reprocessing as required. /// - public class BeatmapOnlineChangeIngest : Component + public partial class BeatmapOnlineChangeIngest : Component { private readonly BeatmapUpdater beatmapUpdater; private readonly RealmAccess realm; diff --git a/osu.Game/Beatmaps/BeatmapStatisticIcon.cs b/osu.Game/Beatmaps/BeatmapStatisticIcon.cs index 8002910b52..ca07e5f365 100644 --- a/osu.Game/Beatmaps/BeatmapStatisticIcon.cs +++ b/osu.Game/Beatmaps/BeatmapStatisticIcon.cs @@ -13,7 +13,7 @@ namespace osu.Game.Beatmaps /// /// A default implementation of an icon used to represent beatmap statistics. /// - public class BeatmapStatisticIcon : Sprite + public partial class BeatmapStatisticIcon : Sprite { private readonly BeatmapStatisticsIconType iconType; diff --git a/osu.Game/Beatmaps/DifficultyRecommender.cs b/osu.Game/Beatmaps/DifficultyRecommender.cs index ed2d6cd3a8..7a23b32c84 100644 --- a/osu.Game/Beatmaps/DifficultyRecommender.cs +++ b/osu.Game/Beatmaps/DifficultyRecommender.cs @@ -19,7 +19,7 @@ namespace osu.Game.Beatmaps /// A class which will recommend the most suitable difficulty for the local user from a beatmap set. /// This requires the user to be logged in, as it sources from the user's online profile. /// - public class DifficultyRecommender : Component + public partial class DifficultyRecommender : Component { [Resolved] private IAPIProvider api { get; set; } diff --git a/osu.Game/Beatmaps/Drawables/BeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/BeatmapBackgroundSprite.cs index 4ba16839f5..d31a7ae2fe 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapBackgroundSprite.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics.Sprites; namespace osu.Game.Beatmaps.Drawables { - public class BeatmapBackgroundSprite : Sprite + public partial class BeatmapBackgroundSprite : Sprite { private readonly IWorkingBeatmap working; diff --git a/osu.Game/Beatmaps/Drawables/BeatmapDownloadButton.cs b/osu.Game/Beatmaps/Drawables/BeatmapDownloadButton.cs index 4dd3a56244..cf27023a9c 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapDownloadButton.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapDownloadButton.cs @@ -18,7 +18,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Beatmaps.Drawables { - public class BeatmapDownloadButton : CompositeDrawable + public partial class BeatmapDownloadButton : CompositeDrawable { protected bool DownloadEnabled => button.Enabled.Value; diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetOnlineStatusPill.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetOnlineStatusPill.cs index 23d90ab76e..c353b9e904 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapSetOnlineStatusPill.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapSetOnlineStatusPill.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Beatmaps.Drawables { - public class BeatmapSetOnlineStatusPill : CircularContainer, IHasTooltip + public partial class BeatmapSetOnlineStatusPill : CircularContainer, IHasTooltip { private BeatmapOnlineStatus status; diff --git a/osu.Game/Beatmaps/Drawables/BundledBeatmapDownloader.cs b/osu.Game/Beatmaps/Drawables/BundledBeatmapDownloader.cs index 053ac8fc17..21ab1b78ea 100644 --- a/osu.Game/Beatmaps/Drawables/BundledBeatmapDownloader.cs +++ b/osu.Game/Beatmaps/Drawables/BundledBeatmapDownloader.cs @@ -21,7 +21,7 @@ using osu.Game.Utils; namespace osu.Game.Beatmaps.Drawables { - public class BundledBeatmapDownloader : CompositeDrawable + public partial class BundledBeatmapDownloader : CompositeDrawable { private readonly bool shouldPostNotifications; diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs index b9e0a4e6cb..00f9a6b3d5 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays; namespace osu.Game.Beatmaps.Drawables.Cards { - public abstract class BeatmapCard : OsuClickableContainer + public abstract partial class BeatmapCard : OsuClickableContainer { public const float TRANSITION_DURATION = 400; public const float CORNER_RADIUS = 10; diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs index bfec391b1d..d4cbe6ddd0 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Beatmaps.Drawables.Cards { - public class BeatmapCardContent : CompositeDrawable + public partial class BeatmapCardContent : CompositeDrawable { public Drawable MainContent { diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContentBackground.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContentBackground.cs index 64a28c5394..deb56bb281 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContentBackground.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContentBackground.cs @@ -11,7 +11,7 @@ using osu.Game.Overlays; namespace osu.Game.Beatmaps.Drawables.Cards { - public class BeatmapCardContentBackground : CompositeDrawable + public partial class BeatmapCardContentBackground : CompositeDrawable { public BindableBool Dimmed { get; } = new BindableBool(); diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardDifficultyList.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardDifficultyList.cs index 9489116530..84445dc14c 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardDifficultyList.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardDifficultyList.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Beatmaps.Drawables.Cards { - public class BeatmapCardDifficultyList : CompositeDrawable + public partial class BeatmapCardDifficultyList : CompositeDrawable { public BeatmapCardDifficultyList(IBeatmapSetInfo beatmapSetInfo) { @@ -53,7 +53,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards } } - private class BeatmapCardDifficultyRow : CompositeDrawable + private partial class BeatmapCardDifficultyRow : CompositeDrawable { private readonly IBeatmapInfo beatmapInfo; diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardDownloadProgressBar.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardDownloadProgressBar.cs index d55622d7aa..3737715a7d 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardDownloadProgressBar.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardDownloadProgressBar.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays; namespace osu.Game.Beatmaps.Drawables.Cards { - public class BeatmapCardDownloadProgressBar : CompositeDrawable + public partial class BeatmapCardDownloadProgressBar : CompositeDrawable { public IBindable State => state; private readonly Bindable state = new Bindable(); diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs index 646c990564..5c6f0c4ee1 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs @@ -17,7 +17,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Beatmaps.Drawables.Cards { - public class BeatmapCardExtra : BeatmapCard + public partial class BeatmapCardExtra : BeatmapCard { protected override Drawable IdleContent => idleBottomContent; protected override Drawable DownloadInProgressContent => downloadProgressBar; diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtraInfoRow.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtraInfoRow.cs index 7ba677e5dc..3a1b8f7e86 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtraInfoRow.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtraInfoRow.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Beatmaps.Drawables.Cards { - public class BeatmapCardExtraInfoRow : CompositeDrawable + public partial class BeatmapCardExtraInfoRow : CompositeDrawable { [Resolved(CanBeNull = true)] private BeatmapCardContent? content { get; set; } diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs index addc88700c..720d892495 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs @@ -18,7 +18,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Beatmaps.Drawables.Cards { - public class BeatmapCardNormal : BeatmapCard + public partial class BeatmapCardNormal : BeatmapCard { protected override Drawable IdleContent => idleBottomContent; protected override Drawable DownloadInProgressContent => downloadProgressBar; diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardThumbnail.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardThumbnail.cs index 55d3f0b969..781133aac7 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardThumbnail.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardThumbnail.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Beatmaps.Drawables.Cards { - public class BeatmapCardThumbnail : Container + public partial class BeatmapCardThumbnail : Container { public BindableBool Dimmed { get; } = new BindableBool(); diff --git a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs index af1a8eb06a..ee45d56b6e 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Beatmaps.Drawables.Cards.Buttons { - public abstract class BeatmapCardIconButton : OsuClickableContainer + public abstract partial class BeatmapCardIconButton : OsuClickableContainer { private Colour4 idleColour; diff --git a/osu.Game/Beatmaps/Drawables/Cards/Buttons/DownloadButton.cs b/osu.Game/Beatmaps/Drawables/Cards/Buttons/DownloadButton.cs index 1b15b2498c..7f23b46150 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Buttons/DownloadButton.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Buttons/DownloadButton.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Beatmaps.Drawables.Cards.Buttons { - public class DownloadButton : BeatmapCardIconButton + public partial class DownloadButton : BeatmapCardIconButton { public Bindable State { get; } = new Bindable(); diff --git a/osu.Game/Beatmaps/Drawables/Cards/Buttons/FavouriteButton.cs b/osu.Game/Beatmaps/Drawables/Cards/Buttons/FavouriteButton.cs index bc0fcb92bb..f698185863 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Buttons/FavouriteButton.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Buttons/FavouriteButton.cs @@ -15,7 +15,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Beatmaps.Drawables.Cards.Buttons { - public class FavouriteButton : BeatmapCardIconButton, IHasCurrentValue + public partial class FavouriteButton : BeatmapCardIconButton, IHasCurrentValue { private readonly BindableWithCurrent current; diff --git a/osu.Game/Beatmaps/Drawables/Cards/Buttons/GoToBeatmapButton.cs b/osu.Game/Beatmaps/Drawables/Cards/Buttons/GoToBeatmapButton.cs index 127c5bd903..3df94bf233 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Buttons/GoToBeatmapButton.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Buttons/GoToBeatmapButton.cs @@ -10,7 +10,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Beatmaps.Drawables.Cards.Buttons { - public class GoToBeatmapButton : BeatmapCardIconButton + public partial class GoToBeatmapButton : BeatmapCardIconButton { public IBindable State => state; private readonly Bindable state = new Bindable(); diff --git a/osu.Game/Beatmaps/Drawables/Cards/Buttons/PlayButton.cs b/osu.Game/Beatmaps/Drawables/Cards/Buttons/PlayButton.cs index c5436182a4..f808fd21b7 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Buttons/PlayButton.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Buttons/PlayButton.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Beatmaps.Drawables.Cards.Buttons { - public class PlayButton : OsuHoverContainer + public partial class PlayButton : OsuHoverContainer { public IBindable Progress => progress; private readonly BindableDouble progress = new BindableDouble(); diff --git a/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs b/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs index 9b200d62aa..fe2ee8c7cc 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays; namespace osu.Game.Beatmaps.Drawables.Cards { - public class CollapsibleButtonContainer : Container + public partial class CollapsibleButtonContainer : Container { public Bindable ShowDetails = new Bindable(); public Bindable FavouriteState = new Bindable(); diff --git a/osu.Game/Beatmaps/Drawables/Cards/ExpandedContentScrollContainer.cs b/osu.Game/Beatmaps/Drawables/Cards/ExpandedContentScrollContainer.cs index c0ed6ac1a9..9a2a37a09a 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/ExpandedContentScrollContainer.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/ExpandedContentScrollContainer.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Beatmaps.Drawables.Cards { - public class ExpandedContentScrollContainer : OsuScrollContainer + public partial class ExpandedContentScrollContainer : OsuScrollContainer { public const float HEIGHT = 200; @@ -61,7 +61,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards protected override bool OnClick(ClickEvent e) => true; - private class ExpandedContentScrollbar : OsuScrollbar + private partial class ExpandedContentScrollbar : OsuScrollbar { public ExpandedContentScrollbar(Direction scrollDir) : base(scrollDir) diff --git a/osu.Game/Beatmaps/Drawables/Cards/HoverHandlingContainer.cs b/osu.Game/Beatmaps/Drawables/Cards/HoverHandlingContainer.cs index 7d70f3c4cd..91cd498b81 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/HoverHandlingContainer.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/HoverHandlingContainer.cs @@ -7,7 +7,7 @@ using osu.Framework.Input.Events; namespace osu.Game.Beatmaps.Drawables.Cards { - public class HoverHandlingContainer : Container + public partial class HoverHandlingContainer : Container { public Func? Hovered { get; set; } public Action? Unhovered { get; set; } diff --git a/osu.Game/Beatmaps/Drawables/Cards/IconPill.cs b/osu.Game/Beatmaps/Drawables/Cards/IconPill.cs index aad71610a5..3cabbba98d 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/IconPill.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/IconPill.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Beatmaps.Drawables.Cards { - public abstract class IconPill : CircularContainer, IHasTooltip + public abstract partial class IconPill : CircularContainer, IHasTooltip { public Vector2 IconSize { diff --git a/osu.Game/Beatmaps/Drawables/Cards/Statistics/BeatmapCardDateStatistic.cs b/osu.Game/Beatmaps/Drawables/Cards/Statistics/BeatmapCardDateStatistic.cs index f6fc3070aa..2948e89e60 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Statistics/BeatmapCardDateStatistic.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Statistics/BeatmapCardDateStatistic.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics; namespace osu.Game.Beatmaps.Drawables.Cards.Statistics { - public class BeatmapCardDateStatistic : BeatmapCardStatistic + public partial class BeatmapCardDateStatistic : BeatmapCardStatistic { private readonly DateTimeOffset dateTime; diff --git a/osu.Game/Beatmaps/Drawables/Cards/Statistics/BeatmapCardStatistic.cs b/osu.Game/Beatmaps/Drawables/Cards/Statistics/BeatmapCardStatistic.cs index 89a4687500..10de2b9128 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Statistics/BeatmapCardStatistic.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Statistics/BeatmapCardStatistic.cs @@ -19,7 +19,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Statistics /// /// A single statistic shown on a beatmap card. /// - public abstract class BeatmapCardStatistic : CompositeDrawable, IHasTooltip, IHasCustomTooltip + public abstract partial class BeatmapCardStatistic : CompositeDrawable, IHasTooltip, IHasCustomTooltip { protected IconUsage Icon { diff --git a/osu.Game/Beatmaps/Drawables/Cards/Statistics/FavouritesStatistic.cs b/osu.Game/Beatmaps/Drawables/Cards/Statistics/FavouritesStatistic.cs index cef1f630ed..439e6acd22 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Statistics/FavouritesStatistic.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Statistics/FavouritesStatistic.cs @@ -15,7 +15,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Statistics /// /// Shows the number of favourites that a beatmap set has received. /// - public class FavouritesStatistic : BeatmapCardStatistic, IHasCurrentValue + public partial class FavouritesStatistic : BeatmapCardStatistic, IHasCurrentValue { private readonly BindableWithCurrent current; diff --git a/osu.Game/Beatmaps/Drawables/Cards/Statistics/HypesStatistic.cs b/osu.Game/Beatmaps/Drawables/Cards/Statistics/HypesStatistic.cs index 26b90ba0c0..840763b58e 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Statistics/HypesStatistic.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Statistics/HypesStatistic.cs @@ -10,7 +10,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Statistics /// /// Shows the number of current hypes that a map has received, as well as the number of hypes required for nomination. /// - public class HypesStatistic : BeatmapCardStatistic + public partial class HypesStatistic : BeatmapCardStatistic { private HypesStatistic(BeatmapSetHypeStatus hypeStatus) { diff --git a/osu.Game/Beatmaps/Drawables/Cards/Statistics/NominationsStatistic.cs b/osu.Game/Beatmaps/Drawables/Cards/Statistics/NominationsStatistic.cs index 4f3605c138..083f1a353b 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Statistics/NominationsStatistic.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Statistics/NominationsStatistic.cs @@ -10,7 +10,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Statistics /// /// Shows the number of current nominations that a map has received, as well as the number of nominations required for qualification. /// - public class NominationsStatistic : BeatmapCardStatistic + public partial class NominationsStatistic : BeatmapCardStatistic { private NominationsStatistic(BeatmapSetNominationStatus nominationStatus) { diff --git a/osu.Game/Beatmaps/Drawables/Cards/Statistics/PlayCountStatistic.cs b/osu.Game/Beatmaps/Drawables/Cards/Statistics/PlayCountStatistic.cs index f66d51de5d..45ab6ddb40 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/Statistics/PlayCountStatistic.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/Statistics/PlayCountStatistic.cs @@ -13,7 +13,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Statistics /// /// Shows the number of times the given beatmap set has been played. /// - public class PlayCountStatistic : BeatmapCardStatistic + public partial class PlayCountStatistic : BeatmapCardStatistic { public PlayCountStatistic(IBeatmapSetOnlineInfo onlineInfo) { diff --git a/osu.Game/Beatmaps/Drawables/Cards/StoryboardIconPill.cs b/osu.Game/Beatmaps/Drawables/Cards/StoryboardIconPill.cs index dcb2c3c760..6de16da2b1 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/StoryboardIconPill.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/StoryboardIconPill.cs @@ -9,7 +9,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Beatmaps.Drawables.Cards { - public class StoryboardIconPill : IconPill + public partial class StoryboardIconPill : IconPill { public StoryboardIconPill() : base(FontAwesome.Solid.Image) diff --git a/osu.Game/Beatmaps/Drawables/Cards/VideoIconPill.cs b/osu.Game/Beatmaps/Drawables/Cards/VideoIconPill.cs index 9ca1e5c4c4..63b5e95b12 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/VideoIconPill.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/VideoIconPill.cs @@ -9,7 +9,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Beatmaps.Drawables.Cards { - public class VideoIconPill : IconPill + public partial class VideoIconPill : IconPill { public VideoIconPill() : base(FontAwesome.Solid.Film) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 679e9c3665..1665ec52fa 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Beatmaps.Drawables { - public class DifficultyIcon : CompositeDrawable, IHasCustomTooltip, IHasCurrentValue + public partial class DifficultyIcon : CompositeDrawable, IHasCustomTooltip, IHasCurrentValue { /// /// Size of this difficulty icon. diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs index 4732de6e79..3fa24bcc3e 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Beatmaps.Drawables { - internal class DifficultyIconTooltip : VisibilityContainer, ITooltip + internal partial class DifficultyIconTooltip : VisibilityContainer, ITooltip { private OsuSpriteText difficultyName; private StarRatingDisplay starRating; diff --git a/osu.Game/Beatmaps/Drawables/DifficultySpectrumDisplay.cs b/osu.Game/Beatmaps/Drawables/DifficultySpectrumDisplay.cs index 22ca0a9037..efce0f80f1 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultySpectrumDisplay.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultySpectrumDisplay.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Beatmaps.Drawables { - public class DifficultySpectrumDisplay : CompositeDrawable + public partial class DifficultySpectrumDisplay : CompositeDrawable { private Vector2 dotSize = new Vector2(4, 8); @@ -83,7 +83,7 @@ namespace osu.Game.Beatmaps.Drawables } } - private class RulesetDifficultyGroup : FillFlowContainer + private partial class RulesetDifficultyGroup : FillFlowContainer { private readonly int rulesetId; private readonly IEnumerable beatmapInfos; @@ -143,7 +143,7 @@ namespace osu.Game.Beatmaps.Drawables } } - private class DifficultyDot : CircularContainer + private partial class DifficultyDot : CircularContainer { private readonly double starDifficulty; diff --git a/osu.Game/Beatmaps/Drawables/DownloadProgressBar.cs b/osu.Game/Beatmaps/Drawables/DownloadProgressBar.cs index 50bd7ad48e..9877b628db 100644 --- a/osu.Game/Beatmaps/Drawables/DownloadProgressBar.cs +++ b/osu.Game/Beatmaps/Drawables/DownloadProgressBar.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Beatmaps.Drawables { - public class DownloadProgressBar : CompositeDrawable + public partial class DownloadProgressBar : CompositeDrawable { private readonly ProgressBar progressBar; private readonly BeatmapDownloadTracker downloadTracker; diff --git a/osu.Game/Beatmaps/Drawables/OnlineBeatmapSetCover.cs b/osu.Game/Beatmaps/Drawables/OnlineBeatmapSetCover.cs index 063990c89c..e4ffc1d553 100644 --- a/osu.Game/Beatmaps/Drawables/OnlineBeatmapSetCover.cs +++ b/osu.Game/Beatmaps/Drawables/OnlineBeatmapSetCover.cs @@ -11,7 +11,7 @@ using osu.Framework.Graphics.Textures; namespace osu.Game.Beatmaps.Drawables { [LongRunningLoad] - public class OnlineBeatmapSetCover : Sprite + public partial class OnlineBeatmapSetCover : Sprite { private readonly IBeatmapSetOnlineInfo set; private readonly BeatmapSetCoverType type; diff --git a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs index 9585f1bdb5..36fff1dc3c 100644 --- a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs +++ b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs @@ -23,7 +23,7 @@ namespace osu.Game.Beatmaps.Drawables /// /// A pill that displays the star rating of a beatmap. /// - public class StarRatingDisplay : CompositeDrawable, IHasCurrentValue + public partial class StarRatingDisplay : CompositeDrawable, IHasCurrentValue { private readonly bool animated; private readonly Box background; diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs index f37771a74d..2cd9785048 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapBackgroundSprite.cs @@ -14,7 +14,7 @@ namespace osu.Game.Beatmaps.Drawables /// /// Display a beatmap background from a local source, but fallback to online source if not available. /// - public class UpdateableBeatmapBackgroundSprite : ModelBackedDrawable + public partial class UpdateableBeatmapBackgroundSprite : ModelBackedDrawable { public readonly Bindable Beatmap = new Bindable(); diff --git a/osu.Game/Beatmaps/Drawables/UpdateableOnlineBeatmapSetCover.cs b/osu.Game/Beatmaps/Drawables/UpdateableOnlineBeatmapSetCover.cs index 236bb63e24..93b0dd5c15 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableOnlineBeatmapSetCover.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableOnlineBeatmapSetCover.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics; namespace osu.Game.Beatmaps.Drawables { - public class UpdateableOnlineBeatmapSetCover : ModelBackedDrawable + public partial class UpdateableOnlineBeatmapSetCover : ModelBackedDrawable { private readonly BeatmapSetCoverType coverType; diff --git a/osu.Game/Beatmaps/FramedBeatmapClock.cs b/osu.Game/Beatmaps/FramedBeatmapClock.cs index c7050cc50f..080b0ce7ec 100644 --- a/osu.Game/Beatmaps/FramedBeatmapClock.cs +++ b/osu.Game/Beatmaps/FramedBeatmapClock.cs @@ -24,7 +24,7 @@ namespace osu.Game.Beatmaps /// - Exposes track length. /// - Allows changing the source to a new track (for cases like editor track updating). /// - public class FramedBeatmapClock : Component, IFrameBasedClock, IAdjustableClock, ISourceChangeableClock + public partial class FramedBeatmapClock : Component, IFrameBasedClock, IAdjustableClock, ISourceChangeableClock { private readonly bool applyOffsets; diff --git a/osu.Game/Collections/CollectionDropdown.cs b/osu.Game/Collections/CollectionDropdown.cs index f203d49900..19fa3a3d66 100644 --- a/osu.Game/Collections/CollectionDropdown.cs +++ b/osu.Game/Collections/CollectionDropdown.cs @@ -24,7 +24,7 @@ namespace osu.Game.Collections /// /// A dropdown to select the collection to be used to filter results. /// - public class CollectionDropdown : OsuDropdown + public partial class CollectionDropdown : OsuDropdown { /// /// Whether to show the "manage collections..." menu item in the dropdown. @@ -140,7 +140,7 @@ namespace osu.Game.Collections protected virtual CollectionDropdownMenu CreateCollectionMenu() => new CollectionDropdownMenu(); - public class CollectionDropdownHeader : OsuDropdownHeader + public partial class CollectionDropdownHeader : OsuDropdownHeader { public CollectionDropdownHeader() { @@ -150,7 +150,7 @@ namespace osu.Game.Collections } } - protected class CollectionDropdownMenu : OsuDropdownMenu + protected partial class CollectionDropdownMenu : OsuDropdownMenu { public CollectionDropdownMenu() { @@ -164,7 +164,7 @@ namespace osu.Game.Collections }; } - protected class CollectionDropdownDrawableMenuItem : OsuDropdownMenu.DrawableOsuDropdownMenuItem + protected partial class CollectionDropdownDrawableMenuItem : OsuDropdownMenu.DrawableOsuDropdownMenuItem { private IconButton addOrRemoveButton = null!; diff --git a/osu.Game/Collections/DeleteCollectionDialog.cs b/osu.Game/Collections/DeleteCollectionDialog.cs index bf187265c1..4b23f661f9 100644 --- a/osu.Game/Collections/DeleteCollectionDialog.cs +++ b/osu.Game/Collections/DeleteCollectionDialog.cs @@ -8,7 +8,7 @@ using osu.Game.Overlays.Dialog; namespace osu.Game.Collections { - public class DeleteCollectionDialog : DeleteConfirmationDialog + public partial class DeleteCollectionDialog : DeleteConfirmationDialog { public DeleteCollectionDialog(Live collection, Action deleteAction) { diff --git a/osu.Game/Collections/DrawableCollectionList.cs b/osu.Game/Collections/DrawableCollectionList.cs index 0f4362fff3..0fdf196c4a 100644 --- a/osu.Game/Collections/DrawableCollectionList.cs +++ b/osu.Game/Collections/DrawableCollectionList.cs @@ -18,7 +18,7 @@ namespace osu.Game.Collections /// /// Visualises a list of s. /// - public class DrawableCollectionList : OsuRearrangeableListContainer> + public partial class DrawableCollectionList : OsuRearrangeableListContainer> { protected override ScrollContainer CreateScrollContainer() => scroll = new Scroll(); @@ -68,7 +68,7 @@ namespace osu.Game.Collections /// /// Use to transfer the placeholder into the main list. /// - private class Scroll : OsuScrollContainer + private partial class Scroll : OsuScrollContainer { /// /// The currently-displayed placeholder item. @@ -132,7 +132,7 @@ namespace osu.Game.Collections /// /// The flow of . Disables layout easing unless a drag is in progress. /// - private class Flow : FillFlowContainer>> + private partial class Flow : FillFlowContainer>> { public readonly IBindable DragActive = new Bindable(); diff --git a/osu.Game/Collections/DrawableCollectionListItem.cs b/osu.Game/Collections/DrawableCollectionListItem.cs index d1e40f6262..23156b1ad5 100644 --- a/osu.Game/Collections/DrawableCollectionListItem.cs +++ b/osu.Game/Collections/DrawableCollectionListItem.cs @@ -23,7 +23,7 @@ namespace osu.Game.Collections /// /// Visualises a inside a . /// - public class DrawableCollectionListItem : OsuRearrangeableListItem> + public partial class DrawableCollectionListItem : OsuRearrangeableListItem> { private const float item_height = 35; private const float button_width = item_height * 0.75f; @@ -44,7 +44,7 @@ namespace osu.Game.Collections /// /// The main content of the . /// - private class ItemContent : CircularContainer + private partial class ItemContent : CircularContainer { private readonly Live collection; @@ -113,7 +113,7 @@ namespace osu.Game.Collections } } - private class ItemTextBox : OsuTextBox + private partial class ItemTextBox : OsuTextBox { protected override float LeftRightPadding => item_height / 2; @@ -125,7 +125,7 @@ namespace osu.Game.Collections } } - public class DeleteButton : CompositeDrawable + public partial class DeleteButton : CompositeDrawable { public Func IsTextBoxHovered = null!; diff --git a/osu.Game/Collections/ManageCollectionsDialog.cs b/osu.Game/Collections/ManageCollectionsDialog.cs index 13737dbd78..36142cf26f 100644 --- a/osu.Game/Collections/ManageCollectionsDialog.cs +++ b/osu.Game/Collections/ManageCollectionsDialog.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Collections { - public class ManageCollectionsDialog : OsuFocusedOverlayContainer + public partial class ManageCollectionsDialog : OsuFocusedOverlayContainer { private const double enter_duration = 500; private const double exit_duration = 200; diff --git a/osu.Game/Configuration/SettingSourceAttribute.cs b/osu.Game/Configuration/SettingSourceAttribute.cs index 630b65ae82..043bba3134 100644 --- a/osu.Game/Configuration/SettingSourceAttribute.cs +++ b/osu.Game/Configuration/SettingSourceAttribute.cs @@ -107,7 +107,7 @@ namespace osu.Game.Configuration } } - public static class SettingSourceExtensions + public static partial class SettingSourceExtensions { public static IEnumerable CreateSettingsControls(this object obj) { @@ -267,12 +267,12 @@ namespace osu.Game.Configuration .OrderBy(attr => attr.Item1) .ToArray(); - private class ModSettingsEnumDropdown : SettingsEnumDropdown + private partial class ModSettingsEnumDropdown : SettingsEnumDropdown where T : struct, Enum { protected override OsuDropdown CreateDropdown() => new ModDropdownControl(); - private class ModDropdownControl : DropdownControl + private partial class ModDropdownControl : DropdownControl { // Set menu's max height low enough to workaround nested scroll issues (see https://github.com/ppy/osu-framework/issues/4536). protected override DropdownMenu CreateMenu() => base.CreateMenu().With(m => m.MaxHeight = 100); diff --git a/osu.Game/Database/BeatmapLookupCache.cs b/osu.Game/Database/BeatmapLookupCache.cs index 53cb7d72fc..d9bf0138dc 100644 --- a/osu.Game/Database/BeatmapLookupCache.cs +++ b/osu.Game/Database/BeatmapLookupCache.cs @@ -13,7 +13,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Database { - public class BeatmapLookupCache : OnlineLookupCache + public partial class BeatmapLookupCache : OnlineLookupCache { /// /// Perform an API lookup on the specified beatmap, populating a model. diff --git a/osu.Game/Database/ImportProgressNotification.cs b/osu.Game/Database/ImportProgressNotification.cs index aaee3e117f..762918f376 100644 --- a/osu.Game/Database/ImportProgressNotification.cs +++ b/osu.Game/Database/ImportProgressNotification.cs @@ -5,7 +5,7 @@ using osu.Game.Overlays.Notifications; namespace osu.Game.Database { - public class ImportProgressNotification : ProgressNotification + public partial class ImportProgressNotification : ProgressNotification { public ImportProgressNotification() { diff --git a/osu.Game/Database/LegacyImportManager.cs b/osu.Game/Database/LegacyImportManager.cs index 78ebd8750e..901b953bf2 100644 --- a/osu.Game/Database/LegacyImportManager.cs +++ b/osu.Game/Database/LegacyImportManager.cs @@ -22,7 +22,7 @@ namespace osu.Game.Database /// /// Handles migration of legacy user data from osu-stable. /// - public class LegacyImportManager : Component + public partial class LegacyImportManager : Component { [Resolved] private SkinManager skins { get; set; } = null!; diff --git a/osu.Game/Database/MemoryCachingComponent.cs b/osu.Game/Database/MemoryCachingComponent.cs index 571a9ccc7c..5d1a381f09 100644 --- a/osu.Game/Database/MemoryCachingComponent.cs +++ b/osu.Game/Database/MemoryCachingComponent.cs @@ -18,7 +18,7 @@ namespace osu.Game.Database /// A component which performs lookups (or calculations) and caches the results. /// Currently not persisted between game sessions. /// - public abstract class MemoryCachingComponent : Component + public abstract partial class MemoryCachingComponent : Component { private readonly ConcurrentDictionary cache = new ConcurrentDictionary(); diff --git a/osu.Game/Database/ModelDownloader.cs b/osu.Game/Database/ModelDownloader.cs index 6cba8fe819..3e2d034937 100644 --- a/osu.Game/Database/ModelDownloader.cs +++ b/osu.Game/Database/ModelDownloader.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays.Notifications; namespace osu.Game.Database { - public abstract class ModelDownloader : IModelDownloader + public abstract partial class ModelDownloader : IModelDownloader where TModel : class, IHasGuidPrimaryKey, ISoftDelete, IEquatable, T where T : class { @@ -124,7 +124,7 @@ namespace osu.Game.Database private bool canDownload(T model) => GetExistingDownload(model) == null && api != null; - private class DownloadNotification : ProgressNotification + private partial class DownloadNotification : ProgressNotification { public override bool IsImportant => false; @@ -134,7 +134,7 @@ namespace osu.Game.Database Text = CompletionText }; - private class SilencedProgressCompletionNotification : ProgressCompletionNotification + private partial class SilencedProgressCompletionNotification : ProgressCompletionNotification { public override bool IsImportant => false; } diff --git a/osu.Game/Database/OnlineLookupCache.cs b/osu.Game/Database/OnlineLookupCache.cs index 317c37bbfb..d9b37e2f29 100644 --- a/osu.Game/Database/OnlineLookupCache.cs +++ b/osu.Game/Database/OnlineLookupCache.cs @@ -15,7 +15,7 @@ using osu.Game.Online.API; namespace osu.Game.Database { - public abstract class OnlineLookupCache : MemoryCachingComponent + public abstract partial class OnlineLookupCache : MemoryCachingComponent where TLookup : IEquatable where TValue : class, IHasOnlineID where TRequest : APIRequest diff --git a/osu.Game/Database/TooManyDownloadsNotification.cs b/osu.Game/Database/TooManyDownloadsNotification.cs index 14012e1d34..92e9a73026 100644 --- a/osu.Game/Database/TooManyDownloadsNotification.cs +++ b/osu.Game/Database/TooManyDownloadsNotification.cs @@ -9,7 +9,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Database { - public class TooManyDownloadsNotification : SimpleNotification + public partial class TooManyDownloadsNotification : SimpleNotification { public TooManyDownloadsNotification() { diff --git a/osu.Game/Database/UserLookupCache.cs b/osu.Game/Database/UserLookupCache.cs index 87f08d36ae..b1609fbf7b 100644 --- a/osu.Game/Database/UserLookupCache.cs +++ b/osu.Game/Database/UserLookupCache.cs @@ -13,7 +13,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Database { - public class UserLookupCache : OnlineLookupCache + public partial class UserLookupCache : OnlineLookupCache { /// /// Perform an API lookup on the specified user, populating a model. diff --git a/osu.Game/Graphics/Backgrounds/Background.cs b/osu.Game/Graphics/Backgrounds/Background.cs index 0899c0706d..bc2ad81fef 100644 --- a/osu.Game/Graphics/Backgrounds/Background.cs +++ b/osu.Game/Graphics/Backgrounds/Background.cs @@ -18,7 +18,7 @@ namespace osu.Game.Graphics.Backgrounds /// /// A background which offers blurring via a on demand. /// - public class Background : CompositeDrawable, IEquatable + public partial class Background : CompositeDrawable, IEquatable { public readonly Sprite Sprite; diff --git a/osu.Game/Graphics/Backgrounds/BeatmapBackground.cs b/osu.Game/Graphics/Backgrounds/BeatmapBackground.cs index 543bfe2bac..b79eb4927f 100644 --- a/osu.Game/Graphics/Backgrounds/BeatmapBackground.cs +++ b/osu.Game/Graphics/Backgrounds/BeatmapBackground.cs @@ -9,7 +9,7 @@ using osu.Game.Beatmaps; namespace osu.Game.Graphics.Backgrounds { - public class BeatmapBackground : Background + public partial class BeatmapBackground : Background { public readonly WorkingBeatmap Beatmap; diff --git a/osu.Game/Graphics/Backgrounds/BeatmapBackgroundWithStoryboard.cs b/osu.Game/Graphics/Backgrounds/BeatmapBackgroundWithStoryboard.cs index 0dcfa4e9aa..9c0d109ce4 100644 --- a/osu.Game/Graphics/Backgrounds/BeatmapBackgroundWithStoryboard.cs +++ b/osu.Game/Graphics/Backgrounds/BeatmapBackgroundWithStoryboard.cs @@ -14,7 +14,7 @@ using osu.Game.Storyboards.Drawables; namespace osu.Game.Graphics.Backgrounds { - public class BeatmapBackgroundWithStoryboard : BeatmapBackground + public partial class BeatmapBackgroundWithStoryboard : BeatmapBackground { private readonly InterpolatingFramedClock storyboardClock; diff --git a/osu.Game/Graphics/Backgrounds/SeasonalBackgroundLoader.cs b/osu.Game/Graphics/Backgrounds/SeasonalBackgroundLoader.cs index 9d873762bf..6f6febb646 100644 --- a/osu.Game/Graphics/Backgrounds/SeasonalBackgroundLoader.cs +++ b/osu.Game/Graphics/Backgrounds/SeasonalBackgroundLoader.cs @@ -17,7 +17,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Graphics.Backgrounds { - public class SeasonalBackgroundLoader : Component + public partial class SeasonalBackgroundLoader : Component { /// /// Fired when background should be changed due to receiving backgrounds from API @@ -97,7 +97,7 @@ namespace osu.Game.Graphics.Backgrounds } [LongRunningLoad] - public class SeasonalBackground : Background + public partial class SeasonalBackground : Background { private readonly string url; private const string fallback_texture_name = @"Backgrounds/bg1"; diff --git a/osu.Game/Graphics/Backgrounds/SkinBackground.cs b/osu.Game/Graphics/Backgrounds/SkinBackground.cs index e4bf3b94c5..e30bb961a0 100644 --- a/osu.Game/Graphics/Backgrounds/SkinBackground.cs +++ b/osu.Game/Graphics/Backgrounds/SkinBackground.cs @@ -8,7 +8,7 @@ using osu.Game.Skinning; namespace osu.Game.Graphics.Backgrounds { - internal class SkinBackground : Background + internal partial class SkinBackground : Background { private readonly Skin skin; diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index 09d137011c..94397f7ffb 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -21,7 +21,7 @@ using osu.Framework.Bindables; namespace osu.Game.Graphics.Backgrounds { - public class Triangles : Drawable + public partial class Triangles : Drawable { private const float triangle_size = 100; private const float base_velocity = 50; diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index 00fea601c6..724005a0cc 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -22,7 +22,7 @@ namespace osu.Game.Graphics.Containers /// /// This container will also trigger beat events when the beat matching clock is paused at 's BPM. /// - public class BeatSyncedContainer : Container + public partial class BeatSyncedContainer : Container { private int lastBeat; diff --git a/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs b/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs index f34a856707..55160e14af 100644 --- a/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs +++ b/osu.Game/Graphics/Containers/ConstrainedIconContainer.cs @@ -14,7 +14,7 @@ namespace osu.Game.Graphics.Containers /// /// Display an icon that is forced to scale to the size of this container. /// - public class ConstrainedIconContainer : CompositeDrawable + public partial class ConstrainedIconContainer : CompositeDrawable { public Drawable Icon { diff --git a/osu.Game/Graphics/Containers/ExpandingButtonContainer.cs b/osu.Game/Graphics/Containers/ExpandingButtonContainer.cs index f66afb27c4..a06af61125 100644 --- a/osu.Game/Graphics/Containers/ExpandingButtonContainer.cs +++ b/osu.Game/Graphics/Containers/ExpandingButtonContainer.cs @@ -11,7 +11,7 @@ namespace osu.Game.Graphics.Containers /// /// Mostly used for buttons with explanatory labels, in which the label would display after a "long hover". /// - public class ExpandingButtonContainer : ExpandingContainer + public partial class ExpandingButtonContainer : ExpandingContainer { protected ExpandingButtonContainer(float contractedWidth, float expandedWidth) : base(contractedWidth, expandedWidth) diff --git a/osu.Game/Graphics/Containers/ExpandingContainer.cs b/osu.Game/Graphics/Containers/ExpandingContainer.cs index debc068220..60b9e6a167 100644 --- a/osu.Game/Graphics/Containers/ExpandingContainer.cs +++ b/osu.Game/Graphics/Containers/ExpandingContainer.cs @@ -14,7 +14,7 @@ namespace osu.Game.Graphics.Containers /// /// Represents a with the ability to expand/contract on hover. /// - public class ExpandingContainer : Container, IExpandingContainer + public partial class ExpandingContainer : Container, IExpandingContainer { private readonly float contractedWidth; private readonly float expandedWidth; diff --git a/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs b/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs index 7d38478b81..cbe327bac7 100644 --- a/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs +++ b/osu.Game/Graphics/Containers/HoldToConfirmContainer.cs @@ -22,7 +22,7 @@ namespace osu.Game.Graphics.Containers /// The is exposed as a transforming bindable which smoothly tracks the progress of a hold operation. /// It can be used for animating and displaying progress directly. /// - public abstract class HoldToConfirmContainer : Container + public abstract partial class HoldToConfirmContainer : Container { public const double DANGEROUS_HOLD_ACTIVATION_DELAY = 500; diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index bf96695fd3..2d27ce906b 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -18,7 +18,7 @@ using osu.Game.Users; namespace osu.Game.Graphics.Containers { - public class LinkFlowContainer : OsuTextFlowContainer + public partial class LinkFlowContainer : OsuTextFlowContainer { public LinkFlowContainer(Action defaultCreationParameters = null) : base(defaultCreationParameters) diff --git a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs index bf8d70a200..735b8b4e7d 100644 --- a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs +++ b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs @@ -15,7 +15,7 @@ namespace osu.Game.Graphics.Containers /// /// A container that handles tracking of an through different layout scenarios. /// - public class LogoTrackingContainer : Container + public partial class LogoTrackingContainer : Container { public Facade LogoFacade => facade; @@ -131,7 +131,7 @@ namespace osu.Game.Graphics.Containers base.Dispose(isDisposing); } - private class InternalFacade : Facade + private partial class InternalFacade : Facade { public new void SetSize(Vector2 size) { @@ -142,7 +142,7 @@ namespace osu.Game.Graphics.Containers /// /// A dummy object used to denote another object's location. /// - public abstract class Facade : Drawable + public abstract partial class Facade : Drawable { public override Vector2 Size { diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs index 3855ed6d4e..e884b5db69 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs @@ -19,7 +19,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.Containers.Markdown { - public class OsuMarkdownContainer : MarkdownContainer + public partial class OsuMarkdownContainer : MarkdownContainer { /// /// Allows this markdown container to parse and link footnotes. diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownFencedCodeBlock.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownFencedCodeBlock.cs index fc7401046f..b5bbe3e2cc 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownFencedCodeBlock.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownFencedCodeBlock.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays; namespace osu.Game.Graphics.Containers.Markdown { - public class OsuMarkdownFencedCodeBlock : MarkdownFencedCodeBlock + public partial class OsuMarkdownFencedCodeBlock : MarkdownFencedCodeBlock { // TODO : change to monospace font for this component public OsuMarkdownFencedCodeBlock(FencedCodeBlock fencedCodeBlock) @@ -24,7 +24,7 @@ namespace osu.Game.Graphics.Containers.Markdown public override MarkdownTextFlowContainer CreateTextFlow() => new CodeBlockTextFlowContainer(); - private class CodeBlockBackground : Box + private partial class CodeBlockBackground : Box { [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -34,7 +34,7 @@ namespace osu.Game.Graphics.Containers.Markdown } } - private class CodeBlockTextFlowContainer : OsuMarkdownTextFlowContainer + private partial class CodeBlockTextFlowContainer : OsuMarkdownTextFlowContainer { [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownHeading.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownHeading.cs index 0c70952222..800a0e1fc3 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownHeading.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownHeading.cs @@ -10,7 +10,7 @@ using osu.Framework.Graphics.Sprites; namespace osu.Game.Graphics.Containers.Markdown { - public class OsuMarkdownHeading : MarkdownHeading + public partial class OsuMarkdownHeading : MarkdownHeading { private readonly int level; @@ -66,7 +66,7 @@ namespace osu.Game.Graphics.Containers.Markdown } } - private class HeadingTextFlowContainer : OsuMarkdownTextFlowContainer + private partial class HeadingTextFlowContainer : OsuMarkdownTextFlowContainer { public float FontSize; public FontWeight FontWeight; diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownImage.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownImage.cs index 9ad501fdff..8ccac158eb 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownImage.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownImage.cs @@ -10,7 +10,7 @@ using osu.Framework.Localisation; namespace osu.Game.Graphics.Containers.Markdown { - public class OsuMarkdownImage : MarkdownImage, IHasTooltip + public partial class OsuMarkdownImage : MarkdownImage, IHasTooltip { public LocalisableString TooltipText { get; } diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownLinkText.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownLinkText.cs index 3a16eb0a0f..0049feca02 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownLinkText.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownLinkText.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays; namespace osu.Game.Graphics.Containers.Markdown { - public class OsuMarkdownLinkText : MarkdownLinkText + public partial class OsuMarkdownLinkText : MarkdownLinkText { [Resolved(canBeNull: true)] private ILinkHandler linkHandler { get; set; } @@ -54,7 +54,7 @@ namespace osu.Game.Graphics.Containers.Markdown protected override void OnLinkPressed() => linkHandler?.HandleLink(Url); - private class OsuMarkdownLinkCompiler : DrawableLinkCompiler + private partial class OsuMarkdownLinkCompiler : DrawableLinkCompiler { public OsuMarkdownLinkCompiler(IEnumerable parts) : base(parts) diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownListItem.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownListItem.cs index 153c4f9f93..2d38e44d32 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownListItem.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownListItem.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Graphics.Containers.Markdown { - public abstract class OsuMarkdownListItem : CompositeDrawable + public abstract partial class OsuMarkdownListItem : CompositeDrawable { [Resolved] private IMarkdownTextComponent parentTextComponent { get; set; } diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownOrderedListItem.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownOrderedListItem.cs index 116a8e2872..6eac9378ae 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownOrderedListItem.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownOrderedListItem.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Sprites; namespace osu.Game.Graphics.Containers.Markdown { - public class OsuMarkdownOrderedListItem : OsuMarkdownListItem + public partial class OsuMarkdownOrderedListItem : OsuMarkdownListItem { private const float left_padding = 30; diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownQuoteBlock.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownQuoteBlock.cs index 3ef67df7a9..447085a48c 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownQuoteBlock.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownQuoteBlock.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays; namespace osu.Game.Graphics.Containers.Markdown { - public class OsuMarkdownQuoteBlock : MarkdownQuoteBlock + public partial class OsuMarkdownQuoteBlock : MarkdownQuoteBlock { public OsuMarkdownQuoteBlock(QuoteBlock quoteBlock) : base(quoteBlock) @@ -30,7 +30,7 @@ namespace osu.Game.Graphics.Containers.Markdown }); } - private class QuoteBackground : Box + private partial class QuoteBackground : Box { [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownSeparator.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownSeparator.cs index abbc10a7e2..343a1d1015 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownSeparator.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownSeparator.cs @@ -11,11 +11,11 @@ using osu.Game.Overlays; namespace osu.Game.Graphics.Containers.Markdown { - public class OsuMarkdownSeparator : MarkdownSeparator + public partial class OsuMarkdownSeparator : MarkdownSeparator { protected override Drawable CreateSeparator() => new Separator(); - private class Separator : Box + private partial class Separator : Box { [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTable.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTable.cs index ee851045f9..c9c1098e05 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTable.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTable.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Containers.Markdown; namespace osu.Game.Graphics.Containers.Markdown { - public class OsuMarkdownTable : MarkdownTable + public partial class OsuMarkdownTable : MarkdownTable { public OsuMarkdownTable(Table table) : base(table) diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTableCell.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTableCell.cs index 3863beb133..dbf15a2546 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTableCell.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTableCell.cs @@ -13,7 +13,7 @@ using osu.Game.Overlays; namespace osu.Game.Graphics.Containers.Markdown { - public class OsuMarkdownTableCell : MarkdownTableCell + public partial class OsuMarkdownTableCell : MarkdownTableCell { private readonly bool isHeading; @@ -45,7 +45,7 @@ namespace osu.Game.Graphics.Containers.Markdown return new TableBodyBorder(); } - private class TableHeadBorder : Box + private partial class TableHeadBorder : Box { [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -58,7 +58,7 @@ namespace osu.Game.Graphics.Containers.Markdown } } - private class TableBodyBorder : Box + private partial class TableBodyBorder : Box { [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -69,7 +69,7 @@ namespace osu.Game.Graphics.Containers.Markdown } } - private class TableCellTextFlowContainer : OsuMarkdownTextFlowContainer + private partial class TableCellTextFlowContainer : OsuMarkdownTextFlowContainer { public FontWeight Weight { get; set; } diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs index 9d7b47281f..7de63fe09c 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Graphics.Containers.Markdown { - public class OsuMarkdownTextFlowContainer : MarkdownTextFlowContainer + public partial class OsuMarkdownTextFlowContainer : MarkdownTextFlowContainer { protected override void AddLinkText(string text, LinkInline linkInline) => AddDrawable(new OsuMarkdownLinkText(text, linkInline)); @@ -64,7 +64,7 @@ namespace osu.Game.Graphics.Containers.Markdown AddDrawable(new DrawableFlag(countryCode) { Size = new Vector2(20, 15) }); } - private class OsuMarkdownInlineCode : Container + private partial class OsuMarkdownInlineCode : Container { [Resolved] private IMarkdownTextComponent parentTextComponent { get; set; } diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownUnorderedListItem.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownUnorderedListItem.cs index f8e8571557..64e98511c2 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownUnorderedListItem.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownUnorderedListItem.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Sprites; namespace osu.Game.Graphics.Containers.Markdown { - public class OsuMarkdownUnorderedListItem : OsuMarkdownListItem + public partial class OsuMarkdownUnorderedListItem : OsuMarkdownListItem { private const float left_padding = 20; diff --git a/osu.Game/Graphics/Containers/OsuClickableContainer.cs b/osu.Game/Graphics/Containers/OsuClickableContainer.cs index 03a1cfcc13..4729ddf1a8 100644 --- a/osu.Game/Graphics/Containers/OsuClickableContainer.cs +++ b/osu.Game/Graphics/Containers/OsuClickableContainer.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Graphics.Containers { - public class OsuClickableContainer : ClickableContainer, IHasTooltip + public partial class OsuClickableContainer : ClickableContainer, IHasTooltip { private readonly HoverSampleSet sampleSet; diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index e8a0c0cd25..740c170f8f 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -18,7 +18,7 @@ using osu.Game.Overlays; namespace osu.Game.Graphics.Containers { [Cached(typeof(IPreviewTrackOwner))] - public abstract class OsuFocusedOverlayContainer : FocusedOverlayContainer, IPreviewTrackOwner, IKeyBindingHandler + public abstract partial class OsuFocusedOverlayContainer : FocusedOverlayContainer, IPreviewTrackOwner, IKeyBindingHandler { private Sample samplePopIn; private Sample samplePopOut; diff --git a/osu.Game/Graphics/Containers/OsuHoverContainer.cs b/osu.Game/Graphics/Containers/OsuHoverContainer.cs index 93205e0d03..b4b80f7574 100644 --- a/osu.Game/Graphics/Containers/OsuHoverContainer.cs +++ b/osu.Game/Graphics/Containers/OsuHoverContainer.cs @@ -13,7 +13,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Graphics.Containers { - public class OsuHoverContainer : OsuClickableContainer + public partial class OsuHoverContainer : OsuClickableContainer { protected const float FADE_DURATION = 500; diff --git a/osu.Game/Graphics/Containers/OsuRearrangeableListContainer.cs b/osu.Game/Graphics/Containers/OsuRearrangeableListContainer.cs index b604ae73eb..fcc48d80ea 100644 --- a/osu.Game/Graphics/Containers/OsuRearrangeableListContainer.cs +++ b/osu.Game/Graphics/Containers/OsuRearrangeableListContainer.cs @@ -14,7 +14,7 @@ using osu.Framework.Utils; namespace osu.Game.Graphics.Containers { - public abstract class OsuRearrangeableListContainer : RearrangeableListContainer + public abstract partial class OsuRearrangeableListContainer : RearrangeableListContainer { /// /// Whether any item is currently being dragged. Used to hide other items' drag handles. diff --git a/osu.Game/Graphics/Containers/OsuRearrangeableListItem.cs b/osu.Game/Graphics/Containers/OsuRearrangeableListItem.cs index e6183ea837..39a3edb82c 100644 --- a/osu.Game/Graphics/Containers/OsuRearrangeableListItem.cs +++ b/osu.Game/Graphics/Containers/OsuRearrangeableListItem.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Graphics.Containers { - public abstract class OsuRearrangeableListItem : RearrangeableListItem + public abstract partial class OsuRearrangeableListItem : RearrangeableListItem { public const float FADE_DURATION = 100; @@ -129,7 +129,7 @@ namespace osu.Game.Graphics.Containers protected abstract Drawable CreateContent(); - public class PlaylistItemHandle : SpriteIcon + public partial class PlaylistItemHandle : SpriteIcon { public bool HandlingDrag { get; private set; } private bool isHovering; diff --git a/osu.Game/Graphics/Containers/OsuScrollContainer.cs b/osu.Game/Graphics/Containers/OsuScrollContainer.cs index 7e5d5e53d3..e39fd45a16 100644 --- a/osu.Game/Graphics/Containers/OsuScrollContainer.cs +++ b/osu.Game/Graphics/Containers/OsuScrollContainer.cs @@ -14,7 +14,7 @@ using osuTK.Input; namespace osu.Game.Graphics.Containers { - public class OsuScrollContainer : OsuScrollContainer + public partial class OsuScrollContainer : OsuScrollContainer { public OsuScrollContainer() { @@ -26,7 +26,7 @@ namespace osu.Game.Graphics.Containers } } - public class OsuScrollContainer : ScrollContainer where T : Drawable + public partial class OsuScrollContainer : ScrollContainer where T : Drawable { public const float SCROLL_BAR_HEIGHT = 10; public const float SCROLL_BAR_PADDING = 3; @@ -131,7 +131,7 @@ namespace osu.Game.Graphics.Containers protected override ScrollbarContainer CreateScrollbar(Direction direction) => new OsuScrollbar(direction); - protected class OsuScrollbar : ScrollbarContainer + protected partial class OsuScrollbar : ScrollbarContainer { private Color4 hoverColour; private Color4 defaultColour; diff --git a/osu.Game/Graphics/Containers/OsuTextFlowContainer.cs b/osu.Game/Graphics/Containers/OsuTextFlowContainer.cs index 5cdccee01d..d3bbc2e80b 100644 --- a/osu.Game/Graphics/Containers/OsuTextFlowContainer.cs +++ b/osu.Game/Graphics/Containers/OsuTextFlowContainer.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.Containers { - public class OsuTextFlowContainer : TextFlowContainer + public partial class OsuTextFlowContainer : TextFlowContainer { public OsuTextFlowContainer(Action defaultCreationParameters = null) : base(defaultCreationParameters) diff --git a/osu.Game/Graphics/Containers/ParallaxContainer.cs b/osu.Game/Graphics/Containers/ParallaxContainer.cs index f70abc16dd..3893413f61 100644 --- a/osu.Game/Graphics/Containers/ParallaxContainer.cs +++ b/osu.Game/Graphics/Containers/ParallaxContainer.cs @@ -15,7 +15,7 @@ using osu.Framework.Utils; namespace osu.Game.Graphics.Containers { - public class ParallaxContainer : Container, IRequireHighFrequencyMousePosition + public partial class ParallaxContainer : Container, IRequireHighFrequencyMousePosition { public const float DEFAULT_PARALLAX_AMOUNT = 0.02f; diff --git a/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs b/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs index db265d6d64..e37d23fe97 100644 --- a/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs +++ b/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Graphics.Containers { - public class ReverseChildIDFillFlowContainer : FillFlowContainer where T : Drawable + public partial class ReverseChildIDFillFlowContainer : FillFlowContainer where T : Drawable { protected override int Compare(Drawable x, Drawable y) => CompareReverseChildID(x, y); } diff --git a/osu.Game/Graphics/Containers/ScalingContainer.cs b/osu.Game/Graphics/Containers/ScalingContainer.cs index 11e57d4be3..fb5c3e3b60 100644 --- a/osu.Game/Graphics/Containers/ScalingContainer.cs +++ b/osu.Game/Graphics/Containers/ScalingContainer.cs @@ -21,7 +21,7 @@ namespace osu.Game.Graphics.Containers /// /// Handles user-defined scaling, allowing application at multiple levels defined by . /// - public class ScalingContainer : Container + public partial class ScalingContainer : Container { internal const float TRANSITION_DURATION = 500; @@ -82,7 +82,7 @@ namespace osu.Game.Graphics.Containers }; } - public class ScalingDrawSizePreservingFillContainer : DrawSizePreservingFillContainer + public partial class ScalingDrawSizePreservingFillContainer : DrawSizePreservingFillContainer { private readonly bool applyUIScale; private Bindable uiScale; @@ -211,7 +211,7 @@ namespace osu.Game.Graphics.Containers .OnComplete(_ => { sizableContainer.Masking = requiresMasking; }); } - private class ScalingBackgroundScreen : BackgroundScreenDefault + private partial class ScalingBackgroundScreen : BackgroundScreenDefault { protected override bool AllowStoryboardBackground => false; @@ -221,7 +221,7 @@ namespace osu.Game.Graphics.Containers } } - private class SizeableAlwaysInputContainer : Container + private partial class SizeableAlwaysInputContainer : Container { [Resolved] private GameHost host { get; set; } diff --git a/osu.Game/Graphics/Containers/SectionsContainer.cs b/osu.Game/Graphics/Containers/SectionsContainer.cs index 97e9ff88b5..123589c552 100644 --- a/osu.Game/Graphics/Containers/SectionsContainer.cs +++ b/osu.Game/Graphics/Containers/SectionsContainer.cs @@ -20,7 +20,7 @@ namespace osu.Game.Graphics.Containers /// A container that can scroll to each section inside it. /// [Cached] - public class SectionsContainer : Container + public partial class SectionsContainer : Container where T : Drawable { public Bindable SelectedSection { get; } = new Bindable(); diff --git a/osu.Game/Graphics/Containers/SelectionCycleFillFlowContainer.cs b/osu.Game/Graphics/Containers/SelectionCycleFillFlowContainer.cs index 2667b8b8e0..62544c6111 100644 --- a/osu.Game/Graphics/Containers/SelectionCycleFillFlowContainer.cs +++ b/osu.Game/Graphics/Containers/SelectionCycleFillFlowContainer.cs @@ -16,7 +16,7 @@ namespace osu.Game.Graphics.Containers /// A FillFlowContainer that provides functionality to cycle selection between children /// The selection wraps around when overflowing past the first or last child. /// - public class SelectionCycleFillFlowContainer : FillFlowContainer where T : Drawable, IStateful + public partial class SelectionCycleFillFlowContainer : FillFlowContainer where T : Drawable, IStateful { public T Selected => (selectedIndex >= 0 && selectedIndex < Count) ? this[selectedIndex.Value] : null; diff --git a/osu.Game/Graphics/Containers/ShakeContainer.cs b/osu.Game/Graphics/Containers/ShakeContainer.cs index 7b6fc22cc0..9a1ddac40d 100644 --- a/osu.Game/Graphics/Containers/ShakeContainer.cs +++ b/osu.Game/Graphics/Containers/ShakeContainer.cs @@ -11,7 +11,7 @@ namespace osu.Game.Graphics.Containers /// /// A container that adds the ability to shake its contents. /// - public class ShakeContainer : Container + public partial class ShakeContainer : Container { /// /// The length of a single shake. diff --git a/osu.Game/Graphics/Containers/UprightAspectMaintainingContainer.cs b/osu.Game/Graphics/Containers/UprightAspectMaintainingContainer.cs index 300b5bd4b4..38ab6deb97 100644 --- a/osu.Game/Graphics/Containers/UprightAspectMaintainingContainer.cs +++ b/osu.Game/Graphics/Containers/UprightAspectMaintainingContainer.cs @@ -12,7 +12,7 @@ namespace osu.Game.Graphics.Containers /// /// A container that reverts any rotation (and optionally scale) applied by its direct parent. /// - public class UprightAspectMaintainingContainer : Container + public partial class UprightAspectMaintainingContainer : Container { /// /// Controls how much this container scales compared to its parent (default is 1.0f). diff --git a/osu.Game/Graphics/Containers/UserDimContainer.cs b/osu.Game/Graphics/Containers/UserDimContainer.cs index 0b20159190..25830c9d54 100644 --- a/osu.Game/Graphics/Containers/UserDimContainer.cs +++ b/osu.Game/Graphics/Containers/UserDimContainer.cs @@ -14,7 +14,7 @@ namespace osu.Game.Graphics.Containers /// /// A container that applies user-configured visual settings to its contents. /// - public abstract class UserDimContainer : Container + public abstract partial class UserDimContainer : Container { /// /// Amount of lightening to apply to current dim level during break times. diff --git a/osu.Game/Graphics/Containers/UserTrackingScrollContainer.cs b/osu.Game/Graphics/Containers/UserTrackingScrollContainer.cs index 2bb9d7261d..715677aec1 100644 --- a/osu.Game/Graphics/Containers/UserTrackingScrollContainer.cs +++ b/osu.Game/Graphics/Containers/UserTrackingScrollContainer.cs @@ -7,7 +7,7 @@ using osu.Framework.Graphics; namespace osu.Game.Graphics.Containers { - public class UserTrackingScrollContainer : UserTrackingScrollContainer + public partial class UserTrackingScrollContainer : UserTrackingScrollContainer { public UserTrackingScrollContainer() { @@ -19,7 +19,7 @@ namespace osu.Game.Graphics.Containers } } - public class UserTrackingScrollContainer : OsuScrollContainer + public partial class UserTrackingScrollContainer : OsuScrollContainer where T : Drawable { /// diff --git a/osu.Game/Graphics/Containers/WaveContainer.cs b/osu.Game/Graphics/Containers/WaveContainer.cs index ba85ef0aab..952ef3f182 100644 --- a/osu.Game/Graphics/Containers/WaveContainer.cs +++ b/osu.Game/Graphics/Containers/WaveContainer.cs @@ -13,7 +13,7 @@ using osuTK.Graphics; namespace osu.Game.Graphics.Containers { - public class WaveContainer : VisibilityContainer + public partial class WaveContainer : VisibilityContainer { public const float APPEAR_DURATION = 800; public const float DISAPPEAR_DURATION = 500; @@ -131,7 +131,7 @@ namespace osu.Game.Graphics.Containers wavesContainer.Height = Math.Max(0, DrawHeight - (contentContainer.DrawHeight - contentContainer.Y * DrawHeight)); } - private class Wave : VisibilityContainer + private partial class Wave : VisibilityContainer { public float FinalPosition; diff --git a/osu.Game/Graphics/Cursor/GlobalCursorDisplay.cs b/osu.Game/Graphics/Cursor/GlobalCursorDisplay.cs index f5429723be..85a2d68e55 100644 --- a/osu.Game/Graphics/Cursor/GlobalCursorDisplay.cs +++ b/osu.Game/Graphics/Cursor/GlobalCursorDisplay.cs @@ -16,7 +16,7 @@ namespace osu.Game.Graphics.Cursor /// A container which provides the main . /// Also handles cases where a more localised cursor is provided by another component (via ). /// - public class GlobalCursorDisplay : Container, IProvideCursor + public partial class GlobalCursorDisplay : Container, IProvideCursor { /// /// Control whether any cursor should be displayed. diff --git a/osu.Game/Graphics/Cursor/MenuCursorContainer.cs b/osu.Game/Graphics/Cursor/MenuCursorContainer.cs index adc0f81daf..b63e73e679 100644 --- a/osu.Game/Graphics/Cursor/MenuCursorContainer.cs +++ b/osu.Game/Graphics/Cursor/MenuCursorContainer.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Graphics.Cursor { - public class MenuCursorContainer : CursorContainer + public partial class MenuCursorContainer : CursorContainer { private readonly IBindable screenshotCursorVisibility = new Bindable(true); public override bool IsPresent => screenshotCursorVisibility.Value && base.IsPresent; @@ -241,7 +241,7 @@ namespace osu.Game.Graphics.Cursor channel.Play(); } - public class Cursor : Container + public partial class Cursor : Container { private Container cursorContainer = null!; private Bindable cursorScale = null!; @@ -284,7 +284,7 @@ namespace osu.Game.Graphics.Cursor } } - private class MouseInputDetector : Component + private partial class MouseInputDetector : Component { /// /// Whether the last input applied to the game is sourced from mouse. diff --git a/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs b/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs index fbaefe24b0..27700e71d9 100644 --- a/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs +++ b/osu.Game/Graphics/Cursor/OsuContextMenuContainer.cs @@ -10,7 +10,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Graphics.Cursor { - public class OsuContextMenuContainer : ContextMenuContainer + public partial class OsuContextMenuContainer : ContextMenuContainer { [Cached] private OsuContextMenuSamples samples = new OsuContextMenuSamples(); diff --git a/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs b/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs index 8bf4dfcd24..dc75d626b9 100644 --- a/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs +++ b/osu.Game/Graphics/Cursor/OsuTooltipContainer.cs @@ -16,7 +16,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.Cursor { - public class OsuTooltipContainer : TooltipContainer + public partial class OsuTooltipContainer : TooltipContainer { protected override ITooltip CreateTooltip() => new OsuTooltip(); @@ -27,7 +27,7 @@ namespace osu.Game.Graphics.Cursor protected override double AppearDelay => (1 - CurrentTooltip.Alpha) * base.AppearDelay; // reduce appear delay if the tooltip is already partly visible. - public class OsuTooltip : Tooltip + public partial class OsuTooltip : Tooltip { private readonly Box background; private readonly OsuSpriteText text; diff --git a/osu.Game/Graphics/DateTooltip.cs b/osu.Game/Graphics/DateTooltip.cs index 77bf78b213..d9bb2b610a 100644 --- a/osu.Game/Graphics/DateTooltip.cs +++ b/osu.Game/Graphics/DateTooltip.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Graphics { - public class DateTooltip : VisibilityContainer, ITooltip + public partial class DateTooltip : VisibilityContainer, ITooltip { private readonly OsuSpriteText dateText, timeText; private readonly Box background; diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index 0008d0fcaa..553b27acb1 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -12,7 +12,7 @@ using osu.Game.Utils; namespace osu.Game.Graphics { - public class DrawableDate : OsuSpriteText, IHasCustomTooltip + public partial class DrawableDate : OsuSpriteText, IHasCustomTooltip { private DateTimeOffset date; diff --git a/osu.Game/Graphics/ErrorTextFlowContainer.cs b/osu.Game/Graphics/ErrorTextFlowContainer.cs index 0d47245e8c..65a90534e5 100644 --- a/osu.Game/Graphics/ErrorTextFlowContainer.cs +++ b/osu.Game/Graphics/ErrorTextFlowContainer.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Graphics { - public class ErrorTextFlowContainer : OsuTextFlowContainer + public partial class ErrorTextFlowContainer : OsuTextFlowContainer { private readonly List errorTextParts = new List(); diff --git a/osu.Game/Graphics/InputBlockingContainer.cs b/osu.Game/Graphics/InputBlockingContainer.cs index 66caa57c1a..f652dc8850 100644 --- a/osu.Game/Graphics/InputBlockingContainer.cs +++ b/osu.Game/Graphics/InputBlockingContainer.cs @@ -9,7 +9,7 @@ namespace osu.Game.Graphics /// /// A simple container which blocks input events from travelling through it. /// - public class InputBlockingContainer : Container + public partial class InputBlockingContainer : Container { protected override bool OnHover(HoverEvent e) => true; diff --git a/osu.Game/Graphics/ParticleExplosion.cs b/osu.Game/Graphics/ParticleExplosion.cs index a902c8426f..56e1568441 100644 --- a/osu.Game/Graphics/ParticleExplosion.cs +++ b/osu.Game/Graphics/ParticleExplosion.cs @@ -18,7 +18,7 @@ namespace osu.Game.Graphics /// /// An explosion of textured particles based on how osu-stable randomises the explosion pattern. /// - public class ParticleExplosion : Sprite + public partial class ParticleExplosion : Sprite { private readonly int particleCount; private readonly double duration; diff --git a/osu.Game/Graphics/ParticleSpewer.cs b/osu.Game/Graphics/ParticleSpewer.cs index 41a7d82e74..8519cf0c59 100644 --- a/osu.Game/Graphics/ParticleSpewer.cs +++ b/osu.Game/Graphics/ParticleSpewer.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Graphics { - public abstract class ParticleSpewer : Sprite + public abstract partial class ParticleSpewer : Sprite { private readonly FallingParticle[] particles; private int currentIndex; diff --git a/osu.Game/Graphics/ScreenshotManager.cs b/osu.Game/Graphics/ScreenshotManager.cs index 2cc9e63c87..29e9b0276c 100644 --- a/osu.Game/Graphics/ScreenshotManager.cs +++ b/osu.Game/Graphics/ScreenshotManager.cs @@ -25,7 +25,7 @@ using SixLabors.ImageSharp.Formats.Jpeg; namespace osu.Game.Graphics { - public class ScreenshotManager : Component, IKeyBindingHandler, IHandleGlobalKeyboardInput + public partial class ScreenshotManager : Component, IKeyBindingHandler, IHandleGlobalKeyboardInput { private readonly BindableBool cursorVisibility = new BindableBool(true); diff --git a/osu.Game/Graphics/Sprites/GlowingSpriteText.cs b/osu.Game/Graphics/Sprites/GlowingSpriteText.cs index dca6b7158b..ae594ddfe2 100644 --- a/osu.Game/Graphics/Sprites/GlowingSpriteText.cs +++ b/osu.Game/Graphics/Sprites/GlowingSpriteText.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Graphics.Sprites { - public class GlowingSpriteText : Container, IHasText + public partial class GlowingSpriteText : Container, IHasText { private readonly OsuSpriteText spriteText, blurredText; diff --git a/osu.Game/Graphics/Sprites/LogoAnimation.cs b/osu.Game/Graphics/Sprites/LogoAnimation.cs index 097de4dfcb..e177cc604b 100644 --- a/osu.Game/Graphics/Sprites/LogoAnimation.cs +++ b/osu.Game/Graphics/Sprites/LogoAnimation.cs @@ -11,7 +11,7 @@ using osu.Framework.Graphics.Sprites; namespace osu.Game.Graphics.Sprites { - public class LogoAnimation : Sprite + public partial class LogoAnimation : Sprite { [BackgroundDependencyLoader] private void load(ShaderManager shaders) diff --git a/osu.Game/Graphics/Sprites/OsuSpriteText.cs b/osu.Game/Graphics/Sprites/OsuSpriteText.cs index a46ed27b9b..e149e0abfb 100644 --- a/osu.Game/Graphics/Sprites/OsuSpriteText.cs +++ b/osu.Game/Graphics/Sprites/OsuSpriteText.cs @@ -7,7 +7,7 @@ using osu.Framework.Graphics.Sprites; namespace osu.Game.Graphics.Sprites { - public class OsuSpriteText : SpriteText + public partial class OsuSpriteText : SpriteText { public OsuSpriteText() { diff --git a/osu.Game/Graphics/Sprites/SizePreservingSpriteText.cs b/osu.Game/Graphics/Sprites/SizePreservingSpriteText.cs index baffe106ed..458dac2b91 100644 --- a/osu.Game/Graphics/Sprites/SizePreservingSpriteText.cs +++ b/osu.Game/Graphics/Sprites/SizePreservingSpriteText.cs @@ -15,7 +15,7 @@ namespace osu.Game.Graphics.Sprites /// /// A wrapped version of which will expand in size based on text content, but never shrink back down. /// - public class SizePreservingSpriteText : CompositeDrawable + public partial class SizePreservingSpriteText : CompositeDrawable { private readonly OsuSpriteText text = new OsuSpriteText(); diff --git a/osu.Game/Graphics/UserInterface/BackButton.cs b/osu.Game/Graphics/UserInterface/BackButton.cs index d2ed71dfc6..cd9a357ea4 100644 --- a/osu.Game/Graphics/UserInterface/BackButton.cs +++ b/osu.Game/Graphics/UserInterface/BackButton.cs @@ -13,7 +13,7 @@ using osu.Game.Input.Bindings; namespace osu.Game.Graphics.UserInterface { - public class BackButton : VisibilityContainer + public partial class BackButton : VisibilityContainer { public Action Action; @@ -60,7 +60,7 @@ namespace osu.Game.Graphics.UserInterface button.FadeOut(400, Easing.OutQuint); } - public class Receptor : Drawable, IKeyBindingHandler + public partial class Receptor : Drawable, IKeyBindingHandler { public Action OnBackPressed; diff --git a/osu.Game/Graphics/UserInterface/Bar.cs b/osu.Game/Graphics/UserInterface/Bar.cs index e9a20761b3..53217e2120 100644 --- a/osu.Game/Graphics/UserInterface/Bar.cs +++ b/osu.Game/Graphics/UserInterface/Bar.cs @@ -12,7 +12,7 @@ using osu.Framework.Graphics.Shapes; namespace osu.Game.Graphics.UserInterface { - public class Bar : Container, IHasAccentColour + public partial class Bar : Container, IHasAccentColour { private readonly Box background; private readonly Box bar; diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs index 3f356c0225..c394e58d87 100644 --- a/osu.Game/Graphics/UserInterface/BarGraph.cs +++ b/osu.Game/Graphics/UserInterface/BarGraph.cs @@ -17,7 +17,7 @@ using System; namespace osu.Game.Graphics.UserInterface { - public class BarGraph : Drawable + public partial class BarGraph : Drawable { private const int resize_duration = 250; private const Easing easing = Easing.InOutCubic; diff --git a/osu.Game/Graphics/UserInterface/BasicSearchTextBox.cs b/osu.Game/Graphics/UserInterface/BasicSearchTextBox.cs index e0efa1d81c..c4e03133dc 100644 --- a/osu.Game/Graphics/UserInterface/BasicSearchTextBox.cs +++ b/osu.Game/Graphics/UserInterface/BasicSearchTextBox.cs @@ -9,7 +9,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterface { - public class BasicSearchTextBox : SearchTextBox + public partial class BasicSearchTextBox : SearchTextBox { public BasicSearchTextBox() { diff --git a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs index b6ae4d6dc5..67b63e120b 100644 --- a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs @@ -14,7 +14,7 @@ using osu.Framework.Graphics.Sprites; namespace osu.Game.Graphics.UserInterface { - public class BreadcrumbControl : OsuTabControl + public partial class BreadcrumbControl : OsuTabControl { private const float padding = 10; @@ -44,7 +44,7 @@ namespace osu.Game.Graphics.UserInterface }; } - public class BreadcrumbTabItem : OsuTabItem, IStateful + public partial class BreadcrumbTabItem : OsuTabItem, IStateful { protected virtual float ChevronSize => 10; diff --git a/osu.Game/Graphics/UserInterface/CommaSeparatedScoreCounter.cs b/osu.Game/Graphics/UserInterface/CommaSeparatedScoreCounter.cs index bec78c68d3..ba76a17fc6 100644 --- a/osu.Game/Graphics/UserInterface/CommaSeparatedScoreCounter.cs +++ b/osu.Game/Graphics/UserInterface/CommaSeparatedScoreCounter.cs @@ -10,7 +10,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.UserInterface { - public abstract class CommaSeparatedScoreCounter : RollingCounter + public abstract partial class CommaSeparatedScoreCounter : RollingCounter { protected override double RollingDuration => 1000; protected override Easing RollingEasing => Easing.Out; diff --git a/osu.Game/Graphics/UserInterface/DangerousTriangleButton.cs b/osu.Game/Graphics/UserInterface/DangerousTriangleButton.cs index 1414979531..c2c01a0ddb 100644 --- a/osu.Game/Graphics/UserInterface/DangerousTriangleButton.cs +++ b/osu.Game/Graphics/UserInterface/DangerousTriangleButton.cs @@ -7,7 +7,7 @@ using osu.Framework.Allocation; namespace osu.Game.Graphics.UserInterface { - public class DangerousTriangleButton : TriangleButton + public partial class DangerousTriangleButton : TriangleButton { [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game/Graphics/UserInterface/DialogButton.cs b/osu.Game/Graphics/UserInterface/DialogButton.cs index 52ad5c6b80..670778b07b 100644 --- a/osu.Game/Graphics/UserInterface/DialogButton.cs +++ b/osu.Game/Graphics/UserInterface/DialogButton.cs @@ -22,7 +22,7 @@ using osuTK.Graphics; namespace osu.Game.Graphics.UserInterface { - public class DialogButton : OsuClickableContainer, IStateful + public partial class DialogButton : OsuClickableContainer, IStateful { private const float idle_width = 0.8f; private const float hover_width = 0.9f; diff --git a/osu.Game/Graphics/UserInterface/DownloadButton.cs b/osu.Game/Graphics/UserInterface/DownloadButton.cs index dfbe6bd44d..73783e718c 100644 --- a/osu.Game/Graphics/UserInterface/DownloadButton.cs +++ b/osu.Game/Graphics/UserInterface/DownloadButton.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterface { - public class DownloadButton : GrayButton + public partial class DownloadButton : GrayButton { [Resolved] private OsuColour colours { get; set; } diff --git a/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs b/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs index 6c8eeed391..ad02e3b2ab 100644 --- a/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs +++ b/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Graphics.UserInterface { - public class DrawableOsuMenuItem : Menu.DrawableMenuItem + public partial class DrawableOsuMenuItem : Menu.DrawableMenuItem { public const int MARGIN_HORIZONTAL = 17; public const int MARGIN_VERTICAL = 4; @@ -95,7 +95,7 @@ namespace osu.Game.Graphics.UserInterface protected sealed override Drawable CreateContent() => text = CreateTextContainer(); protected virtual TextContainer CreateTextContainer() => new TextContainer(); - protected class TextContainer : Container, IHasText + protected partial class TextContainer : Container, IHasText { public LocalisableString Text { diff --git a/osu.Game/Graphics/UserInterface/DrawableStatefulMenuItem.cs b/osu.Game/Graphics/UserInterface/DrawableStatefulMenuItem.cs index 5a7cf0d73e..ec3a5744f8 100644 --- a/osu.Game/Graphics/UserInterface/DrawableStatefulMenuItem.cs +++ b/osu.Game/Graphics/UserInterface/DrawableStatefulMenuItem.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterface { - public class DrawableStatefulMenuItem : DrawableOsuMenuItem + public partial class DrawableStatefulMenuItem : DrawableOsuMenuItem { protected new StatefulMenuItem Item => (StatefulMenuItem)base.Item; @@ -21,7 +21,7 @@ namespace osu.Game.Graphics.UserInterface protected override TextContainer CreateTextContainer() => new ToggleTextContainer(Item); - private class ToggleTextContainer : TextContainer + private partial class ToggleTextContainer : TextContainer { private readonly StatefulMenuItem menuItem; private readonly Bindable state; diff --git a/osu.Game/Graphics/UserInterface/ExpandableSlider.cs b/osu.Game/Graphics/UserInterface/ExpandableSlider.cs index 92b0059157..9669fe89a5 100644 --- a/osu.Game/Graphics/UserInterface/ExpandableSlider.cs +++ b/osu.Game/Graphics/UserInterface/ExpandableSlider.cs @@ -19,7 +19,7 @@ namespace osu.Game.Graphics.UserInterface /// /// An implementation for the UI slider bar control. /// - public class ExpandableSlider : CompositeDrawable, IExpandable, IHasCurrentValue + public partial class ExpandableSlider : CompositeDrawable, IExpandable, IHasCurrentValue where T : struct, IEquatable, IComparable, IConvertible where TSlider : OsuSliderBar, new() { @@ -130,7 +130,7 @@ namespace osu.Game.Graphics.UserInterface /// /// An implementation for the UI slider bar control. /// - public class ExpandableSlider : ExpandableSlider> + public partial class ExpandableSlider : ExpandableSlider> where T : struct, IEquatable, IComparable, IConvertible { } diff --git a/osu.Game/Graphics/UserInterface/ExpandingBar.cs b/osu.Game/Graphics/UserInterface/ExpandingBar.cs index b2ffb4da7d..6d7c41ee7c 100644 --- a/osu.Game/Graphics/UserInterface/ExpandingBar.cs +++ b/osu.Game/Graphics/UserInterface/ExpandingBar.cs @@ -13,7 +13,7 @@ namespace osu.Game.Graphics.UserInterface /// A rounded bar which can be expanded or collapsed. /// Generally used for tabs or breadcrumbs. /// - public class ExpandingBar : Circle + public partial class ExpandingBar : Circle { private bool expanded = true; diff --git a/osu.Game/Graphics/UserInterface/ExternalLinkButton.cs b/osu.Game/Graphics/UserInterface/ExternalLinkButton.cs index e51dbeed14..efbbaaca85 100644 --- a/osu.Game/Graphics/UserInterface/ExternalLinkButton.cs +++ b/osu.Game/Graphics/UserInterface/ExternalLinkButton.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Graphics.UserInterface { - public class ExternalLinkButton : CompositeDrawable, IHasTooltip, IHasContextMenu + public partial class ExternalLinkButton : CompositeDrawable, IHasTooltip, IHasContextMenu { public string? Link { get; set; } diff --git a/osu.Game/Graphics/UserInterface/FPSCounter.cs b/osu.Game/Graphics/UserInterface/FPSCounter.cs index e9fb6a046a..9dbeba6449 100644 --- a/osu.Game/Graphics/UserInterface/FPSCounter.cs +++ b/osu.Game/Graphics/UserInterface/FPSCounter.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterface { - public class FPSCounter : VisibilityContainer, IHasCustomTooltip + public partial class FPSCounter : VisibilityContainer, IHasCustomTooltip { private OsuSpriteText counterUpdateFrameTime = null!; private OsuSpriteText counterDrawFPS = null!; diff --git a/osu.Game/Graphics/UserInterface/FPSCounterTooltip.cs b/osu.Game/Graphics/UserInterface/FPSCounterTooltip.cs index bf53bff9b4..17e7be1d8b 100644 --- a/osu.Game/Graphics/UserInterface/FPSCounterTooltip.cs +++ b/osu.Game/Graphics/UserInterface/FPSCounterTooltip.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterface { - public class FPSCounterTooltip : CompositeDrawable, ITooltip + public partial class FPSCounterTooltip : CompositeDrawable, ITooltip { private OsuTextFlowContainer textFlow = null!; diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index 0c18fd36fc..338f32f321 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -15,7 +15,7 @@ namespace osu.Game.Graphics.UserInterface /// /// A textbox which holds focus eagerly. /// - public class FocusedTextBox : OsuTextBox, IKeyBindingHandler + public partial class FocusedTextBox : OsuTextBox, IKeyBindingHandler { private bool focus; diff --git a/osu.Game/Graphics/UserInterface/GradientLineTabControl.cs b/osu.Game/Graphics/UserInterface/GradientLineTabControl.cs index e16f1ee897..7e29053035 100644 --- a/osu.Game/Graphics/UserInterface/GradientLineTabControl.cs +++ b/osu.Game/Graphics/UserInterface/GradientLineTabControl.cs @@ -13,7 +13,7 @@ using osu.Framework.Graphics.Colour; namespace osu.Game.Graphics.UserInterface { - public abstract class GradientLineTabControl : PageTabControl + public abstract partial class GradientLineTabControl : PageTabControl { protected Color4 LineColour { @@ -46,7 +46,7 @@ namespace osu.Game.Graphics.UserInterface Spacing = new Vector2(20, 0), }; - private class GradientLine : GridContainer + private partial class GradientLine : GridContainer { public GradientLine() { diff --git a/osu.Game/Graphics/UserInterface/GrayButton.cs b/osu.Game/Graphics/UserInterface/GrayButton.cs index d95032bce6..3df234e97d 100644 --- a/osu.Game/Graphics/UserInterface/GrayButton.cs +++ b/osu.Game/Graphics/UserInterface/GrayButton.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterface { - public class GrayButton : OsuAnimatedButton + public partial class GrayButton : OsuAnimatedButton { protected SpriteIcon Icon { get; private set; } protected Box Background { get; private set; } diff --git a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs index 0958e1832e..d74a4f2cdb 100644 --- a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs +++ b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs @@ -13,7 +13,7 @@ namespace osu.Game.Graphics.UserInterface /// The history of committed text can be navigated using up/down arrows. /// This resembles the operation of command-line terminals. /// - public class HistoryTextBox : FocusedTextBox + public partial class HistoryTextBox : FocusedTextBox { private readonly LimitedCapacityQueue messageHistory; diff --git a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs index 99cec7411c..ed1838abd0 100644 --- a/osu.Game/Graphics/UserInterface/HoverClickSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverClickSounds.cs @@ -19,7 +19,7 @@ namespace osu.Game.Graphics.UserInterface /// Adds hover and click sounds to a drawable. /// Does not draw anything. /// - public class HoverClickSounds : HoverSounds + public partial class HoverClickSounds : HoverSounds { public Bindable Enabled = new Bindable(true); diff --git a/osu.Game/Graphics/UserInterface/HoverSampleDebounceComponent.cs b/osu.Game/Graphics/UserInterface/HoverSampleDebounceComponent.cs index 20715309a2..53f1c06a67 100644 --- a/osu.Game/Graphics/UserInterface/HoverSampleDebounceComponent.cs +++ b/osu.Game/Graphics/UserInterface/HoverSampleDebounceComponent.cs @@ -14,7 +14,7 @@ namespace osu.Game.Graphics.UserInterface /// /// Handles debouncing hover sounds at a global level to ensure the effects are not overwhelming. /// - public abstract class HoverSampleDebounceComponent : CompositeDrawable + public abstract partial class HoverSampleDebounceComponent : CompositeDrawable { private Bindable lastPlaybackTime; diff --git a/osu.Game/Graphics/UserInterface/HoverSounds.cs b/osu.Game/Graphics/UserInterface/HoverSounds.cs index dd03e83ab1..012594b404 100644 --- a/osu.Game/Graphics/UserInterface/HoverSounds.cs +++ b/osu.Game/Graphics/UserInterface/HoverSounds.cs @@ -16,7 +16,7 @@ namespace osu.Game.Graphics.UserInterface /// Adds hover sounds to a drawable. /// Does not draw anything. /// - public class HoverSounds : HoverSampleDebounceComponent + public partial class HoverSounds : HoverSampleDebounceComponent { private Sample sampleHover; diff --git a/osu.Game/Graphics/UserInterface/IconButton.cs b/osu.Game/Graphics/UserInterface/IconButton.cs index e0b5999c4d..47f06715b5 100644 --- a/osu.Game/Graphics/UserInterface/IconButton.cs +++ b/osu.Game/Graphics/UserInterface/IconButton.cs @@ -11,7 +11,7 @@ using osu.Framework.Input.Events; namespace osu.Game.Graphics.UserInterface { - public class IconButton : OsuAnimatedButton + public partial class IconButton : OsuAnimatedButton { public const float DEFAULT_BUTTON_SIZE = 30; diff --git a/osu.Game/Graphics/UserInterface/LineGraph.cs b/osu.Game/Graphics/UserInterface/LineGraph.cs index fe634390a2..18c022818f 100644 --- a/osu.Game/Graphics/UserInterface/LineGraph.cs +++ b/osu.Game/Graphics/UserInterface/LineGraph.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Graphics.UserInterface { - public class LineGraph : Container + public partial class LineGraph : Container { /// /// Manually set the max value, otherwise will be used. diff --git a/osu.Game/Graphics/UserInterface/LoadingButton.cs b/osu.Game/Graphics/UserInterface/LoadingButton.cs index 44067bac8b..8a841ffc94 100644 --- a/osu.Game/Graphics/UserInterface/LoadingButton.cs +++ b/osu.Game/Graphics/UserInterface/LoadingButton.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterface { - public abstract class LoadingButton : OsuHoverContainer + public abstract partial class LoadingButton : OsuHoverContainer { private bool isLoading; diff --git a/osu.Game/Graphics/UserInterface/LoadingLayer.cs b/osu.Game/Graphics/UserInterface/LoadingLayer.cs index 9f6177c226..9059b61a33 100644 --- a/osu.Game/Graphics/UserInterface/LoadingLayer.cs +++ b/osu.Game/Graphics/UserInterface/LoadingLayer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Graphics.UserInterface /// Also optionally dims target elements. /// Useful for disabling all elements in a form and showing we are waiting on a response, for instance. /// - public class LoadingLayer : LoadingSpinner + public partial class LoadingLayer : LoadingSpinner { private readonly bool blockInput; diff --git a/osu.Game/Graphics/UserInterface/LoadingSpinner.cs b/osu.Game/Graphics/UserInterface/LoadingSpinner.cs index 864dd0a65e..0ea44dfe49 100644 --- a/osu.Game/Graphics/UserInterface/LoadingSpinner.cs +++ b/osu.Game/Graphics/UserInterface/LoadingSpinner.cs @@ -15,7 +15,7 @@ namespace osu.Game.Graphics.UserInterface /// /// A loading spinner. /// - public class LoadingSpinner : VisibilityContainer + public partial class LoadingSpinner : VisibilityContainer { private readonly SpriteIcon spinner; diff --git a/osu.Game/Graphics/UserInterface/Nub.cs b/osu.Game/Graphics/UserInterface/Nub.cs index db3a41e303..4f56872f42 100644 --- a/osu.Game/Graphics/UserInterface/Nub.cs +++ b/osu.Game/Graphics/UserInterface/Nub.cs @@ -19,7 +19,7 @@ using osu.Game.Overlays; namespace osu.Game.Graphics.UserInterface { - public class Nub : Container, IHasCurrentValue, IHasAccentColour + public partial class Nub : Container, IHasCurrentValue, IHasAccentColour { public const float HEIGHT = 15; diff --git a/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs b/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs index f720678a93..5ef590d253 100644 --- a/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuAnimatedButton.cs @@ -18,7 +18,7 @@ namespace osu.Game.Graphics.UserInterface /// /// Highlight on hover, bounce on click. /// - public class OsuAnimatedButton : OsuClickableContainer + public partial class OsuAnimatedButton : OsuClickableContainer { /// /// The colour that should be flashed when the is clicked. diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index dae5de2d65..1de15bc13c 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -20,7 +20,7 @@ namespace osu.Game.Graphics.UserInterface /// /// A button with added default sound effects. /// - public class OsuButton : Button + public partial class OsuButton : Button { public LocalisableString Text { diff --git a/osu.Game/Graphics/UserInterface/OsuCheckbox.cs b/osu.Game/Graphics/UserInterface/OsuCheckbox.cs index 8772c1e2d9..160105af1a 100644 --- a/osu.Game/Graphics/UserInterface/OsuCheckbox.cs +++ b/osu.Game/Graphics/UserInterface/OsuCheckbox.cs @@ -15,7 +15,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Graphics.UserInterface { - public class OsuCheckbox : Checkbox + public partial class OsuCheckbox : Checkbox { /// /// Whether to play sounds when the state changes as a result of user interaction. diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs index cc5ce8f46d..1b5f7cc4b5 100644 --- a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs @@ -12,7 +12,7 @@ using osu.Framework.Graphics.UserInterface; namespace osu.Game.Graphics.UserInterface { - public class OsuContextMenu : OsuMenu + public partial class OsuContextMenu : OsuMenu { private const int fade_duration = 250; diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenuSamples.cs b/osu.Game/Graphics/UserInterface/OsuContextMenuSamples.cs index c329974e28..6d7543c472 100644 --- a/osu.Game/Graphics/UserInterface/OsuContextMenuSamples.cs +++ b/osu.Game/Graphics/UserInterface/OsuContextMenuSamples.cs @@ -11,7 +11,7 @@ using osu.Framework.Graphics; namespace osu.Game.Graphics.UserInterface { - public class OsuContextMenuSamples : Component + public partial class OsuContextMenuSamples : Component { private Sample sampleClick; private Sample sampleOpen; diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index ce2a690e92..3230bb0569 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -22,7 +22,7 @@ using osuTK.Graphics; namespace osu.Game.Graphics.UserInterface { - public class OsuDropdown : Dropdown + public partial class OsuDropdown : Dropdown { private const float corner_radius = 5; @@ -32,7 +32,7 @@ namespace osu.Game.Graphics.UserInterface #region OsuDropdownMenu - protected class OsuDropdownMenu : DropdownMenu, IKeyBindingHandler + protected partial class OsuDropdownMenu : DropdownMenu, IKeyBindingHandler { public override bool HandleNonPositionalInput => State == MenuState.Open; @@ -135,7 +135,7 @@ namespace osu.Game.Graphics.UserInterface #region DrawableOsuDropdownMenuItem - public class DrawableOsuDropdownMenuItem : DrawableDropdownMenuItem + public partial class DrawableOsuDropdownMenuItem : DrawableDropdownMenuItem { // IsHovered is used public override bool HandlePositionalInput => true; @@ -203,7 +203,7 @@ namespace osu.Game.Graphics.UserInterface protected override Drawable CreateContent() => new Content(); - protected new class Content : CompositeDrawable, IHasText + protected new partial class Content : CompositeDrawable, IHasText { public LocalisableString Text { @@ -297,7 +297,7 @@ namespace osu.Game.Graphics.UserInterface #endregion - public class OsuDropdownHeader : DropdownHeader + public partial class OsuDropdownHeader : DropdownHeader { protected readonly SpriteText Text; diff --git a/osu.Game/Graphics/UserInterface/OsuEnumDropdown.cs b/osu.Game/Graphics/UserInterface/OsuEnumDropdown.cs index 3d4a8cf359..9ef58f4c49 100644 --- a/osu.Game/Graphics/UserInterface/OsuEnumDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuEnumDropdown.cs @@ -7,7 +7,7 @@ using System; namespace osu.Game.Graphics.UserInterface { - public class OsuEnumDropdown : OsuDropdown + public partial class OsuEnumDropdown : OsuDropdown where T : struct, Enum { public OsuEnumDropdown() diff --git a/osu.Game/Graphics/UserInterface/OsuMenu.cs b/osu.Game/Graphics/UserInterface/OsuMenu.cs index a11bffd05d..73d57af793 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenu.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenu.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterface { - public class OsuMenu : Menu + public partial class OsuMenu : Menu { private Sample sampleOpen; private Sample sampleClose; diff --git a/osu.Game/Graphics/UserInterface/OsuNumberBox.cs b/osu.Game/Graphics/UserInterface/OsuNumberBox.cs index 93d47792c8..f6a3abdaae 100644 --- a/osu.Game/Graphics/UserInterface/OsuNumberBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuNumberBox.cs @@ -7,7 +7,7 @@ using osu.Framework.Extensions; namespace osu.Game.Graphics.UserInterface { - public class OsuNumberBox : OsuTextBox + public partial class OsuNumberBox : OsuTextBox { protected override bool AllowIme => false; diff --git a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs index 305b1b6687..63c98d7838 100644 --- a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs @@ -19,7 +19,7 @@ using osu.Framework.Platform; namespace osu.Game.Graphics.UserInterface { - public class OsuPasswordTextBox : OsuTextBox, ISuppressKeyEventLogging + public partial class OsuPasswordTextBox : OsuTextBox, ISuppressKeyEventLogging { protected override Drawable GetDrawableCharacter(char c) => new FallingDownContainer { @@ -73,7 +73,7 @@ namespace osu.Game.Graphics.UserInterface private void updateCapsWarning(bool visible) => warning.FadeTo(visible ? 1 : 0, 250, Easing.OutQuint); - public class PasswordMaskChar : Container + public partial class PasswordMaskChar : Container { private readonly CircularContainer circle; @@ -110,7 +110,7 @@ namespace osu.Game.Graphics.UserInterface } } - private class CapsWarning : SpriteIcon, IHasTooltip + private partial class CapsWarning : SpriteIcon, IHasTooltip { public LocalisableString TooltipText => "caps lock is active"; diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index 4d3f4be8f6..6d6a591673 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -25,7 +25,7 @@ using osu.Game.Utils; namespace osu.Game.Graphics.UserInterface { - public class OsuSliderBar : SliderBar, IHasTooltip, IHasAccentColour + public partial class OsuSliderBar : SliderBar, IHasTooltip, IHasAccentColour where T : struct, IEquatable, IComparable, IConvertible { /// diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 3cfe401bb9..05309760e7 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -22,7 +22,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.UserInterface { - public class OsuTabControl : TabControl + public partial class OsuTabControl : TabControl { private Color4 accentColour; @@ -98,7 +98,7 @@ namespace osu.Game.Graphics.UserInterface strip.Width = Interpolation.ValueAt(Math.Clamp(Clock.ElapsedFrameTime, 0, 1000), strip.Width, StripWidth, 0, 500, Easing.OutQuint); } - public class OsuTabItem : TabItem, IHasAccentColour + public partial class OsuTabItem : TabItem, IHasAccentColour { protected readonly SpriteText Text; protected readonly Box Bar; diff --git a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs index 6e6296c24b..fa58ae27f2 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs @@ -22,7 +22,7 @@ namespace osu.Game.Graphics.UserInterface /// /// A Checkbox styled to be placed in line with an /// - public class OsuTabControlCheckbox : Checkbox + public partial class OsuTabControlCheckbox : Checkbox { private readonly Box box; private readonly SpriteText text; diff --git a/osu.Game/Graphics/UserInterface/OsuTabDropdown.cs b/osu.Game/Graphics/UserInterface/OsuTabDropdown.cs index d9d9a21401..01d072b6d7 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabDropdown.cs @@ -13,7 +13,7 @@ using osu.Framework.Input.Events; namespace osu.Game.Graphics.UserInterface { - public class OsuTabDropdown : OsuDropdown, IHasAccentColour + public partial class OsuTabDropdown : OsuDropdown, IHasAccentColour { private Color4 accentColour; @@ -60,7 +60,7 @@ namespace osu.Game.Graphics.UserInterface tabDropdownHeader.AccentColour = accentColour; } - private class OsuTabDropdownMenu : OsuDropdownMenu + private partial class OsuTabDropdownMenu : OsuDropdownMenu { public OsuTabDropdownMenu() { @@ -73,7 +73,7 @@ namespace osu.Game.Graphics.UserInterface protected override DrawableDropdownMenuItem CreateDrawableDropdownMenuItem(MenuItem item) => new DrawableOsuTabDropdownMenuItem(item); - private class DrawableOsuTabDropdownMenuItem : DrawableOsuDropdownMenuItem + private partial class DrawableOsuTabDropdownMenuItem : DrawableOsuDropdownMenuItem { public DrawableOsuTabDropdownMenuItem(MenuItem item) : base(item) @@ -83,7 +83,7 @@ namespace osu.Game.Graphics.UserInterface } } - protected class OsuTabDropdownHeader : OsuDropdownHeader, IHasAccentColour + protected partial class OsuTabDropdownHeader : OsuDropdownHeader, IHasAccentColour { private Color4 accentColour; diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs index 18977638f3..1114c29afd 100644 --- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs @@ -24,7 +24,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterface { - public class OsuTextBox : BasicTextBox + public partial class OsuTextBox : BasicTextBox { /// /// Whether to allow playing a different samples based on the type of character. @@ -302,7 +302,7 @@ namespace osu.Game.Graphics.UserInterface sampleLastPlaybackTime = Time.Current; }); - private class OsuCaret : Caret + private partial class OsuCaret : Caret { private const float caret_move_time = 60; @@ -349,7 +349,7 @@ namespace osu.Game.Graphics.UserInterface } } - private class CaretBeatSyncedContainer : BeatSyncedContainer + private partial class CaretBeatSyncedContainer : BeatSyncedContainer { private bool hasSelection; diff --git a/osu.Game/Graphics/UserInterface/PageSelector/PageEllipsis.cs b/osu.Game/Graphics/UserInterface/PageSelector/PageEllipsis.cs index b750abcd2b..068e477d79 100644 --- a/osu.Game/Graphics/UserInterface/PageSelector/PageEllipsis.cs +++ b/osu.Game/Graphics/UserInterface/PageSelector/PageEllipsis.cs @@ -11,7 +11,7 @@ using osu.Game.Overlays; namespace osu.Game.Graphics.UserInterface.PageSelector { - internal class PageEllipsis : CompositeDrawable + internal partial class PageEllipsis : CompositeDrawable { [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) diff --git a/osu.Game/Graphics/UserInterface/PageSelector/PageSelector.cs b/osu.Game/Graphics/UserInterface/PageSelector/PageSelector.cs index 7c5d38b91b..63f35d5f89 100644 --- a/osu.Game/Graphics/UserInterface/PageSelector/PageSelector.cs +++ b/osu.Game/Graphics/UserInterface/PageSelector/PageSelector.cs @@ -11,7 +11,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Graphics.UserInterface.PageSelector { - public class PageSelector : CompositeDrawable + public partial class PageSelector : CompositeDrawable { public readonly BindableInt CurrentPage = new BindableInt { MinValue = 0, }; diff --git a/osu.Game/Graphics/UserInterface/PageSelector/PageSelectorButton.cs b/osu.Game/Graphics/UserInterface/PageSelector/PageSelectorButton.cs index adeae4fc8d..9388f045d3 100644 --- a/osu.Game/Graphics/UserInterface/PageSelector/PageSelectorButton.cs +++ b/osu.Game/Graphics/UserInterface/PageSelector/PageSelectorButton.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays; namespace osu.Game.Graphics.UserInterface.PageSelector { - public abstract class PageSelectorButton : OsuClickableContainer + public abstract partial class PageSelectorButton : OsuClickableContainer { protected const int DURATION = 200; diff --git a/osu.Game/Graphics/UserInterface/PageSelector/PageSelectorPageButton.cs b/osu.Game/Graphics/UserInterface/PageSelector/PageSelectorPageButton.cs index 7696087195..3e5d1fac6d 100644 --- a/osu.Game/Graphics/UserInterface/PageSelector/PageSelectorPageButton.cs +++ b/osu.Game/Graphics/UserInterface/PageSelector/PageSelectorPageButton.cs @@ -10,7 +10,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.UserInterface.PageSelector { - public class PageSelectorPageButton : PageSelectorButton + public partial class PageSelectorPageButton : PageSelectorButton { private readonly BindableBool selected = new BindableBool(); diff --git a/osu.Game/Graphics/UserInterface/PageSelector/PageSelectorPrevNextButton.cs b/osu.Game/Graphics/UserInterface/PageSelector/PageSelectorPrevNextButton.cs index a96cc892d4..e5e0dab2f0 100644 --- a/osu.Game/Graphics/UserInterface/PageSelector/PageSelectorPrevNextButton.cs +++ b/osu.Game/Graphics/UserInterface/PageSelector/PageSelectorPrevNextButton.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterface.PageSelector { - public class PageSelectorPrevNextButton : PageSelectorButton + public partial class PageSelectorPrevNextButton : PageSelectorButton { private readonly bool rightAligned; private readonly LocalisableString text; diff --git a/osu.Game/Graphics/UserInterface/PageTabControl.cs b/osu.Game/Graphics/UserInterface/PageTabControl.cs index 13654fac85..2fe8acfbd5 100644 --- a/osu.Game/Graphics/UserInterface/PageTabControl.cs +++ b/osu.Game/Graphics/UserInterface/PageTabControl.cs @@ -18,7 +18,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.UserInterface { - public class PageTabControl : OsuTabControl + public partial class PageTabControl : OsuTabControl { protected override TabItem CreateTabItem(T value) => new PageTabItem(value); @@ -33,7 +33,7 @@ namespace osu.Game.Graphics.UserInterface AccentColour = colours.Yellow; } - public class PageTabItem : TabItem, IHasAccentColour + public partial class PageTabItem : TabItem, IHasAccentColour { private const float transition_duration = 100; diff --git a/osu.Game/Graphics/UserInterface/PercentageCounter.cs b/osu.Game/Graphics/UserInterface/PercentageCounter.cs index e5b0f0cbee..de93d9b2b4 100644 --- a/osu.Game/Graphics/UserInterface/PercentageCounter.cs +++ b/osu.Game/Graphics/UserInterface/PercentageCounter.cs @@ -14,7 +14,7 @@ namespace osu.Game.Graphics.UserInterface /// /// Used as an accuracy counter. Represented visually as a percentage. /// - public class PercentageCounter : RollingCounter + public partial class PercentageCounter : RollingCounter { protected override double RollingDuration => 750; diff --git a/osu.Game/Graphics/UserInterface/ProgressBar.cs b/osu.Game/Graphics/UserInterface/ProgressBar.cs index 774704223b..8f383c76db 100644 --- a/osu.Game/Graphics/UserInterface/ProgressBar.cs +++ b/osu.Game/Graphics/UserInterface/ProgressBar.cs @@ -11,7 +11,7 @@ using osuTK.Graphics; namespace osu.Game.Graphics.UserInterface { - public class ProgressBar : SliderBar + public partial class ProgressBar : SliderBar { public Action OnSeek; diff --git a/osu.Game/Graphics/UserInterface/RollingCounter.cs b/osu.Game/Graphics/UserInterface/RollingCounter.cs index 2f8c8414e2..b80c0e3b58 100644 --- a/osu.Game/Graphics/UserInterface/RollingCounter.cs +++ b/osu.Game/Graphics/UserInterface/RollingCounter.cs @@ -16,7 +16,7 @@ using osu.Framework.Localisation; namespace osu.Game.Graphics.UserInterface { - public abstract class RollingCounter : Container, IHasCurrentValue + public abstract partial class RollingCounter : Container, IHasCurrentValue where T : struct, IEquatable { private readonly BindableWithCurrent current = new BindableWithCurrent(); diff --git a/osu.Game/Graphics/UserInterface/ScoreCounter.cs b/osu.Game/Graphics/UserInterface/ScoreCounter.cs index 2efe27c842..255b2149f0 100644 --- a/osu.Game/Graphics/UserInterface/ScoreCounter.cs +++ b/osu.Game/Graphics/UserInterface/ScoreCounter.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.UserInterface { - public abstract class ScoreCounter : RollingCounter + public abstract partial class ScoreCounter : RollingCounter { protected override double RollingDuration => 1000; protected override Easing RollingEasing => Easing.Out; diff --git a/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs index edd705ca00..65dce422d6 100644 --- a/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs @@ -13,7 +13,7 @@ namespace osu.Game.Graphics.UserInterface /// /// A which follows the active screen (and allows navigation) in a stack. /// - public class ScreenBreadcrumbControl : BreadcrumbControl + public partial class ScreenBreadcrumbControl : BreadcrumbControl { public ScreenBreadcrumbControl(ScreenStack stack) { diff --git a/osu.Game/Graphics/UserInterface/SearchTextBox.cs b/osu.Game/Graphics/UserInterface/SearchTextBox.cs index 2c2597f149..2d09a239bb 100644 --- a/osu.Game/Graphics/UserInterface/SearchTextBox.cs +++ b/osu.Game/Graphics/UserInterface/SearchTextBox.cs @@ -10,7 +10,7 @@ using osuTK.Input; namespace osu.Game.Graphics.UserInterface { - public class SearchTextBox : FocusedTextBox + public partial class SearchTextBox : FocusedTextBox { protected virtual bool AllowCommit => false; diff --git a/osu.Game/Graphics/UserInterface/SeekLimitedSearchTextBox.cs b/osu.Game/Graphics/UserInterface/SeekLimitedSearchTextBox.cs index f64f455f6b..a85cd36808 100644 --- a/osu.Game/Graphics/UserInterface/SeekLimitedSearchTextBox.cs +++ b/osu.Game/Graphics/UserInterface/SeekLimitedSearchTextBox.cs @@ -8,7 +8,7 @@ namespace osu.Game.Graphics.UserInterface /// /// A which does not handle left/right arrow keys for seeking. /// - public class SeekLimitedSearchTextBox : BasicSearchTextBox + public partial class SeekLimitedSearchTextBox : BasicSearchTextBox { public override bool HandleLeftRightArrows => false; } diff --git a/osu.Game/Graphics/UserInterface/ShearedButton.cs b/osu.Game/Graphics/UserInterface/ShearedButton.cs index e406e273e6..f1afacb2f4 100644 --- a/osu.Game/Graphics/UserInterface/ShearedButton.cs +++ b/osu.Game/Graphics/UserInterface/ShearedButton.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterface { - public class ShearedButton : OsuClickableContainer + public partial class ShearedButton : OsuClickableContainer { public LocalisableString Text { diff --git a/osu.Game/Graphics/UserInterface/ShearedOverlayHeader.cs b/osu.Game/Graphics/UserInterface/ShearedOverlayHeader.cs index deb2374e88..99eb439f75 100644 --- a/osu.Game/Graphics/UserInterface/ShearedOverlayHeader.cs +++ b/osu.Game/Graphics/UserInterface/ShearedOverlayHeader.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterface { - public class ShearedOverlayHeader : CompositeDrawable + public partial class ShearedOverlayHeader : CompositeDrawable { public const float HEIGHT = main_area_height + 2 * corner_radius; diff --git a/osu.Game/Graphics/UserInterface/ShearedSearchTextBox.cs b/osu.Game/Graphics/UserInterface/ShearedSearchTextBox.cs index d7e027b3f9..7bd083f9d5 100644 --- a/osu.Game/Graphics/UserInterface/ShearedSearchTextBox.cs +++ b/osu.Game/Graphics/UserInterface/ShearedSearchTextBox.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterface { - public class ShearedSearchTextBox : CompositeDrawable, IHasCurrentValue + public partial class ShearedSearchTextBox : CompositeDrawable, IHasCurrentValue { private const float corner_radius = 7; @@ -95,7 +95,7 @@ namespace osu.Game.Graphics.UserInterface public override bool HandleNonPositionalInput => textBox.HandleNonPositionalInput; - private class InnerSearchTextBox : SearchTextBox + private partial class InnerSearchTextBox : SearchTextBox { [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -112,7 +112,7 @@ namespace osu.Game.Graphics.UserInterface protected override SpriteText CreatePlaceholder() => new SearchPlaceholder(); - internal class SearchPlaceholder : SpriteText + internal partial class SearchPlaceholder : SpriteText { public override void Show() { diff --git a/osu.Game/Graphics/UserInterface/ShearedToggleButton.cs b/osu.Game/Graphics/UserInterface/ShearedToggleButton.cs index 9ef09d799e..d5e0abe9d8 100644 --- a/osu.Game/Graphics/UserInterface/ShearedToggleButton.cs +++ b/osu.Game/Graphics/UserInterface/ShearedToggleButton.cs @@ -8,7 +8,7 @@ using osu.Framework.Bindables; namespace osu.Game.Graphics.UserInterface { - public class ShearedToggleButton : ShearedButton + public partial class ShearedToggleButton : ShearedButton { private Sample? sampleClick; private Sample? sampleOff; diff --git a/osu.Game/Graphics/UserInterface/ShowMoreButton.cs b/osu.Game/Graphics/UserInterface/ShowMoreButton.cs index ed64a31412..3afb7e701f 100644 --- a/osu.Game/Graphics/UserInterface/ShowMoreButton.cs +++ b/osu.Game/Graphics/UserInterface/ShowMoreButton.cs @@ -19,7 +19,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Graphics.UserInterface { - public class ShowMoreButton : LoadingButton + public partial class ShowMoreButton : LoadingButton { private const int duration = 200; @@ -115,7 +115,7 @@ namespace osu.Game.Graphics.UserInterface rightIcon.SetHoveredState(false); } - public class ChevronIcon : SpriteIcon + public partial class ChevronIcon : SpriteIcon { [Resolved] private OverlayColourProvider colourProvider { get; set; } diff --git a/osu.Game/Graphics/UserInterface/SlimEnumDropdown.cs b/osu.Game/Graphics/UserInterface/SlimEnumDropdown.cs index 534fcf76e5..e3f5bc65e6 100644 --- a/osu.Game/Graphics/UserInterface/SlimEnumDropdown.cs +++ b/osu.Game/Graphics/UserInterface/SlimEnumDropdown.cs @@ -9,12 +9,12 @@ using osu.Framework.Graphics.UserInterface; namespace osu.Game.Graphics.UserInterface { - public class SlimEnumDropdown : OsuEnumDropdown + public partial class SlimEnumDropdown : OsuEnumDropdown where T : struct, Enum { protected override DropdownHeader CreateHeader() => new SlimDropdownHeader(); - private class SlimDropdownHeader : OsuDropdownHeader + private partial class SlimDropdownHeader : OsuDropdownHeader { public SlimDropdownHeader() { diff --git a/osu.Game/Graphics/UserInterface/StarCounter.cs b/osu.Game/Graphics/UserInterface/StarCounter.cs index d9274bf2cb..d7d088d798 100644 --- a/osu.Game/Graphics/UserInterface/StarCounter.cs +++ b/osu.Game/Graphics/UserInterface/StarCounter.cs @@ -13,7 +13,7 @@ using osu.Framework.Graphics.Sprites; namespace osu.Game.Graphics.UserInterface { - public class StarCounter : Container + public partial class StarCounter : Container { private readonly FillFlowContainer stars; @@ -120,7 +120,7 @@ namespace osu.Game.Graphics.UserInterface } } - public class DefaultStar : Star + public partial class DefaultStar : Star { private const double scaling_duration = 1000; @@ -156,7 +156,7 @@ namespace osu.Game.Graphics.UserInterface } } - public abstract class Star : CompositeDrawable + public abstract partial class Star : CompositeDrawable { public abstract void DisplayAt(float scale); } diff --git a/osu.Game/Graphics/UserInterface/TimeSlider.cs b/osu.Game/Graphics/UserInterface/TimeSlider.cs index d45c6614aa..46f0821033 100644 --- a/osu.Game/Graphics/UserInterface/TimeSlider.cs +++ b/osu.Game/Graphics/UserInterface/TimeSlider.cs @@ -10,7 +10,7 @@ namespace osu.Game.Graphics.UserInterface /// /// A slider bar which displays a millisecond time value. /// - public class TimeSlider : OsuSliderBar + public partial class TimeSlider : OsuSliderBar { public override LocalisableString TooltipText => $"{Current.Value:N0} ms"; } diff --git a/osu.Game/Graphics/UserInterface/TriangleButton.cs b/osu.Game/Graphics/UserInterface/TriangleButton.cs index 60d1824e5a..3038813b89 100644 --- a/osu.Game/Graphics/UserInterface/TriangleButton.cs +++ b/osu.Game/Graphics/UserInterface/TriangleButton.cs @@ -15,7 +15,7 @@ namespace osu.Game.Graphics.UserInterface /// /// A button with moving triangles in the background. /// - public class TriangleButton : OsuButton, IFilterable + public partial class TriangleButton : OsuButton, IFilterable { protected Triangles Triangles { get; private set; } diff --git a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs index 1b8848f3d5..aa542b8f49 100644 --- a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs +++ b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs @@ -22,7 +22,7 @@ using osu.Game.Screens.Select; namespace osu.Game.Graphics.UserInterface { - public class TwoLayerButton : OsuClickableContainer + public partial class TwoLayerButton : OsuClickableContainer { private readonly BouncingIcon bouncingIcon; @@ -207,7 +207,7 @@ namespace osu.Game.Graphics.UserInterface return base.OnClick(e); } - private class BouncingIcon : BeatSyncedContainer + private partial class BouncingIcon : BeatSyncedContainer { private const double beat_in_time = 60; diff --git a/osu.Game/Graphics/UserInterfaceV2/ColourDisplay.cs b/osu.Game/Graphics/UserInterfaceV2/ColourDisplay.cs index 93852f19c4..9ddbf84c39 100644 --- a/osu.Game/Graphics/UserInterfaceV2/ColourDisplay.cs +++ b/osu.Game/Graphics/UserInterfaceV2/ColourDisplay.cs @@ -24,7 +24,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 /// /// A component which displays a colour along with related description text. /// - public class ColourDisplay : CompositeDrawable, IHasCurrentValue + public partial class ColourDisplay : CompositeDrawable, IHasCurrentValue { /// /// Invoked when the user has requested the colour corresponding to this @@ -86,7 +86,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 }; } - private class ColourCircle : OsuClickableContainer, IHasPopover, IHasContextMenu + private partial class ColourCircle : OsuClickableContainer, IHasPopover, IHasContextMenu { public Bindable Current { get; } = new Bindable(); diff --git a/osu.Game/Graphics/UserInterfaceV2/ColourPalette.cs b/osu.Game/Graphics/UserInterfaceV2/ColourPalette.cs index f61d6db8b1..f554887510 100644 --- a/osu.Game/Graphics/UserInterfaceV2/ColourPalette.cs +++ b/osu.Game/Graphics/UserInterfaceV2/ColourPalette.cs @@ -23,7 +23,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 /// /// A component which displays a collection of colours in individual s. /// - public class ColourPalette : CompositeDrawable + public partial class ColourPalette : CompositeDrawable { public BindableList Colours { get; } = new BindableList(); @@ -119,7 +119,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 } } - internal class AddColourButton : CompositeDrawable + internal partial class AddColourButton : CompositeDrawable { public Action Action { diff --git a/osu.Game/Graphics/UserInterfaceV2/LabelledColourPalette.cs b/osu.Game/Graphics/UserInterfaceV2/LabelledColourPalette.cs index b144f8f696..721d8990ba 100644 --- a/osu.Game/Graphics/UserInterfaceV2/LabelledColourPalette.cs +++ b/osu.Game/Graphics/UserInterfaceV2/LabelledColourPalette.cs @@ -9,7 +9,7 @@ using osu.Framework.Localisation; namespace osu.Game.Graphics.UserInterfaceV2 { - public class LabelledColourPalette : LabelledDrawable + public partial class LabelledColourPalette : LabelledDrawable { public LabelledColourPalette() : base(true) diff --git a/osu.Game/Graphics/UserInterfaceV2/LabelledComponent.cs b/osu.Game/Graphics/UserInterfaceV2/LabelledComponent.cs index 977ef5d7bc..8fd9a62ad7 100644 --- a/osu.Game/Graphics/UserInterfaceV2/LabelledComponent.cs +++ b/osu.Game/Graphics/UserInterfaceV2/LabelledComponent.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics.UserInterface; namespace osu.Game.Graphics.UserInterfaceV2 { - public abstract class LabelledComponent : LabelledDrawable, IHasCurrentValue + public abstract partial class LabelledComponent : LabelledDrawable, IHasCurrentValue where TDrawable : Drawable, IHasCurrentValue { protected LabelledComponent(bool padded) diff --git a/osu.Game/Graphics/UserInterfaceV2/LabelledDrawable.cs b/osu.Game/Graphics/UserInterfaceV2/LabelledDrawable.cs index 8c98a3e0a7..9b7087ce6d 100644 --- a/osu.Game/Graphics/UserInterfaceV2/LabelledDrawable.cs +++ b/osu.Game/Graphics/UserInterfaceV2/LabelledDrawable.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterfaceV2 { - public abstract class LabelledDrawable : CompositeDrawable + public abstract partial class LabelledDrawable : CompositeDrawable where T : Drawable { private float? fixedLabelWidth; diff --git a/osu.Game/Graphics/UserInterfaceV2/LabelledDropdown.cs b/osu.Game/Graphics/UserInterfaceV2/LabelledDropdown.cs index bfb009658d..0e2ea362da 100644 --- a/osu.Game/Graphics/UserInterfaceV2/LabelledDropdown.cs +++ b/osu.Game/Graphics/UserInterfaceV2/LabelledDropdown.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Graphics.UserInterfaceV2 { - public class LabelledDropdown : LabelledComponent, TItem> + public partial class LabelledDropdown : LabelledComponent, TItem> { public LabelledDropdown() : base(true) diff --git a/osu.Game/Graphics/UserInterfaceV2/LabelledEnumDropdown.cs b/osu.Game/Graphics/UserInterfaceV2/LabelledEnumDropdown.cs index 594f132154..3ca460be90 100644 --- a/osu.Game/Graphics/UserInterfaceV2/LabelledEnumDropdown.cs +++ b/osu.Game/Graphics/UserInterfaceV2/LabelledEnumDropdown.cs @@ -8,7 +8,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Graphics.UserInterfaceV2 { - public class LabelledEnumDropdown : LabelledDropdown + public partial class LabelledEnumDropdown : LabelledDropdown where TEnum : struct, Enum { protected override OsuDropdown CreateDropdown() => new OsuEnumDropdown(); diff --git a/osu.Game/Graphics/UserInterfaceV2/LabelledNumberBox.cs b/osu.Game/Graphics/UserInterfaceV2/LabelledNumberBox.cs index cb032698ef..2643db0547 100644 --- a/osu.Game/Graphics/UserInterfaceV2/LabelledNumberBox.cs +++ b/osu.Game/Graphics/UserInterfaceV2/LabelledNumberBox.cs @@ -7,7 +7,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Graphics.UserInterfaceV2 { - public class LabelledNumberBox : LabelledTextBox + public partial class LabelledNumberBox : LabelledTextBox { protected override OsuTextBox CreateTextBox() => new OsuNumberBox(); } diff --git a/osu.Game/Graphics/UserInterfaceV2/LabelledSliderBar.cs b/osu.Game/Graphics/UserInterfaceV2/LabelledSliderBar.cs index 50b6834f01..00f4ef1a30 100644 --- a/osu.Game/Graphics/UserInterfaceV2/LabelledSliderBar.cs +++ b/osu.Game/Graphics/UserInterfaceV2/LabelledSliderBar.cs @@ -9,7 +9,7 @@ using osu.Game.Overlays.Settings; namespace osu.Game.Graphics.UserInterfaceV2 { - public class LabelledSliderBar : LabelledComponent, TNumber> + public partial class LabelledSliderBar : LabelledComponent, TNumber> where TNumber : struct, IEquatable, IComparable, IConvertible { public LabelledSliderBar() diff --git a/osu.Game/Graphics/UserInterfaceV2/LabelledSwitchButton.cs b/osu.Game/Graphics/UserInterfaceV2/LabelledSwitchButton.cs index 99a1a98d5b..3c27829de3 100644 --- a/osu.Game/Graphics/UserInterfaceV2/LabelledSwitchButton.cs +++ b/osu.Game/Graphics/UserInterfaceV2/LabelledSwitchButton.cs @@ -5,7 +5,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 { - public class LabelledSwitchButton : LabelledComponent + public partial class LabelledSwitchButton : LabelledComponent { public LabelledSwitchButton() : base(true) diff --git a/osu.Game/Graphics/UserInterfaceV2/LabelledTextBox.cs b/osu.Game/Graphics/UserInterfaceV2/LabelledTextBox.cs index 97bc845766..454be02d0b 100644 --- a/osu.Game/Graphics/UserInterfaceV2/LabelledTextBox.cs +++ b/osu.Game/Graphics/UserInterfaceV2/LabelledTextBox.cs @@ -13,7 +13,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Graphics.UserInterfaceV2 { - public class LabelledTextBox : LabelledComponent + public partial class LabelledTextBox : LabelledComponent { public event TextBox.OnCommitHandler OnCommit; diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuColourPicker.cs b/osu.Game/Graphics/UserInterfaceV2/OsuColourPicker.cs index f4ae2f0fd7..fed17eaf20 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuColourPicker.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuColourPicker.cs @@ -7,7 +7,7 @@ using osu.Framework.Graphics.UserInterface; namespace osu.Game.Graphics.UserInterfaceV2 { - public class OsuColourPicker : ColourPicker + public partial class OsuColourPicker : ColourPicker { public OsuColourPicker() { diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelector.cs b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelector.cs index 0e348108aa..21f926ba42 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelector.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelector.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Graphics.UserInterfaceV2 { - public class OsuDirectorySelector : DirectorySelector + public partial class OsuDirectorySelector : DirectorySelector { public const float ITEM_HEIGHT = 20; diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs index 08a569269e..0917b9db97 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorBreadcrumbDisplay.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterfaceV2 { - internal class OsuDirectorySelectorBreadcrumbDisplay : DirectorySelectorBreadcrumbDisplay + internal partial class OsuDirectorySelectorBreadcrumbDisplay : DirectorySelectorBreadcrumbDisplay { protected override Drawable CreateCaption() => new OsuSpriteText { @@ -30,7 +30,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 Padding = new MarginPadding(15); } - private class OsuBreadcrumbDisplayComputer : OsuBreadcrumbDisplayDirectory + private partial class OsuBreadcrumbDisplayComputer : OsuBreadcrumbDisplayDirectory { protected override IconUsage? Icon => null; @@ -40,7 +40,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 } } - private class OsuBreadcrumbDisplayDirectory : OsuDirectorySelectorDirectory + private partial class OsuBreadcrumbDisplayDirectory : OsuDirectorySelectorDirectory { public OsuBreadcrumbDisplayDirectory(DirectoryInfo directory, string displayName = null) : base(directory, displayName) diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorDirectory.cs b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorDirectory.cs index 1896d7ee4d..932017b03e 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorDirectory.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorDirectory.cs @@ -16,7 +16,7 @@ using osu.Game.Overlays; namespace osu.Game.Graphics.UserInterfaceV2 { - internal class OsuDirectorySelectorDirectory : DirectorySelectorDirectory + internal partial class OsuDirectorySelectorDirectory : DirectorySelectorDirectory { public OsuDirectorySelectorDirectory(DirectoryInfo directory, string displayName = null) : base(directory, displayName) @@ -45,7 +45,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 ? FontAwesome.Solid.Database : FontAwesome.Regular.Folder; - internal class Background : CompositeDrawable + internal partial class Background : CompositeDrawable { [BackgroundDependencyLoader(true)] private void load(OverlayColourProvider overlayColourProvider, OsuColour colours) diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs index 7aaf12ca34..7665ed507f 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorHiddenToggle.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Graphics.UserInterfaceV2 { - internal class OsuDirectorySelectorHiddenToggle : OsuCheckbox + internal partial class OsuDirectorySelectorHiddenToggle : OsuCheckbox { public OsuDirectorySelectorHiddenToggle() { diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorParentDirectory.cs b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorParentDirectory.cs index 7d2b28e803..beaeb86243 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorParentDirectory.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuDirectorySelectorParentDirectory.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Sprites; namespace osu.Game.Graphics.UserInterfaceV2 { - internal class OsuDirectorySelectorParentDirectory : OsuDirectorySelectorDirectory + internal partial class OsuDirectorySelectorParentDirectory : OsuDirectorySelectorDirectory { protected override IconUsage? Icon => FontAwesome.Solid.Folder; diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs b/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs index 70af68d595..37e15c6127 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs @@ -16,7 +16,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Graphics.UserInterfaceV2 { - public class OsuFileSelector : FileSelector + public partial class OsuFileSelector : FileSelector { public OsuFileSelector(string initialPath = null, string[] validFileExtensions = null) : base(initialPath, validFileExtensions) @@ -43,7 +43,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 protected override void NotifySelectionError() => this.FlashColour(Colour4.Red, 300); - protected class OsuDirectoryListingFile : DirectoryListingFile + protected partial class OsuDirectoryListingFile : DirectoryListingFile { public OsuDirectoryListingFile(FileInfo file) : base(file) diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuHSVColourPicker.cs b/osu.Game/Graphics/UserInterfaceV2/OsuHSVColourPicker.cs index 1a8fa435cb..ff51f3aa92 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuHSVColourPicker.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuHSVColourPicker.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterfaceV2 { - public class OsuHSVColourPicker : HSVColourPicker + public partial class OsuHSVColourPicker : HSVColourPicker { private const float spacing = 10; private const float corner_radius = 10; @@ -42,7 +42,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 Colour = Colour4.Black.Opacity(0.3f) }; - private class OsuHueSelector : HueSelector + private partial class OsuHueSelector : HueSelector { public OsuHueSelector() { @@ -52,7 +52,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 protected override Drawable CreateSliderNub() => new SliderNub(this); - private class SliderNub : CompositeDrawable + private partial class SliderNub : CompositeDrawable { private readonly Bindable hue; private readonly Box fill; @@ -85,7 +85,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 } } - private class OsuSaturationValueSelector : SaturationValueSelector + private partial class OsuSaturationValueSelector : SaturationValueSelector { public OsuSaturationValueSelector() { @@ -95,7 +95,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 protected override Marker CreateMarker() => new OsuMarker(); - private class OsuMarker : Marker + private partial class OsuMarker : Marker { private readonly Box previewBox; diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuHexColourPicker.cs b/osu.Game/Graphics/UserInterfaceV2/OsuHexColourPicker.cs index 12313791f0..9aa650d88d 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuHexColourPicker.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuHexColourPicker.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays; namespace osu.Game.Graphics.UserInterfaceV2 { - public class OsuHexColourPicker : HexColourPicker + public partial class OsuHexColourPicker : HexColourPicker { public OsuHexColourPicker() { @@ -31,7 +31,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 protected override TextBox CreateHexCodeTextBox() => new OsuTextBox(); protected override ColourPreview CreateColourPreview() => new OsuColourPreview(); - private class OsuColourPreview : ColourPreview + private partial class OsuColourPreview : ColourPreview { private readonly Box preview; diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuPopover.cs b/osu.Game/Graphics/UserInterfaceV2/OsuPopover.cs index e468e14f45..e66e48373c 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuPopover.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuPopover.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterfaceV2 { - public class OsuPopover : Popover, IKeyBindingHandler + public partial class OsuPopover : Popover, IKeyBindingHandler { private const float fade_duration = 250; private const double scale_duration = 500; diff --git a/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs b/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs index 4477633da1..8bdfa01e9c 100644 --- a/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs +++ b/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Graphics.UserInterfaceV2 { - public class RoundedButton : OsuButton, IFilterable + public partial class RoundedButton : OsuButton, IFilterable { public override float Height { diff --git a/osu.Game/Graphics/UserInterfaceV2/SwitchButton.cs b/osu.Game/Graphics/UserInterfaceV2/SwitchButton.cs index b5c1c0a854..cf569a73ca 100644 --- a/osu.Game/Graphics/UserInterfaceV2/SwitchButton.cs +++ b/osu.Game/Graphics/UserInterfaceV2/SwitchButton.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Graphics.UserInterfaceV2 { - public class SwitchButton : Checkbox + public partial class SwitchButton : Checkbox { private const float border_thickness = 4.5f; private const float padding = 1.25f; @@ -128,7 +128,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 circularContainer.TransformBorderTo((Current.Value ? enabledColour : disabledColour).Lighten(IsHovered ? 0.3f : 0)); } - private class CircularBorderContainer : CircularContainer + private partial class CircularBorderContainer : CircularContainer { public void TransformBorderTo(ColourInfo colour) => this.TransformTo(nameof(BorderColour), colour, 250, Easing.OutQuint); diff --git a/osu.Game/Input/Bindings/DatabasedKeyBindingContainer.cs b/osu.Game/Input/Bindings/DatabasedKeyBindingContainer.cs index 4f079ab435..fab0be6cf0 100644 --- a/osu.Game/Input/Bindings/DatabasedKeyBindingContainer.cs +++ b/osu.Game/Input/Bindings/DatabasedKeyBindingContainer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Input.Bindings /// A KeyBindingInputManager with a database backing for custom overrides. /// /// The type of the custom action. - public class DatabasedKeyBindingContainer : KeyBindingContainer + public partial class DatabasedKeyBindingContainer : KeyBindingContainer where T : struct { private readonly RulesetInfo ruleset; diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index ebdc446ec8..07cef50dec 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -11,7 +11,7 @@ using osu.Game.Localisation; namespace osu.Game.Input.Bindings { - public class GlobalActionContainer : DatabasedKeyBindingContainer, IHandleGlobalKeyboardInput + public partial class GlobalActionContainer : DatabasedKeyBindingContainer, IHandleGlobalKeyboardInput { private readonly Drawable? handler; diff --git a/osu.Game/Input/ConfineMouseTracker.cs b/osu.Game/Input/ConfineMouseTracker.cs index 7e8ace5693..de8660dbce 100644 --- a/osu.Game/Input/ConfineMouseTracker.cs +++ b/osu.Game/Input/ConfineMouseTracker.cs @@ -18,7 +18,7 @@ namespace osu.Game.Input /// If is true, we should also confine the mouse cursor if it has been /// requested with . /// - public class ConfineMouseTracker : Component + public partial class ConfineMouseTracker : Component { private Bindable frameworkConfineMode; private Bindable frameworkWindowMode; diff --git a/osu.Game/Input/GameIdleTracker.cs b/osu.Game/Input/GameIdleTracker.cs index d82cc25851..560ec1bc1e 100644 --- a/osu.Game/Input/GameIdleTracker.cs +++ b/osu.Game/Input/GameIdleTracker.cs @@ -7,7 +7,7 @@ using osu.Framework.Input; namespace osu.Game.Input { - public class GameIdleTracker : IdleTracker + public partial class GameIdleTracker : IdleTracker { private InputManager inputManager; diff --git a/osu.Game/Input/IdleTracker.cs b/osu.Game/Input/IdleTracker.cs index 45036b3e41..54157c9e3d 100644 --- a/osu.Game/Input/IdleTracker.cs +++ b/osu.Game/Input/IdleTracker.cs @@ -17,7 +17,7 @@ namespace osu.Game.Input /// /// Track whether the end-user is in an idle state, based on their last interaction with the game. /// - public class IdleTracker : Component, IKeyBindingHandler, IKeyBindingHandler, IHandleGlobalKeyboardInput + public partial class IdleTracker : Component, IKeyBindingHandler, IKeyBindingHandler, IHandleGlobalKeyboardInput { private readonly double timeToIdle; diff --git a/osu.Game/Input/OsuUserInputManager.cs b/osu.Game/Input/OsuUserInputManager.cs index 7a9002a004..ab43497156 100644 --- a/osu.Game/Input/OsuUserInputManager.cs +++ b/osu.Game/Input/OsuUserInputManager.cs @@ -8,7 +8,7 @@ using osuTK.Input; namespace osu.Game.Input { - public class OsuUserInputManager : UserInputManager + public partial class OsuUserInputManager : UserInputManager { internal OsuUserInputManager() { diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 65f78e1fd7..f2b9b6e968 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -26,7 +26,7 @@ using osu.Game.Users; namespace osu.Game.Online.API { - public class APIAccess : Component, IAPIProvider + public partial class APIAccess : Component, IAPIProvider { private readonly OsuConfigManager config; diff --git a/osu.Game/Online/API/DummyAPIAccess.cs b/osu.Game/Online/API/DummyAPIAccess.cs index 609efd8ab6..abe2755654 100644 --- a/osu.Game/Online/API/DummyAPIAccess.cs +++ b/osu.Game/Online/API/DummyAPIAccess.cs @@ -15,7 +15,7 @@ using osu.Game.Users; namespace osu.Game.Online.API { - public class DummyAPIAccess : Component, IAPIProvider + public partial class DummyAPIAccess : Component, IAPIProvider { public const int DUMMY_USER_ID = 1001; diff --git a/osu.Game/Online/BeatmapDownloadTracker.cs b/osu.Game/Online/BeatmapDownloadTracker.cs index 19708cc07d..144c4445a3 100644 --- a/osu.Game/Online/BeatmapDownloadTracker.cs +++ b/osu.Game/Online/BeatmapDownloadTracker.cs @@ -10,7 +10,7 @@ using osu.Game.Online.API; namespace osu.Game.Online { - public class BeatmapDownloadTracker : DownloadTracker + public partial class BeatmapDownloadTracker : DownloadTracker { [Resolved(CanBeNull = true)] protected BeatmapModelDownloader? Downloader { get; private set; } diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 25a53360f0..eaef940d5f 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -24,7 +24,7 @@ namespace osu.Game.Online.Chat /// /// Manages everything channel related /// - public class ChannelManager : CompositeComponent, IChannelPostTarget + public partial class ChannelManager : CompositeComponent, IChannelPostTarget { /// /// The channels the player joins on startup diff --git a/osu.Game/Online/Chat/DrawableLinkCompiler.cs b/osu.Game/Online/Chat/DrawableLinkCompiler.cs index 44e66c1a69..ee53c00668 100644 --- a/osu.Game/Online/Chat/DrawableLinkCompiler.cs +++ b/osu.Game/Online/Chat/DrawableLinkCompiler.cs @@ -20,7 +20,7 @@ namespace osu.Game.Online.Chat /// /// An invisible drawable that brings multiple pieces together to form a consumable clickable link. /// - public class DrawableLinkCompiler : OsuHoverContainer + public partial class DrawableLinkCompiler : OsuHoverContainer { /// /// Each word part of a chat link (split for word-wrap support). @@ -52,7 +52,7 @@ namespace osu.Game.Online.Chat protected override IEnumerable EffectTargets => Parts; - private class LinkHoverSounds : HoverClickSounds + private partial class LinkHoverSounds : HoverClickSounds { private readonly List parts; diff --git a/osu.Game/Online/Chat/ExternalLinkOpener.cs b/osu.Game/Online/Chat/ExternalLinkOpener.cs index 587159179f..201212c648 100644 --- a/osu.Game/Online/Chat/ExternalLinkOpener.cs +++ b/osu.Game/Online/Chat/ExternalLinkOpener.cs @@ -13,7 +13,7 @@ using osu.Game.Overlays.Dialog; namespace osu.Game.Online.Chat { - public class ExternalLinkOpener : Component + public partial class ExternalLinkOpener : Component { [Resolved] private GameHost host { get; set; } = null!; @@ -37,7 +37,7 @@ namespace osu.Game.Online.Chat host.OpenUrlExternally(url); } - public class ExternalLinkDialog : PopupDialog + public partial class ExternalLinkDialog : PopupDialog { public ExternalLinkDialog(string url, Action openExternalLinkAction, Action copyExternalLinkAction) { diff --git a/osu.Game/Online/Chat/MessageNotifier.cs b/osu.Game/Online/Chat/MessageNotifier.cs index 22c2b4690e..4872d93467 100644 --- a/osu.Game/Online/Chat/MessageNotifier.cs +++ b/osu.Game/Online/Chat/MessageNotifier.cs @@ -23,7 +23,7 @@ namespace osu.Game.Online.Chat /// /// Component that handles creating and posting notifications for incoming messages. /// - public class MessageNotifier : Component + public partial class MessageNotifier : Component { [Resolved] private INotificationOverlay notifications { get; set; } @@ -138,7 +138,7 @@ namespace osu.Game.Online.Chat return Regex.IsMatch(message, $@"(^|\W)({fullName}|{underscoreName})($|\W)", RegexOptions.IgnoreCase); } - public class PrivateMessageNotification : HighlightMessageNotification + public partial class PrivateMessageNotification : HighlightMessageNotification { public PrivateMessageNotification(Message message, Channel channel) : base(message, channel) @@ -148,7 +148,7 @@ namespace osu.Game.Online.Chat } } - public class MentionNotification : HighlightMessageNotification + public partial class MentionNotification : HighlightMessageNotification { public MentionNotification(Message message, Channel channel) : base(message, channel) @@ -158,7 +158,7 @@ namespace osu.Game.Online.Chat } } - public abstract class HighlightMessageNotification : SimpleNotification + public abstract partial class HighlightMessageNotification : SimpleNotification { protected HighlightMessageNotification(Message message, Channel channel) { diff --git a/osu.Game/Online/Chat/NowPlayingCommand.cs b/osu.Game/Online/Chat/NowPlayingCommand.cs index 6a25ceb919..76f1de5f29 100644 --- a/osu.Game/Online/Chat/NowPlayingCommand.cs +++ b/osu.Game/Online/Chat/NowPlayingCommand.cs @@ -12,7 +12,7 @@ using osu.Game.Users; namespace osu.Game.Online.Chat { - public class NowPlayingCommand : Component + public partial class NowPlayingCommand : Component { [Resolved] private IChannelPostTarget channelManager { get; set; } diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs index de68dd231f..9c89333ee7 100644 --- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs +++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs @@ -23,7 +23,7 @@ namespace osu.Game.Online.Chat /// /// Display a chat channel in an insolated region. /// - public class StandAloneChatDisplay : CompositeDrawable + public partial class StandAloneChatDisplay : CompositeDrawable { public readonly Bindable Channel = new Bindable(); @@ -120,7 +120,7 @@ namespace osu.Game.Online.Chat AddInternal(drawableChannel); } - public class ChatTextBox : HistoryTextBox + public partial class ChatTextBox : HistoryTextBox { protected override bool OnKeyDown(KeyDownEvent e) { @@ -156,7 +156,7 @@ namespace osu.Game.Online.Chat public Action FocusLost; } - public class StandAloneDrawableChannel : DrawableChannel + public partial class StandAloneDrawableChannel : DrawableChannel { public Func CreateChatLineAction; @@ -170,7 +170,7 @@ namespace osu.Game.Online.Chat protected override DaySeparator CreateDaySeparator(DateTimeOffset time) => new StandAloneDaySeparator(time); } - protected class StandAloneDaySeparator : DaySeparator + protected partial class StandAloneDaySeparator : DaySeparator { protected override float TextSize => 14; protected override float LineHeight => 1; @@ -190,7 +190,7 @@ namespace osu.Game.Online.Chat } } - protected class StandAloneMessage : ChatLine + protected partial class StandAloneMessage : ChatLine { protected override float TextSize => 15; protected override float Spacing => 5; diff --git a/osu.Game/Online/DownloadTracker.cs b/osu.Game/Online/DownloadTracker.cs index 85af9abb33..27a765ca20 100644 --- a/osu.Game/Online/DownloadTracker.cs +++ b/osu.Game/Online/DownloadTracker.cs @@ -6,7 +6,7 @@ using osu.Framework.Graphics; namespace osu.Game.Online { - public abstract class DownloadTracker : Component + public abstract partial class DownloadTracker : Component where T : class { public readonly T TrackedItem; diff --git a/osu.Game/Online/Leaderboards/DrawableRank.cs b/osu.Game/Online/Leaderboards/DrawableRank.cs index 35bdc4e31f..5a65c15444 100644 --- a/osu.Game/Online/Leaderboards/DrawableRank.cs +++ b/osu.Game/Online/Leaderboards/DrawableRank.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Online.Leaderboards { - public class DrawableRank : CompositeDrawable + public partial class DrawableRank : CompositeDrawable { private readonly ScoreRank rank; diff --git a/osu.Game/Online/Leaderboards/Leaderboard.cs b/osu.Game/Online/Leaderboards/Leaderboard.cs index 69b4e5b209..93aa0b95a7 100644 --- a/osu.Game/Online/Leaderboards/Leaderboard.cs +++ b/osu.Game/Online/Leaderboards/Leaderboard.cs @@ -31,7 +31,7 @@ namespace osu.Game.Online.Leaderboards /// /// The scope of the leaderboard (ie. global or local). /// The score model class. - public abstract class Leaderboard : CompositeDrawable + public abstract partial class Leaderboard : CompositeDrawable { /// /// The currently displayed scores. diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index a7b6bd044d..e20b28ee0c 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -37,7 +37,7 @@ using osu.Game.Utils; namespace osu.Game.Online.Leaderboards { - public class LeaderboardScore : OsuClickableContainer, IHasContextMenu, IHasCustomTooltip + public partial class LeaderboardScore : OsuClickableContainer, IHasContextMenu, IHasCustomTooltip { public const float HEIGHT = 60; @@ -310,7 +310,7 @@ namespace osu.Game.Online.Leaderboards base.OnHoverLost(e); } - private class ScoreComponentLabel : Container, IHasTooltip + private partial class ScoreComponentLabel : Container, IHasTooltip { private const float icon_size = 20; private readonly FillFlowContainer content; @@ -372,7 +372,7 @@ namespace osu.Game.Online.Leaderboards } } - private class RankLabel : Container, IHasTooltip + private partial class RankLabel : Container, IHasTooltip { public RankLabel(int? rank) { @@ -391,7 +391,7 @@ namespace osu.Game.Online.Leaderboards public LocalisableString TooltipText { get; } } - private class DateLabel : DrawableDate + private partial class DateLabel : DrawableDate { public DateLabel(DateTimeOffset date) : base(date) diff --git a/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs b/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs index f51f57c031..170f266307 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs @@ -20,7 +20,7 @@ using osu.Game.Configuration; namespace osu.Game.Online.Leaderboards { - public class LeaderboardScoreTooltip : VisibilityContainer, ITooltip + public partial class LeaderboardScoreTooltip : VisibilityContainer, ITooltip { private OsuSpriteText timestampLabel = null!; private FillFlowContainer topScoreStatistics = null!; @@ -147,7 +147,7 @@ namespace osu.Game.Online.Leaderboards public void Move(Vector2 pos) => Position = pos; - private class HitResultCell : CompositeDrawable + private partial class HitResultCell : CompositeDrawable { private readonly LocalisableString displayName; private readonly HitResult result; @@ -189,7 +189,7 @@ namespace osu.Game.Online.Leaderboards } } - private class ModCell : CompositeDrawable + private partial class ModCell : CompositeDrawable { private readonly Mod mod; diff --git a/osu.Game/Online/Leaderboards/UpdateableRank.cs b/osu.Game/Online/Leaderboards/UpdateableRank.cs index e640fe8494..46cfe8ec65 100644 --- a/osu.Game/Online/Leaderboards/UpdateableRank.cs +++ b/osu.Game/Online/Leaderboards/UpdateableRank.cs @@ -9,7 +9,7 @@ using osu.Game.Scoring; namespace osu.Game.Online.Leaderboards { - public class UpdateableRank : ModelBackedDrawable + public partial class UpdateableRank : ModelBackedDrawable { public ScoreRank? Rank { diff --git a/osu.Game/Online/Leaderboards/UserTopScoreContainer.cs b/osu.Game/Online/Leaderboards/UserTopScoreContainer.cs index 391e8804f0..af59da2fb8 100644 --- a/osu.Game/Online/Leaderboards/UserTopScoreContainer.cs +++ b/osu.Game/Online/Leaderboards/UserTopScoreContainer.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Online.Leaderboards { - public class UserTopScoreContainer : VisibilityContainer + public partial class UserTopScoreContainer : VisibilityContainer { private const int duration = 500; diff --git a/osu.Game/Online/Metadata/MetadataClient.cs b/osu.Game/Online/Metadata/MetadataClient.cs index 60867da2d7..d4e7540fe7 100644 --- a/osu.Game/Online/Metadata/MetadataClient.cs +++ b/osu.Game/Online/Metadata/MetadataClient.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics; namespace osu.Game.Online.Metadata { - public abstract class MetadataClient : Component, IMetadataClient, IMetadataServer + public abstract partial class MetadataClient : Component, IMetadataClient, IMetadataServer { public abstract Task BeatmapSetsUpdated(BeatmapUpdates updates); diff --git a/osu.Game/Online/Metadata/OnlineMetadataClient.cs b/osu.Game/Online/Metadata/OnlineMetadataClient.cs index 06d24a82f3..ba7ccb24f7 100644 --- a/osu.Game/Online/Metadata/OnlineMetadataClient.cs +++ b/osu.Game/Online/Metadata/OnlineMetadataClient.cs @@ -13,7 +13,7 @@ using osu.Game.Online.API; namespace osu.Game.Online.Metadata { - public class OnlineMetadataClient : MetadataClient + public partial class OnlineMetadataClient : MetadataClient { private readonly string endpoint; diff --git a/osu.Game/Online/Multiplayer/MultiplayerClient.cs b/osu.Game/Online/Multiplayer/MultiplayerClient.cs index b39781ebc2..bd87f2d43e 100644 --- a/osu.Game/Online/Multiplayer/MultiplayerClient.cs +++ b/osu.Game/Online/Multiplayer/MultiplayerClient.cs @@ -26,7 +26,7 @@ using osu.Game.Utils; namespace osu.Game.Online.Multiplayer { - public abstract class MultiplayerClient : Component, IMultiplayerClient, IMultiplayerRoomServer + public abstract partial class MultiplayerClient : Component, IMultiplayerClient, IMultiplayerRoomServer { public Action? PostNotification { protected get; set; } diff --git a/osu.Game/Online/Multiplayer/OnlineMultiplayerClient.cs b/osu.Game/Online/Multiplayer/OnlineMultiplayerClient.cs index 190d150502..386a3d5262 100644 --- a/osu.Game/Online/Multiplayer/OnlineMultiplayerClient.cs +++ b/osu.Game/Online/Multiplayer/OnlineMultiplayerClient.cs @@ -18,7 +18,7 @@ namespace osu.Game.Online.Multiplayer /// /// A with online connectivity. /// - public class OnlineMultiplayerClient : MultiplayerClient + public partial class OnlineMultiplayerClient : MultiplayerClient { private readonly string endpoint; diff --git a/osu.Game/Online/Multiplayer/ServerShutdownNotification.cs b/osu.Game/Online/Multiplayer/ServerShutdownNotification.cs index c114741be8..1de18e44a7 100644 --- a/osu.Game/Online/Multiplayer/ServerShutdownNotification.cs +++ b/osu.Game/Online/Multiplayer/ServerShutdownNotification.cs @@ -10,7 +10,7 @@ using osu.Game.Utils; namespace osu.Game.Online.Multiplayer { - public class ServerShutdownNotification : SimpleNotification + public partial class ServerShutdownNotification : SimpleNotification { private readonly DateTimeOffset endDate; private ScheduledDelegate? updateDelegate; diff --git a/osu.Game/Online/OnlineViewContainer.cs b/osu.Game/Online/OnlineViewContainer.cs index 7af1ac9d5d..46f64fbb61 100644 --- a/osu.Game/Online/OnlineViewContainer.cs +++ b/osu.Game/Online/OnlineViewContainer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Online /// A for displaying online content which require a local user to be logged in. /// Shows its children only when the local user is logged in and supports displaying a placeholder if not. /// - public class OnlineViewContainer : Container + public partial class OnlineViewContainer : Container { protected LoadingSpinner LoadingSpinner { get; private set; } diff --git a/osu.Game/Online/Placeholders/ClickablePlaceholder.cs b/osu.Game/Online/Placeholders/ClickablePlaceholder.cs index 7f9e16399e..9bef1d4b7a 100644 --- a/osu.Game/Online/Placeholders/ClickablePlaceholder.cs +++ b/osu.Game/Online/Placeholders/ClickablePlaceholder.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Online.Placeholders { - public class ClickablePlaceholder : Placeholder + public partial class ClickablePlaceholder : Placeholder { public Action Action; diff --git a/osu.Game/Online/Placeholders/LoginPlaceholder.cs b/osu.Game/Online/Placeholders/LoginPlaceholder.cs index 6a4065208e..de7ac6e936 100644 --- a/osu.Game/Online/Placeholders/LoginPlaceholder.cs +++ b/osu.Game/Online/Placeholders/LoginPlaceholder.cs @@ -10,7 +10,7 @@ using osu.Game.Overlays; namespace osu.Game.Online.Placeholders { - public sealed class LoginPlaceholder : ClickablePlaceholder + public sealed partial class LoginPlaceholder : ClickablePlaceholder { [Resolved(CanBeNull = true)] private LoginOverlay login { get; set; } diff --git a/osu.Game/Online/Placeholders/MessagePlaceholder.cs b/osu.Game/Online/Placeholders/MessagePlaceholder.cs index 451a4cba85..07a111a10f 100644 --- a/osu.Game/Online/Placeholders/MessagePlaceholder.cs +++ b/osu.Game/Online/Placeholders/MessagePlaceholder.cs @@ -9,7 +9,7 @@ using osu.Framework.Localisation; namespace osu.Game.Online.Placeholders { - public class MessagePlaceholder : Placeholder + public partial class MessagePlaceholder : Placeholder { private readonly LocalisableString message; diff --git a/osu.Game/Online/Placeholders/Placeholder.cs b/osu.Game/Online/Placeholders/Placeholder.cs index 3a05ce1365..37669fb899 100644 --- a/osu.Game/Online/Placeholders/Placeholder.cs +++ b/osu.Game/Online/Placeholders/Placeholder.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Online.Placeholders { - public abstract class Placeholder : OsuTextFlowContainer, IEquatable + public abstract partial class Placeholder : OsuTextFlowContainer, IEquatable { protected const float TEXT_SIZE = 22; diff --git a/osu.Game/Online/PollingComponent.cs b/osu.Game/Online/PollingComponent.cs index fcea650e2d..a44308c726 100644 --- a/osu.Game/Online/PollingComponent.cs +++ b/osu.Game/Online/PollingComponent.cs @@ -16,7 +16,7 @@ namespace osu.Game.Online /// /// A component which requires a constant polling process. /// - public abstract class PollingComponent : CompositeComponent + public abstract partial class PollingComponent : CompositeComponent { private double? lastTimePolled; diff --git a/osu.Game/Online/Rooms/APICreatedRoom.cs b/osu.Game/Online/Rooms/APICreatedRoom.cs index ca1179efeb..254a338a60 100644 --- a/osu.Game/Online/Rooms/APICreatedRoom.cs +++ b/osu.Game/Online/Rooms/APICreatedRoom.cs @@ -7,7 +7,7 @@ using Newtonsoft.Json; namespace osu.Game.Online.Rooms { - public class APICreatedRoom : Room + public partial class APICreatedRoom : Room { [JsonProperty("error")] public string Error { get; set; } diff --git a/osu.Game/Online/Rooms/OnlinePlayBeatmapAvailabilityTracker.cs b/osu.Game/Online/Rooms/OnlinePlayBeatmapAvailabilityTracker.cs index 7f8f9703e4..1d496cc636 100644 --- a/osu.Game/Online/Rooms/OnlinePlayBeatmapAvailabilityTracker.cs +++ b/osu.Game/Online/Rooms/OnlinePlayBeatmapAvailabilityTracker.cs @@ -27,7 +27,7 @@ namespace osu.Game.Online.Rooms /// This differs from a regular download tracking composite as this accounts for the /// databased beatmap set's checksum, to disallow from playing with an altered version of the beatmap. /// - public class OnlinePlayBeatmapAvailabilityTracker : CompositeComponent + public partial class OnlinePlayBeatmapAvailabilityTracker : CompositeComponent { public readonly IBindable SelectedItem = new Bindable(); diff --git a/osu.Game/Online/Rooms/Room.cs b/osu.Game/Online/Rooms/Room.cs index adfd4c226a..bdd7d6ce1c 100644 --- a/osu.Game/Online/Rooms/Room.cs +++ b/osu.Game/Online/Rooms/Room.cs @@ -16,7 +16,7 @@ using osu.Game.Online.Rooms.RoomStatuses; namespace osu.Game.Online.Rooms { [JsonObject(MemberSerialization.OptIn)] - public class Room + public partial class Room { [Cached] [JsonProperty("id")] diff --git a/osu.Game/Online/ScoreDownloadTracker.cs b/osu.Game/Online/ScoreDownloadTracker.cs index 680bb16264..4ddcb40368 100644 --- a/osu.Game/Online/ScoreDownloadTracker.cs +++ b/osu.Game/Online/ScoreDownloadTracker.cs @@ -11,7 +11,7 @@ using osu.Game.Scoring; namespace osu.Game.Online { - public class ScoreDownloadTracker : DownloadTracker + public partial class ScoreDownloadTracker : DownloadTracker { [Resolved(CanBeNull = true)] protected ScoreModelDownloader? Downloader { get; private set; } diff --git a/osu.Game/Online/Spectator/OnlineSpectatorClient.cs b/osu.Game/Online/Spectator/OnlineSpectatorClient.cs index 48d5c0bea9..d69bd81b57 100644 --- a/osu.Game/Online/Spectator/OnlineSpectatorClient.cs +++ b/osu.Game/Online/Spectator/OnlineSpectatorClient.cs @@ -12,7 +12,7 @@ using osu.Game.Online.Multiplayer; namespace osu.Game.Online.Spectator { - public class OnlineSpectatorClient : SpectatorClient + public partial class OnlineSpectatorClient : SpectatorClient { private readonly string endpoint; diff --git a/osu.Game/Online/Spectator/SpectatorClient.cs b/osu.Game/Online/Spectator/SpectatorClient.cs index 592bae80ba..b0ee0bc37b 100644 --- a/osu.Game/Online/Spectator/SpectatorClient.cs +++ b/osu.Game/Online/Spectator/SpectatorClient.cs @@ -21,7 +21,7 @@ using osu.Game.Screens.Play; namespace osu.Game.Online.Spectator { - public abstract class SpectatorClient : Component, ISpectatorClient + public abstract partial class SpectatorClient : Component, ISpectatorClient { /// /// The maximum milliseconds between frame bundle sends. diff --git a/osu.Game/Online/Spectator/SpectatorScoreProcessor.cs b/osu.Game/Online/Spectator/SpectatorScoreProcessor.cs index 573c504add..c97871c3aa 100644 --- a/osu.Game/Online/Spectator/SpectatorScoreProcessor.cs +++ b/osu.Game/Online/Spectator/SpectatorScoreProcessor.cs @@ -21,7 +21,7 @@ namespace osu.Game.Online.Spectator /// A wrapper over a for spectated users. /// This should be used when a local "playable" beatmap is unavailable or expensive to generate for the spectated user. /// - public class SpectatorScoreProcessor : Component + public partial class SpectatorScoreProcessor : Component { /// /// The current total score. diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index a93c187e53..544b8ad837 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -71,7 +71,7 @@ namespace osu.Game /// for initial components that are generally retrieved via DI. /// [Cached(typeof(OsuGame))] - public class OsuGame : OsuGameBase, IKeyBindingHandler, ILocalUserPlayInfo, IPerformFromScreenRunner, IOverlayManager, ILinkHandler + public partial class OsuGame : OsuGameBase, IKeyBindingHandler, ILocalUserPlayInfo, IPerformFromScreenRunner, IOverlayManager, ILinkHandler { /// /// The amount of global offset to apply when a left/right anchored overlay is displayed (ie. settings or notifications). diff --git a/osu.Game/Overlays/AccountCreation/AccountCreationBackground.cs b/osu.Game/Overlays/AccountCreation/AccountCreationBackground.cs index 2b372c18eb..0042b9f8f6 100644 --- a/osu.Game/Overlays/AccountCreation/AccountCreationBackground.cs +++ b/osu.Game/Overlays/AccountCreation/AccountCreationBackground.cs @@ -10,7 +10,7 @@ using osu.Framework.Graphics.Textures; namespace osu.Game.Overlays.AccountCreation { - public class AccountCreationBackground : Sprite + public partial class AccountCreationBackground : Sprite { public AccountCreationBackground() { diff --git a/osu.Game/Overlays/AccountCreation/AccountCreationScreen.cs b/osu.Game/Overlays/AccountCreation/AccountCreationScreen.cs index 299a41f45b..a7dd53f511 100644 --- a/osu.Game/Overlays/AccountCreation/AccountCreationScreen.cs +++ b/osu.Game/Overlays/AccountCreation/AccountCreationScreen.cs @@ -8,7 +8,7 @@ using osu.Framework.Screens; namespace osu.Game.Overlays.AccountCreation { - public abstract class AccountCreationScreen : Screen + public abstract partial class AccountCreationScreen : Screen { public override void OnEntering(ScreenTransitionEvent e) { diff --git a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs index 2120f351a2..ea1ee2c9a9 100644 --- a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs +++ b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs @@ -25,7 +25,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.AccountCreation { - public class ScreenEntry : AccountCreationScreen + public partial class ScreenEntry : AccountCreationScreen { private ErrorTextFlowContainer usernameDescription; private ErrorTextFlowContainer emailAddressDescription; diff --git a/osu.Game/Overlays/AccountCreation/ScreenWarning.cs b/osu.Game/Overlays/AccountCreation/ScreenWarning.cs index f8070788c2..a833a871f9 100644 --- a/osu.Game/Overlays/AccountCreation/ScreenWarning.cs +++ b/osu.Game/Overlays/AccountCreation/ScreenWarning.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.AccountCreation { - public class ScreenWarning : AccountCreationScreen + public partial class ScreenWarning : AccountCreationScreen { private OsuTextFlowContainer multiAccountExplanationText; private LinkFlowContainer furtherAssistance; diff --git a/osu.Game/Overlays/AccountCreation/ScreenWelcome.cs b/osu.Game/Overlays/AccountCreation/ScreenWelcome.cs index 1936ad533a..4becb225f8 100644 --- a/osu.Game/Overlays/AccountCreation/ScreenWelcome.cs +++ b/osu.Game/Overlays/AccountCreation/ScreenWelcome.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Overlays.AccountCreation { - public class ScreenWelcome : AccountCreationScreen + public partial class ScreenWelcome : AccountCreationScreen { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Overlays/AccountCreationOverlay.cs b/osu.Game/Overlays/AccountCreationOverlay.cs index c51ed07c38..6f79316670 100644 --- a/osu.Game/Overlays/AccountCreationOverlay.cs +++ b/osu.Game/Overlays/AccountCreationOverlay.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public class AccountCreationOverlay : OsuFocusedOverlayContainer + public partial class AccountCreationOverlay : OsuFocusedOverlayContainer { private const float transition_time = 400; diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingCardSizeTabControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingCardSizeTabControl.cs index 13da9d335c..feb0c27ee7 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingCardSizeTabControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingCardSizeTabControl.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Overlays.BeatmapListing { - public class BeatmapListingCardSizeTabControl : OsuTabControl + public partial class BeatmapListingCardSizeTabControl : OsuTabControl { public BeatmapListingCardSizeTabControl() { @@ -35,7 +35,7 @@ namespace osu.Game.Overlays.BeatmapListing protected override TabItem CreateTabItem(BeatmapCardSize value) => new TabItem(value); - private class TabItem : TabItem + private partial class TabItem : TabItem { private Box background; private SpriteIcon icon; diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs index ff9a46ed4f..c5c252fb5d 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs @@ -26,7 +26,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapListing { - public class BeatmapListingFilterControl : CompositeDrawable + public partial class BeatmapListingFilterControl : CompositeDrawable { /// /// Fired when a search finishes. diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs index ccab810612..76b6dec65b 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs @@ -8,11 +8,11 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.BeatmapListing { - public class BeatmapListingHeader : OverlayHeader + public partial class BeatmapListingHeader : OverlayHeader { protected override OverlayTitle CreateTitle() => new BeatmapListingTitle(); - private class BeatmapListingTitle : OverlayTitle + private partial class BeatmapListingTitle : OverlayTitle { public BeatmapListingTitle() { diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs index 86cf3b5588..f28ec9c295 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs @@ -24,7 +24,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapListing { - public class BeatmapListingSearchControl : CompositeDrawable + public partial class BeatmapListingSearchControl : CompositeDrawable { /// /// Any time the text box receives key events (even while masked). @@ -165,7 +165,7 @@ namespace osu.Game.Overlays.BeatmapListing public void TakeFocus() => textBox.TakeFocus(); - private class BeatmapSearchTextBox : BasicSearchTextBox + private partial class BeatmapSearchTextBox : BasicSearchTextBox { /// /// Any time the text box receives key events (even while masked). @@ -198,7 +198,7 @@ namespace osu.Game.Overlays.BeatmapListing } } - private class TopSearchBeatmapSetCover : UpdateableOnlineBeatmapSetCover + private partial class TopSearchBeatmapSetCover : UpdateableOnlineBeatmapSetCover { protected override bool TransformImmediately => true; } diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs index bc1f30dcaf..34e0408db6 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs @@ -13,7 +13,7 @@ using osu.Framework.Input.Events; namespace osu.Game.Overlays.BeatmapListing { - public class BeatmapListingSortTabControl : OverlaySortTabControl + public partial class BeatmapListingSortTabControl : OverlaySortTabControl { public readonly Bindable SortDirection = new Bindable(Overlays.SortDirection.Descending); @@ -72,7 +72,7 @@ namespace osu.Game.Overlays.BeatmapListing SortDirection = { BindTarget = SortDirection }, }; - private class BeatmapSortTabControl : SortTabControl + private partial class BeatmapSortTabControl : SortTabControl { protected override bool AddEnumEntriesAutomatically => false; @@ -84,7 +84,7 @@ namespace osu.Game.Overlays.BeatmapListing }; } - private class BeatmapSortTabItem : SortTabItem + private partial class BeatmapSortTabItem : SortTabItem { public readonly Bindable SortDirection = new Bindable(); @@ -100,7 +100,7 @@ namespace osu.Game.Overlays.BeatmapListing }; } - private class BeatmapTabButton : TabButton + private partial class BeatmapTabButton : TabButton { public readonly Bindable SortDirection = new Bindable(); diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs index 8ae39aeaca..3ab0e47a6c 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs @@ -18,7 +18,7 @@ using osu.Framework.Localisation; namespace osu.Game.Overlays.BeatmapListing { - public class BeatmapSearchFilterRow : CompositeDrawable, IHasCurrentValue + public partial class BeatmapSearchFilterRow : CompositeDrawable, IHasCurrentValue { private readonly BindableWithCurrent current = new BindableWithCurrent(); @@ -69,7 +69,7 @@ namespace osu.Game.Overlays.BeatmapListing [NotNull] protected virtual Drawable CreateFilter() => new BeatmapSearchFilter(); - protected class BeatmapSearchFilter : TabControl + protected partial class BeatmapSearchFilter : TabControl { public BeatmapSearchFilter() { @@ -98,7 +98,7 @@ namespace osu.Game.Overlays.BeatmapListing protected override TabItem CreateTabItem(T value) => new FilterTabItem(value); - private class FilterDropdown : OsuTabDropdown + private partial class FilterDropdown : OsuTabDropdown { protected override DropdownHeader CreateHeader() => new FilterHeader { @@ -106,7 +106,7 @@ namespace osu.Game.Overlays.BeatmapListing Origin = Anchor.TopRight }; - private class FilterHeader : OsuTabDropdownHeader + private partial class FilterHeader : OsuTabDropdownHeader { public FilterHeader() { diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchGeneralFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchGeneralFilterRow.cs index c01aa9a1c4..10ec66e396 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchGeneralFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchGeneralFilterRow.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapListing { - public class BeatmapSearchGeneralFilterRow : BeatmapSearchMultipleSelectionFilterRow + public partial class BeatmapSearchGeneralFilterRow : BeatmapSearchMultipleSelectionFilterRow { public BeatmapSearchGeneralFilterRow() : base(BeatmapsStrings.ListingSearchFiltersGeneral) @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.BeatmapListing protected override MultipleSelectionFilter CreateMultipleSelectionFilter() => new GeneralFilter(); - private class GeneralFilter : MultipleSelectionFilter + private partial class GeneralFilter : MultipleSelectionFilter { protected override MultipleSelectionFilterTabItem CreateTabItem(SearchGeneral value) { @@ -30,7 +30,7 @@ namespace osu.Game.Overlays.BeatmapListing } } - private class FeaturedArtistsTabItem : MultipleSelectionFilterTabItem + private partial class FeaturedArtistsTabItem : MultipleSelectionFilterTabItem { public FeaturedArtistsTabItem() : base(SearchGeneral.FeaturedArtists) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs index cca75e9548..79a794a9ad 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Overlays.BeatmapListing { - public class BeatmapSearchMultipleSelectionFilterRow : BeatmapSearchFilterRow> + public partial class BeatmapSearchMultipleSelectionFilterRow : BeatmapSearchFilterRow> { public new readonly BindableList Current = new BindableList(); @@ -42,7 +42,7 @@ namespace osu.Game.Overlays.BeatmapListing [NotNull] protected virtual MultipleSelectionFilter CreateMultipleSelectionFilter() => new MultipleSelectionFilter(); - protected class MultipleSelectionFilter : FillFlowContainer + protected partial class MultipleSelectionFilter : FillFlowContainer { public readonly BindableList Current = new BindableList(); @@ -85,7 +85,7 @@ namespace osu.Game.Overlays.BeatmapListing } } - protected class MultipleSelectionFilterTabItem : FilterTabItem + protected partial class MultipleSelectionFilterTabItem : FilterTabItem { public MultipleSelectionFilterTabItem(T value) : base(value) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs index 526c14511e..fa37810f37 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets; namespace osu.Game.Overlays.BeatmapListing { - public class BeatmapSearchRulesetFilterRow : BeatmapSearchFilterRow + public partial class BeatmapSearchRulesetFilterRow : BeatmapSearchFilterRow { public BeatmapSearchRulesetFilterRow() : base(BeatmapsStrings.ListingSearchFiltersMode) @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.BeatmapListing protected override Drawable CreateFilter() => new RulesetFilter(); - private class RulesetFilter : BeatmapSearchFilter + private partial class RulesetFilter : BeatmapSearchFilter { [BackgroundDependencyLoader] private void load(RulesetStore rulesets) @@ -32,7 +32,7 @@ namespace osu.Game.Overlays.BeatmapListing } } - private class RulesetFilterTabItemAny : FilterTabItem + private partial class RulesetFilterTabItemAny : FilterTabItem { protected override LocalisableString LabelFor(RulesetInfo info) => BeatmapsStrings.ModeAny; diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchScoreFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchScoreFilterRow.cs index 09b44be6c9..031833a107 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchScoreFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchScoreFilterRow.cs @@ -12,7 +12,7 @@ using osu.Game.Scoring; namespace osu.Game.Overlays.BeatmapListing { - public class BeatmapSearchScoreFilterRow : BeatmapSearchMultipleSelectionFilterRow + public partial class BeatmapSearchScoreFilterRow : BeatmapSearchMultipleSelectionFilterRow { public BeatmapSearchScoreFilterRow() : base(BeatmapsStrings.ListingSearchFiltersRank) @@ -21,14 +21,14 @@ namespace osu.Game.Overlays.BeatmapListing protected override MultipleSelectionFilter CreateMultipleSelectionFilter() => new RankFilter(); - private class RankFilter : MultipleSelectionFilter + private partial class RankFilter : MultipleSelectionFilter { protected override MultipleSelectionFilterTabItem CreateTabItem(ScoreRank value) => new RankItem(value); protected override IEnumerable GetValues() => base.GetValues().Where(r => r > ScoreRank.F).Reverse(); } - private class RankItem : MultipleSelectionFilterTabItem + private partial class RankItem : MultipleSelectionFilterTabItem { public RankItem(ScoreRank value) : base(value) diff --git a/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs b/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs index cc131ffc27..7b95ae8ea8 100644 --- a/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs +++ b/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapListing { - public class FilterTabItem : TabItem + public partial class FilterTabItem : TabItem { [Resolved] private OverlayColourProvider colourProvider { get; set; } diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index 2d9583b864..d6d4f1a67b 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -31,7 +31,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public class BeatmapListingOverlay : OnlineOverlay + public partial class BeatmapListingOverlay : OnlineOverlay { [Resolved] private PreviewTrackManager previewTrackManager { get; set; } @@ -248,7 +248,7 @@ namespace osu.Game.Overlays base.Dispose(isDisposing); } - public class NotFoundDrawable : CompositeDrawable + public partial class NotFoundDrawable : CompositeDrawable { public NotFoundDrawable() { @@ -292,7 +292,7 @@ namespace osu.Game.Overlays // TODO: localisation requires Text/LinkFlowContainer support for localising strings with links inside // (https://github.com/ppy/osu-framework/issues/4530) - public class SupporterRequiredDrawable : CompositeDrawable + public partial class SupporterRequiredDrawable : CompositeDrawable { private LinkFlowContainer supporterRequiredText; diff --git a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs index 2341997626..1d01495188 100644 --- a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs +++ b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs @@ -21,7 +21,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Overlays.BeatmapSet { - public class AuthorInfo : Container + public partial class AuthorInfo : Container { private const float height = 50; @@ -105,7 +105,7 @@ namespace osu.Game.Overlays.BeatmapSet } } - private class Field : FillFlowContainer + private partial class Field : FillFlowContainer { public Field(string first, string second, FontUsage secondFont) { diff --git a/osu.Game/Overlays/BeatmapSet/BasicStats.cs b/osu.Game/Overlays/BeatmapSet/BasicStats.cs index a8bbb9fe1c..4a9a3d8089 100644 --- a/osu.Game/Overlays/BeatmapSet/BasicStats.cs +++ b/osu.Game/Overlays/BeatmapSet/BasicStats.cs @@ -22,7 +22,7 @@ using osuTK; namespace osu.Game.Overlays.BeatmapSet { - public class BasicStats : Container + public partial class BasicStats : Container { private readonly Statistic length, bpm, circleCount, sliderCount; @@ -117,7 +117,7 @@ namespace osu.Game.Overlays.BeatmapSet updateDisplay(); } - private class Statistic : Container, IHasTooltip + private partial class Statistic : Container, IHasTooltip { private readonly OsuSpriteText value; diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapAvailability.cs b/osu.Game/Overlays/BeatmapSet/BeatmapAvailability.cs index d893ef80d8..d18e1c93c9 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapAvailability.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapAvailability.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet { - public class BeatmapAvailability : Container + public partial class BeatmapAvailability : Container { private APIBeatmapSet beatmapSet; diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapBadge.cs b/osu.Game/Overlays/BeatmapSet/BeatmapBadge.cs index 52fed99431..feb27aaa60 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapBadge.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapBadge.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays.BeatmapSet { - public abstract class BeatmapBadge : CompositeDrawable + public abstract partial class BeatmapBadge : CompositeDrawable { /// /// The text displayed on the badge's label. diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index b27d9b3f1e..84d12f2611 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -27,7 +27,7 @@ using osuTK; namespace osu.Game.Overlays.BeatmapSet { - public class BeatmapPicker : Container + public partial class BeatmapPicker : Container { private const float tile_icon_padding = 7; private const float tile_spacing = 2; @@ -209,7 +209,7 @@ namespace osu.Game.Overlays.BeatmapSet Difficulties.Children.ToList().ForEach(diff => diff.State = diff.Beatmap == Beatmap.Value ? DifficultySelectorState.Selected : DifficultySelectorState.NotSelected); } - public class DifficultiesContainer : FillFlowContainer + public partial class DifficultiesContainer : FillFlowContainer { public Action OnLostHover; @@ -220,7 +220,7 @@ namespace osu.Game.Overlays.BeatmapSet } } - public class DifficultySelectorButton : OsuClickableContainer, IStateful + public partial class DifficultySelectorButton : OsuClickableContainer, IStateful { private const float transition_duration = 100; private const float size = 54; @@ -325,7 +325,7 @@ namespace osu.Game.Overlays.BeatmapSet } } - private class Statistic : FillFlowContainer + private partial class Statistic : FillFlowContainer { private readonly OsuSpriteText text; diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapRulesetSelector.cs b/osu.Game/Overlays/BeatmapSet/BeatmapRulesetSelector.cs index 0f5eb18c4e..9291988367 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapRulesetSelector.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapRulesetSelector.cs @@ -11,7 +11,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.BeatmapSet { - public class BeatmapRulesetSelector : OverlayRulesetSelector + public partial class BeatmapRulesetSelector : OverlayRulesetSelector { private readonly Bindable beatmapSet = new Bindable(); diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs b/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs index e9acca5bcd..f802807c3c 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs @@ -17,7 +17,7 @@ using osu.Game.Rulesets; namespace osu.Game.Overlays.BeatmapSet { - public class BeatmapRulesetTabItem : OverlayRulesetTabItem + public partial class BeatmapRulesetTabItem : OverlayRulesetTabItem { public readonly Bindable BeatmapSet = new Bindable(); diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs index 02da7812d1..fa9c9b5018 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet { - public class BeatmapSetHeader : OverlayHeader + public partial class BeatmapSetHeader : OverlayHeader { public readonly Bindable BeatmapSet = new Bindable(); @@ -53,7 +53,7 @@ namespace osu.Game.Overlays.BeatmapSet protected override OverlayTitle CreateTitle() => new BeatmapHeaderTitle(); - private class BeatmapHeaderTitle : OverlayTitle + private partial class BeatmapHeaderTitle : OverlayTitle { public BeatmapHeaderTitle() { diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs index 9e14122ae4..0318dad0e3 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs @@ -26,7 +26,7 @@ using osuTK; namespace osu.Game.Overlays.BeatmapSet { - public class BeatmapSetHeaderContent : CompositeDrawable + public partial class BeatmapSetHeaderContent : CompositeDrawable { public readonly Bindable BeatmapSet = new Bindable(); diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetLayoutSection.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetLayoutSection.cs index 797b6716e7..305a3661a7 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetLayoutSection.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetLayoutSection.cs @@ -12,7 +12,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet { - public class BeatmapSetLayoutSection : Container + public partial class BeatmapSetLayoutSection : Container { public BeatmapSetLayoutSection() { diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs index f7c8aa44ad..cbdb2ea190 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs @@ -21,7 +21,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Overlays.BeatmapSet.Buttons { - public class FavouriteButton : HeaderButton, IHasTooltip + public partial class FavouriteButton : HeaderButton, IHasTooltip { public readonly Bindable BeatmapSet = new Bindable(); diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs index 25d11bd6d7..c653b058ee 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs @@ -10,7 +10,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.BeatmapSet.Buttons { - public class HeaderButton : TriangleButton + public partial class HeaderButton : TriangleButton { public HeaderButton() { diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/HeaderDownloadButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderDownloadButton.cs index c2de96f245..d8dcf2b51b 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/HeaderDownloadButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderDownloadButton.cs @@ -26,7 +26,7 @@ using CommonStrings = osu.Game.Localisation.CommonStrings; namespace osu.Game.Overlays.BeatmapSet.Buttons { - public class HeaderDownloadButton : CompositeDrawable, IHasTooltip + public partial class HeaderDownloadButton : CompositeDrawable, IHasTooltip { private const int text_size = 12; diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/PlayButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/PlayButton.cs index 0ce55ce549..c43be33290 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/PlayButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/PlayButton.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet.Buttons { - public class PlayButton : Container + public partial class PlayButton : Container { public IBindable Playing => playing; diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs index 8fc8927c4b..b3b8b80a0d 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Overlays.BeatmapSet.Buttons { - public class PreviewButton : OsuClickableContainer + public partial class PreviewButton : OsuClickableContainer { private readonly Box background, progress; private readonly PlayButton playButton; diff --git a/osu.Game/Overlays/BeatmapSet/Details.cs b/osu.Game/Overlays/BeatmapSet/Details.cs index 6db54db811..cf78f605aa 100644 --- a/osu.Game/Overlays/BeatmapSet/Details.cs +++ b/osu.Game/Overlays/BeatmapSet/Details.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Overlays.BeatmapSet { - public class Details : FillFlowContainer + public partial class Details : FillFlowContainer { protected readonly UserRatings Ratings; @@ -107,7 +107,7 @@ namespace osu.Game.Overlays.BeatmapSet updateDisplay(); } - private class DetailBox : Container + private partial class DetailBox : Container { private readonly Container content; private readonly Box background; diff --git a/osu.Game/Overlays/BeatmapSet/ExplicitContentBeatmapBadge.cs b/osu.Game/Overlays/BeatmapSet/ExplicitContentBeatmapBadge.cs index 18dcfc0385..f666961784 100644 --- a/osu.Game/Overlays/BeatmapSet/ExplicitContentBeatmapBadge.cs +++ b/osu.Game/Overlays/BeatmapSet/ExplicitContentBeatmapBadge.cs @@ -7,7 +7,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.BeatmapSet { - public class ExplicitContentBeatmapBadge : BeatmapBadge + public partial class ExplicitContentBeatmapBadge : BeatmapBadge { [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game/Overlays/BeatmapSet/FeaturedArtistBeatmapBadge.cs b/osu.Game/Overlays/BeatmapSet/FeaturedArtistBeatmapBadge.cs index a0ee0a18ec..6090ec6fae 100644 --- a/osu.Game/Overlays/BeatmapSet/FeaturedArtistBeatmapBadge.cs +++ b/osu.Game/Overlays/BeatmapSet/FeaturedArtistBeatmapBadge.cs @@ -7,7 +7,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.BeatmapSet { - public class FeaturedArtistBeatmapBadge : BeatmapBadge + public partial class FeaturedArtistBeatmapBadge : BeatmapBadge { [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 08423f2aa7..514a4ea8cd 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -14,7 +14,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.BeatmapSet { - public class Info : Container + public partial class Info : Container { private const float metadata_width = 175; private const float spacing = 20; diff --git a/osu.Game/Overlays/BeatmapSet/LeaderboardModSelector.cs b/osu.Game/Overlays/BeatmapSet/LeaderboardModSelector.cs index 8311368da3..9c8f810607 100644 --- a/osu.Game/Overlays/BeatmapSet/LeaderboardModSelector.cs +++ b/osu.Game/Overlays/BeatmapSet/LeaderboardModSelector.cs @@ -20,7 +20,7 @@ using osu.Framework.Extensions.IEnumerableExtensions; namespace osu.Game.Overlays.BeatmapSet { - public class LeaderboardModSelector : CompositeDrawable + public partial class LeaderboardModSelector : CompositeDrawable { public readonly BindableList SelectedMods = new BindableList(); public readonly Bindable Ruleset = new Bindable(); @@ -107,7 +107,7 @@ namespace osu.Game.Overlays.BeatmapSet public void DeselectAll() => modsContainer.ForEach(mod => mod.Selected.Value = false); - private class ModButton : ModIcon + private partial class ModButton : ModIcon { private const int duration = 200; diff --git a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs index db7d04f597..476a252c7b 100644 --- a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs +++ b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs @@ -13,7 +13,7 @@ using osu.Framework.Graphics; namespace osu.Game.Overlays.BeatmapSet { - public class LeaderboardScopeSelector : GradientLineTabControl + public partial class LeaderboardScopeSelector : GradientLineTabControl { protected override bool AddEnumEntriesAutomatically => false; @@ -33,7 +33,7 @@ namespace osu.Game.Overlays.BeatmapSet LineColour = colourProvider.Background1; } - private class ScopeSelectorTabItem : PageTabItem + private partial class ScopeSelectorTabItem : PageTabItem { public ScopeSelectorTabItem(BeatmapLeaderboardScope value) : base(value) diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSection.cs b/osu.Game/Overlays/BeatmapSet/MetadataSection.cs index 317b369d8f..6390c52ff3 100644 --- a/osu.Game/Overlays/BeatmapSet/MetadataSection.cs +++ b/osu.Game/Overlays/BeatmapSet/MetadataSection.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet { - public class MetadataSection : Container + public partial class MetadataSection : Container { private readonly FillFlowContainer textContainer; private readonly MetadataType type; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index 06bf9e1d50..01e4416156 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class DrawableTopScore : CompositeDrawable + public partial class DrawableTopScore : CompositeDrawable { private readonly Box background; @@ -89,7 +89,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores background.Colour = colourProvider.Background4; } - private class AutoSizingGrid : GridContainer + private partial class AutoSizingGrid : GridContainer { public AutoSizingGrid() { diff --git a/osu.Game/Overlays/BeatmapSet/Scores/NoScoresPlaceholder.cs b/osu.Game/Overlays/BeatmapSet/Scores/NoScoresPlaceholder.cs index 47690bab1f..f7703af27d 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/NoScoresPlaceholder.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/NoScoresPlaceholder.cs @@ -12,7 +12,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class NoScoresPlaceholder : Container + public partial class NoScoresPlaceholder : Container { private readonly SpriteText text; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/NotSupporterPlaceholder.cs b/osu.Game/Overlays/BeatmapSet/Scores/NotSupporterPlaceholder.cs index b83b4d6b26..04ab3ec72f 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/NotSupporterPlaceholder.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/NotSupporterPlaceholder.cs @@ -13,7 +13,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class NotSupporterPlaceholder : Container + public partial class NotSupporterPlaceholder : Container { public NotSupporterPlaceholder() { diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 11aefd435d..006eec2838 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -28,7 +28,7 @@ using osu.Game.Scoring.Drawables; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class ScoreTable : TableContainer + public partial class ScoreTable : TableContainer { private const float horizontal_inset = 20; private const float row_height = 22; @@ -207,7 +207,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores protected override Drawable CreateHeader(int index, TableColumn column) => new HeaderText(column?.Header ?? default); - private class HeaderText : OsuSpriteText + private partial class HeaderText : OsuSpriteText { public HeaderText(LocalisableString text) { @@ -222,7 +222,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } } - private class StatisticText : OsuSpriteText, IHasTooltip + private partial class StatisticText : OsuSpriteText, IHasTooltip { private readonly double? count; private readonly double? maxCount; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs index c17bb70bc2..130dfd45e7 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs @@ -14,7 +14,7 @@ using osu.Game.Scoring; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class ScoreTableRowBackground : CompositeDrawable + public partial class ScoreTableRowBackground : CompositeDrawable { private const int fade_duration = 100; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreboardTime.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreboardTime.cs index 72aa221432..04cbf171f6 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreboardTime.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreboardTime.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class ScoreboardTime : DrawableDate + public partial class ScoreboardTime : DrawableDate { public ScoreboardTime(DateTimeOffset date, float textSize = OsuFont.DEFAULT_FONT_SIZE, bool italic = true) : base(date, textSize, italic) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 53818bbee3..9eb04d9cc5 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -24,7 +24,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class ScoresContainer : BeatmapSetLayoutSection + public partial class ScoresContainer : BeatmapSetLayoutSection { private const int spacing = 15; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index 653bfd6d2c..e030b1e34f 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -27,7 +27,7 @@ using osuTK; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class TopScoreStatisticsSection : CompositeDrawable + public partial class TopScoreStatisticsSection : CompositeDrawable { private const float margin = 10; private const float top_columns_min_width = 64; @@ -143,7 +143,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Text = stat.MaxCount == null ? stat.Count.ToLocalisableString(@"N0") : (LocalisableString)$"{stat.Count}/{stat.MaxCount}" }; - private class InfoColumn : CompositeDrawable + private partial class InfoColumn : CompositeDrawable { private readonly Box separator; private readonly OsuSpriteText text; @@ -204,7 +204,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } } - private class TextColumn : InfoColumn, IHasCurrentValue + private partial class TextColumn : InfoColumn, IHasCurrentValue { private readonly OsuTextFlowContainer text; @@ -249,7 +249,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } } - private class ModsInfoColumn : InfoColumn + private partial class ModsInfoColumn : InfoColumn { private readonly FillFlowContainer modsContainer; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index 2eaa03a05d..afaed85250 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -22,7 +22,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet.Scores { - public class TopScoreUserSection : CompositeDrawable + public partial class TopScoreUserSection : CompositeDrawable { private readonly SpriteText rankText; private readonly UpdateableRank rank; diff --git a/osu.Game/Overlays/BeatmapSet/SpotlightBeatmapBadge.cs b/osu.Game/Overlays/BeatmapSet/SpotlightBeatmapBadge.cs index 44b3acea5f..00534ff700 100644 --- a/osu.Game/Overlays/BeatmapSet/SpotlightBeatmapBadge.cs +++ b/osu.Game/Overlays/BeatmapSet/SpotlightBeatmapBadge.cs @@ -7,7 +7,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.BeatmapSet { - public class SpotlightBeatmapBadge : BeatmapBadge + public partial class SpotlightBeatmapBadge : BeatmapBadge { [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game/Overlays/BeatmapSet/SuccessRate.cs b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs index cbcef9fcec..48732ac586 100644 --- a/osu.Game/Overlays/BeatmapSet/SuccessRate.cs +++ b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs @@ -18,7 +18,7 @@ using osu.Game.Screens.Select.Details; namespace osu.Game.Overlays.BeatmapSet { - public class SuccessRate : Container + public partial class SuccessRate : Container { protected readonly FailRetryGraph Graph; @@ -127,7 +127,7 @@ namespace osu.Game.Overlays.BeatmapSet Graph.Padding = new MarginPadding { Top = header.DrawHeight }; } - private class SuccessRatePercentage : OsuSpriteText, IHasTooltip + private partial class SuccessRatePercentage : OsuSpriteText, IHasTooltip { public LocalisableString TooltipText { get; set; } } diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 207dc91ca5..fd831ad4ae 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -22,7 +22,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public class BeatmapSetOverlay : OnlineOverlay + public partial class BeatmapSetOverlay : OnlineOverlay { public const float X_PADDING = 40; public const float Y_PADDING = 25; @@ -118,7 +118,7 @@ namespace osu.Game.Overlays Show(); } - private class CommentsSection : BeatmapSetLayoutSection + private partial class CommentsSection : BeatmapSetLayoutSection { public readonly Bindable BeatmapSet = new Bindable(); diff --git a/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs index 5b83f0e62e..e730496b5c 100644 --- a/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs +++ b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs @@ -11,11 +11,11 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays { - public abstract class BreadcrumbControlOverlayHeader : TabControlOverlayHeader + public abstract partial class BreadcrumbControlOverlayHeader : TabControlOverlayHeader { protected override OsuTabControl CreateTabControl() => new OverlayHeaderBreadcrumbControl(); - public class OverlayHeaderBreadcrumbControl : BreadcrumbControl + public partial class OverlayHeaderBreadcrumbControl : BreadcrumbControl { public OverlayHeaderBreadcrumbControl() { @@ -34,7 +34,7 @@ namespace osu.Game.Overlays AccentColour = AccentColour, }; - private class ControlTabItem : BreadcrumbTabItem + private partial class ControlTabItem : BreadcrumbTabItem { protected override float ChevronSize => 8; diff --git a/osu.Game/Overlays/Changelog/ChangelogBuild.cs b/osu.Game/Overlays/Changelog/ChangelogBuild.cs index 575f1a398a..fd7a3f8791 100644 --- a/osu.Game/Overlays/Changelog/ChangelogBuild.cs +++ b/osu.Game/Overlays/Changelog/ChangelogBuild.cs @@ -16,7 +16,7 @@ using osu.Framework.Allocation; namespace osu.Game.Overlays.Changelog { - public class ChangelogBuild : FillFlowContainer + public partial class ChangelogBuild : FillFlowContainer { public const float HORIZONTAL_PADDING = 70; diff --git a/osu.Game/Overlays/Changelog/ChangelogContent.cs b/osu.Game/Overlays/Changelog/ChangelogContent.cs index e04133f2e4..51ef4ddf94 100644 --- a/osu.Game/Overlays/Changelog/ChangelogContent.cs +++ b/osu.Game/Overlays/Changelog/ChangelogContent.cs @@ -8,7 +8,7 @@ using System; namespace osu.Game.Overlays.Changelog { - public class ChangelogContent : FillFlowContainer + public partial class ChangelogContent : FillFlowContainer { public Action? BuildSelected; diff --git a/osu.Game/Overlays/Changelog/ChangelogEntry.cs b/osu.Game/Overlays/Changelog/ChangelogEntry.cs index 4d034007b1..ab671d9c86 100644 --- a/osu.Game/Overlays/Changelog/ChangelogEntry.cs +++ b/osu.Game/Overlays/Changelog/ChangelogEntry.cs @@ -21,7 +21,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Overlays.Changelog { - public class ChangelogEntry : FillFlowContainer + public partial class ChangelogEntry : FillFlowContainer { private readonly APIChangelogEntry entry; diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index 6ce6b82c8f..54ada24987 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -18,7 +18,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Changelog { - public class ChangelogHeader : BreadcrumbControlOverlayHeader + public partial class ChangelogHeader : BreadcrumbControlOverlayHeader { public readonly Bindable Build = new Bindable(); @@ -117,7 +117,7 @@ namespace osu.Game.Overlays.Changelog currentStream.Value = Streams.Items.FirstOrDefault(s => s.Name == Build.Value.UpdateStream.Name); } - private class ChangelogHeaderTitle : OverlayTitle + private partial class ChangelogHeaderTitle : OverlayTitle { public ChangelogHeaderTitle() { diff --git a/osu.Game/Overlays/Changelog/ChangelogListing.cs b/osu.Game/Overlays/Changelog/ChangelogListing.cs index e848f26587..d30fd97652 100644 --- a/osu.Game/Overlays/Changelog/ChangelogListing.cs +++ b/osu.Game/Overlays/Changelog/ChangelogListing.cs @@ -15,7 +15,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Changelog { - public class ChangelogListing : ChangelogContent + public partial class ChangelogListing : ChangelogContent { private readonly List entries; diff --git a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs index e4f240f0e7..ddee6ff8bb 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs @@ -24,7 +24,7 @@ using osuTK; namespace osu.Game.Overlays.Changelog { - public class ChangelogSingleBuild : ChangelogContent + public partial class ChangelogSingleBuild : ChangelogContent { private APIChangelogBuild build; @@ -91,7 +91,7 @@ namespace osu.Game.Overlays.Changelog } } - public class ChangelogBuildWithNavigation : ChangelogBuild + public partial class ChangelogBuildWithNavigation : ChangelogBuild { public ChangelogBuildWithNavigation(APIChangelogBuild build) : base(build) @@ -140,7 +140,7 @@ namespace osu.Game.Overlays.Changelog } } - private class NavigationIconButton : IconButton + private partial class NavigationIconButton : IconButton { public Action SelectBuild; diff --git a/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs b/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs index d84ed3c807..04526eb7ba 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs @@ -22,7 +22,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Changelog { - public class ChangelogSupporterPromo : CompositeDrawable + public partial class ChangelogSupporterPromo : CompositeDrawable { private const float image_container_width = 164; private const float heart_size = 75; @@ -160,7 +160,7 @@ namespace osu.Game.Overlays.Changelog supportLinkText.AddText(" today!"); } - private class SupporterPromoLinkFlowContainer : LinkFlowContainer + private partial class SupporterPromoLinkFlowContainer : LinkFlowContainer { public SupporterPromoLinkFlowContainer(Action defaultCreationParameters) : base(defaultCreationParameters) @@ -169,7 +169,7 @@ namespace osu.Game.Overlays.Changelog protected override DrawableLinkCompiler CreateLinkCompiler(ITextPart textPart) => new SupporterPromoLinkCompiler(textPart); - private class SupporterPromoLinkCompiler : DrawableLinkCompiler + private partial class SupporterPromoLinkCompiler : DrawableLinkCompiler { public SupporterPromoLinkCompiler(ITextPart part) : base(part) diff --git a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamControl.cs b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamControl.cs index 1db2d2f172..155cbc7d65 100644 --- a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamControl.cs +++ b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamControl.cs @@ -7,7 +7,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Changelog { - public class ChangelogUpdateStreamControl : OverlayStreamControl + public partial class ChangelogUpdateStreamControl : OverlayStreamControl { public ChangelogUpdateStreamControl() { diff --git a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs index 974b283ccf..08ea373fb1 100644 --- a/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs +++ b/osu.Game/Overlays/Changelog/ChangelogUpdateStreamItem.cs @@ -11,7 +11,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Changelog { - public class ChangelogUpdateStreamItem : OverlayStreamItem + public partial class ChangelogUpdateStreamItem : OverlayStreamItem { public ChangelogUpdateStreamItem(APIUpdateStream stream) : base(stream) diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs index 7e0d5e9432..90863a90a2 100644 --- a/osu.Game/Overlays/ChangelogOverlay.cs +++ b/osu.Game/Overlays/ChangelogOverlay.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public class ChangelogOverlay : OnlineOverlay + public partial class ChangelogOverlay : OnlineOverlay { public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks; diff --git a/osu.Game/Overlays/Chat/ChannelList/ChannelList.cs b/osu.Game/Overlays/Chat/ChannelList/ChannelList.cs index d9f962ca97..e6fe97f3c6 100644 --- a/osu.Game/Overlays/Chat/ChannelList/ChannelList.cs +++ b/osu.Game/Overlays/Chat/ChannelList/ChannelList.cs @@ -19,7 +19,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Chat.ChannelList { - public class ChannelList : Container + public partial class ChannelList : Container { public Action? OnRequestSelect; public Action? OnRequestLeave; @@ -140,7 +140,7 @@ namespace osu.Game.Overlays.Chat.ChannelList announceChannelGroup.Show(); } - private class ChannelGroup : FillFlowContainer + private partial class ChannelGroup : FillFlowContainer { public readonly FillFlowContainer ItemFlow; diff --git a/osu.Game/Overlays/Chat/ChannelList/ChannelListItem.cs b/osu.Game/Overlays/Chat/ChannelList/ChannelListItem.cs index c18e9e11fa..57b6f6268c 100644 --- a/osu.Game/Overlays/Chat/ChannelList/ChannelListItem.cs +++ b/osu.Game/Overlays/Chat/ChannelList/ChannelListItem.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Overlays.Chat.ChannelList { - public class ChannelListItem : OsuClickableContainer + public partial class ChannelListItem : OsuClickableContainer { public event Action? OnRequestSelect; public event Action? OnRequestLeave; diff --git a/osu.Game/Overlays/Chat/ChannelList/ChannelListItemCloseButton.cs b/osu.Game/Overlays/Chat/ChannelList/ChannelListItemCloseButton.cs index 46d70b2d67..204b9aab19 100644 --- a/osu.Game/Overlays/Chat/ChannelList/ChannelListItemCloseButton.cs +++ b/osu.Game/Overlays/Chat/ChannelList/ChannelListItemCloseButton.cs @@ -12,7 +12,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Chat.ChannelList { - public class ChannelListItemCloseButton : OsuClickableContainer + public partial class ChannelListItemCloseButton : OsuClickableContainer { private SpriteIcon icon = null!; diff --git a/osu.Game/Overlays/Chat/ChannelList/ChannelListItemMentionPill.cs b/osu.Game/Overlays/Chat/ChannelList/ChannelListItemMentionPill.cs index 2ead841f58..bbd042cfc9 100644 --- a/osu.Game/Overlays/Chat/ChannelList/ChannelListItemMentionPill.cs +++ b/osu.Game/Overlays/Chat/ChannelList/ChannelListItemMentionPill.cs @@ -13,7 +13,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Chat.ChannelList { - public class ChannelListItemMentionPill : CircularContainer + public partial class ChannelListItemMentionPill : CircularContainer { public readonly BindableInt Mentions = new BindableInt(); diff --git a/osu.Game/Overlays/Chat/ChannelScrollContainer.cs b/osu.Game/Overlays/Chat/ChannelScrollContainer.cs index dee7730e2c..090f7835ae 100644 --- a/osu.Game/Overlays/Chat/ChannelScrollContainer.cs +++ b/osu.Game/Overlays/Chat/ChannelScrollContainer.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Chat /// /// An with functionality to automatically scroll whenever the maximum scrollable distance increases. /// - public class ChannelScrollContainer : OsuScrollContainer + public partial class ChannelScrollContainer : OsuScrollContainer { /// /// The chat will be automatically scrolled to end if and only if diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index a991103fac..1c768101bf 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -26,7 +26,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Chat { - public class ChatLine : CompositeDrawable + public partial class ChatLine : CompositeDrawable { public Message Message { @@ -248,7 +248,7 @@ namespace osu.Game.Overlays.Chat }; } - private class MessageSender : OsuClickableContainer, IHasContextMenu + private partial class MessageSender : OsuClickableContainer, IHasContextMenu { private readonly APIUser sender; diff --git a/osu.Game/Overlays/Chat/ChatOverlayTopBar.cs b/osu.Game/Overlays/Chat/ChatOverlayTopBar.cs index ad9ae412da..0410174dc1 100644 --- a/osu.Game/Overlays/Chat/ChatOverlayTopBar.cs +++ b/osu.Game/Overlays/Chat/ChatOverlayTopBar.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Chat { - public class ChatOverlayTopBar : Container + public partial class ChatOverlayTopBar : Container { private Box background = null!; diff --git a/osu.Game/Overlays/Chat/ChatTextBar.cs b/osu.Game/Overlays/Chat/ChatTextBar.cs index 73314c2e44..bcf5c1a409 100644 --- a/osu.Game/Overlays/Chat/ChatTextBar.cs +++ b/osu.Game/Overlays/Chat/ChatTextBar.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Overlays.Chat { - public class ChatTextBar : Container + public partial class ChatTextBar : Container { public readonly BindableBool ShowSearch = new BindableBool(); diff --git a/osu.Game/Overlays/Chat/ChatTextBox.cs b/osu.Game/Overlays/Chat/ChatTextBox.cs index f0bdbce08d..780c85a9c1 100644 --- a/osu.Game/Overlays/Chat/ChatTextBox.cs +++ b/osu.Game/Overlays/Chat/ChatTextBox.cs @@ -7,7 +7,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Chat { - public class ChatTextBox : HistoryTextBox + public partial class ChatTextBox : HistoryTextBox { public readonly BindableBool ShowSearch = new BindableBool(); diff --git a/osu.Game/Overlays/Chat/DaySeparator.cs b/osu.Game/Overlays/Chat/DaySeparator.cs index d68f325738..e737b787ba 100644 --- a/osu.Game/Overlays/Chat/DaySeparator.cs +++ b/osu.Game/Overlays/Chat/DaySeparator.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays.Chat { - public class DaySeparator : Container + public partial class DaySeparator : Container { protected virtual float TextSize => 15; diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index 65876fd7c5..aa17df4907 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Chat { - public class DrawableChannel : Container + public partial class DrawableChannel : Container { public readonly Channel Channel; protected FillFlowContainer ChatLineFlow; diff --git a/osu.Game/Overlays/Chat/Listing/ChannelListing.cs b/osu.Game/Overlays/Chat/Listing/ChannelListing.cs index 44255eb754..809ea2f11d 100644 --- a/osu.Game/Overlays/Chat/Listing/ChannelListing.cs +++ b/osu.Game/Overlays/Chat/Listing/ChannelListing.cs @@ -13,7 +13,7 @@ using osu.Game.Online.Chat; namespace osu.Game.Overlays.Chat.Listing { - public class ChannelListing : VisibilityContainer + public partial class ChannelListing : VisibilityContainer { public event Action? OnRequestJoin; public event Action? OnRequestLeave; diff --git a/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs b/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs index ffeab3b380..22a3bdc06f 100644 --- a/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs +++ b/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs @@ -22,7 +22,7 @@ using osuTK; namespace osu.Game.Overlays.Chat.Listing { - public class ChannelListingItem : OsuClickableContainer, IFilterable + public partial class ChannelListingItem : OsuClickableContainer, IFilterable { public event Action? OnRequestJoin; public event Action? OnRequestLeave; diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index e9d28dcf28..98e153108f 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -26,7 +26,7 @@ using osu.Game.Overlays.Chat.Listing; namespace osu.Game.Overlays { - public class ChatOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent, IKeyBindingHandler + public partial class ChatOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent, IKeyBindingHandler { public string IconTexture => "Icons/Hexacons/messaging"; public LocalisableString Title => ChatStrings.HeaderTitle; diff --git a/osu.Game/Overlays/Comments/Buttons/ChevronButton.cs b/osu.Game/Overlays/Comments/Buttons/ChevronButton.cs index 46a455cbb3..88e7d00476 100644 --- a/osu.Game/Overlays/Comments/Buttons/ChevronButton.cs +++ b/osu.Game/Overlays/Comments/Buttons/ChevronButton.cs @@ -12,7 +12,7 @@ using osu.Framework.Allocation; namespace osu.Game.Overlays.Comments.Buttons { - public class ChevronButton : OsuHoverContainer + public partial class ChevronButton : OsuHoverContainer { public readonly BindableBool Expanded = new BindableBool(true); diff --git a/osu.Game/Overlays/Comments/Buttons/CommentRepliesButton.cs b/osu.Game/Overlays/Comments/Buttons/CommentRepliesButton.cs index d24a0cd27b..d9576f5b72 100644 --- a/osu.Game/Overlays/Comments/Buttons/CommentRepliesButton.cs +++ b/osu.Game/Overlays/Comments/Buttons/CommentRepliesButton.cs @@ -17,7 +17,7 @@ using static osu.Game.Graphics.UserInterface.ShowMoreButton; namespace osu.Game.Overlays.Comments.Buttons { - public abstract class CommentRepliesButton : CompositeDrawable + public abstract partial class CommentRepliesButton : CompositeDrawable { protected LocalisableString Text { diff --git a/osu.Game/Overlays/Comments/Buttons/LoadRepliesButton.cs b/osu.Game/Overlays/Comments/Buttons/LoadRepliesButton.cs index 42aca2f4a3..65d8685403 100644 --- a/osu.Game/Overlays/Comments/Buttons/LoadRepliesButton.cs +++ b/osu.Game/Overlays/Comments/Buttons/LoadRepliesButton.cs @@ -9,7 +9,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments.Buttons { - public class LoadRepliesButton : LoadingButton + public partial class LoadRepliesButton : LoadingButton { private ButtonContent content; @@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Comments.Buttons protected override void OnLoadFinished() => content.ToggleTextVisibility(true); - private class ButtonContent : CommentRepliesButton + private partial class ButtonContent : CommentRepliesButton { public ButtonContent() { diff --git a/osu.Game/Overlays/Comments/Buttons/ShowMoreRepliesButton.cs b/osu.Game/Overlays/Comments/Buttons/ShowMoreRepliesButton.cs index 6f3841d52e..0aedbe4c53 100644 --- a/osu.Game/Overlays/Comments/Buttons/ShowMoreRepliesButton.cs +++ b/osu.Game/Overlays/Comments/Buttons/ShowMoreRepliesButton.cs @@ -15,7 +15,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments.Buttons { - public class ShowMoreRepliesButton : LoadingButton + public partial class ShowMoreRepliesButton : LoadingButton { protected override IEnumerable EffectTargets => new[] { text }; diff --git a/osu.Game/Overlays/Comments/Buttons/ShowRepliesButton.cs b/osu.Game/Overlays/Comments/Buttons/ShowRepliesButton.cs index 845a630d97..aa9b2df7e4 100644 --- a/osu.Game/Overlays/Comments/Buttons/ShowRepliesButton.cs +++ b/osu.Game/Overlays/Comments/Buttons/ShowRepliesButton.cs @@ -9,7 +9,7 @@ using osu.Framework.Input.Events; namespace osu.Game.Overlays.Comments.Buttons { - public class ShowRepliesButton : CommentRepliesButton + public partial class ShowRepliesButton : CommentRepliesButton { public readonly BindableBool Expanded = new BindableBool(true); diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs index 7ba6de86b7..2b597d5638 100644 --- a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -17,7 +17,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments { - public abstract class CancellableCommentEditor : CommentEditor + public abstract partial class CancellableCommentEditor : CommentEditor { public Action OnCancel; @@ -32,7 +32,7 @@ namespace osu.Game.Overlays.Comments }); } - private class CancelButton : OsuHoverContainer + private partial class CancelButton : OsuHoverContainer { protected override IEnumerable EffectTargets => new[] { background }; diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index e2a7e78356..72edd1877e 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -20,7 +20,7 @@ using osu.Framework.Bindables; namespace osu.Game.Overlays.Comments { - public abstract class CommentEditor : CompositeDrawable + public abstract partial class CommentEditor : CompositeDrawable { private const int side_padding = 8; @@ -133,7 +133,7 @@ namespace osu.Game.Overlays.Comments Current.BindValueChanged(text => commitButton.IsBlocked.Value = string.IsNullOrEmpty(text.NewValue), true); } - private class EditorTextBox : BasicTextBox + private partial class EditorTextBox : BasicTextBox { protected override float LeftRightPadding => side_padding; @@ -167,7 +167,7 @@ namespace osu.Game.Overlays.Comments }; } - private class CommitButton : LoadingButton + private partial class CommitButton : LoadingButton { private const int duration = 200; diff --git a/osu.Game/Overlays/Comments/CommentMarkdownContainer.cs b/osu.Game/Overlays/Comments/CommentMarkdownContainer.cs index b32b1c74c4..664946fc63 100644 --- a/osu.Game/Overlays/Comments/CommentMarkdownContainer.cs +++ b/osu.Game/Overlays/Comments/CommentMarkdownContainer.cs @@ -9,13 +9,13 @@ using osu.Game.Graphics.Containers.Markdown; namespace osu.Game.Overlays.Comments { - public class CommentMarkdownContainer : OsuMarkdownContainer + public partial class CommentMarkdownContainer : OsuMarkdownContainer { protected override bool Autolinks => true; protected override MarkdownHeading CreateHeading(HeadingBlock headingBlock) => new CommentMarkdownHeading(headingBlock); - private class CommentMarkdownHeading : OsuMarkdownHeading + private partial class CommentMarkdownHeading : OsuMarkdownHeading { public CommentMarkdownHeading(HeadingBlock headingBlock) : base(headingBlock) diff --git a/osu.Game/Overlays/Comments/CommentReportButton.cs b/osu.Game/Overlays/Comments/CommentReportButton.cs index 4f5c5c6dcf..10bd3a64bf 100644 --- a/osu.Game/Overlays/Comments/CommentReportButton.cs +++ b/osu.Game/Overlays/Comments/CommentReportButton.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Overlays.Comments { - public class CommentReportButton : CompositeDrawable, IHasPopover + public partial class CommentReportButton : CompositeDrawable, IHasPopover { private readonly Comment comment; diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 4a836e0e62..7bd2d6a5e6 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -23,7 +23,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Overlays.Comments { - public class CommentsContainer : CompositeDrawable + public partial class CommentsContainer : CompositeDrawable { private readonly Bindable type = new Bindable(); private readonly BindableLong id = new BindableLong(); @@ -317,7 +317,7 @@ namespace osu.Game.Overlays.Comments base.Dispose(isDisposing); } - private class NoCommentsPlaceholder : CompositeDrawable + private partial class NoCommentsPlaceholder : CompositeDrawable { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Overlays/Comments/CommentsHeader.cs b/osu.Game/Overlays/Comments/CommentsHeader.cs index 5684841c37..e6d44e618b 100644 --- a/osu.Game/Overlays/Comments/CommentsHeader.cs +++ b/osu.Game/Overlays/Comments/CommentsHeader.cs @@ -20,7 +20,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments { - public class CommentsHeader : CompositeDrawable + public partial class CommentsHeader : CompositeDrawable { public readonly Bindable Sort = new Bindable(); public readonly BindableBool ShowDeleted = new BindableBool(); @@ -67,7 +67,7 @@ namespace osu.Game.Overlays.Comments background.Colour = colourProvider.Background4; } - private class ShowDeletedButton : HeaderButton + private partial class ShowDeletedButton : HeaderButton { public readonly BindableBool Checked = new BindableBool(); diff --git a/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs b/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs index 84d1f67486..1770fcb269 100644 --- a/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs +++ b/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs @@ -11,7 +11,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments { - public class CommentsShowMoreButton : ShowMoreButton + public partial class CommentsShowMoreButton : ShowMoreButton { public readonly BindableInt Current = new BindableInt(); diff --git a/osu.Game/Overlays/Comments/DeletedCommentsCounter.cs b/osu.Game/Overlays/Comments/DeletedCommentsCounter.cs index 2c7ed4f5b3..6adb388185 100644 --- a/osu.Game/Overlays/Comments/DeletedCommentsCounter.cs +++ b/osu.Game/Overlays/Comments/DeletedCommentsCounter.cs @@ -14,7 +14,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays.Comments { - public class DeletedCommentsCounter : CompositeDrawable + public partial class DeletedCommentsCounter : CompositeDrawable { public readonly BindableBool ShowDeleted = new BindableBool(); diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index aa08de798c..6cb5a0fbac 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -32,7 +32,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments { [Cached] - public class DrawableComment : CompositeDrawable + public partial class DrawableComment : CompositeDrawable { private const int avatar_size = 40; @@ -497,7 +497,7 @@ namespace osu.Game.Overlays.Comments }; } - private class PinnedCommentNotice : FillFlowContainer + private partial class PinnedCommentNotice : FillFlowContainer { public PinnedCommentNotice() { @@ -524,7 +524,7 @@ namespace osu.Game.Overlays.Comments } } - private class ParentUsername : FillFlowContainer, IHasTooltip + private partial class ParentUsername : FillFlowContainer, IHasTooltip { public LocalisableString TooltipText => getParentMessage(); diff --git a/osu.Game/Overlays/Comments/HeaderButton.cs b/osu.Game/Overlays/Comments/HeaderButton.cs index 186b892c4d..de99cd6cc8 100644 --- a/osu.Game/Overlays/Comments/HeaderButton.cs +++ b/osu.Game/Overlays/Comments/HeaderButton.cs @@ -11,7 +11,7 @@ using osu.Framework.Input.Events; namespace osu.Game.Overlays.Comments { - public class HeaderButton : Container + public partial class HeaderButton : Container { private const int transition_duration = 200; diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index 39fd52aa2a..f3b2a2f97c 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Overlays.Comments { - public class ReportCommentPopover : OsuPopover + public partial class ReportCommentPopover : OsuPopover { public Action? Action; diff --git a/osu.Game/Overlays/Comments/TotalCommentsCounter.cs b/osu.Game/Overlays/Comments/TotalCommentsCounter.cs index 218d8383f6..38928f6f3d 100644 --- a/osu.Game/Overlays/Comments/TotalCommentsCounter.cs +++ b/osu.Game/Overlays/Comments/TotalCommentsCounter.cs @@ -15,7 +15,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments { - public class TotalCommentsCounter : CompositeDrawable + public partial class TotalCommentsCounter : CompositeDrawable { public readonly BindableInt Current = new BindableInt(); diff --git a/osu.Game/Overlays/Comments/VotePill.cs b/osu.Game/Overlays/Comments/VotePill.cs index 7a4b83cc48..6cfa5cb9e8 100644 --- a/osu.Game/Overlays/Comments/VotePill.cs +++ b/osu.Game/Overlays/Comments/VotePill.cs @@ -24,7 +24,7 @@ using System.Linq; namespace osu.Game.Overlays.Comments { - public class VotePill : LoadingButton, IHasAccentColour + public partial class VotePill : LoadingButton, IHasAccentColour { private const int duration = 200; diff --git a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs index aae4932c22..632ba4b838 100644 --- a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs +++ b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs @@ -30,7 +30,7 @@ using osuTK; namespace osu.Game.Overlays.Dashboard { - internal class CurrentlyPlayingDisplay : CompositeDrawable + internal partial class CurrentlyPlayingDisplay : CompositeDrawable { private const float search_textbox_height = 40; private const float padding = 10; @@ -153,7 +153,7 @@ namespace osu.Game.Overlays.Dashboard panel.Origin = Anchor.TopCentre; }); - public class PlayingUserPanel : CompositeDrawable, IFilterable + public partial class PlayingUserPanel : CompositeDrawable, IFilterable { public readonly APIUser User; diff --git a/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs b/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs index 370181a0cb..5cbeb8f306 100644 --- a/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs +++ b/osu.Game/Overlays/Dashboard/DashboardOverlayHeader.cs @@ -10,11 +10,11 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Dashboard { - public class DashboardOverlayHeader : TabControlOverlayHeader + public partial class DashboardOverlayHeader : TabControlOverlayHeader { protected override OverlayTitle CreateTitle() => new DashboardTitle(); - private class DashboardTitle : OverlayTitle + private partial class DashboardTitle : OverlayTitle { public DashboardTitle() { diff --git a/osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs b/osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs index bfd356193d..73fab6d62b 100644 --- a/osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs +++ b/osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Overlays.Dashboard.Friends { - public class FriendDisplay : CompositeDrawable + public partial class FriendDisplay : CompositeDrawable { private List users = new List(); diff --git a/osu.Game/Overlays/Dashboard/Friends/FriendOnlineStreamControl.cs b/osu.Game/Overlays/Dashboard/Friends/FriendOnlineStreamControl.cs index fc6158e747..9f429c23d8 100644 --- a/osu.Game/Overlays/Dashboard/Friends/FriendOnlineStreamControl.cs +++ b/osu.Game/Overlays/Dashboard/Friends/FriendOnlineStreamControl.cs @@ -9,7 +9,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Dashboard.Friends { - public class FriendOnlineStreamControl : OverlayStreamControl + public partial class FriendOnlineStreamControl : OverlayStreamControl { protected override OverlayStreamItem CreateStreamItem(FriendStream value) => new FriendsOnlineStatusItem(value); diff --git a/osu.Game/Overlays/Dashboard/Friends/FriendsOnlineStatusItem.cs b/osu.Game/Overlays/Dashboard/Friends/FriendsOnlineStatusItem.cs index 7e2ec3f442..785eef38ad 100644 --- a/osu.Game/Overlays/Dashboard/Friends/FriendsOnlineStatusItem.cs +++ b/osu.Game/Overlays/Dashboard/Friends/FriendsOnlineStatusItem.cs @@ -11,7 +11,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Dashboard.Friends { - public class FriendsOnlineStatusItem : OverlayStreamItem + public partial class FriendsOnlineStatusItem : OverlayStreamItem { public FriendsOnlineStatusItem(FriendStream value) : base(value) diff --git a/osu.Game/Overlays/Dashboard/Friends/UserListToolbar.cs b/osu.Game/Overlays/Dashboard/Friends/UserListToolbar.cs index 25ddb9e704..db8510325c 100644 --- a/osu.Game/Overlays/Dashboard/Friends/UserListToolbar.cs +++ b/osu.Game/Overlays/Dashboard/Friends/UserListToolbar.cs @@ -10,7 +10,7 @@ using osu.Framework.Bindables; namespace osu.Game.Overlays.Dashboard.Friends { - public class UserListToolbar : CompositeDrawable + public partial class UserListToolbar : CompositeDrawable { public Bindable SortCriteria => sortControl.Current; diff --git a/osu.Game/Overlays/Dashboard/Friends/UserSortTabControl.cs b/osu.Game/Overlays/Dashboard/Friends/UserSortTabControl.cs index 466e36c1a9..886ed08af2 100644 --- a/osu.Game/Overlays/Dashboard/Friends/UserSortTabControl.cs +++ b/osu.Game/Overlays/Dashboard/Friends/UserSortTabControl.cs @@ -9,7 +9,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Dashboard.Friends { - public class UserSortTabControl : OverlaySortTabControl + public partial class UserSortTabControl : OverlaySortTabControl { } diff --git a/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapListing.cs b/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapListing.cs index e9c7af3339..0282ba8785 100644 --- a/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapListing.cs +++ b/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapListing.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Overlays.Dashboard.Home { - public class DashboardBeatmapListing : CompositeDrawable + public partial class DashboardBeatmapListing : CompositeDrawable { private readonly List newBeatmaps; private readonly List popularBeatmaps; diff --git a/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapPanel.cs index 1e4ba2ef05..792d6cc785 100644 --- a/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/DashboardBeatmapPanel.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Overlays.Dashboard.Home { - public abstract class DashboardBeatmapPanel : OsuClickableContainer + public abstract partial class DashboardBeatmapPanel : OsuClickableContainer { [Resolved] protected OverlayColourProvider ColourProvider { get; private set; } diff --git a/osu.Game/Overlays/Dashboard/Home/DashboardNewBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Home/DashboardNewBeatmapPanel.cs index 258fd56dd7..fef33bdf5a 100644 --- a/osu.Game/Overlays/Dashboard/Home/DashboardNewBeatmapPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/DashboardNewBeatmapPanel.cs @@ -10,7 +10,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Dashboard.Home { - public class DashboardNewBeatmapPanel : DashboardBeatmapPanel + public partial class DashboardNewBeatmapPanel : DashboardBeatmapPanel { public DashboardNewBeatmapPanel(APIBeatmapSet beatmapSet) : base(beatmapSet) diff --git a/osu.Game/Overlays/Dashboard/Home/DashboardPopularBeatmapPanel.cs b/osu.Game/Overlays/Dashboard/Home/DashboardPopularBeatmapPanel.cs index 743bd5440f..54d95c994b 100644 --- a/osu.Game/Overlays/Dashboard/Home/DashboardPopularBeatmapPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/DashboardPopularBeatmapPanel.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Overlays.Dashboard.Home { - public class DashboardPopularBeatmapPanel : DashboardBeatmapPanel + public partial class DashboardPopularBeatmapPanel : DashboardBeatmapPanel { public DashboardPopularBeatmapPanel(APIBeatmapSet beatmapSet) : base(beatmapSet) diff --git a/osu.Game/Overlays/Dashboard/Home/DrawableBeatmapList.cs b/osu.Game/Overlays/Dashboard/Home/DrawableBeatmapList.cs index 8f140facef..af36f71dd2 100644 --- a/osu.Game/Overlays/Dashboard/Home/DrawableBeatmapList.cs +++ b/osu.Game/Overlays/Dashboard/Home/DrawableBeatmapList.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Overlays.Dashboard.Home { - public abstract class DrawableBeatmapList : CompositeDrawable + public abstract partial class DrawableBeatmapList : CompositeDrawable { private readonly List beatmapSets; diff --git a/osu.Game/Overlays/Dashboard/Home/DrawableNewBeatmapList.cs b/osu.Game/Overlays/Dashboard/Home/DrawableNewBeatmapList.cs index c6917b41fb..8a60d8568c 100644 --- a/osu.Game/Overlays/Dashboard/Home/DrawableNewBeatmapList.cs +++ b/osu.Game/Overlays/Dashboard/Home/DrawableNewBeatmapList.cs @@ -10,7 +10,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Dashboard.Home { - public class DrawableNewBeatmapList : DrawableBeatmapList + public partial class DrawableNewBeatmapList : DrawableBeatmapList { public DrawableNewBeatmapList(List beatmapSets) : base(beatmapSets) diff --git a/osu.Game/Overlays/Dashboard/Home/DrawablePopularBeatmapList.cs b/osu.Game/Overlays/Dashboard/Home/DrawablePopularBeatmapList.cs index 9ff12623e0..aab99d0ed3 100644 --- a/osu.Game/Overlays/Dashboard/Home/DrawablePopularBeatmapList.cs +++ b/osu.Game/Overlays/Dashboard/Home/DrawablePopularBeatmapList.cs @@ -10,7 +10,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Dashboard.Home { - public class DrawablePopularBeatmapList : DrawableBeatmapList + public partial class DrawablePopularBeatmapList : DrawableBeatmapList { public DrawablePopularBeatmapList(List beatmapSets) : base(beatmapSets) diff --git a/osu.Game/Overlays/Dashboard/Home/HomePanel.cs b/osu.Game/Overlays/Dashboard/Home/HomePanel.cs index 099e16cd55..8023c093aa 100644 --- a/osu.Game/Overlays/Dashboard/Home/HomePanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/HomePanel.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Dashboard.Home { - public class HomePanel : Container + public partial class HomePanel : Container { protected override Container Content => content; diff --git a/osu.Game/Overlays/Dashboard/Home/News/FeaturedNewsItemPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/FeaturedNewsItemPanel.cs index 1d904526fd..3066d253eb 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/FeaturedNewsItemPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/FeaturedNewsItemPanel.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Dashboard.Home.News { - public class FeaturedNewsItemPanel : HomePanel + public partial class FeaturedNewsItemPanel : HomePanel { private readonly APINewsPost post; @@ -104,7 +104,7 @@ namespace osu.Game.Overlays.Dashboard.Home.News }; } - private class ClickableNewsBackground : OsuHoverContainer + private partial class ClickableNewsBackground : OsuHoverContainer { private readonly APINewsPost post; @@ -137,7 +137,7 @@ namespace osu.Game.Overlays.Dashboard.Home.News } } - private class Date : CompositeDrawable, IHasCustomTooltip + private partial class Date : CompositeDrawable, IHasCustomTooltip { private readonly DateTimeOffset date; diff --git a/osu.Game/Overlays/Dashboard/Home/News/NewsGroupItem.cs b/osu.Game/Overlays/Dashboard/Home/News/NewsGroupItem.cs index 9b66e5524b..e277a5fa16 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/NewsGroupItem.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/NewsGroupItem.cs @@ -14,7 +14,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Dashboard.Home.News { - public class NewsGroupItem : CompositeDrawable + public partial class NewsGroupItem : CompositeDrawable { private readonly APINewsPost post; @@ -69,7 +69,7 @@ namespace osu.Game.Overlays.Dashboard.Home.News }; } - private class Date : CompositeDrawable, IHasCustomTooltip + private partial class Date : CompositeDrawable, IHasCustomTooltip { private readonly DateTimeOffset date; diff --git a/osu.Game/Overlays/Dashboard/Home/News/NewsItemGroupPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/NewsItemGroupPanel.cs index 4456a292a5..fa59f38690 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/NewsItemGroupPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/NewsItemGroupPanel.cs @@ -12,7 +12,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Dashboard.Home.News { - public class NewsItemGroupPanel : HomePanel + public partial class NewsItemGroupPanel : HomePanel { private readonly List posts; diff --git a/osu.Game/Overlays/Dashboard/Home/News/NewsTitleLink.cs b/osu.Game/Overlays/Dashboard/Home/News/NewsTitleLink.cs index e384c3e6e5..1960e0372e 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/NewsTitleLink.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/NewsTitleLink.cs @@ -13,7 +13,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Dashboard.Home.News { - public class NewsTitleLink : OsuHoverContainer + public partial class NewsTitleLink : OsuHoverContainer { private readonly APINewsPost post; diff --git a/osu.Game/Overlays/Dashboard/Home/News/ShowMoreNewsPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/ShowMoreNewsPanel.cs index 9b1d77a8c2..3e61dd1938 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/ShowMoreNewsPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/ShowMoreNewsPanel.cs @@ -13,7 +13,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Dashboard.Home.News { - public class ShowMoreNewsPanel : OsuHoverContainer + public partial class ShowMoreNewsPanel : OsuHoverContainer { protected override IEnumerable EffectTargets => new[] { text }; diff --git a/osu.Game/Overlays/DashboardOverlay.cs b/osu.Game/Overlays/DashboardOverlay.cs index d919022dbb..527ac1689b 100644 --- a/osu.Game/Overlays/DashboardOverlay.cs +++ b/osu.Game/Overlays/DashboardOverlay.cs @@ -9,7 +9,7 @@ using osu.Game.Overlays.Dashboard.Friends; namespace osu.Game.Overlays { - public class DashboardOverlay : TabbableOnlineOverlay + public partial class DashboardOverlay : TabbableOnlineOverlay { public DashboardOverlay() : base(OverlayColourScheme.Purple) diff --git a/osu.Game/Overlays/Dialog/ConfirmDialog.cs b/osu.Game/Overlays/Dialog/ConfirmDialog.cs index c17080f602..f1caac8b5d 100644 --- a/osu.Game/Overlays/Dialog/ConfirmDialog.cs +++ b/osu.Game/Overlays/Dialog/ConfirmDialog.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Dialog /// /// A dialog which confirms a user action. /// - public class ConfirmDialog : PopupDialog + public partial class ConfirmDialog : PopupDialog { /// /// Construct a new confirmation dialog. diff --git a/osu.Game/Overlays/Dialog/DeleteConfirmationDialog.cs b/osu.Game/Overlays/Dialog/DeleteConfirmationDialog.cs index fd26dd7e8e..ddb59c4c9e 100644 --- a/osu.Game/Overlays/Dialog/DeleteConfirmationDialog.cs +++ b/osu.Game/Overlays/Dialog/DeleteConfirmationDialog.cs @@ -12,7 +12,7 @@ namespace osu.Game.Overlays.Dialog /// Differs from in that the confirmation button is a "dangerous" one /// (requires the confirm button to be held). /// - public abstract class DeleteConfirmationDialog : PopupDialog + public abstract partial class DeleteConfirmationDialog : PopupDialog { /// /// The action which performs the deletion. diff --git a/osu.Game/Overlays/Dialog/PopupDialog.cs b/osu.Game/Overlays/Dialog/PopupDialog.cs index 864120cc49..80e0ffe427 100644 --- a/osu.Game/Overlays/Dialog/PopupDialog.cs +++ b/osu.Game/Overlays/Dialog/PopupDialog.cs @@ -21,7 +21,7 @@ using osuTK.Input; namespace osu.Game.Overlays.Dialog { - public abstract class PopupDialog : VisibilityContainer + public abstract partial class PopupDialog : VisibilityContainer { public const float ENTER_DURATION = 500; public const float EXIT_DURATION = 200; diff --git a/osu.Game/Overlays/Dialog/PopupDialogButton.cs b/osu.Game/Overlays/Dialog/PopupDialogButton.cs index e1cc31da82..91a19add21 100644 --- a/osu.Game/Overlays/Dialog/PopupDialogButton.cs +++ b/osu.Game/Overlays/Dialog/PopupDialogButton.cs @@ -8,7 +8,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Dialog { - public class PopupDialogButton : DialogButton + public partial class PopupDialogButton : DialogButton { public PopupDialogButton(HoverSampleSet sampleSet = HoverSampleSet.Button) : base(sampleSet) diff --git a/osu.Game/Overlays/Dialog/PopupDialogCancelButton.cs b/osu.Game/Overlays/Dialog/PopupDialogCancelButton.cs index f23a40b7ab..f4289c66f1 100644 --- a/osu.Game/Overlays/Dialog/PopupDialogCancelButton.cs +++ b/osu.Game/Overlays/Dialog/PopupDialogCancelButton.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Dialog { - public class PopupDialogCancelButton : PopupDialogButton + public partial class PopupDialogCancelButton : PopupDialogButton { [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game/Overlays/Dialog/PopupDialogDangerousButton.cs b/osu.Game/Overlays/Dialog/PopupDialogDangerousButton.cs index bd7cb4ed33..6b3716ac8d 100644 --- a/osu.Game/Overlays/Dialog/PopupDialogDangerousButton.cs +++ b/osu.Game/Overlays/Dialog/PopupDialogDangerousButton.cs @@ -16,7 +16,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Overlays.Dialog { - public class PopupDialogDangerousButton : PopupDialogButton + public partial class PopupDialogDangerousButton : PopupDialogButton { private Box progressBox; private DangerousConfirmContainer confirmContainer; @@ -46,7 +46,7 @@ namespace osu.Game.Overlays.Dialog confirmContainer.Progress.BindValueChanged(progress => progressBox.Width = (float)progress.NewValue, true); } - private class DangerousConfirmContainer : HoldToConfirmContainer + private partial class DangerousConfirmContainer : HoldToConfirmContainer { public DangerousConfirmContainer() : base(isDangerousAction: true) diff --git a/osu.Game/Overlays/Dialog/PopupDialogOkButton.cs b/osu.Game/Overlays/Dialog/PopupDialogOkButton.cs index 3496627c89..eb4a0f0709 100644 --- a/osu.Game/Overlays/Dialog/PopupDialogOkButton.cs +++ b/osu.Game/Overlays/Dialog/PopupDialogOkButton.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Dialog { - public class PopupDialogOkButton : PopupDialogButton + public partial class PopupDialogOkButton : PopupDialogButton { [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game/Overlays/DialogOverlay.cs b/osu.Game/Overlays/DialogOverlay.cs index ba8083e535..098a5d0a33 100644 --- a/osu.Game/Overlays/DialogOverlay.cs +++ b/osu.Game/Overlays/DialogOverlay.cs @@ -16,7 +16,7 @@ using osu.Game.Audio.Effects; namespace osu.Game.Overlays { - public class DialogOverlay : OsuFocusedOverlayContainer, IDialogOverlay + public partial class DialogOverlay : OsuFocusedOverlayContainer, IDialogOverlay { private readonly Container dialogContainer; diff --git a/osu.Game/Overlays/FirstRunSetup/FirstRunSetupScreen.cs b/osu.Game/Overlays/FirstRunSetup/FirstRunSetupScreen.cs index cef1f1c869..76921718f2 100644 --- a/osu.Game/Overlays/FirstRunSetup/FirstRunSetupScreen.cs +++ b/osu.Game/Overlays/FirstRunSetup/FirstRunSetupScreen.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Overlays.FirstRunSetup { - public abstract class FirstRunSetupScreen : Screen + public abstract partial class FirstRunSetupScreen : Screen { private const float offset = 100; diff --git a/osu.Game/Overlays/FirstRunSetup/ProgressRoundedButton.cs b/osu.Game/Overlays/FirstRunSetup/ProgressRoundedButton.cs index 95ebb256c4..a4762fdaed 100644 --- a/osu.Game/Overlays/FirstRunSetup/ProgressRoundedButton.cs +++ b/osu.Game/Overlays/FirstRunSetup/ProgressRoundedButton.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Overlays.FirstRunSetup { - public class ProgressRoundedButton : RoundedButton + public partial class ProgressRoundedButton : RoundedButton { public new Action? Action; diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenBeatmaps.cs b/osu.Game/Overlays/FirstRunSetup/ScreenBeatmaps.cs index 4963de7251..75bc8fd3a8 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenBeatmaps.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenBeatmaps.cs @@ -20,7 +20,7 @@ using Realms; namespace osu.Game.Overlays.FirstRunSetup { [LocalisableDescription(typeof(FirstRunSetupBeatmapScreenStrings), nameof(FirstRunSetupBeatmapScreenStrings.Header))] - public class ScreenBeatmaps : FirstRunSetupScreen + public partial class ScreenBeatmaps : FirstRunSetupScreen { private ProgressRoundedButton downloadBundledButton = null!; private ProgressRoundedButton downloadTutorialButton = null!; diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenBehaviour.cs b/osu.Game/Overlays/FirstRunSetup/ScreenBehaviour.cs index 9573b4859f..95af8ec0f3 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenBehaviour.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenBehaviour.cs @@ -19,7 +19,7 @@ using osu.Game.Overlays.Settings.Sections; namespace osu.Game.Overlays.FirstRunSetup { [LocalisableDescription(typeof(FirstRunSetupOverlayStrings), nameof(FirstRunSetupOverlayStrings.Behaviour))] - public class ScreenBehaviour : FirstRunSetupScreen + public partial class ScreenBehaviour : FirstRunSetupScreen { private SearchContainer searchContainer; diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index a34f8f0c1b..29cf3824fd 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -26,7 +26,7 @@ using osuTK; namespace osu.Game.Overlays.FirstRunSetup { [LocalisableDescription(typeof(FirstRunOverlayImportFromStableScreenStrings), nameof(FirstRunOverlayImportFromStableScreenStrings.Header))] - public class ScreenImportFromStable : FirstRunSetupScreen + public partial class ScreenImportFromStable : FirstRunSetupScreen { private static readonly Vector2 button_size = new Vector2(400, 50); @@ -139,7 +139,7 @@ namespace osu.Game.Overlays.FirstRunSetup c.Current.Disabled = !allow; } - private class ImportCheckbox : SettingsCheckbox + private partial class ImportCheckbox : SettingsCheckbox { public readonly StableContent StableContent; @@ -181,7 +181,7 @@ namespace osu.Game.Overlays.FirstRunSetup } } - internal class StableLocatorLabelledTextBox : LabelledTextBoxWithPopover, ICanAcceptFiles + internal partial class StableLocatorLabelledTextBox : LabelledTextBoxWithPopover, ICanAcceptFiles { [Resolved] private LegacyImportManager legacyImportManager { get; set; } = null!; @@ -245,7 +245,7 @@ namespace osu.Game.Overlays.FirstRunSetup public override Popover GetPopover() => new DirectoryChooserPopover(currentDirectory); - private class DirectoryChooserPopover : OsuPopover + private partial class DirectoryChooserPopover : OsuPopover { public DirectoryChooserPopover(Bindable currentDirectory) { diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs b/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs index 0d4496a6a3..b28b04f228 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs @@ -32,7 +32,7 @@ using osuTK; namespace osu.Game.Overlays.FirstRunSetup { [LocalisableDescription(typeof(GraphicsSettingsStrings), nameof(GraphicsSettingsStrings.UIScaling))] - public class ScreenUIScale : FirstRunSetupScreen + public partial class ScreenUIScale : FirstRunSetupScreen { [BackgroundDependencyLoader] private void load(OsuConfigManager config) @@ -80,7 +80,7 @@ namespace osu.Game.Overlays.FirstRunSetup }; } - private class InverseScalingDrawSizePreservingFillContainer : ScalingContainer.ScalingDrawSizePreservingFillContainer + private partial class InverseScalingDrawSizePreservingFillContainer : ScalingContainer.ScalingDrawSizePreservingFillContainer { private Vector2 initialSize; @@ -102,14 +102,14 @@ namespace osu.Game.Overlays.FirstRunSetup } } - private class NestedSongSelect : PlaySongSelect + private partial class NestedSongSelect : PlaySongSelect { protected override bool ControlGlobalMusic => false; public override bool? AllowTrackAdjustments => false; } - private class PinnedMainMenu : MainMenu + private partial class PinnedMainMenu : MainMenu { public override void OnEntering(ScreenTransitionEvent e) { @@ -120,12 +120,12 @@ namespace osu.Game.Overlays.FirstRunSetup } } - private class UIScaleSlider : OsuSliderBar + private partial class UIScaleSlider : OsuSliderBar { public override LocalisableString TooltipText => base.TooltipText + "x"; } - private class SampleScreenContainer : CompositeDrawable + private partial class SampleScreenContainer : CompositeDrawable { private readonly OsuScreen screen; diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs index 3113e11346..fe3aaeb9d8 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs @@ -24,7 +24,7 @@ using osuTK; namespace osu.Game.Overlays.FirstRunSetup { [LocalisableDescription(typeof(FirstRunSetupOverlayStrings), nameof(FirstRunSetupOverlayStrings.WelcomeTitle))] - public class ScreenWelcome : FirstRunSetupScreen + public partial class ScreenWelcome : FirstRunSetupScreen { [BackgroundDependencyLoader] private void load(FrameworkConfigManager frameworkConfig) @@ -66,7 +66,7 @@ namespace osu.Game.Overlays.FirstRunSetup }; } - private class LanguageSelectionFlow : FillFlowContainer + private partial class LanguageSelectionFlow : FillFlowContainer { private Bindable frameworkLocale = null!; private IBindable localisationParameters = null!; @@ -107,7 +107,7 @@ namespace osu.Game.Overlays.FirstRunSetup c.Selected = c.Language == language; } - private class LanguageButton : OsuClickableContainer + private partial class LanguageButton : OsuClickableContainer { public readonly Language Language; diff --git a/osu.Game/Overlays/FirstRunSetupOverlay.cs b/osu.Game/Overlays/FirstRunSetupOverlay.cs index 8c9ca7e35b..45fc9d27ea 100644 --- a/osu.Game/Overlays/FirstRunSetupOverlay.cs +++ b/osu.Game/Overlays/FirstRunSetupOverlay.cs @@ -31,7 +31,7 @@ using osu.Game.Screens.Menu; namespace osu.Game.Overlays { [Cached] - public class FirstRunSetupOverlay : ShearedOverlayContainer + public partial class FirstRunSetupOverlay : ShearedOverlayContainer { [Resolved] private IPerformFromScreenRunner performer { get; set; } = null!; diff --git a/osu.Game/Overlays/FullscreenOverlay.cs b/osu.Game/Overlays/FullscreenOverlay.cs index 63a9ebc750..2cc8354e50 100644 --- a/osu.Game/Overlays/FullscreenOverlay.cs +++ b/osu.Game/Overlays/FullscreenOverlay.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public abstract class FullscreenOverlay : WaveOverlayContainer, INamedOverlayComponent + public abstract partial class FullscreenOverlay : WaveOverlayContainer, INamedOverlayComponent where T : OverlayHeader { public virtual string IconTexture => Header.Title.IconTexture ?? string.Empty; diff --git a/osu.Game/Overlays/HoldToConfirmOverlay.cs b/osu.Game/Overlays/HoldToConfirmOverlay.cs index dd03206eab..ac8b4ad0a8 100644 --- a/osu.Game/Overlays/HoldToConfirmOverlay.cs +++ b/osu.Game/Overlays/HoldToConfirmOverlay.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays /// An overlay which will display a black screen that dims over a period before confirming an exit action. /// Action is BYO (derived class will need to call and from a user event). /// - public abstract class HoldToConfirmOverlay : HoldToConfirmContainer + public abstract partial class HoldToConfirmOverlay : HoldToConfirmContainer { private Box overlay; diff --git a/osu.Game/Overlays/Login/LoginForm.cs b/osu.Game/Overlays/Login/LoginForm.cs index 0042f4607d..af145c418c 100644 --- a/osu.Game/Overlays/Login/LoginForm.cs +++ b/osu.Game/Overlays/Login/LoginForm.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Overlays.Login { - public class LoginForm : FillFlowContainer + public partial class LoginForm : FillFlowContainer { private TextBox username = null!; private TextBox password = null!; diff --git a/osu.Game/Overlays/Login/LoginPanel.cs b/osu.Game/Overlays/Login/LoginPanel.cs index 32a7fca1a6..44f2f3273a 100644 --- a/osu.Game/Overlays/Login/LoginPanel.cs +++ b/osu.Game/Overlays/Login/LoginPanel.cs @@ -22,7 +22,7 @@ using Container = osu.Framework.Graphics.Containers.Container; namespace osu.Game.Overlays.Login { - public class LoginPanel : FillFlowContainer + public partial class LoginPanel : FillFlowContainer { private bool bounding = true; private LoginForm form; diff --git a/osu.Game/Overlays/Login/UserDropdown.cs b/osu.Game/Overlays/Login/UserDropdown.cs index 73ccfb3443..dfc9d12977 100644 --- a/osu.Game/Overlays/Login/UserDropdown.cs +++ b/osu.Game/Overlays/Login/UserDropdown.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Login { - public class UserDropdown : OsuEnumDropdown + public partial class UserDropdown : OsuEnumDropdown { protected override DropdownHeader CreateHeader() => new UserDropdownHeader(); @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Login } } - protected class UserDropdownMenu : OsuDropdownMenu + protected partial class UserDropdownMenu : OsuDropdownMenu { public UserDropdownMenu() { @@ -58,7 +58,7 @@ namespace osu.Game.Overlays.Login protected override DrawableDropdownMenuItem CreateDrawableDropdownMenuItem(MenuItem item) => new DrawableUserDropdownMenuItem(item); - private class DrawableUserDropdownMenuItem : DrawableOsuDropdownMenuItem + private partial class DrawableUserDropdownMenuItem : DrawableOsuDropdownMenuItem { public DrawableUserDropdownMenuItem(MenuItem item) : base(item) @@ -74,7 +74,7 @@ namespace osu.Game.Overlays.Login } } - private class UserDropdownHeader : OsuDropdownHeader + private partial class UserDropdownHeader : OsuDropdownHeader { public const float LABEL_LEFT_MARGIN = 20; diff --git a/osu.Game/Overlays/LoginOverlay.cs b/osu.Game/Overlays/LoginOverlay.cs index 2362b2ad88..536811dfcf 100644 --- a/osu.Game/Overlays/LoginOverlay.cs +++ b/osu.Game/Overlays/LoginOverlay.cs @@ -15,7 +15,7 @@ using osu.Game.Overlays.Login; namespace osu.Game.Overlays { - public class LoginOverlay : OsuFocusedOverlayContainer + public partial class LoginOverlay : OsuFocusedOverlayContainer { private LoginPanel panel; diff --git a/osu.Game/Overlays/MedalOverlay.cs b/osu.Game/Overlays/MedalOverlay.cs index 9b856014f9..bd895fe6bf 100644 --- a/osu.Game/Overlays/MedalOverlay.cs +++ b/osu.Game/Overlays/MedalOverlay.cs @@ -27,7 +27,7 @@ using osu.Framework.Utils; namespace osu.Game.Overlays { - public class MedalOverlay : FocusedOverlayContainer + public partial class MedalOverlay : FocusedOverlayContainer { public const float DISC_SIZE = 400; @@ -266,7 +266,7 @@ namespace osu.Game.Overlays Expire(); } - private class BackgroundStrip : Container + private partial class BackgroundStrip : Container { public BackgroundStrip(float start, float end) { @@ -286,7 +286,7 @@ namespace osu.Game.Overlays } } - private class MedalParticle : CircularContainer + private partial class MedalParticle : CircularContainer { private readonly float direction; diff --git a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs index 1c007c913e..a25147b69f 100644 --- a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs +++ b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs @@ -19,7 +19,7 @@ using osu.Game.Users; namespace osu.Game.Overlays.MedalSplash { [LongRunningLoad] - public class DrawableMedal : Container, IStateful + public partial class DrawableMedal : Container, IStateful { private const float scale_when_unlocked = 0.76f; private const float scale_when_full = 0.6f; diff --git a/osu.Game/Overlays/Mods/AddPresetButton.cs b/osu.Game/Overlays/Mods/AddPresetButton.cs index 1242088cf5..731079d1d9 100644 --- a/osu.Game/Overlays/Mods/AddPresetButton.cs +++ b/osu.Game/Overlays/Mods/AddPresetButton.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Overlays.Mods { - public class AddPresetButton : ShearedToggleButton, IHasPopover + public partial class AddPresetButton : ShearedToggleButton, IHasPopover { [Resolved] private OsuColour colours { get; set; } = null!; diff --git a/osu.Game/Overlays/Mods/AddPresetPopover.cs b/osu.Game/Overlays/Mods/AddPresetPopover.cs index 8188c98e46..33d72ff383 100644 --- a/osu.Game/Overlays/Mods/AddPresetPopover.cs +++ b/osu.Game/Overlays/Mods/AddPresetPopover.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Overlays.Mods { - internal class AddPresetPopover : OsuPopover + internal partial class AddPresetPopover : OsuPopover { private readonly AddPresetButton button; diff --git a/osu.Game/Overlays/Mods/DeleteModPresetDialog.cs b/osu.Game/Overlays/Mods/DeleteModPresetDialog.cs index b3a19e35ce..800ebe8b4e 100644 --- a/osu.Game/Overlays/Mods/DeleteModPresetDialog.cs +++ b/osu.Game/Overlays/Mods/DeleteModPresetDialog.cs @@ -7,7 +7,7 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Overlays.Mods { - public class DeleteModPresetDialog : DeleteConfirmationDialog + public partial class DeleteModPresetDialog : DeleteConfirmationDialog { public DeleteModPresetDialog(Live modPreset) { diff --git a/osu.Game/Overlays/Mods/DeselectAllModsButton.cs b/osu.Game/Overlays/Mods/DeselectAllModsButton.cs index 61fca9e091..3e5a3b12d1 100644 --- a/osu.Game/Overlays/Mods/DeselectAllModsButton.cs +++ b/osu.Game/Overlays/Mods/DeselectAllModsButton.cs @@ -15,7 +15,7 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Overlays.Mods { - public class DeselectAllModsButton : ShearedButton, IKeyBindingHandler + public partial class DeselectAllModsButton : ShearedButton, IKeyBindingHandler { private readonly Bindable> selectedMods = new Bindable>(); diff --git a/osu.Game/Overlays/Mods/DifficultyMultiplierDisplay.cs b/osu.Game/Overlays/Mods/DifficultyMultiplierDisplay.cs index f582a010c6..ee4f932326 100644 --- a/osu.Game/Overlays/Mods/DifficultyMultiplierDisplay.cs +++ b/osu.Game/Overlays/Mods/DifficultyMultiplierDisplay.cs @@ -11,7 +11,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Mods { - public sealed class DifficultyMultiplierDisplay : ModsEffectDisplay + public sealed partial class DifficultyMultiplierDisplay : ModsEffectDisplay { protected override LocalisableString Label => DifficultyMultiplierDisplayStrings.DifficultyMultiplier; diff --git a/osu.Game/Overlays/Mods/IncompatibilityDisplayingModPanel.cs b/osu.Game/Overlays/Mods/IncompatibilityDisplayingModPanel.cs index 8cedd6b374..93279b6e1c 100644 --- a/osu.Game/Overlays/Mods/IncompatibilityDisplayingModPanel.cs +++ b/osu.Game/Overlays/Mods/IncompatibilityDisplayingModPanel.cs @@ -14,7 +14,7 @@ using osu.Game.Utils; namespace osu.Game.Overlays.Mods { - public class IncompatibilityDisplayingModPanel : ModPanel, IHasCustomTooltip + public partial class IncompatibilityDisplayingModPanel : ModPanel, IHasCustomTooltip { private readonly BindableBool incompatible = new BindableBool(); diff --git a/osu.Game/Overlays/Mods/IncompatibilityDisplayingTooltip.cs b/osu.Game/Overlays/Mods/IncompatibilityDisplayingTooltip.cs index 3f44e82d50..1723634774 100644 --- a/osu.Game/Overlays/Mods/IncompatibilityDisplayingTooltip.cs +++ b/osu.Game/Overlays/Mods/IncompatibilityDisplayingTooltip.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Overlays.Mods { - internal class IncompatibilityDisplayingTooltip : ModButtonTooltip + internal partial class IncompatibilityDisplayingTooltip : ModButtonTooltip { private readonly OsuSpriteText incompatibleText; diff --git a/osu.Game/Overlays/Mods/ModButtonTooltip.cs b/osu.Game/Overlays/Mods/ModButtonTooltip.cs index e19f24103f..52b27f1e00 100644 --- a/osu.Game/Overlays/Mods/ModButtonTooltip.cs +++ b/osu.Game/Overlays/Mods/ModButtonTooltip.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Overlays.Mods { - public class ModButtonTooltip : VisibilityContainer, ITooltip + public partial class ModButtonTooltip : VisibilityContainer, ITooltip { private readonly OsuSpriteText descriptionText; private readonly Box background; diff --git a/osu.Game/Overlays/Mods/ModColumn.cs b/osu.Game/Overlays/Mods/ModColumn.cs index b9f7114f74..5d9f616e5f 100644 --- a/osu.Game/Overlays/Mods/ModColumn.cs +++ b/osu.Game/Overlays/Mods/ModColumn.cs @@ -25,7 +25,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Mods { - public class ModColumn : ModSelectColumn + public partial class ModColumn : ModSelectColumn { public readonly ModType ModType; @@ -219,7 +219,7 @@ namespace osu.Game.Overlays.Mods dequeuedAction(); } - private class ToggleAllCheckbox : OsuCheckbox + private partial class ToggleAllCheckbox : OsuCheckbox { private Color4 accentColour; diff --git a/osu.Game/Overlays/Mods/ModPanel.cs b/osu.Game/Overlays/Mods/ModPanel.cs index 7bdb9511ac..b5fee9d116 100644 --- a/osu.Game/Overlays/Mods/ModPanel.cs +++ b/osu.Game/Overlays/Mods/ModPanel.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Overlays.Mods { - public class ModPanel : ModSelectPanel + public partial class ModPanel : ModSelectPanel { public Mod Mod => modState.Mod; public override BindableBool Active => modState.Active; diff --git a/osu.Game/Overlays/Mods/ModPresetColumn.cs b/osu.Game/Overlays/Mods/ModPresetColumn.cs index 176c527a10..bf5e576277 100644 --- a/osu.Game/Overlays/Mods/ModPresetColumn.cs +++ b/osu.Game/Overlays/Mods/ModPresetColumn.cs @@ -18,7 +18,7 @@ using Realms; namespace osu.Game.Overlays.Mods { - public class ModPresetColumn : ModSelectColumn + public partial class ModPresetColumn : ModSelectColumn { [Resolved] private RealmAccess realm { get; set; } = null!; diff --git a/osu.Game/Overlays/Mods/ModPresetPanel.cs b/osu.Game/Overlays/Mods/ModPresetPanel.cs index b314a19142..6e12e34124 100644 --- a/osu.Game/Overlays/Mods/ModPresetPanel.cs +++ b/osu.Game/Overlays/Mods/ModPresetPanel.cs @@ -17,7 +17,7 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Overlays.Mods { - public class ModPresetPanel : ModSelectPanel, IHasCustomTooltip, IHasContextMenu + public partial class ModPresetPanel : ModSelectPanel, IHasCustomTooltip, IHasContextMenu { public readonly Live Preset; diff --git a/osu.Game/Overlays/Mods/ModPresetTooltip.cs b/osu.Game/Overlays/Mods/ModPresetTooltip.cs index 97d118fbfd..ff4f00da69 100644 --- a/osu.Game/Overlays/Mods/ModPresetTooltip.cs +++ b/osu.Game/Overlays/Mods/ModPresetTooltip.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Overlays.Mods { - public class ModPresetTooltip : VisibilityContainer, ITooltip + public partial class ModPresetTooltip : VisibilityContainer, ITooltip { protected override Container Content { get; } @@ -62,7 +62,7 @@ namespace osu.Game.Overlays.Mods public void Move(Vector2 pos) => Position = pos; - private class ModPresetRow : FillFlowContainer + private partial class ModPresetRow : FillFlowContainer { public ModPresetRow(Mod mod) { diff --git a/osu.Game/Overlays/Mods/ModSelectColumn.cs b/osu.Game/Overlays/Mods/ModSelectColumn.cs index d5dc079628..e5154fd631 100644 --- a/osu.Game/Overlays/Mods/ModSelectColumn.cs +++ b/osu.Game/Overlays/Mods/ModSelectColumn.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Mods { - public abstract class ModSelectColumn : CompositeDrawable, IHasAccentColour + public abstract partial class ModSelectColumn : CompositeDrawable, IHasAccentColour { public readonly Container TopLevelContent; diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index ccc075b190..16602db4be 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -28,7 +28,7 @@ using osuTK; namespace osu.Game.Overlays.Mods { - public abstract class ModSelectOverlay : ShearedOverlayContainer, ISamplePlaybackDisabler + public abstract partial class ModSelectOverlay : ShearedOverlayContainer, ISamplePlaybackDisabler { public const int BUTTON_WIDTH = 200; @@ -612,7 +612,7 @@ namespace osu.Game.Overlays.Mods /// Manages horizontal scrolling of mod columns, along with the "active" states of each column based on visibility. /// [Cached] - internal class ColumnScrollContainer : OsuScrollContainer + internal partial class ColumnScrollContainer : OsuScrollContainer { public ColumnScrollContainer() : base(Direction.Horizontal) @@ -653,7 +653,7 @@ namespace osu.Game.Overlays.Mods /// /// Manages layout of mod columns. /// - internal class ColumnFlowContainer : FillFlowContainer + internal partial class ColumnFlowContainer : FillFlowContainer { public IEnumerable Columns => Children.Select(dimWrapper => dimWrapper.Column); @@ -669,7 +669,7 @@ namespace osu.Game.Overlays.Mods /// /// Encapsulates a column and provides dim and input blocking based on an externally managed "active" state. /// - internal class ColumnDimContainer : Container + internal partial class ColumnDimContainer : Container { public ModSelectColumn Column { get; } @@ -759,7 +759,7 @@ namespace osu.Game.Overlays.Mods /// /// A container which blocks and handles input, managing the "return from customisation" state change. /// - private class ClickToReturnContainer : Container + private partial class ClickToReturnContainer : Container { public BindableBool HandleMouse { get; } = new BindableBool(); diff --git a/osu.Game/Overlays/Mods/ModSelectPanel.cs b/osu.Game/Overlays/Mods/ModSelectPanel.cs index 27abface0c..81285833bd 100644 --- a/osu.Game/Overlays/Mods/ModSelectPanel.cs +++ b/osu.Game/Overlays/Mods/ModSelectPanel.cs @@ -24,7 +24,7 @@ using osuTK.Input; namespace osu.Game.Overlays.Mods { - public abstract class ModSelectPanel : OsuClickableContainer, IHasAccentColour + public abstract partial class ModSelectPanel : OsuClickableContainer, IHasAccentColour { public abstract BindableBool Active { get; } diff --git a/osu.Game/Overlays/Mods/ModSettingsArea.cs b/osu.Game/Overlays/Mods/ModSettingsArea.cs index 0932c2c832..f11fef1299 100644 --- a/osu.Game/Overlays/Mods/ModSettingsArea.cs +++ b/osu.Game/Overlays/Mods/ModSettingsArea.cs @@ -22,7 +22,7 @@ using osuTK; namespace osu.Game.Overlays.Mods { - public class ModSettingsArea : CompositeDrawable + public partial class ModSettingsArea : CompositeDrawable { public Bindable> SelectedMods { get; } = new Bindable>(Array.Empty()); @@ -110,7 +110,7 @@ namespace osu.Game.Overlays.Mods protected override bool OnMouseDown(MouseDownEvent e) => true; protected override bool OnHover(HoverEvent e) => true; - private class ModSettingsColumn : CompositeDrawable + private partial class ModSettingsColumn : CompositeDrawable { public ModSettingsColumn(Mod mod, IEnumerable settingsControls) { diff --git a/osu.Game/Overlays/Mods/ModsEffectDisplay.cs b/osu.Game/Overlays/Mods/ModsEffectDisplay.cs index eed3181e49..3f31736ee1 100644 --- a/osu.Game/Overlays/Mods/ModsEffectDisplay.cs +++ b/osu.Game/Overlays/Mods/ModsEffectDisplay.cs @@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Mods /// /// Base class for displays of mods effects. /// - public abstract class ModsEffectDisplay : Container, IHasCurrentValue + public abstract partial class ModsEffectDisplay : Container, IHasCurrentValue { public const float HEIGHT = 42; private const float transition_duration = 200; @@ -201,7 +201,7 @@ namespace osu.Game.Overlays.Mods DifficultyIncrease } - private class EffectCounter : RollingCounter + private partial class EffectCounter : RollingCounter { private readonly string? format; diff --git a/osu.Game/Overlays/Mods/SelectAllModsButton.cs b/osu.Game/Overlays/Mods/SelectAllModsButton.cs index fc24e99c7e..f4b8025227 100644 --- a/osu.Game/Overlays/Mods/SelectAllModsButton.cs +++ b/osu.Game/Overlays/Mods/SelectAllModsButton.cs @@ -16,7 +16,7 @@ using osu.Game.Screens.OnlinePlay; namespace osu.Game.Overlays.Mods { - public class SelectAllModsButton : ShearedButton, IKeyBindingHandler + public partial class SelectAllModsButton : ShearedButton, IKeyBindingHandler { private readonly Bindable> selectedMods = new Bindable>(); private readonly Bindable>> availableMods = new Bindable>>(); diff --git a/osu.Game/Overlays/Mods/ShearedOverlayContainer.cs b/osu.Game/Overlays/Mods/ShearedOverlayContainer.cs index 2585e44e05..7f7b09a62c 100644 --- a/osu.Game/Overlays/Mods/ShearedOverlayContainer.cs +++ b/osu.Game/Overlays/Mods/ShearedOverlayContainer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Mods /// A sheared overlay which provides a header and footer and basic animations. /// Exposes , and as valid targets for content. /// - public abstract class ShearedOverlayContainer : OsuFocusedOverlayContainer + public abstract partial class ShearedOverlayContainer : OsuFocusedOverlayContainer { protected const float PADDING = 14; diff --git a/osu.Game/Overlays/Mods/UserModSelectOverlay.cs b/osu.Game/Overlays/Mods/UserModSelectOverlay.cs index 1090306c5b..49469b99f3 100644 --- a/osu.Game/Overlays/Mods/UserModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/UserModSelectOverlay.cs @@ -8,7 +8,7 @@ using osu.Game.Utils; namespace osu.Game.Overlays.Mods { - public class UserModSelectOverlay : ModSelectOverlay + public partial class UserModSelectOverlay : ModSelectOverlay { public UserModSelectOverlay(OverlayColourScheme colourScheme = OverlayColourScheme.Green) : base(colourScheme) @@ -38,7 +38,7 @@ namespace osu.Game.Overlays.Mods return modsAfterRemoval.ToList(); } - private class UserModColumn : ModColumn + private partial class UserModColumn : ModColumn { public UserModColumn(ModType modType, bool allowIncompatibleSelection) : base(modType, allowIncompatibleSelection) diff --git a/osu.Game/Overlays/Music/FilterControl.cs b/osu.Game/Overlays/Music/FilterControl.cs index ffa50c3a35..a61702645a 100644 --- a/osu.Game/Overlays/Music/FilterControl.cs +++ b/osu.Game/Overlays/Music/FilterControl.cs @@ -13,7 +13,7 @@ using osu.Framework.Allocation; namespace osu.Game.Overlays.Music { - public class FilterControl : Container + public partial class FilterControl : Container { public Action FilterChanged; @@ -58,7 +58,7 @@ namespace osu.Game.Overlays.Music Collection = collectionDropdown.Current.Value?.Collection }; - public class FilterTextBox : BasicSearchTextBox + public partial class FilterTextBox : BasicSearchTextBox { protected override bool AllowCommit => true; diff --git a/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs b/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs index 8df465e075..827caf0467 100644 --- a/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs +++ b/osu.Game/Overlays/Music/MusicKeyBindingHandler.cs @@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Music /// /// Handles s related to music playback, and displays s via the global accordingly. /// - public class MusicKeyBindingHandler : Component, IKeyBindingHandler + public partial class MusicKeyBindingHandler : Component, IKeyBindingHandler { [Resolved] private IBindable beatmap { get; set; } @@ -89,7 +89,7 @@ namespace osu.Game.Overlays.Music { } - private class MusicActionToast : Toast + private partial class MusicActionToast : Toast { private readonly GlobalAction action; diff --git a/osu.Game/Overlays/Music/NowPlayingCollectionDropdown.cs b/osu.Game/Overlays/Music/NowPlayingCollectionDropdown.cs index 635a2e5044..ae59fbb35e 100644 --- a/osu.Game/Overlays/Music/NowPlayingCollectionDropdown.cs +++ b/osu.Game/Overlays/Music/NowPlayingCollectionDropdown.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Music /// /// A for use in the . /// - public class NowPlayingCollectionDropdown : CollectionDropdown + public partial class NowPlayingCollectionDropdown : CollectionDropdown { protected override bool ShowManageCollectionsItem => false; @@ -25,7 +25,7 @@ namespace osu.Game.Overlays.Music protected override CollectionDropdownMenu CreateCollectionMenu() => new CollectionsMenu(); - private class CollectionsMenu : CollectionDropdownMenu + private partial class CollectionsMenu : CollectionDropdownMenu { public CollectionsMenu() { @@ -42,7 +42,7 @@ namespace osu.Game.Overlays.Music } } - private class CollectionsHeader : CollectionDropdownHeader + private partial class CollectionsHeader : CollectionDropdownHeader { [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game/Overlays/Music/Playlist.cs b/osu.Game/Overlays/Music/Playlist.cs index b48257a61a..ab51ca7e1d 100644 --- a/osu.Game/Overlays/Music/Playlist.cs +++ b/osu.Game/Overlays/Music/Playlist.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Overlays.Music { - public class Playlist : OsuRearrangeableListContainer> + public partial class Playlist : OsuRearrangeableListContainer> { public Action>? RequestSelection; diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index b30ae095b1..00c5ce8002 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Music { - public class PlaylistItem : OsuRearrangeableListItem>, IFilterable + public partial class PlaylistItem : OsuRearrangeableListItem>, IFilterable { public readonly Bindable> SelectedSet = new Bindable>(); diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 63f1aa248c..43b9024303 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -22,7 +22,7 @@ using Realms; namespace osu.Game.Overlays.Music { - public class PlaylistOverlay : VisibilityContainer + public partial class PlaylistOverlay : VisibilityContainer { private const float transition_duration = 600; public const float PLAYLIST_HEIGHT = 510; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 793b7e294f..1ad5a8c08b 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -25,7 +25,7 @@ namespace osu.Game.Overlays /// /// Handles playback of the global music track. /// - public class MusicController : CompositeDrawable + public partial class MusicController : CompositeDrawable { [Resolved] private BeatmapManager beatmaps { get; set; } diff --git a/osu.Game/Overlays/News/Displays/ArticleListing.cs b/osu.Game/Overlays/News/Displays/ArticleListing.cs index 8465ebf07c..b6ce16ae7d 100644 --- a/osu.Game/Overlays/News/Displays/ArticleListing.cs +++ b/osu.Game/Overlays/News/Displays/ArticleListing.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.News.Displays /// /// Lists articles in a vertical flow for a specified year. /// - public class ArticleListing : CompositeDrawable + public partial class ArticleListing : CompositeDrawable { private readonly Action fetchMorePosts; diff --git a/osu.Game/Overlays/News/NewsCard.cs b/osu.Game/Overlays/News/NewsCard.cs index c8e0b0c7ef..e0be5cc4a9 100644 --- a/osu.Game/Overlays/News/NewsCard.cs +++ b/osu.Game/Overlays/News/NewsCard.cs @@ -21,7 +21,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.News { - public class NewsCard : OsuHoverContainer + public partial class NewsCard : OsuHoverContainer { protected override IEnumerable EffectTargets => new[] { background }; @@ -121,7 +121,7 @@ namespace osu.Game.Overlays.News main.AddText(post.Author, t => t.Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold)); } - private class DateContainer : CircularContainer, IHasCustomTooltip + private partial class DateContainer : CircularContainer, IHasCustomTooltip { private readonly DateTimeOffset date; diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs index d204dfcf2e..44e2f6a8cb 100644 --- a/osu.Game/Overlays/News/NewsHeader.cs +++ b/osu.Game/Overlays/News/NewsHeader.cs @@ -12,7 +12,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.News { - public class NewsHeader : BreadcrumbControlOverlayHeader + public partial class NewsHeader : BreadcrumbControlOverlayHeader { public static LocalisableString FrontPageString => NewsStrings.IndexTitleInfo; @@ -62,7 +62,7 @@ namespace osu.Game.Overlays.News protected override OverlayTitle CreateTitle() => new NewsHeaderTitle(); - private class NewsHeaderTitle : OverlayTitle + private partial class NewsHeaderTitle : OverlayTitle { public NewsHeaderTitle() { diff --git a/osu.Game/Overlays/News/NewsPostBackground.cs b/osu.Game/Overlays/News/NewsPostBackground.cs index b77623842c..05f8a639fa 100644 --- a/osu.Game/Overlays/News/NewsPostBackground.cs +++ b/osu.Game/Overlays/News/NewsPostBackground.cs @@ -11,7 +11,7 @@ using osu.Framework.Graphics.Textures; namespace osu.Game.Overlays.News { [LongRunningLoad] - public class NewsPostBackground : Sprite + public partial class NewsPostBackground : Sprite { private readonly string sourceUrl; diff --git a/osu.Game/Overlays/News/Sidebar/MonthSection.cs b/osu.Game/Overlays/News/Sidebar/MonthSection.cs index 894f8d5667..d205fcb908 100644 --- a/osu.Game/Overlays/News/Sidebar/MonthSection.cs +++ b/osu.Game/Overlays/News/Sidebar/MonthSection.cs @@ -23,7 +23,7 @@ using osu.Framework.Platform; namespace osu.Game.Overlays.News.Sidebar { - public class MonthSection : CompositeDrawable + public partial class MonthSection : CompositeDrawable { public int Year { get; private set; } public int Month { get; private set; } @@ -79,7 +79,7 @@ namespace osu.Game.Overlays.News.Sidebar sampleClose = audio.Samples.Get(@"UI/dropdown-close"); } - private class DropdownHeader : OsuClickableContainer + private partial class DropdownHeader : OsuClickableContainer { public readonly BindableBool Expanded = new BindableBool(); @@ -122,7 +122,7 @@ namespace osu.Game.Overlays.News.Sidebar } } - private class PostButton : OsuHoverContainer + private partial class PostButton : OsuHoverContainer { protected override IEnumerable EffectTargets => new[] { text }; @@ -154,7 +154,7 @@ namespace osu.Game.Overlays.News.Sidebar } } - private class PostsContainer : Container + private partial class PostsContainer : Container { public readonly BindableBool Expanded = new BindableBool(); diff --git a/osu.Game/Overlays/News/Sidebar/NewsSidebar.cs b/osu.Game/Overlays/News/Sidebar/NewsSidebar.cs index 884e15c03b..939e5367b7 100644 --- a/osu.Game/Overlays/News/Sidebar/NewsSidebar.cs +++ b/osu.Game/Overlays/News/Sidebar/NewsSidebar.cs @@ -13,7 +13,7 @@ using System.Linq; namespace osu.Game.Overlays.News.Sidebar { - public class NewsSidebar : OverlaySidebar + public partial class NewsSidebar : OverlaySidebar { [Cached] public readonly Bindable Metadata = new Bindable(); diff --git a/osu.Game/Overlays/News/Sidebar/YearsPanel.cs b/osu.Game/Overlays/News/Sidebar/YearsPanel.cs index 915ed1817c..524ffbf63d 100644 --- a/osu.Game/Overlays/News/Sidebar/YearsPanel.cs +++ b/osu.Game/Overlays/News/Sidebar/YearsPanel.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.News.Sidebar { - public class YearsPanel : CompositeDrawable + public partial class YearsPanel : CompositeDrawable { private readonly Bindable metadata = new Bindable(); @@ -79,7 +79,7 @@ namespace osu.Game.Overlays.News.Sidebar Show(); } - public class YearButton : OsuHoverContainer + public partial class YearButton : OsuHoverContainer { public int Year { get; } diff --git a/osu.Game/Overlays/NewsOverlay.cs b/osu.Game/Overlays/NewsOverlay.cs index 87b7ebbe89..cb9d940a05 100644 --- a/osu.Game/Overlays/NewsOverlay.cs +++ b/osu.Game/Overlays/NewsOverlay.cs @@ -15,7 +15,7 @@ using osu.Game.Overlays.News.Sidebar; namespace osu.Game.Overlays { - public class NewsOverlay : OnlineOverlay + public partial class NewsOverlay : OnlineOverlay { private readonly Bindable article = new Bindable(); diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 36548c893c..3f3c6551c6 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -20,7 +20,7 @@ using NotificationsStrings = osu.Game.Localisation.NotificationsStrings; namespace osu.Game.Overlays { - public class NotificationOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent, INotificationOverlay + public partial class NotificationOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent, INotificationOverlay { public string IconTexture => "Icons/Hexacons/notification"; public LocalisableString Title => NotificationsStrings.HeaderTitle; diff --git a/osu.Game/Overlays/NotificationOverlayToastTray.cs b/osu.Game/Overlays/NotificationOverlayToastTray.cs index 329379de4a..7a793ee092 100644 --- a/osu.Game/Overlays/NotificationOverlayToastTray.cs +++ b/osu.Game/Overlays/NotificationOverlayToastTray.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays /// /// A tray which attaches to the left of to show temporary toasts. /// - public class NotificationOverlayToastTray : CompositeDrawable + public partial class NotificationOverlayToastTray : CompositeDrawable { public override bool IsPresent => toastContentBackground.Height > 0 || toastFlow.Count > 0; diff --git a/osu.Game/Overlays/Notifications/Notification.cs b/osu.Game/Overlays/Notifications/Notification.cs index 8be9d2072b..77d3317b1f 100644 --- a/osu.Game/Overlays/Notifications/Notification.cs +++ b/osu.Game/Overlays/Notifications/Notification.cs @@ -23,7 +23,7 @@ using osuTK.Input; namespace osu.Game.Overlays.Notifications { - public abstract class Notification : Container + public abstract partial class Notification : Container { /// /// Notification was closed, either by user or otherwise. @@ -269,7 +269,7 @@ namespace osu.Game.Overlays.Notifications }); } - private class DragContainer : Container + private partial class DragContainer : Container { private Vector2 velocity; private Vector2 lastPosition; @@ -381,7 +381,7 @@ namespace osu.Game.Overlays.Notifications } } - internal class CloseButton : OsuClickableContainer + internal partial class CloseButton : OsuClickableContainer { private SpriteIcon icon = null!; private Box background = null!; @@ -436,7 +436,7 @@ namespace osu.Game.Overlays.Notifications } } - public class NotificationLight : Container + public partial class NotificationLight : Container { private bool pulsate; private Container pulsateLayer = null!; diff --git a/osu.Game/Overlays/Notifications/NotificationSection.cs b/osu.Game/Overlays/Notifications/NotificationSection.cs index 16105f913f..d55a2abd2a 100644 --- a/osu.Game/Overlays/Notifications/NotificationSection.cs +++ b/osu.Game/Overlays/Notifications/NotificationSection.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Overlays.Notifications { - public class NotificationSection : AlwaysUpdateFillFlowContainer + public partial class NotificationSection : AlwaysUpdateFillFlowContainer { private OsuSpriteText countDrawable = null!; @@ -135,7 +135,7 @@ namespace osu.Game.Overlays.Notifications return count; } - private class ClearAllButton : OsuClickableContainer + private partial class ClearAllButton : OsuClickableContainer { private readonly OsuSpriteText text; @@ -162,7 +162,7 @@ namespace osu.Game.Overlays.Notifications } } - public class AlwaysUpdateFillFlowContainer : FillFlowContainer + public partial class AlwaysUpdateFillFlowContainer : FillFlowContainer where T : Drawable { // this is required to ensure correct layout and scheduling on children. diff --git a/osu.Game/Overlays/Notifications/ProgressCompletionNotification.cs b/osu.Game/Overlays/Notifications/ProgressCompletionNotification.cs index 3cbdf7edf7..46972d4b5e 100644 --- a/osu.Game/Overlays/Notifications/ProgressCompletionNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressCompletionNotification.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Sprites; namespace osu.Game.Overlays.Notifications { - public class ProgressCompletionNotification : SimpleNotification + public partial class ProgressCompletionNotification : SimpleNotification { public ProgressCompletionNotification() { diff --git a/osu.Game/Overlays/Notifications/ProgressNotification.cs b/osu.Game/Overlays/Notifications/ProgressNotification.cs index 9812feb4a1..5cce0f8c5b 100644 --- a/osu.Game/Overlays/Notifications/ProgressNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressNotification.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Notifications { - public class ProgressNotification : Notification, IHasCompletionTarget + public partial class ProgressNotification : Notification, IHasCompletionTarget { private const float loading_spinner_size = 22; @@ -255,7 +255,7 @@ namespace osu.Game.Overlays.Notifications } } - private class ProgressBar : Container + private partial class ProgressBar : Container { private readonly Box box; diff --git a/osu.Game/Overlays/Notifications/SimpleErrorNotification.cs b/osu.Game/Overlays/Notifications/SimpleErrorNotification.cs index ffefcb033f..7d0d07fc1b 100644 --- a/osu.Game/Overlays/Notifications/SimpleErrorNotification.cs +++ b/osu.Game/Overlays/Notifications/SimpleErrorNotification.cs @@ -7,7 +7,7 @@ using osu.Framework.Graphics.Sprites; namespace osu.Game.Overlays.Notifications { - public class SimpleErrorNotification : SimpleNotification + public partial class SimpleErrorNotification : SimpleNotification { public override string PopInSampleName => "UI/error-notification-pop-in"; diff --git a/osu.Game/Overlays/Notifications/SimpleNotification.cs b/osu.Game/Overlays/Notifications/SimpleNotification.cs index f3bb6a0578..109b31ff71 100644 --- a/osu.Game/Overlays/Notifications/SimpleNotification.cs +++ b/osu.Game/Overlays/Notifications/SimpleNotification.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Overlays.Notifications { - public class SimpleNotification : Notification + public partial class SimpleNotification : Notification { private LocalisableString text; diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index 949f1e7b96..66fb3571ba 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -28,7 +28,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public class NowPlayingOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent + public partial class NowPlayingOverlay : OsuFocusedOverlayContainer, INamedOverlayComponent { public string IconTexture => "Icons/Hexacons/music"; public LocalisableString Title => NowPlayingStrings.HeaderTitle; @@ -356,7 +356,7 @@ namespace osu.Game.Overlays musicController.TrackChanged -= trackChanged; } - private class MusicIconButton : IconButton + private partial class MusicIconButton : IconButton { public MusicIconButton() { @@ -380,7 +380,7 @@ namespace osu.Game.Overlays } } - private class Background : BufferedContainer + private partial class Background : BufferedContainer { private readonly Sprite sprite; private readonly WorkingBeatmap beatmap; @@ -419,7 +419,7 @@ namespace osu.Game.Overlays } } - private class DragContainer : Container + private partial class DragContainer : Container { protected override bool OnDragStart(DragStartEvent e) { @@ -443,7 +443,7 @@ namespace osu.Game.Overlays } } - private class HoverableProgressBar : ProgressBar + private partial class HoverableProgressBar : ProgressBar { public HoverableProgressBar() : base(true) diff --git a/osu.Game/Overlays/OSD/CopyUrlToast.cs b/osu.Game/Overlays/OSD/CopyUrlToast.cs index ea835a1c5e..ce5a5f56c4 100644 --- a/osu.Game/Overlays/OSD/CopyUrlToast.cs +++ b/osu.Game/Overlays/OSD/CopyUrlToast.cs @@ -5,7 +5,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.OSD { - public class CopyUrlToast : Toast + public partial class CopyUrlToast : Toast { public CopyUrlToast() : base(UserInterfaceStrings.GeneralHeader, ToastStrings.UrlCopied, "") diff --git a/osu.Game/Overlays/OSD/Toast.cs b/osu.Game/Overlays/OSD/Toast.cs index a9fab0a23d..ff8696c04f 100644 --- a/osu.Game/Overlays/OSD/Toast.cs +++ b/osu.Game/Overlays/OSD/Toast.cs @@ -16,7 +16,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.OSD { - public abstract class Toast : Container + public abstract partial class Toast : Container { private const int toast_minimum_width = 240; diff --git a/osu.Game/Overlays/OSD/TrackedSettingToast.cs b/osu.Game/Overlays/OSD/TrackedSettingToast.cs index 3bed5e7e4c..1aa6de423e 100644 --- a/osu.Game/Overlays/OSD/TrackedSettingToast.cs +++ b/osu.Game/Overlays/OSD/TrackedSettingToast.cs @@ -21,7 +21,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.OSD { - public class TrackedSettingToast : Toast + public partial class TrackedSettingToast : Toast { private const int lights_bottom_margin = 40; @@ -129,7 +129,7 @@ namespace osu.Game.Overlays.OSD sampleChange = audio.Samples.Get("UI/osd-change"); } - private class OptionLight : Container + private partial class OptionLight : Container { private Color4 glowingColour, idleColour; diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index f2836885ce..d60077cfa9 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -20,7 +20,7 @@ namespace osu.Game.Overlays /// An on-screen display which automatically tracks and displays toast notifications for . /// Can also display custom content via /// - public class OnScreenDisplay : Container + public partial class OnScreenDisplay : Container { private readonly Container box; diff --git a/osu.Game/Overlays/OnlineOverlay.cs b/osu.Game/Overlays/OnlineOverlay.cs index 24bc7a73e0..0e0ce56446 100644 --- a/osu.Game/Overlays/OnlineOverlay.cs +++ b/osu.Game/Overlays/OnlineOverlay.cs @@ -12,7 +12,7 @@ using osu.Game.Online; namespace osu.Game.Overlays { - public abstract class OnlineOverlay : FullscreenOverlay + public abstract partial class OnlineOverlay : FullscreenOverlay where T : OverlayHeader { protected override Container Content => content; diff --git a/osu.Game/Overlays/OverlayHeader.cs b/osu.Game/Overlays/OverlayHeader.cs index ed8e3849d4..f8935f7f0a 100644 --- a/osu.Game/Overlays/OverlayHeader.cs +++ b/osu.Game/Overlays/OverlayHeader.cs @@ -12,7 +12,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public abstract class OverlayHeader : Container + public abstract partial class OverlayHeader : Container { public OverlayTitle Title { get; } diff --git a/osu.Game/Overlays/OverlayHeaderBackground.cs b/osu.Game/Overlays/OverlayHeaderBackground.cs index 540b28d9b2..a089001385 100644 --- a/osu.Game/Overlays/OverlayHeaderBackground.cs +++ b/osu.Game/Overlays/OverlayHeaderBackground.cs @@ -11,7 +11,7 @@ using osu.Framework.Graphics.Textures; namespace osu.Game.Overlays { - public class OverlayHeaderBackground : CompositeDrawable + public partial class OverlayHeaderBackground : CompositeDrawable { public OverlayHeaderBackground(string textureName) { @@ -21,7 +21,7 @@ namespace osu.Game.Overlays InternalChild = new DelayedLoadWrapper(() => new Background(textureName)); } - private class Background : Sprite + private partial class Background : Sprite { private readonly string textureName; diff --git a/osu.Game/Overlays/OverlayPanelDisplayStyleControl.cs b/osu.Game/Overlays/OverlayPanelDisplayStyleControl.cs index 14a99cd5bb..d7d6bd4a2a 100644 --- a/osu.Game/Overlays/OverlayPanelDisplayStyleControl.cs +++ b/osu.Game/Overlays/OverlayPanelDisplayStyleControl.cs @@ -19,7 +19,7 @@ using osu.Framework.Extensions; namespace osu.Game.Overlays { - public class OverlayPanelDisplayStyleControl : OsuTabControl + public partial class OverlayPanelDisplayStyleControl : OsuTabControl { protected override Dropdown CreateDropdown() => null; @@ -51,7 +51,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Horizontal }; - private class PanelDisplayTabItem : TabItem, IHasTooltip + private partial class PanelDisplayTabItem : TabItem, IHasTooltip { public IconUsage Icon { diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs index a0efb197c2..bcce2ce433 100644 --- a/osu.Game/Overlays/OverlayRulesetSelector.cs +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Overlays { - public class OverlayRulesetSelector : RulesetSelector + public partial class OverlayRulesetSelector : RulesetSelector { public OverlayRulesetSelector() { diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index ba0b81a514..d5c70a46d0 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -18,7 +18,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Overlays { - public class OverlayRulesetTabItem : TabItem, IHasTooltip + public partial class OverlayRulesetTabItem : TabItem, IHasTooltip { private Color4 accentColour; diff --git a/osu.Game/Overlays/OverlayScrollContainer.cs b/osu.Game/Overlays/OverlayScrollContainer.cs index 95b27665f4..5bd7f014a9 100644 --- a/osu.Game/Overlays/OverlayScrollContainer.cs +++ b/osu.Game/Overlays/OverlayScrollContainer.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays /// /// which provides . Mostly used in . /// - public class OverlayScrollContainer : UserTrackingScrollContainer + public partial class OverlayScrollContainer : UserTrackingScrollContainer { /// /// Scroll position at which the will be shown. @@ -62,7 +62,7 @@ namespace osu.Game.Overlays Button.State = Visibility.Hidden; } - public class ScrollToTopButton : OsuHoverContainer + public partial class ScrollToTopButton : OsuHoverContainer { private const int fade_duration = 500; diff --git a/osu.Game/Overlays/OverlaySidebar.cs b/osu.Game/Overlays/OverlaySidebar.cs index 62f3e1af13..87ce1b7e8c 100644 --- a/osu.Game/Overlays/OverlaySidebar.cs +++ b/osu.Game/Overlays/OverlaySidebar.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Overlays { - public abstract class OverlaySidebar : CompositeDrawable + public abstract partial class OverlaySidebar : CompositeDrawable { private readonly Box sidebarBackground; private readonly Box scrollbarBackground; diff --git a/osu.Game/Overlays/OverlaySortTabControl.cs b/osu.Game/Overlays/OverlaySortTabControl.cs index befb011353..8af2ab3823 100644 --- a/osu.Game/Overlays/OverlaySortTabControl.cs +++ b/osu.Game/Overlays/OverlaySortTabControl.cs @@ -24,7 +24,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays { - public class OverlaySortTabControl : CompositeDrawable, IHasCurrentValue + public partial class OverlaySortTabControl : CompositeDrawable, IHasCurrentValue { public TabControl TabControl { get; } @@ -74,7 +74,7 @@ namespace osu.Game.Overlays [NotNull] protected virtual SortTabControl CreateControl() => new SortTabControl(); - protected class SortTabControl : OsuTabControl + protected partial class SortTabControl : OsuTabControl { protected override Dropdown CreateDropdown() => null; @@ -93,7 +93,7 @@ namespace osu.Game.Overlays } } - protected class SortTabItem : TabItem + protected partial class SortTabItem : TabItem { public SortTabItem(T value) : base(value) @@ -117,7 +117,7 @@ namespace osu.Game.Overlays } } - protected class TabButton : HeaderButton + protected partial class TabButton : HeaderButton { public readonly BindableBool Active = new BindableBool(); diff --git a/osu.Game/Overlays/OverlayStreamControl.cs b/osu.Game/Overlays/OverlayStreamControl.cs index 1bd244176e..84de384fb5 100644 --- a/osu.Game/Overlays/OverlayStreamControl.cs +++ b/osu.Game/Overlays/OverlayStreamControl.cs @@ -12,7 +12,7 @@ using JetBrains.Annotations; namespace osu.Game.Overlays { - public abstract class OverlayStreamControl : TabControl + public abstract partial class OverlayStreamControl : TabControl { protected OverlayStreamControl() { diff --git a/osu.Game/Overlays/OverlayStreamItem.cs b/osu.Game/Overlays/OverlayStreamItem.cs index 3e09956480..9b18e5cccf 100644 --- a/osu.Game/Overlays/OverlayStreamItem.cs +++ b/osu.Game/Overlays/OverlayStreamItem.cs @@ -18,7 +18,7 @@ using osu.Framework.Localisation; namespace osu.Game.Overlays { - public abstract class OverlayStreamItem : TabItem + public abstract partial class OverlayStreamItem : TabItem { public readonly Bindable SelectedItem = new Bindable(); diff --git a/osu.Game/Overlays/OverlayTabControl.cs b/osu.Game/Overlays/OverlayTabControl.cs index 35e073a3a1..884e31868f 100644 --- a/osu.Game/Overlays/OverlayTabControl.cs +++ b/osu.Game/Overlays/OverlayTabControl.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public abstract class OverlayTabControl : OsuTabControl + public abstract partial class OverlayTabControl : OsuTabControl { private readonly Box bar; @@ -58,7 +58,7 @@ namespace osu.Game.Overlays protected override TabItem CreateTabItem(T value) => new OverlayTabItem(value); - protected class OverlayTabItem : TabItem, IHasAccentColour + protected partial class OverlayTabItem : TabItem, IHasAccentColour { protected readonly ExpandingBar Bar; protected readonly OsuSpriteText Text; diff --git a/osu.Game/Overlays/OverlayTitle.cs b/osu.Game/Overlays/OverlayTitle.cs index f2c42034a3..1d207e5f7d 100644 --- a/osu.Game/Overlays/OverlayTitle.cs +++ b/osu.Game/Overlays/OverlayTitle.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Overlays { - public abstract class OverlayTitle : CompositeDrawable, INamedOverlayComponent + public abstract partial class OverlayTitle : CompositeDrawable, INamedOverlayComponent { public const float ICON_SIZE = 30; @@ -69,7 +69,7 @@ namespace osu.Game.Overlays }; } - private class OverlayTitleIcon : Sprite + private partial class OverlayTitleIcon : Sprite { private readonly string textureName; diff --git a/osu.Game/Overlays/OverlayView.cs b/osu.Game/Overlays/OverlayView.cs index 80df0c695f..e919641b9b 100644 --- a/osu.Game/Overlays/OverlayView.cs +++ b/osu.Game/Overlays/OverlayView.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays /// Automatically performs a data fetch on load. /// /// The type of the API response. - public abstract class OverlayView : CompositeDrawable + public abstract partial class OverlayView : CompositeDrawable where T : class { [Resolved] diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index dcc8b19021..5ba3963a45 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -23,7 +23,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header { - public class BottomHeaderContainer : CompositeDrawable + public partial class BottomHeaderContainer : CompositeDrawable { public readonly Bindable User = new Bindable(); diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index b07817de46..5f6af7a6e2 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Overlays.Profile.Header { - public class CentreHeaderContainer : CompositeDrawable + public partial class CentreHeaderContainer : CompositeDrawable { public readonly BindableBool DetailsVisible = new BindableBool(true); public readonly Bindable User = new Bindable(); diff --git a/osu.Game/Overlays/Profile/Header/Components/DrawableBadge.cs b/osu.Game/Overlays/Profile/Header/Components/DrawableBadge.cs index 2ee80a7494..5f100bc882 100644 --- a/osu.Game/Overlays/Profile/Header/Components/DrawableBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/DrawableBadge.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Overlays.Profile.Header.Components { [LongRunningLoad] - public class DrawableBadge : OsuClickableContainer + public partial class DrawableBadge : OsuClickableContainer { public static readonly Vector2 DRAWABLE_BADGE_SIZE = new Vector2(86, 40); diff --git a/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs b/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs index 62b228c285..a778ddd2b1 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Overlays.Profile.Header.Components { - public class ExpandDetailsButton : ProfileHeaderButton + public partial class ExpandDetailsButton : ProfileHeaderButton { public readonly BindableBool DetailsVisible = new BindableBool(); diff --git a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs index 6fbfff1dd7..c278a6c48b 100644 --- a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs @@ -12,7 +12,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Header.Components { - public class FollowersButton : ProfileHeaderStatisticsButton + public partial class FollowersButton : ProfileHeaderStatisticsButton { public readonly Bindable User = new Bindable(); diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index fdf7478834..ef2f35e9a8 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -18,7 +18,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Header.Components { - public class LevelBadge : CompositeDrawable, IHasTooltip + public partial class LevelBadge : CompositeDrawable, IHasTooltip { public readonly Bindable User = new Bindable(); diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs index 1ba391431f..0351230fb3 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { - public class LevelProgressBar : CompositeDrawable, IHasTooltip + public partial class LevelProgressBar : CompositeDrawable, IHasTooltip { public readonly Bindable User = new Bindable(); diff --git a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs index 7bfc78cb2d..887cf10cce 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs @@ -12,7 +12,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Header.Components { - public class MappingSubscribersButton : ProfileHeaderStatisticsButton + public partial class MappingSubscribersButton : ProfileHeaderStatisticsButton { public readonly Bindable User = new Bindable(); diff --git a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs index 46cb811846..4886324a22 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Overlays.Profile.Header.Components { - public class MessageUserButton : ProfileHeaderButton + public partial class MessageUserButton : ProfileHeaderButton { public readonly Bindable User = new Bindable(); diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs index 7ac472ee00..244f185e28 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs @@ -13,7 +13,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { - public class OverlinedInfoContainer : CompositeDrawable + public partial class OverlinedInfoContainer : CompositeDrawable { private readonly Circle line; private readonly OsuSpriteText title; diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs index 9e5a0f5962..c040f5a787 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs @@ -14,7 +14,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Header.Components { - public class OverlinedTotalPlayTime : CompositeDrawable, IHasTooltip + public partial class OverlinedTotalPlayTime : CompositeDrawable, IHasTooltip { public readonly Bindable User = new Bindable(); diff --git a/osu.Game/Overlays/Profile/Header/Components/PreviousUsernames.cs b/osu.Game/Overlays/Profile/Header/Components/PreviousUsernames.cs index 808c814928..0abc4de5ef 100644 --- a/osu.Game/Overlays/Profile/Header/Components/PreviousUsernames.cs +++ b/osu.Game/Overlays/Profile/Header/Components/PreviousUsernames.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Overlays.Profile.Header.Components { - public class PreviousUsernames : CompositeDrawable + public partial class PreviousUsernames : CompositeDrawable { private const int duration = 200; private const int margin = 10; @@ -147,7 +147,7 @@ namespace osu.Game.Overlays.Profile.Header.Components this.MoveToY(0, duration, Easing.OutQuint); } - private class HoverIconContainer : Container + private partial class HoverIconContainer : Container { public Action ActivateHover; diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs index 5bdf9c19e1..c4a46440d2 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Overlays.Profile.Header.Components { - public abstract class ProfileHeaderButton : OsuHoverContainer + public abstract partial class ProfileHeaderButton : OsuHoverContainer { private readonly Box background; private readonly Container content; diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderStatisticsButton.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderStatisticsButton.cs index 3b3251fc4e..5ad726a3ea 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderStatisticsButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderStatisticsButton.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Overlays.Profile.Header.Components { - public abstract class ProfileHeaderStatisticsButton : ProfileHeaderButton + public abstract partial class ProfileHeaderStatisticsButton : ProfileHeaderButton { private readonly OsuSpriteText drawableText; diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index 3a47570cf7..72446bde3a 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets; namespace osu.Game.Overlays.Profile.Header.Components { - public class ProfileRulesetSelector : OverlayRulesetSelector + public partial class ProfileRulesetSelector : OverlayRulesetSelector { public readonly Bindable User = new Bindable(); diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs index d75fe1ae84..72adc96f9a 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { - public class ProfileRulesetTabItem : OverlayRulesetTabItem + public partial class ProfileRulesetTabItem : OverlayRulesetTabItem { private bool isDefault; @@ -50,7 +50,7 @@ namespace osu.Game.Overlays.Profile.Header.Components Add(icon = new DefaultRulesetIcon { Alpha = 0 }); } - public class DefaultRulesetIcon : SpriteIcon, IHasTooltip + public partial class DefaultRulesetIcon : SpriteIcon, IHasTooltip { public LocalisableString TooltipText => UsersStrings.ShowEditDefaultPlaymodeIsDefaultTooltip; diff --git a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs index 85fb5c4e5c..51531977d2 100644 --- a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs @@ -17,7 +17,7 @@ using osu.Game.Users; namespace osu.Game.Overlays.Profile.Header.Components { - public class RankGraph : UserGraph + public partial class RankGraph : UserGraph { private const int ranked_days = 88; diff --git a/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs b/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs index a05d8ba152..4028eb1389 100644 --- a/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs +++ b/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs @@ -17,7 +17,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Header.Components { - public class SupporterIcon : OsuClickableContainer + public partial class SupporterIcon : OsuClickableContainer { private readonly Box background; private readonly FillFlowContainer iconContainer; diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index d65691f531..44986dc178 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -22,7 +22,7 @@ using osuTK; namespace osu.Game.Overlays.Profile.Header { - public class DetailHeaderContainer : CompositeDrawable + public partial class DetailHeaderContainer : CompositeDrawable { private readonly Dictionary scoreRankInfos = new Dictionary(); private OverlinedInfoContainer medalInfo; @@ -187,7 +187,7 @@ namespace osu.Game.Overlays.Profile.Header rankGraph.Statistics.Value = user?.Statistics; } - private class ScoreRankInfo : CompositeDrawable + private partial class ScoreRankInfo : CompositeDrawable { private readonly OsuSpriteText rankCount; diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index deb675df1d..ab800d006d 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header { - public class MedalHeaderContainer : CompositeDrawable + public partial class MedalHeaderContainer : CompositeDrawable { private FillFlowContainer badgeFlowContainer; diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 67a6df3228..8826dd982d 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -25,7 +25,7 @@ using osuTK; namespace osu.Game.Overlays.Profile.Header { - public class TopHeaderContainer : CompositeDrawable + public partial class TopHeaderContainer : CompositeDrawable { private const float avatar_size = 110; @@ -201,7 +201,7 @@ namespace osu.Game.Overlays.Profile.Header } } - private class UserStatsLine : Container + private partial class UserStatsLine : Container { public UserStatsLine(LocalisableString left, LocalisableString right) { diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 1eca6a81cf..8443678989 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -18,7 +18,7 @@ using osu.Game.Users; namespace osu.Game.Overlays.Profile { - public class ProfileHeader : TabControlOverlayHeader + public partial class ProfileHeader : TabControlOverlayHeader { private UserCoverBackground coverContainer; @@ -104,7 +104,7 @@ namespace osu.Game.Overlays.Profile private void updateDisplay(APIUser user) => coverContainer.User = user; - private class ProfileHeaderTitle : OverlayTitle + private partial class ProfileHeaderTitle : OverlayTitle { public ProfileHeaderTitle() { @@ -113,7 +113,7 @@ namespace osu.Game.Overlays.Profile } } - private class ProfileCoverBackground : UserCoverBackground + private partial class ProfileCoverBackground : UserCoverBackground { protected override double LoadDelay => 0; } diff --git a/osu.Game/Overlays/Profile/ProfileSection.cs b/osu.Game/Overlays/Profile/ProfileSection.cs index 67738943e8..fc99050f73 100644 --- a/osu.Game/Overlays/Profile/ProfileSection.cs +++ b/osu.Game/Overlays/Profile/ProfileSection.cs @@ -19,7 +19,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Profile { - public abstract class ProfileSection : Container + public abstract partial class ProfileSection : Container { public abstract LocalisableString Title { get; } @@ -107,7 +107,7 @@ namespace osu.Game.Overlays.Profile underscore.Colour = colourProvider.Highlight1; } - private class SectionTriangles : Container + private partial class SectionTriangles : Container { private readonly Triangles triangles; private readonly Box foreground; diff --git a/osu.Game/Overlays/Profile/Sections/AboutSection.cs b/osu.Game/Overlays/Profile/Sections/AboutSection.cs index 2b6ce732a2..ac3dca5107 100644 --- a/osu.Game/Overlays/Profile/Sections/AboutSection.cs +++ b/osu.Game/Overlays/Profile/Sections/AboutSection.cs @@ -8,7 +8,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Sections { - public class AboutSection : ProfileSection + public partial class AboutSection : ProfileSection { public override LocalisableString Title => UsersStrings.ShowExtraMeTitle; diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs b/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs index 5d36537c3e..5a80a4d444 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs @@ -14,7 +14,7 @@ namespace osu.Game.Overlays.Profile.Sections /// /// Display artist/title/mapper information, commonly used as the left portion of a profile or score display row. /// - public abstract class BeatmapMetadataContainer : OsuHoverContainer + public abstract partial class BeatmapMetadataContainer : OsuHoverContainer { private readonly IBeatmapInfo beatmapInfo; diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index aaaed5ad0a..8c1eea6520 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -17,7 +17,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Overlays.Profile.Sections.Beatmaps { - public class PaginatedBeatmapContainer : PaginatedProfileSubsection + public partial class PaginatedBeatmapContainer : PaginatedProfileSubsection { private const float panel_padding = 10f; private readonly BeatmapSetType type; diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs index e3cff5da05..9f2e79b371 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs @@ -10,7 +10,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Sections { - public class BeatmapsSection : ProfileSection + public partial class BeatmapsSection : ProfileSection { public override LocalisableString Title => UsersStrings.ShowExtraBeatmapsTitle; diff --git a/osu.Game/Overlays/Profile/Sections/CounterPill.cs b/osu.Game/Overlays/Profile/Sections/CounterPill.cs index e9b55f62ef..c93cdb84f2 100644 --- a/osu.Game/Overlays/Profile/Sections/CounterPill.cs +++ b/osu.Game/Overlays/Profile/Sections/CounterPill.cs @@ -14,7 +14,7 @@ using osu.Framework.Extensions.LocalisationExtensions; namespace osu.Game.Overlays.Profile.Sections { - public class CounterPill : CircularContainer + public partial class CounterPill : CircularContainer { public readonly BindableInt Current = new BindableInt(); diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs index f0819c4474..e0837320b2 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs @@ -13,7 +13,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Profile.Sections.Historical { - public abstract class ChartProfileSubsection : ProfileSubsection + public abstract partial class ChartProfileSubsection : ProfileSubsection { private ProfileLineChart chart; diff --git a/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs b/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs index 70ab95b848..414c6f194a 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs @@ -21,7 +21,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Sections.Historical { - public class DrawableMostPlayedBeatmap : CompositeDrawable + public partial class DrawableMostPlayedBeatmap : CompositeDrawable { private const int cover_width = 100; private const int corner_radius = 6; @@ -110,7 +110,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical }); } - private class MostPlayedBeatmapContainer : ProfileItemContainer + private partial class MostPlayedBeatmapContainer : ProfileItemContainer { [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -120,7 +120,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical } } - private class MostPlayedBeatmapMetadataContainer : BeatmapMetadataContainer + private partial class MostPlayedBeatmapMetadataContainer : BeatmapMetadataContainer { public MostPlayedBeatmapMetadataContainer(IBeatmapInfo beatmapInfo) : base(beatmapInfo) @@ -159,7 +159,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical } } - private class PlayCountText : CompositeDrawable, IHasTooltip + private partial class PlayCountText : CompositeDrawable, IHasTooltip { public LocalisableString TooltipText => UsersStrings.ShowExtraHistoricalMostPlayedCount; diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs index 34c9892f06..222969bdfd 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs @@ -16,7 +16,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Overlays.Profile.Sections.Historical { - public class PaginatedMostPlayedBeatmapContainer : PaginatedProfileSubsection + public partial class PaginatedMostPlayedBeatmapContainer : PaginatedProfileSubsection { public PaginatedMostPlayedBeatmapContainer(Bindable user) : base(user, UsersStrings.ShowExtraHistoricalMostPlayedTitle) diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs index 73e39a2440..186bf73898 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs @@ -10,7 +10,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Sections.Historical { - public class PlayHistorySubsection : ChartProfileSubsection + public partial class PlayHistorySubsection : ChartProfileSubsection { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalMonthlyPlaycountsCountLabel; diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ProfileLineChart.cs b/osu.Game/Overlays/Profile/Sections/Historical/ProfileLineChart.cs index 78a28a39d2..da86d870fc 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ProfileLineChart.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ProfileLineChart.cs @@ -20,7 +20,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Profile.Sections.Historical { - public class ProfileLineChart : CompositeDrawable + public partial class ProfileLineChart : CompositeDrawable { private APIUserHistoryCount[] values; @@ -242,7 +242,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical return Math.Max((long)(tickMultiplier * tickBase), 1); } - private class TickText : OsuSpriteText + private partial class TickText : OsuSpriteText { [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -251,7 +251,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical } } - private class TickLine : Box + private partial class TickLine : Box { [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs index 89e8f51338..d1d1e76e14 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs @@ -10,7 +10,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Sections.Historical { - public class ReplaysSubsection : ChartProfileSubsection + public partial class ReplaysSubsection : ChartProfileSubsection { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalReplaysWatchedCountsCountLabel; diff --git a/osu.Game/Overlays/Profile/Sections/Historical/UserHistoryGraph.cs b/osu.Game/Overlays/Profile/Sections/Historical/UserHistoryGraph.cs index 48d75a4953..3f68ffdd0e 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/UserHistoryGraph.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/UserHistoryGraph.cs @@ -13,7 +13,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Profile.Sections.Historical { - public class UserHistoryGraph : UserGraph + public partial class UserHistoryGraph : UserGraph { private readonly LocalisableString tooltipCounterName; diff --git a/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs b/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs index f1e1c44734..13e0aefc65 100644 --- a/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs +++ b/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs @@ -12,7 +12,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Sections { - public class HistoricalSection : ProfileSection + public partial class HistoricalSection : ProfileSection { public override LocalisableString Title => UsersStrings.ShowExtraHistoricalTitle; diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index 44f1af4b72..122b20cbfc 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Overlays.Profile.Sections.Kudosu { - public class DrawableKudosuHistoryItem : CompositeDrawable + public partial class DrawableKudosuHistoryItem : CompositeDrawable { private const int height = 25; diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs index bb9d48c473..2b4d58b845 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs @@ -20,7 +20,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Profile.Sections.Kudosu { - public class KudosuInfo : Container + public partial class KudosuInfo : Container { private readonly Bindable user = new Bindable(); @@ -39,7 +39,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu protected override bool OnClick(ClickEvent e) => true; - private class CountTotal : CountSection + private partial class CountTotal : CountSection { public CountTotal() : base(UsersStrings.ShowExtraKudosuTotal) @@ -50,7 +50,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu } } - private class CountSection : Container + private partial class CountSection : Container { private readonly OsuSpriteText valueText; protected readonly LinkFlowContainer DescriptionText; diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs index 34e6866d25..c082c634a7 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs @@ -14,7 +14,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Overlays.Profile.Sections.Kudosu { - public class PaginatedKudosuHistoryContainer : PaginatedProfileSubsection + public partial class PaginatedKudosuHistoryContainer : PaginatedProfileSubsection { public PaginatedKudosuHistoryContainer(Bindable user) : base(user, missingText: UsersStrings.ShowExtraKudosuEntryEmpty) diff --git a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs b/osu.Game/Overlays/Profile/Sections/KudosuSection.cs index 517b4d92cf..26cf78c537 100644 --- a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs +++ b/osu.Game/Overlays/Profile/Sections/KudosuSection.cs @@ -10,7 +10,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Sections { - public class KudosuSection : ProfileSection + public partial class KudosuSection : ProfileSection { public override LocalisableString Title => UsersStrings.ShowExtraKudosuTitle; diff --git a/osu.Game/Overlays/Profile/Sections/MedalsSection.cs b/osu.Game/Overlays/Profile/Sections/MedalsSection.cs index a458bc4873..a511dc95a0 100644 --- a/osu.Game/Overlays/Profile/Sections/MedalsSection.cs +++ b/osu.Game/Overlays/Profile/Sections/MedalsSection.cs @@ -8,7 +8,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Sections { - public class MedalsSection : ProfileSection + public partial class MedalsSection : ProfileSection { public override LocalisableString Title => UsersStrings.ShowExtraMedalsTitle; diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs index 8ed1dc3676..530391466a 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs @@ -22,7 +22,7 @@ using osuTK; namespace osu.Game.Overlays.Profile.Sections { - public abstract class PaginatedProfileSubsection : ProfileSubsection + public abstract partial class PaginatedProfileSubsection : ProfileSubsection { /// /// The number of items displayed per page. diff --git a/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs index 392e35ac05..c81a08fa20 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs @@ -12,7 +12,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Sections { - public class ProfileItemContainer : Container + public partial class ProfileItemContainer : Container { private const int hover_duration = 200; diff --git a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs index 8e43519a17..9d88645c9a 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs @@ -13,7 +13,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Profile.Sections { - public abstract class ProfileSubsection : FillFlowContainer + public abstract partial class ProfileSubsection : FillFlowContainer { protected readonly Bindable User = new Bindable(); diff --git a/osu.Game/Overlays/Profile/Sections/ProfileSubsectionHeader.cs b/osu.Game/Overlays/Profile/Sections/ProfileSubsectionHeader.cs index f2770d81cd..598ac19059 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileSubsectionHeader.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileSubsectionHeader.cs @@ -17,7 +17,7 @@ using osu.Framework.Localisation; namespace osu.Game.Overlays.Profile.Sections { - public class ProfileSubsectionHeader : CompositeDrawable, IHasCurrentValue + public partial class ProfileSubsectionHeader : CompositeDrawable, IHasCurrentValue { private readonly BindableWithCurrent current = new BindableWithCurrent(); diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index fda2db7acc..f1f3ecd4fb 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -25,7 +25,7 @@ using osuTK; namespace osu.Game.Overlays.Profile.Sections.Ranks { - public class DrawableProfileScore : CompositeDrawable + public partial class DrawableProfileScore : CompositeDrawable { private const int height = 40; private const int performance_width = 100; @@ -258,7 +258,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks }; } - private class ScoreBeatmapMetadataContainer : BeatmapMetadataContainer + private partial class ScoreBeatmapMetadataContainer : BeatmapMetadataContainer { public ScoreBeatmapMetadataContainer(IBeatmapInfo beatmapInfo) : base(beatmapInfo) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs index 8c46f10ba2..f04d7d9733 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Overlays.Profile.Sections.Ranks { - public class DrawableProfileWeightedScore : DrawableProfileScore + public partial class DrawableProfileWeightedScore : DrawableProfileScore { private readonly double weight; diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index 2564692c87..38fac075fb 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -17,7 +17,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Overlays.Profile.Sections.Ranks { - public class PaginatedScoreContainer : PaginatedProfileSubsection + public partial class PaginatedScoreContainer : PaginatedProfileSubsection { private readonly ScoreType type; diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index 581b6e1139..ca41bff2f9 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -10,7 +10,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Sections { - public class RanksSection : ProfileSection + public partial class RanksSection : ProfileSection { public override LocalisableString Title => UsersStrings.ShowExtraTopRanksTitle; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 6b71ae73e3..4a8b020e33 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -19,7 +19,7 @@ using osu.Game.Rulesets; namespace osu.Game.Overlays.Profile.Sections.Recent { - public class DrawableRecentActivity : CompositeDrawable + public partial class DrawableRecentActivity : CompositeDrawable { private const int font_size = 14; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs b/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs index e3072f3420..5eeed24469 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs @@ -12,7 +12,7 @@ using osu.Framework.Graphics.Textures; namespace osu.Game.Overlays.Profile.Sections.Recent { [LongRunningLoad] - public class MedalIcon : Container + public partial class MedalIcon : Container { private readonly string slug; private readonly Sprite sprite; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 2878e0e940..b07dfc154f 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -16,7 +16,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Overlays.Profile.Sections.Recent { - public class PaginatedRecentActivityContainer : PaginatedProfileSubsection + public partial class PaginatedRecentActivityContainer : PaginatedProfileSubsection { public PaginatedRecentActivityContainer(Bindable user) : base(user, missingText: EventsStrings.Empty) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/RecentActivityIcon.cs b/osu.Game/Overlays/Profile/Sections/Recent/RecentActivityIcon.cs index c55eedd1ed..8c40c6c7a5 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/RecentActivityIcon.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/RecentActivityIcon.cs @@ -13,7 +13,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Sections.Recent { - public class RecentActivityIcon : Container + public partial class RecentActivityIcon : Container { private readonly SpriteIcon icon; private readonly APIRecentActivity activity; diff --git a/osu.Game/Overlays/Profile/Sections/RecentSection.cs b/osu.Game/Overlays/Profile/Sections/RecentSection.cs index c20594f974..f2ebf81504 100644 --- a/osu.Game/Overlays/Profile/Sections/RecentSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RecentSection.cs @@ -9,7 +9,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Sections { - public class RecentSection : ProfileSection + public partial class RecentSection : ProfileSection { public override LocalisableString Title => UsersStrings.ShowExtraRecentActivityTitle; diff --git a/osu.Game/Overlays/Profile/UserGraph.cs b/osu.Game/Overlays/Profile/UserGraph.cs index a8a4de68ff..fa9cbe0449 100644 --- a/osu.Game/Overlays/Profile/UserGraph.cs +++ b/osu.Game/Overlays/Profile/UserGraph.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Profile /// /// Type of data to be used for X-axis of the graph. /// Type of data to be used for Y-axis of the graph. - public abstract class UserGraph : Container, IHasCustomTooltip + public abstract partial class UserGraph : Container, IHasCustomTooltip { protected const float FADE_DURATION = 150; @@ -136,7 +136,7 @@ namespace osu.Game.Overlays.Profile protected abstract UserGraphTooltipContent GetTooltipContent(TKey key, TValue value); - protected class UserLineGraph : LineGraph + protected partial class UserLineGraph : LineGraph { private readonly CircularContainer movingBall; private readonly Container bar; @@ -207,7 +207,7 @@ namespace osu.Game.Overlays.Profile } } - private class UserGraphTooltip : VisibilityContainer, ITooltip + private partial class UserGraphTooltip : VisibilityContainer, ITooltip { protected readonly OsuSpriteText Label, Counter, BottomText; private readonly Box background; diff --git a/osu.Game/Overlays/Rankings/CountryFilter.cs b/osu.Game/Overlays/Rankings/CountryFilter.cs index 9376bafdff..e27fa7c7bd 100644 --- a/osu.Game/Overlays/Rankings/CountryFilter.cs +++ b/osu.Game/Overlays/Rankings/CountryFilter.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Overlays.Rankings { - public class CountryFilter : CompositeDrawable, IHasCurrentValue + public partial class CountryFilter : CompositeDrawable, IHasCurrentValue { private const int duration = 200; private const int height = 70; diff --git a/osu.Game/Overlays/Rankings/CountryPill.cs b/osu.Game/Overlays/Rankings/CountryPill.cs index ee4c4f08af..5efa9d12f0 100644 --- a/osu.Game/Overlays/Rankings/CountryPill.cs +++ b/osu.Game/Overlays/Rankings/CountryPill.cs @@ -22,7 +22,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Rankings { - public class CountryPill : CompositeDrawable, IHasCurrentValue + public partial class CountryPill : CompositeDrawable, IHasCurrentValue { private const int duration = 200; @@ -140,7 +140,7 @@ namespace osu.Game.Overlays.Rankings countryName.Text = country.NewValue.GetDescription(); } - private class CloseButton : OsuHoverContainer + private partial class CloseButton : OsuHoverContainer { private readonly SpriteIcon icon; diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index 936545bd49..3e0f780eeb 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -12,7 +12,7 @@ using osu.Game.Users; namespace osu.Game.Overlays.Rankings { - public class RankingsOverlayHeader : TabControlOverlayHeader + public partial class RankingsOverlayHeader : TabControlOverlayHeader { public Bindable Ruleset => rulesetSelector.Current; @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Rankings protected override Drawable CreateBackground() => new OverlayHeaderBackground("Headers/rankings"); - private class RankingsTitle : OverlayTitle + private partial class RankingsTitle : OverlayTitle { public RankingsTitle() { diff --git a/osu.Game/Overlays/Rankings/RankingsSortTabControl.cs b/osu.Game/Overlays/Rankings/RankingsSortTabControl.cs index 905c0fae65..9e73c3adb0 100644 --- a/osu.Game/Overlays/Rankings/RankingsSortTabControl.cs +++ b/osu.Game/Overlays/Rankings/RankingsSortTabControl.cs @@ -9,7 +9,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Rankings { - public class RankingsSortTabControl : OverlaySortTabControl + public partial class RankingsSortTabControl : OverlaySortTabControl { public RankingsSortTabControl() { diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index 234b91de66..31273e3b01 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -24,7 +24,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Rankings { - public class SpotlightSelector : CompositeDrawable, IHasCurrentValue + public partial class SpotlightSelector : CompositeDrawable, IHasCurrentValue { private readonly BindableWithCurrent current = new BindableWithCurrent(); public readonly Bindable Sort = new Bindable(); @@ -133,7 +133,7 @@ namespace osu.Game.Overlays.Rankings private LocalisableString dateToString(DateTimeOffset date) => date.ToLocalisableString(@"yyyy-MM-dd"); - private class InfoColumn : FillFlowContainer + private partial class InfoColumn : FillFlowContainer { public LocalisableString Value { @@ -175,7 +175,7 @@ namespace osu.Game.Overlays.Rankings } } - private class SpotlightsDropdown : OsuDropdown + private partial class SpotlightsDropdown : OsuDropdown { private OsuDropdownMenu menu; @@ -192,7 +192,7 @@ namespace osu.Game.Overlays.Rankings Padding = new MarginPadding { Vertical = 20 }; } - private class SpotlightsDropdownHeader : OsuDropdownHeader + private partial class SpotlightsDropdownHeader : OsuDropdownHeader { public SpotlightsDropdownHeader() { diff --git a/osu.Game/Overlays/Rankings/SpotlightsLayout.cs b/osu.Game/Overlays/Rankings/SpotlightsLayout.cs index c23b9711dd..8a1b929753 100644 --- a/osu.Game/Overlays/Rankings/SpotlightsLayout.cs +++ b/osu.Game/Overlays/Rankings/SpotlightsLayout.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Overlays.Rankings { - public class SpotlightsLayout : CompositeDrawable + public partial class SpotlightsLayout : CompositeDrawable { public readonly Bindable Ruleset = new Bindable(); diff --git a/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs b/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs index a6f0c7a123..3be5cc994c 100644 --- a/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs @@ -17,7 +17,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Rankings.Tables { - public class CountriesTable : RankingsTable + public partial class CountriesTable : RankingsTable { public CountriesTable(int page, IReadOnlyList rankings) : base(page, rankings) @@ -66,7 +66,7 @@ namespace osu.Game.Overlays.Rankings.Tables } }; - private class CountryName : LinkFlowContainer + private partial class CountryName : LinkFlowContainer { [Resolved(canBeNull: true)] private RankingsOverlay rankings { get; set; } diff --git a/osu.Game/Overlays/Rankings/Tables/PerformanceTable.cs b/osu.Game/Overlays/Rankings/Tables/PerformanceTable.cs index a77546d83f..19ed3afdca 100644 --- a/osu.Game/Overlays/Rankings/Tables/PerformanceTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/PerformanceTable.cs @@ -12,7 +12,7 @@ using osu.Game.Users; namespace osu.Game.Overlays.Rankings.Tables { - public class PerformanceTable : UserBasedTable + public partial class PerformanceTable : UserBasedTable { public PerformanceTable(int page, IReadOnlyList rankings) : base(page, rankings) diff --git a/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs b/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs index 073bf86a7a..affd9a2c44 100644 --- a/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs @@ -20,7 +20,7 @@ using osu.Framework.Localisation; namespace osu.Game.Overlays.Rankings.Tables { - public abstract class RankingsTable : TableContainer + public abstract partial class RankingsTable : TableContainer { protected const int TEXT_SIZE = 12; private const float horizontal_inset = 20; @@ -119,7 +119,7 @@ namespace osu.Game.Overlays.Rankings.Tables public virtual HeaderText CreateHeaderText() => new HeaderText(Header, Highlighted); } - protected class HeaderText : OsuSpriteText + protected partial class HeaderText : OsuSpriteText { private readonly bool isHighlighted; @@ -140,7 +140,7 @@ namespace osu.Game.Overlays.Rankings.Tables } } - protected class RowText : OsuSpriteText + protected partial class RowText : OsuSpriteText { public RowText() { @@ -149,7 +149,7 @@ namespace osu.Game.Overlays.Rankings.Tables } } - protected class ColouredRowText : RowText + protected partial class ColouredRowText : RowText { [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) diff --git a/osu.Game/Overlays/Rankings/Tables/ScoresTable.cs b/osu.Game/Overlays/Rankings/Tables/ScoresTable.cs index 71c78baf3c..0da3fba8cc 100644 --- a/osu.Game/Overlays/Rankings/Tables/ScoresTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/ScoresTable.cs @@ -12,7 +12,7 @@ using osu.Game.Users; namespace osu.Game.Overlays.Rankings.Tables { - public class ScoresTable : UserBasedTable + public partial class ScoresTable : UserBasedTable { public ScoresTable(int page, IReadOnlyList rankings) : base(page, rankings) diff --git a/osu.Game/Overlays/Rankings/Tables/TableRowBackground.cs b/osu.Game/Overlays/Rankings/Tables/TableRowBackground.cs index fd9f6da749..54ec45f4ff 100644 --- a/osu.Game/Overlays/Rankings/Tables/TableRowBackground.cs +++ b/osu.Game/Overlays/Rankings/Tables/TableRowBackground.cs @@ -12,7 +12,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Rankings.Tables { - public class TableRowBackground : CompositeDrawable + public partial class TableRowBackground : CompositeDrawable { private const int fade_duration = 100; diff --git a/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs b/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs index 48185e6083..4d25065578 100644 --- a/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs @@ -17,7 +17,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Rankings.Tables { - public abstract class UserBasedTable : RankingsTable + public abstract partial class UserBasedTable : RankingsTable { protected UserBasedTable(int page, IReadOnlyList rankings) : base(page, rankings) @@ -98,7 +98,7 @@ namespace osu.Game.Overlays.Rankings.Tables public override HeaderText CreateHeaderText() => new GradeHeaderText(Header, Highlighted); } - private class GradeHeaderText : HeaderText + private partial class GradeHeaderText : HeaderText { public GradeHeaderText(LocalisableString text, bool isHighlighted) : base(text, isHighlighted) diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index 586b883604..f25bf80b6a 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -15,7 +15,7 @@ using osu.Game.Overlays.Rankings.Tables; namespace osu.Game.Overlays { - public class RankingsOverlay : TabbableOnlineOverlay + public partial class RankingsOverlay : TabbableOnlineOverlay { protected Bindable Country => Header.Country; diff --git a/osu.Game/Overlays/RestoreDefaultValueButton.cs b/osu.Game/Overlays/RestoreDefaultValueButton.cs index a5da696f58..24dec44588 100644 --- a/osu.Game/Overlays/RestoreDefaultValueButton.cs +++ b/osu.Game/Overlays/RestoreDefaultValueButton.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Overlays { - public class RestoreDefaultValueButton : OsuButton, IHasTooltip, IHasCurrentValue + public partial class RestoreDefaultValueButton : OsuButton, IHasTooltip, IHasCurrentValue { public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks; diff --git a/osu.Game/Overlays/Settings/DangerousSettingsButton.cs b/osu.Game/Overlays/Settings/DangerousSettingsButton.cs index bf7c9ccf2b..248b4d339a 100644 --- a/osu.Game/Overlays/Settings/DangerousSettingsButton.cs +++ b/osu.Game/Overlays/Settings/DangerousSettingsButton.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Settings /// /// A with pink colours to mark dangerous/destructive actions. /// - public class DangerousSettingsButton : SettingsButton + public partial class DangerousSettingsButton : SettingsButton { [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game/Overlays/Settings/OutlinedTextBox.cs b/osu.Game/Overlays/Settings/OutlinedTextBox.cs index de7fe75060..56b662ecf0 100644 --- a/osu.Game/Overlays/Settings/OutlinedTextBox.cs +++ b/osu.Game/Overlays/Settings/OutlinedTextBox.cs @@ -12,7 +12,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Settings { - public class OutlinedTextBox : OsuTextBox + public partial class OutlinedTextBox : OsuTextBox { private const float border_thickness = 3; diff --git a/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs b/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs index 76e75a5b3c..1bc2c08352 100644 --- a/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs +++ b/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs @@ -14,7 +14,7 @@ namespace osu.Game.Overlays.Settings /// A which provides subclasses with the /// from the 's . /// - public abstract class RulesetSettingsSubsection : SettingsSubsection + public abstract partial class RulesetSettingsSubsection : SettingsSubsection { private readonly Ruleset ruleset; diff --git a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs index 9b53d62272..a71f2a6d29 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs @@ -14,7 +14,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Audio { - public class AudioDevicesSettings : SettingsSubsection + public partial class AudioDevicesSettings : SettingsSubsection { protected override LocalisableString Header => AudioSettingsStrings.AudioDevicesHeader; @@ -77,11 +77,11 @@ namespace osu.Game.Overlays.Settings.Sections.Audio } } - private class AudioDeviceSettingsDropdown : SettingsDropdown + private partial class AudioDeviceSettingsDropdown : SettingsDropdown { protected override OsuDropdown CreateDropdown() => new AudioDeviceDropdownControl(); - private class AudioDeviceDropdownControl : DropdownControl + private partial class AudioDeviceDropdownControl : DropdownControl { protected override LocalisableString GenerateItemText(string item) => string.IsNullOrEmpty(item) ? CommonStrings.Default : base.GenerateItemText(item); diff --git a/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs index d25e9490b7..1755c12f94 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs @@ -14,7 +14,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Audio { - public class OffsetSettings : SettingsSubsection + public partial class OffsetSettings : SettingsSubsection { protected override LocalisableString Header => AudioSettingsStrings.OffsetHeader; diff --git a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs index 8f188f04d9..a83707b5f6 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs @@ -13,7 +13,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Audio { - public class VolumeSettings : SettingsSubsection + public partial class VolumeSettings : SettingsSubsection { protected override LocalisableString Header => AudioSettingsStrings.VolumeHeader; @@ -54,7 +54,7 @@ namespace osu.Game.Overlays.Settings.Sections.Audio }; } - private class VolumeAdjustSlider : SettingsSlider + private partial class VolumeAdjustSlider : SettingsSlider { protected override Drawable CreateControl() { diff --git a/osu.Game/Overlays/Settings/Sections/AudioSection.cs b/osu.Game/Overlays/Settings/Sections/AudioSection.cs index 70c74cd77c..542d5bc8fd 100644 --- a/osu.Game/Overlays/Settings/Sections/AudioSection.cs +++ b/osu.Game/Overlays/Settings/Sections/AudioSection.cs @@ -13,7 +13,7 @@ using osu.Game.Overlays.Settings.Sections.Audio; namespace osu.Game.Overlays.Settings.Sections { - public class AudioSection : SettingsSection + public partial class AudioSection : SettingsSection { public override LocalisableString Header => AudioSettingsStrings.AudioSectionHeader; diff --git a/osu.Game/Overlays/Settings/Sections/DebugSection.cs b/osu.Game/Overlays/Settings/Sections/DebugSection.cs index a02e28d33a..2594962314 100644 --- a/osu.Game/Overlays/Settings/Sections/DebugSection.cs +++ b/osu.Game/Overlays/Settings/Sections/DebugSection.cs @@ -11,7 +11,7 @@ using osu.Game.Overlays.Settings.Sections.DebugSettings; namespace osu.Game.Overlays.Settings.Sections { - public class DebugSection : SettingsSection + public partial class DebugSection : SettingsSection { public override LocalisableString Header => DebugSettingsStrings.DebugSectionHeader; diff --git a/osu.Game/Overlays/Settings/Sections/DebugSettings/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/DebugSettings/GeneralSettings.cs index e79d27ad2a..6c2bfedba0 100644 --- a/osu.Game/Overlays/Settings/Sections/DebugSettings/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/DebugSettings/GeneralSettings.cs @@ -15,7 +15,7 @@ using osu.Game.Screens.Utility; namespace osu.Game.Overlays.Settings.Sections.DebugSettings { - public class GeneralSettings : SettingsSubsection + public partial class GeneralSettings : SettingsSubsection { protected override LocalisableString Header => DebugSettingsStrings.GeneralHeader; diff --git a/osu.Game/Overlays/Settings/Sections/DebugSettings/MemorySettings.cs b/osu.Game/Overlays/Settings/Sections/DebugSettings/MemorySettings.cs index 3afb060e49..bf0a48d2c2 100644 --- a/osu.Game/Overlays/Settings/Sections/DebugSettings/MemorySettings.cs +++ b/osu.Game/Overlays/Settings/Sections/DebugSettings/MemorySettings.cs @@ -16,7 +16,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.DebugSettings { - public class MemorySettings : SettingsSubsection + public partial class MemorySettings : SettingsSubsection { protected override LocalisableString Header => DebugSettingsStrings.MemoryHeader; diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/AudioSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/AudioSettings.cs index d369c4470b..00eb6fa62c 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/AudioSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/AudioSettings.cs @@ -11,7 +11,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Gameplay { - public class AudioSettings : SettingsSubsection + public partial class AudioSettings : SettingsSubsection { protected override LocalisableString Header => GameplaySettingsStrings.AudioHeader; diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/BackgroundSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/BackgroundSettings.cs index cc224a4f7f..09e5f3e163 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/BackgroundSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/BackgroundSettings.cs @@ -11,7 +11,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Gameplay { - public class BackgroundSettings : SettingsSubsection + public partial class BackgroundSettings : SettingsSubsection { protected override LocalisableString Header => GameplaySettingsStrings.BackgroundHeader; diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs index 14ff6ac2b5..e8db5fe58a 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs @@ -12,7 +12,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Gameplay { - public class BeatmapSettings : SettingsSubsection + public partial class BeatmapSettings : SettingsSubsection { protected override LocalisableString Header => GameplaySettingsStrings.BeatmapHeader; diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index c16ee39191..96d458a942 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Overlays.Settings.Sections.Gameplay { - public class GeneralSettings : SettingsSubsection + public partial class GeneralSettings : SettingsSubsection { protected override LocalisableString Header => GameplaySettingsStrings.GeneralHeader; diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/HUDSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/HUDSettings.cs index 88a27840d8..c67c14bb43 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/HUDSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/HUDSettings.cs @@ -11,7 +11,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Gameplay { - public class HUDSettings : SettingsSubsection + public partial class HUDSettings : SettingsSubsection { protected override LocalisableString Header => GameplaySettingsStrings.HUDHeader; diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/InputSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/InputSettings.cs index ac59a6c0ed..4d027cf8cb 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/InputSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/InputSettings.cs @@ -12,7 +12,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Gameplay { - public class InputSettings : SettingsSubsection + public partial class InputSettings : SettingsSubsection { protected override LocalisableString Header => GameplaySettingsStrings.InputHeader; diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs index 53f7f52212..69e24bc616 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs @@ -12,7 +12,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Gameplay { - public class ModsSettings : SettingsSubsection + public partial class ModsSettings : SettingsSubsection { protected override LocalisableString Header => GameplaySettingsStrings.ModsHeader; diff --git a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs index 48e76bfeb7..ae6145752b 100644 --- a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs +++ b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs @@ -11,7 +11,7 @@ using osu.Game.Overlays.Settings.Sections.Gameplay; namespace osu.Game.Overlays.Settings.Sections { - public class GameplaySection : SettingsSection + public partial class GameplaySection : SettingsSection { public override LocalisableString Header => GameplaySettingsStrings.GameplaySectionHeader; diff --git a/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs index b7e3bd90b0..a4ec919658 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs @@ -12,7 +12,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.General { - public class LanguageSettings : SettingsSubsection + public partial class LanguageSettings : SettingsSubsection { private SettingsDropdown languageSelection = null!; private Bindable frameworkLocale = null!; diff --git a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs index d97cf699e5..55be06c765 100644 --- a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs @@ -19,7 +19,7 @@ using osu.Game.Updater; namespace osu.Game.Overlays.Settings.Sections.General { - public class UpdateSettings : SettingsSubsection + public partial class UpdateSettings : SettingsSubsection { [Resolved(CanBeNull = true)] private UpdateManager updateManager { get; set; } diff --git a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs index 59cbd8cd5a..c62d44fd30 100644 --- a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs +++ b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays.Settings.Sections.General; namespace osu.Game.Overlays.Settings.Sections { - public class GeneralSection : SettingsSection + public partial class GeneralSection : SettingsSection { [Resolved(CanBeNull = true)] private FirstRunSetupOverlay firstRunSetupOverlay { get; set; } diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 7f0bded806..63689961e6 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -25,7 +25,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Settings.Sections.Graphics { - public class LayoutSettings : SettingsSubsection + public partial class LayoutSettings : SettingsSubsection { protected override LocalisableString Header => GraphicsSettingsStrings.LayoutHeader; @@ -324,7 +324,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics base.Dispose(isDisposing); } - private class ScalingPreview : ScalingContainer + private partial class ScalingPreview : ScalingContainer { public ScalingPreview() { @@ -337,16 +337,16 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics } } - private class UIScaleSlider : OsuSliderBar + private partial class UIScaleSlider : OsuSliderBar { public override LocalisableString TooltipText => base.TooltipText + "x"; } - private class DisplaySettingsDropdown : SettingsDropdown + private partial class DisplaySettingsDropdown : SettingsDropdown { protected override OsuDropdown CreateDropdown() => new DisplaySettingsDropdownControl(); - private class DisplaySettingsDropdownControl : DropdownControl + private partial class DisplaySettingsDropdownControl : DropdownControl { protected override LocalisableString GenerateItemText(Display item) { @@ -355,11 +355,11 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics } } - private class ResolutionSettingsDropdown : SettingsDropdown + private partial class ResolutionSettingsDropdown : SettingsDropdown { protected override OsuDropdown CreateDropdown() => new ResolutionDropdownControl(); - private class ResolutionDropdownControl : DropdownControl + private partial class ResolutionDropdownControl : DropdownControl { protected override LocalisableString GenerateItemText(Size item) { diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index 2e15172e46..775606caf0 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -13,7 +13,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Graphics { - public class RendererSettings : SettingsSubsection + public partial class RendererSettings : SettingsSubsection { protected override LocalisableString Header => GraphicsSettingsStrings.RendererHeader; diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/ScreenshotSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/ScreenshotSettings.cs index 7f88cc23d2..8054b27de5 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/ScreenshotSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/ScreenshotSettings.cs @@ -11,7 +11,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Graphics { - public class ScreenshotSettings : SettingsSubsection + public partial class ScreenshotSettings : SettingsSubsection { protected override LocalisableString Header => GraphicsSettingsStrings.Screenshots; diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/VideoSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/VideoSettings.cs index 56d0a6421b..2e0bbe3c16 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/VideoSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/VideoSettings.cs @@ -13,7 +13,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Graphics { - public class VideoSettings : SettingsSubsection + public partial class VideoSettings : SettingsSubsection { protected override LocalisableString Header => GraphicsSettingsStrings.VideoHeader; diff --git a/osu.Game/Overlays/Settings/Sections/GraphicsSection.cs b/osu.Game/Overlays/Settings/Sections/GraphicsSection.cs index e094e0e051..323cdaf14d 100644 --- a/osu.Game/Overlays/Settings/Sections/GraphicsSection.cs +++ b/osu.Game/Overlays/Settings/Sections/GraphicsSection.cs @@ -11,7 +11,7 @@ using osu.Game.Overlays.Settings.Sections.Graphics; namespace osu.Game.Overlays.Settings.Sections { - public class GraphicsSection : SettingsSection + public partial class GraphicsSection : SettingsSection { public override LocalisableString Header => GraphicsSettingsStrings.GraphicsSectionHeader; diff --git a/osu.Game/Overlays/Settings/Sections/Input/BindingSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/BindingSettings.cs index 2f4840a384..dbd7949206 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/BindingSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/BindingSettings.cs @@ -11,7 +11,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Input { - public class BindingSettings : SettingsSubsection + public partial class BindingSettings : SettingsSubsection { protected override LocalisableString Header => BindingSettingsStrings.ShortcutAndGameplayBindings; diff --git a/osu.Game/Overlays/Settings/Sections/Input/GlobalKeyBindingsSection.cs b/osu.Game/Overlays/Settings/Sections/Input/GlobalKeyBindingsSection.cs index 7ab10a3c3a..862bbbede0 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/GlobalKeyBindingsSection.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/GlobalKeyBindingsSection.cs @@ -9,7 +9,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Input { - public class GlobalKeyBindingsSection : SettingsSection + public partial class GlobalKeyBindingsSection : SettingsSection { public override Drawable CreateIcon() => new SpriteIcon { @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input Add(new EditorKeyBindingsSubsection(manager)); } - private class DefaultBindingsSubsection : KeyBindingsSubsection + private partial class DefaultBindingsSubsection : KeyBindingsSubsection { protected override LocalisableString Header => string.Empty; @@ -39,7 +39,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input } } - private class OverlayBindingsSubsection : KeyBindingsSubsection + private partial class OverlayBindingsSubsection : KeyBindingsSubsection { protected override LocalisableString Header => InputSettingsStrings.OverlaysSection; @@ -50,7 +50,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input } } - private class SongSelectKeyBindingSubsection : KeyBindingsSubsection + private partial class SongSelectKeyBindingSubsection : KeyBindingsSubsection { protected override LocalisableString Header => InputSettingsStrings.SongSelectSection; @@ -61,7 +61,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input } } - private class InGameKeyBindingsSubsection : KeyBindingsSubsection + private partial class InGameKeyBindingsSubsection : KeyBindingsSubsection { protected override LocalisableString Header => InputSettingsStrings.InGameSection; @@ -72,7 +72,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input } } - private class AudioControlKeyBindingsSubsection : KeyBindingsSubsection + private partial class AudioControlKeyBindingsSubsection : KeyBindingsSubsection { protected override LocalisableString Header => InputSettingsStrings.AudioSection; @@ -83,7 +83,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input } } - private class EditorKeyBindingsSubsection : KeyBindingsSubsection + private partial class EditorKeyBindingsSubsection : KeyBindingsSubsection { protected override LocalisableString Header => InputSettingsStrings.EditorSection; diff --git a/osu.Game/Overlays/Settings/Sections/Input/JoystickSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/JoystickSettings.cs index 34be846595..8455c09633 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/JoystickSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/JoystickSettings.cs @@ -12,7 +12,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Input { - public class JoystickSettings : SettingsSubsection + public partial class JoystickSettings : SettingsSubsection { protected override LocalisableString Header => JoystickSettingsStrings.JoystickGamepad; diff --git a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingPanel.cs b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingPanel.cs index 0830241f2b..30429c84f0 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingPanel.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingPanel.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets; namespace osu.Game.Overlays.Settings.Sections.Input { - public class KeyBindingPanel : SettingsSubPanel + public partial class KeyBindingPanel : SettingsSubPanel { protected override Drawable CreateHeader() => new SettingsHeader(InputSettingsStrings.KeyBindingPanelHeader, InputSettingsStrings.KeyBindingPanelDescription); diff --git a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs index 25ab8cfad2..034e142e49 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs @@ -31,7 +31,7 @@ using osuTK.Input; namespace osu.Game.Overlays.Settings.Sections.Input { - public class KeyBindingRow : Container, IFilterable + public partial class KeyBindingRow : Container, IFilterable { /// /// Invoked when the binding of this row is updated with a change being written. @@ -446,7 +446,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input isDefault.Value = bindings.Select(b => b.KeyCombination).SequenceEqual(Defaults); } - private class CancelButton : TriangleButton + private partial class CancelButton : TriangleButton { public CancelButton() { @@ -455,7 +455,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input } } - public class ClearButton : DangerousTriangleButton + public partial class ClearButton : DangerousTriangleButton { public ClearButton() { @@ -464,7 +464,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input } } - public class KeyButton : Container + public partial class KeyButton : Container { public readonly RealmKeyBinding KeyBinding; diff --git a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs index 98d569948f..d6d4abfa92 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Overlays.Settings.Sections.Input { - public abstract class KeyBindingsSubsection : SettingsSubsection + public abstract partial class KeyBindingsSubsection : SettingsSubsection { /// /// After a successful binding, automatically select the next binding row to make quickly @@ -77,7 +77,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input } } - public class ResetButton : DangerousSettingsButton + public partial class ResetButton : DangerousSettingsButton { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs index b815239c9f..5a6338dc09 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/MouseSettings.cs @@ -17,7 +17,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Input { - public class MouseSettings : SettingsSubsection + public partial class MouseSettings : SettingsSubsection { private readonly MouseHandler mouseHandler; @@ -126,7 +126,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input }, true); } - public class SensitivitySetting : SettingsSlider + public partial class SensitivitySetting : SettingsSlider { public SensitivitySetting() { @@ -135,7 +135,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input } } - public class SensitivitySlider : OsuSliderBar + public partial class SensitivitySlider : OsuSliderBar { public override LocalisableString TooltipText => Current.Disabled ? MouseSettingsStrings.EnableHighPrecisionForSensitivityAdjust : $"{base.TooltipText}x"; } diff --git a/osu.Game/Overlays/Settings/Sections/Input/RotationPresetButtons.cs b/osu.Game/Overlays/Settings/Sections/Input/RotationPresetButtons.cs index 2172dc175e..a66e44f8cb 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/RotationPresetButtons.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/RotationPresetButtons.cs @@ -15,7 +15,7 @@ using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Overlays.Settings.Sections.Input { - internal class RotationPresetButtons : CompositeDrawable + internal partial class RotationPresetButtons : CompositeDrawable { public new MarginPadding Padding { @@ -86,7 +86,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input }, true); } - public class RotationButton : RoundedButton + public partial class RotationButton : RoundedButton { [Resolved] private OsuColour colours { get; set; } diff --git a/osu.Game/Overlays/Settings/Sections/Input/RulesetBindingsSection.cs b/osu.Game/Overlays/Settings/Sections/Input/RulesetBindingsSection.cs index 6f3127a377..dcdb15fc19 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/RulesetBindingsSection.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/RulesetBindingsSection.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets; namespace osu.Game.Overlays.Settings.Sections.Input { - public class RulesetBindingsSection : SettingsSection + public partial class RulesetBindingsSection : SettingsSection { public override Drawable CreateIcon() => ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletAreaSelection.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletAreaSelection.cs index 708cd5900a..6f7faf535b 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletAreaSelection.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletAreaSelection.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Settings.Sections.Input { - public class TabletAreaSelection : CompositeDrawable + public partial class TabletAreaSelection : CompositeDrawable { public bool IsWithinBounds { get; private set; } diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs index b6efa00cdb..27612738df 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs @@ -21,7 +21,7 @@ using osu.Game.Online.Chat; namespace osu.Game.Overlays.Settings.Sections.Input { - public class TabletSettings : SettingsSubsection + public partial class TabletSettings : SettingsSubsection { public TabletAreaSelection AreaSelection { get; private set; } diff --git a/osu.Game/Overlays/Settings/Sections/Input/VariantBindingsSubsection.cs b/osu.Game/Overlays/Settings/Sections/Input/VariantBindingsSubsection.cs index a6f6c28463..d00de7f549 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/VariantBindingsSubsection.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/VariantBindingsSubsection.cs @@ -6,7 +6,7 @@ using osu.Game.Rulesets; namespace osu.Game.Overlays.Settings.Sections.Input { - public class VariantBindingsSubsection : KeyBindingsSubsection + public partial class VariantBindingsSubsection : KeyBindingsSubsection { protected override bool AutoAdvanceTarget => true; diff --git a/osu.Game/Overlays/Settings/Sections/InputSection.cs b/osu.Game/Overlays/Settings/Sections/InputSection.cs index 4d75537f6b..0647068da7 100644 --- a/osu.Game/Overlays/Settings/Sections/InputSection.cs +++ b/osu.Game/Overlays/Settings/Sections/InputSection.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays.Settings.Sections.Input; namespace osu.Game.Overlays.Settings.Sections { - public class InputSection : SettingsSection + public partial class InputSection : SettingsSection { private readonly KeyBindingPanel keyConfig; @@ -47,7 +47,7 @@ namespace osu.Game.Overlays.Settings.Sections } } - public class HandlerSection : SettingsSubsection + public partial class HandlerSection : SettingsSubsection { private readonly InputHandler handler; diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs index beae5a6aad..9c0b86c862 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs @@ -11,7 +11,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Maintenance { - public class BeatmapSettings : SettingsSubsection + public partial class BeatmapSettings : SettingsSubsection { protected override LocalisableString Header => CommonStrings.Beatmaps; diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/CollectionsSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/CollectionsSettings.cs index 17fef37e40..4da5aaf492 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/CollectionsSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/CollectionsSettings.cs @@ -10,7 +10,7 @@ using osu.Game.Overlays.Notifications; namespace osu.Game.Overlays.Settings.Sections.Maintenance { - public class CollectionsSettings : SettingsSubsection + public partial class CollectionsSettings : SettingsSubsection { protected override LocalisableString Header => CommonStrings.Collections; diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/DirectorySelectScreen.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/DirectorySelectScreen.cs index 1c9a758c6f..48ad6e2617 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/DirectorySelectScreen.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/DirectorySelectScreen.cs @@ -20,7 +20,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Maintenance { - public abstract class DirectorySelectScreen : OsuScreen + public abstract partial class DirectorySelectScreen : OsuScreen { private TriangleButton selectionButton; diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/MassDeleteConfirmationDialog.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/MassDeleteConfirmationDialog.cs index 19e6f83dac..948d646e3d 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/MassDeleteConfirmationDialog.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/MassDeleteConfirmationDialog.cs @@ -6,7 +6,7 @@ using osu.Game.Overlays.Dialog; namespace osu.Game.Overlays.Settings.Sections.Maintenance { - public class MassDeleteConfirmationDialog : DeleteConfirmationDialog + public partial class MassDeleteConfirmationDialog : DeleteConfirmationDialog { public MassDeleteConfirmationDialog(Action deleteAction) { diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/MassVideoDeleteConfirmationDialog.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/MassVideoDeleteConfirmationDialog.cs index fc8c9d497b..6312e09b3e 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/MassVideoDeleteConfirmationDialog.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/MassVideoDeleteConfirmationDialog.cs @@ -5,7 +5,7 @@ using System; namespace osu.Game.Overlays.Settings.Sections.Maintenance { - public class MassVideoDeleteConfirmationDialog : MassDeleteConfirmationDialog + public partial class MassVideoDeleteConfirmationDialog : MassDeleteConfirmationDialog { public MassVideoDeleteConfirmationDialog(Action deleteAction) : base(deleteAction) diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationRunScreen.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationRunScreen.cs index 158e1a8aa0..5b24460ac2 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationRunScreen.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationRunScreen.cs @@ -22,7 +22,7 @@ using osuTK; namespace osu.Game.Overlays.Settings.Sections.Maintenance { - public class MigrationRunScreen : OsuScreen + public partial class MigrationRunScreen : OsuScreen { private readonly DirectoryInfo destination; diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationSelectScreen.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationSelectScreen.cs index 5de33fdd55..80bf292057 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationSelectScreen.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationSelectScreen.cs @@ -17,7 +17,7 @@ using osu.Game.Overlays.Dialog; namespace osu.Game.Overlays.Settings.Sections.Maintenance { - public class MigrationSelectScreen : DirectorySelectScreen + public partial class MigrationSelectScreen : DirectorySelectScreen { [Resolved] private Storage storage { get; set; } diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/ModPresetSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/ModPresetSettings.cs index 51f6e1bf60..ba45d9c896 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/ModPresetSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/ModPresetSettings.cs @@ -14,7 +14,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Maintenance { - public class ModPresetSettings : SettingsSubsection + public partial class ModPresetSettings : SettingsSubsection { protected override LocalisableString Header => CommonStrings.ModPresets; diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/ScoreSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/ScoreSettings.cs index eb2d3171ea..1f09854843 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/ScoreSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/ScoreSettings.cs @@ -10,7 +10,7 @@ using osu.Game.Scoring; namespace osu.Game.Overlays.Settings.Sections.Maintenance { - public class ScoreSettings : SettingsSubsection + public partial class ScoreSettings : SettingsSubsection { protected override LocalisableString Header => CommonStrings.Scores; diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/SkinSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/SkinSettings.cs index 93c65513b7..e4185fe6c2 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/SkinSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/SkinSettings.cs @@ -10,7 +10,7 @@ using osu.Game.Skinning; namespace osu.Game.Overlays.Settings.Sections.Maintenance { - public class SkinSettings : SettingsSubsection + public partial class SkinSettings : SettingsSubsection { protected override LocalisableString Header => CommonStrings.Skins; diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/StableDirectoryLocationDialog.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/StableDirectoryLocationDialog.cs index 8aff4520b5..633bf8c5a5 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/StableDirectoryLocationDialog.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/StableDirectoryLocationDialog.cs @@ -12,7 +12,7 @@ using osu.Game.Screens; namespace osu.Game.Overlays.Settings.Sections.Maintenance { - public class StableDirectoryLocationDialog : PopupDialog + public partial class StableDirectoryLocationDialog : PopupDialog { [Resolved] private IPerformFromScreenRunner performer { get; set; } diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/StableDirectorySelectScreen.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/StableDirectorySelectScreen.cs index 047d589689..048f3ee683 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/StableDirectorySelectScreen.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/StableDirectorySelectScreen.cs @@ -11,7 +11,7 @@ using osu.Framework.Screens; namespace osu.Game.Overlays.Settings.Sections.Maintenance { - public class StableDirectorySelectScreen : DirectorySelectScreen + public partial class StableDirectorySelectScreen : DirectorySelectScreen { private readonly TaskCompletionSource taskCompletionSource; diff --git a/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs b/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs index 4be6d1653b..bb0a952164 100644 --- a/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs +++ b/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs @@ -9,7 +9,7 @@ using osu.Game.Overlays.Settings.Sections.Maintenance; namespace osu.Game.Overlays.Settings.Sections { - public class MaintenanceSection : SettingsSection + public partial class MaintenanceSection : SettingsSection { public override LocalisableString Header => MaintenanceSettingsStrings.MaintenanceSectionHeader; diff --git a/osu.Game/Overlays/Settings/Sections/Online/AlertsAndPrivacySettings.cs b/osu.Game/Overlays/Settings/Sections/Online/AlertsAndPrivacySettings.cs index 529f1b5ee4..dc6743c042 100644 --- a/osu.Game/Overlays/Settings/Sections/Online/AlertsAndPrivacySettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Online/AlertsAndPrivacySettings.cs @@ -11,7 +11,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Online { - public class AlertsAndPrivacySettings : SettingsSubsection + public partial class AlertsAndPrivacySettings : SettingsSubsection { protected override LocalisableString Header => OnlineSettingsStrings.AlertsAndPrivacyHeader; diff --git a/osu.Game/Overlays/Settings/Sections/Online/IntegrationSettings.cs b/osu.Game/Overlays/Settings/Sections/Online/IntegrationSettings.cs index 17228d6359..33748d0f5e 100644 --- a/osu.Game/Overlays/Settings/Sections/Online/IntegrationSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Online/IntegrationSettings.cs @@ -11,7 +11,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Online { - public class IntegrationSettings : SettingsSubsection + public partial class IntegrationSettings : SettingsSubsection { protected override LocalisableString Header => OnlineSettingsStrings.IntegrationsHeader; diff --git a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs index ba707e2145..d0707a434a 100644 --- a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs @@ -11,7 +11,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Online { - public class WebSettings : SettingsSubsection + public partial class WebSettings : SettingsSubsection { protected override LocalisableString Header => OnlineSettingsStrings.WebHeader; diff --git a/osu.Game/Overlays/Settings/Sections/OnlineSection.cs b/osu.Game/Overlays/Settings/Sections/OnlineSection.cs index feb281f1b8..775c6f9839 100644 --- a/osu.Game/Overlays/Settings/Sections/OnlineSection.cs +++ b/osu.Game/Overlays/Settings/Sections/OnlineSection.cs @@ -11,7 +11,7 @@ using osu.Game.Overlays.Settings.Sections.Online; namespace osu.Game.Overlays.Settings.Sections { - public class OnlineSection : SettingsSection + public partial class OnlineSection : SettingsSection { public override LocalisableString Header => OnlineSettingsStrings.OnlineSectionHeader; diff --git a/osu.Game/Overlays/Settings/Sections/RulesetSection.cs b/osu.Game/Overlays/Settings/Sections/RulesetSection.cs index 6f0b3c27a0..aaad1ec4e2 100644 --- a/osu.Game/Overlays/Settings/Sections/RulesetSection.cs +++ b/osu.Game/Overlays/Settings/Sections/RulesetSection.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets; namespace osu.Game.Overlays.Settings.Sections { - public class RulesetSection : SettingsSection + public partial class RulesetSection : SettingsSection { public override LocalisableString Header => RulesetSettingsStrings.Rulesets; diff --git a/osu.Game/Overlays/Settings/Sections/SizeSlider.cs b/osu.Game/Overlays/Settings/Sections/SizeSlider.cs index 28b4cd6418..26d6147bb7 100644 --- a/osu.Game/Overlays/Settings/Sections/SizeSlider.cs +++ b/osu.Game/Overlays/Settings/Sections/SizeSlider.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Settings.Sections /// /// A slider intended to show a "size" multiplier number, where 1x is 1.0. /// - public class SizeSlider : OsuSliderBar + public partial class SizeSlider : OsuSliderBar where T : struct, IEquatable, IComparable, IConvertible, IFormattable { public override LocalisableString TooltipText => Current.Value.ToString(@"0.##x", NumberFormatInfo.CurrentInfo); diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index f602b73065..826a1e7404 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -24,7 +24,7 @@ using Realms; namespace osu.Game.Overlays.Settings.Sections { - public class SkinSection : SettingsSection + public partial class SkinSection : SettingsSection { private SkinSettingsDropdown skinDropdown; @@ -123,17 +123,17 @@ namespace osu.Game.Overlays.Settings.Sections realmSubscription?.Dispose(); } - private class SkinSettingsDropdown : SettingsDropdown> + private partial class SkinSettingsDropdown : SettingsDropdown> { protected override OsuDropdown> CreateDropdown() => new SkinDropdownControl(); - private class SkinDropdownControl : DropdownControl + private partial class SkinDropdownControl : DropdownControl { protected override LocalisableString GenerateItemText(Live item) => item.ToString(); } } - public class ExportSkinButton : SettingsButton + public partial class ExportSkinButton : SettingsButton { [Resolved] private SkinManager skins { get; set; } @@ -171,7 +171,7 @@ namespace osu.Game.Overlays.Settings.Sections } } - public class DeleteSkinButton : DangerousSettingsButton + public partial class DeleteSkinButton : DangerousSettingsButton { [Resolved] private SkinManager skins { get; set; } diff --git a/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs index 85cfdb33d5..2e8d005401 100644 --- a/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs @@ -12,7 +12,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.UserInterface { - public class GeneralSettings : SettingsSubsection + public partial class GeneralSettings : SettingsSubsection { protected override LocalisableString Header => UserInterfaceStrings.GeneralHeader; diff --git a/osu.Game/Overlays/Settings/Sections/UserInterface/MainMenuSettings.cs b/osu.Game/Overlays/Settings/Sections/UserInterface/MainMenuSettings.cs index 7ca45bb6b8..4577fadb01 100644 --- a/osu.Game/Overlays/Settings/Sections/UserInterface/MainMenuSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/UserInterface/MainMenuSettings.cs @@ -14,7 +14,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Settings.Sections.UserInterface { - public class MainMenuSettings : SettingsSubsection + public partial class MainMenuSettings : SettingsSubsection { protected override LocalisableString Header => UserInterfaceStrings.MainMenuHeader; diff --git a/osu.Game/Overlays/Settings/Sections/UserInterface/SongSelectSettings.cs b/osu.Game/Overlays/Settings/Sections/UserInterface/SongSelectSettings.cs index 708bee6fbd..8b5e0b75b7 100644 --- a/osu.Game/Overlays/Settings/Sections/UserInterface/SongSelectSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/UserInterface/SongSelectSettings.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays.Mods.Input; namespace osu.Game.Overlays.Settings.Sections.UserInterface { - public class SongSelectSettings : SettingsSubsection + public partial class SongSelectSettings : SettingsSubsection { protected override LocalisableString Header => UserInterfaceStrings.SongSelectHeader; diff --git a/osu.Game/Overlays/Settings/Sections/UserInterfaceSection.cs b/osu.Game/Overlays/Settings/Sections/UserInterfaceSection.cs index b2711af612..0926574a54 100644 --- a/osu.Game/Overlays/Settings/Sections/UserInterfaceSection.cs +++ b/osu.Game/Overlays/Settings/Sections/UserInterfaceSection.cs @@ -11,7 +11,7 @@ using osu.Game.Overlays.Settings.Sections.UserInterface; namespace osu.Game.Overlays.Settings.Sections { - public class UserInterfaceSection : SettingsSection + public partial class UserInterfaceSection : SettingsSection { public override LocalisableString Header => UserInterfaceStrings.UserInterfaceSectionHeader; diff --git a/osu.Game/Overlays/Settings/SettingsButton.cs b/osu.Game/Overlays/Settings/SettingsButton.cs index 5f2a416f58..2d7e78d17a 100644 --- a/osu.Game/Overlays/Settings/SettingsButton.cs +++ b/osu.Game/Overlays/Settings/SettingsButton.cs @@ -15,7 +15,7 @@ using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Overlays.Settings { - public class SettingsButton : RoundedButton, IHasTooltip + public partial class SettingsButton : RoundedButton, IHasTooltip { public SettingsButton() { diff --git a/osu.Game/Overlays/Settings/SettingsCheckbox.cs b/osu.Game/Overlays/Settings/SettingsCheckbox.cs index efe7fb6d9e..a413bcf220 100644 --- a/osu.Game/Overlays/Settings/SettingsCheckbox.cs +++ b/osu.Game/Overlays/Settings/SettingsCheckbox.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Settings { - public class SettingsCheckbox : SettingsItem + public partial class SettingsCheckbox : SettingsItem { private LocalisableString labelText; diff --git a/osu.Game/Overlays/Settings/SettingsDropdown.cs b/osu.Game/Overlays/Settings/SettingsDropdown.cs index 347ef03b42..5798d02e03 100644 --- a/osu.Game/Overlays/Settings/SettingsDropdown.cs +++ b/osu.Game/Overlays/Settings/SettingsDropdown.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Settings { - public class SettingsDropdown : SettingsItem + public partial class SettingsDropdown : SettingsItem { protected new OsuDropdown Control => (OsuDropdown)base.Control; @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Settings protected virtual OsuDropdown CreateDropdown() => new DropdownControl(); - protected class DropdownControl : OsuDropdown + protected partial class DropdownControl : OsuDropdown { public DropdownControl() { diff --git a/osu.Game/Overlays/Settings/SettingsEnumDropdown.cs b/osu.Game/Overlays/Settings/SettingsEnumDropdown.cs index 9408e4a9ce..62dd4f2905 100644 --- a/osu.Game/Overlays/Settings/SettingsEnumDropdown.cs +++ b/osu.Game/Overlays/Settings/SettingsEnumDropdown.cs @@ -9,12 +9,12 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Settings { - public class SettingsEnumDropdown : SettingsDropdown + public partial class SettingsEnumDropdown : SettingsDropdown where T : struct, Enum { protected override OsuDropdown CreateDropdown() => new DropdownControl(); - protected new class DropdownControl : OsuEnumDropdown + protected new partial class DropdownControl : OsuEnumDropdown { public DropdownControl() { diff --git a/osu.Game/Overlays/Settings/SettingsFooter.cs b/osu.Game/Overlays/Settings/SettingsFooter.cs index db0dc8fd5e..62933ed556 100644 --- a/osu.Game/Overlays/Settings/SettingsFooter.cs +++ b/osu.Game/Overlays/Settings/SettingsFooter.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Settings { - public class SettingsFooter : FillFlowContainer + public partial class SettingsFooter : FillFlowContainer { [BackgroundDependencyLoader] private void load(OsuGameBase game, RulesetStore rulesets) @@ -78,7 +78,7 @@ namespace osu.Game.Overlays.Settings } } - private class BuildDisplay : OsuAnimatedButton + private partial class BuildDisplay : OsuAnimatedButton { private readonly string version; private readonly bool isDebug; diff --git a/osu.Game/Overlays/Settings/SettingsHeader.cs b/osu.Game/Overlays/Settings/SettingsHeader.cs index 56360fc4a1..f2b84c4ba9 100644 --- a/osu.Game/Overlays/Settings/SettingsHeader.cs +++ b/osu.Game/Overlays/Settings/SettingsHeader.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Overlays.Settings { - public class SettingsHeader : Container + public partial class SettingsHeader : Container { private readonly LocalisableString heading; private readonly LocalisableString subheading; diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index c34964fa96..577f1738ba 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -22,7 +22,7 @@ using osuTK; namespace osu.Game.Overlays.Settings { - public abstract class SettingsItem : Container, IFilterable, ISettingsItem, IHasCurrentValue, IHasTooltip + public abstract partial class SettingsItem : Container, IFilterable, ISettingsItem, IHasCurrentValue, IHasTooltip { protected abstract Drawable CreateControl(); diff --git a/osu.Game/Overlays/Settings/SettingsNumberBox.cs b/osu.Game/Overlays/Settings/SettingsNumberBox.cs index 4f98954289..97b8f6de60 100644 --- a/osu.Game/Overlays/Settings/SettingsNumberBox.cs +++ b/osu.Game/Overlays/Settings/SettingsNumberBox.cs @@ -11,14 +11,14 @@ using osu.Framework.Graphics.UserInterface; namespace osu.Game.Overlays.Settings { - public class SettingsNumberBox : SettingsItem + public partial class SettingsNumberBox : SettingsItem { protected override Drawable CreateControl() => new NumberControl { RelativeSizeAxes = Axes.X, }; - private sealed class NumberControl : CompositeDrawable, IHasCurrentValue + private sealed partial class NumberControl : CompositeDrawable, IHasCurrentValue { private readonly BindableWithCurrent current = new BindableWithCurrent(); @@ -68,7 +68,7 @@ namespace osu.Game.Overlays.Settings } } - private class OutlinedNumberBox : OutlinedTextBox + private partial class OutlinedNumberBox : OutlinedTextBox { protected override bool AllowIme => false; diff --git a/osu.Game/Overlays/Settings/SettingsSection.cs b/osu.Game/Overlays/Settings/SettingsSection.cs index dfdc850ed8..dced187035 100644 --- a/osu.Game/Overlays/Settings/SettingsSection.cs +++ b/osu.Game/Overlays/Settings/SettingsSection.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Overlays.Settings { - public abstract class SettingsSection : Container, IHasFilterableChildren + public abstract partial class SettingsSection : Container, IHasFilterableChildren { protected FillFlowContainer FlowContent; protected override Container Content => FlowContent; diff --git a/osu.Game/Overlays/Settings/SettingsSidebar.cs b/osu.Game/Overlays/Settings/SettingsSidebar.cs index ca6bcae6e4..36411e01cc 100644 --- a/osu.Game/Overlays/Settings/SettingsSidebar.cs +++ b/osu.Game/Overlays/Settings/SettingsSidebar.cs @@ -10,7 +10,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Overlays.Settings { - public class SettingsSidebar : ExpandingButtonContainer + public partial class SettingsSidebar : ExpandingButtonContainer { public const float DEFAULT_WIDTH = 70; public const int EXPANDED_WIDTH = 200; diff --git a/osu.Game/Overlays/Settings/SettingsSlider.cs b/osu.Game/Overlays/Settings/SettingsSlider.cs index 43f007f201..babac8ec69 100644 --- a/osu.Game/Overlays/Settings/SettingsSlider.cs +++ b/osu.Game/Overlays/Settings/SettingsSlider.cs @@ -10,12 +10,12 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Settings { - public class SettingsSlider : SettingsSlider> + public partial class SettingsSlider : SettingsSlider> where T : struct, IEquatable, IComparable, IConvertible { } - public class SettingsSlider : SettingsItem + public partial class SettingsSlider : SettingsItem where TValue : struct, IEquatable, IComparable, IConvertible where TSlider : OsuSliderBar, new() { diff --git a/osu.Game/Overlays/Settings/SettingsSubsection.cs b/osu.Game/Overlays/Settings/SettingsSubsection.cs index 72788c55cd..78fb53230e 100644 --- a/osu.Game/Overlays/Settings/SettingsSubsection.cs +++ b/osu.Game/Overlays/Settings/SettingsSubsection.cs @@ -17,7 +17,7 @@ using osu.Game.Graphics; namespace osu.Game.Overlays.Settings { [ExcludeFromDynamicCompile] - public abstract class SettingsSubsection : FillFlowContainer, IHasFilterableChildren + public abstract partial class SettingsSubsection : FillFlowContainer, IHasFilterableChildren { protected override Container Content => FlowContent; diff --git a/osu.Game/Overlays/Settings/SettingsTextBox.cs b/osu.Game/Overlays/Settings/SettingsTextBox.cs index 4d0f4253eb..3f9fa06384 100644 --- a/osu.Game/Overlays/Settings/SettingsTextBox.cs +++ b/osu.Game/Overlays/Settings/SettingsTextBox.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics; namespace osu.Game.Overlays.Settings { - public class SettingsTextBox : SettingsItem + public partial class SettingsTextBox : SettingsItem { protected override Drawable CreateControl() => new OutlinedTextBox { diff --git a/osu.Game/Overlays/Settings/SidebarButton.cs b/osu.Game/Overlays/Settings/SidebarButton.cs index 2c4832c68a..aec0509394 100644 --- a/osu.Game/Overlays/Settings/SidebarButton.cs +++ b/osu.Game/Overlays/Settings/SidebarButton.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Settings { - public abstract class SidebarButton : OsuButton + public abstract partial class SidebarButton : OsuButton { protected const double FADE_DURATION = 500; diff --git a/osu.Game/Overlays/Settings/SidebarIconButton.cs b/osu.Game/Overlays/Settings/SidebarIconButton.cs index b32337eb2e..4e5b361460 100644 --- a/osu.Game/Overlays/Settings/SidebarIconButton.cs +++ b/osu.Game/Overlays/Settings/SidebarIconButton.cs @@ -15,7 +15,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Overlays.Settings { - public class SidebarIconButton : SidebarButton + public partial class SidebarIconButton : SidebarButton { private const float selection_indicator_height_active = 18; private const float selection_indicator_height_inactive = 4; diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index b28ac4ab8b..291281124c 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -17,7 +17,7 @@ using osu.Game.Localisation; namespace osu.Game.Overlays { - public class SettingsOverlay : SettingsPanel, INamedOverlayComponent + public partial class SettingsOverlay : SettingsPanel, INamedOverlayComponent { public string IconTexture => "Icons/Hexacons/settings"; public LocalisableString Title => SettingsStrings.HeaderTitle; diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index eb457032ea..aefaccdb5d 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -23,7 +23,7 @@ using osu.Game.Overlays.Settings; namespace osu.Game.Overlays { [Cached] - public abstract class SettingsPanel : OsuFocusedOverlayContainer + public abstract partial class SettingsPanel : OsuFocusedOverlayContainer { public const float CONTENT_MARGINS = 20; @@ -273,13 +273,13 @@ namespace osu.Game.Overlays } } - private class NonMaskedContent : Container + private partial class NonMaskedContent : Container { // masking breaks the pan-out transform with nested sub-settings panels. protected override bool ComputeIsMaskedAway(RectangleF maskingBounds) => false; } - public class SettingsSectionsContainer : SectionsContainer + public partial class SettingsSectionsContainer : SectionsContainer { public SearchContainer SearchContainer; diff --git a/osu.Game/Overlays/SettingsSubPanel.cs b/osu.Game/Overlays/SettingsSubPanel.cs index 4548cdfb5d..5890d1c8fa 100644 --- a/osu.Game/Overlays/SettingsSubPanel.cs +++ b/osu.Game/Overlays/SettingsSubPanel.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Overlays { - public abstract class SettingsSubPanel : SettingsPanel + public abstract partial class SettingsSubPanel : SettingsPanel { protected SettingsSubPanel() : base(true) @@ -34,7 +34,7 @@ namespace osu.Game.Overlays protected override bool DimMainContent => false; // dimming is handled by main overlay - public class BackButton : SidebarButton + public partial class BackButton : SidebarButton { private Container content; diff --git a/osu.Game/Overlays/SettingsToolboxGroup.cs b/osu.Game/Overlays/SettingsToolboxGroup.cs index 6dd9e2a56d..56c890e9e2 100644 --- a/osu.Game/Overlays/SettingsToolboxGroup.cs +++ b/osu.Game/Overlays/SettingsToolboxGroup.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public class SettingsToolboxGroup : Container, IExpandable + public partial class SettingsToolboxGroup : Container, IExpandable { private readonly string title; public const int CONTAINER_WIDTH = 270; diff --git a/osu.Game/Overlays/TabControlOverlayHeader.cs b/osu.Game/Overlays/TabControlOverlayHeader.cs index caec4aeed0..cad94eba71 100644 --- a/osu.Game/Overlays/TabControlOverlayHeader.cs +++ b/osu.Game/Overlays/TabControlOverlayHeader.cs @@ -21,7 +21,7 @@ namespace osu.Game.Overlays /// An overlay header which contains a . /// /// The type of item to be represented by tabs. - public abstract class TabControlOverlayHeader : OverlayHeader, IHasCurrentValue + public abstract partial class TabControlOverlayHeader : OverlayHeader, IHasCurrentValue { protected OsuTabControl TabControl; @@ -80,7 +80,7 @@ namespace osu.Game.Overlays [NotNull] protected virtual OsuTabControl CreateTabControl() => new OverlayHeaderTabControl(); - public class OverlayHeaderTabControl : OverlayTabControl + public partial class OverlayHeaderTabControl : OverlayTabControl { private const float bar_height = 1; @@ -103,7 +103,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Horizontal, }; - private class OverlayHeaderTabItem : OverlayTabItem + private partial class OverlayHeaderTabItem : OverlayTabItem { public OverlayHeaderTabItem(T value) : base(value) diff --git a/osu.Game/Overlays/TabbableOnlineOverlay.cs b/osu.Game/Overlays/TabbableOnlineOverlay.cs index a99be4cc18..d92dd4ae54 100644 --- a/osu.Game/Overlays/TabbableOnlineOverlay.cs +++ b/osu.Game/Overlays/TabbableOnlineOverlay.cs @@ -12,7 +12,7 @@ using osu.Game.Online.API; namespace osu.Game.Overlays { - public abstract class TabbableOnlineOverlay : OnlineOverlay + public abstract partial class TabbableOnlineOverlay : OnlineOverlay where THeader : TabControlOverlayHeader { private readonly IBindable apiState = new Bindable(); diff --git a/osu.Game/Overlays/Toolbar/AnalogClockDisplay.cs b/osu.Game/Overlays/Toolbar/AnalogClockDisplay.cs index 477991f599..a5ed0d65bd 100644 --- a/osu.Game/Overlays/Toolbar/AnalogClockDisplay.cs +++ b/osu.Game/Overlays/Toolbar/AnalogClockDisplay.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Toolbar { - public class AnalogClockDisplay : ClockDisplay + public partial class AnalogClockDisplay : ClockDisplay { private const float hand_thickness = 2.4f; @@ -76,7 +76,7 @@ namespace osu.Game.Overlays.Toolbar hand.RotateTo(rotation, duration, Easing.OutElastic); } - private class CentreCircle : CompositeDrawable + private partial class CentreCircle : CompositeDrawable { [BackgroundDependencyLoader] private void load(OsuColour colours) @@ -101,7 +101,7 @@ namespace osu.Game.Overlays.Toolbar } } - private class SecondHand : CompositeDrawable + private partial class SecondHand : CompositeDrawable { [BackgroundDependencyLoader] private void load(OsuColour colours) @@ -126,7 +126,7 @@ namespace osu.Game.Overlays.Toolbar } } - private class LargeHand : CompositeDrawable + private partial class LargeHand : CompositeDrawable { public LargeHand(float length) { diff --git a/osu.Game/Overlays/Toolbar/ClockDisplay.cs b/osu.Game/Overlays/Toolbar/ClockDisplay.cs index 0711341445..088631f8d6 100644 --- a/osu.Game/Overlays/Toolbar/ClockDisplay.cs +++ b/osu.Game/Overlays/Toolbar/ClockDisplay.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Overlays.Toolbar { - public abstract class ClockDisplay : CompositeDrawable + public abstract partial class ClockDisplay : CompositeDrawable { private int? lastSecond; diff --git a/osu.Game/Overlays/Toolbar/DigitalClockDisplay.cs b/osu.Game/Overlays/Toolbar/DigitalClockDisplay.cs index 5592590fd9..bc803db739 100644 --- a/osu.Game/Overlays/Toolbar/DigitalClockDisplay.cs +++ b/osu.Game/Overlays/Toolbar/DigitalClockDisplay.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays.Toolbar { - public class DigitalClockDisplay : ClockDisplay + public partial class DigitalClockDisplay : ClockDisplay { private OsuSpriteText realTime; private OsuSpriteText gameTime; diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 9d0f43c45a..ac0f822f68 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -21,7 +21,7 @@ using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar { - public class Toolbar : OverlayContainer, IKeyBindingHandler + public partial class Toolbar : OverlayContainer, IKeyBindingHandler { public const float HEIGHT = 40; public const float TOOLTIP_HEIGHT = 30; @@ -194,7 +194,7 @@ namespace osu.Game.Overlays.Toolbar rulesetSelector.Current.BindTo(ruleset); } - public class ToolbarBackground : Container + public partial class ToolbarBackground : Container { private readonly Box gradientBackground; diff --git a/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs b/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs index a2de186488..efcb011293 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarBeatmapListingButton.cs @@ -9,7 +9,7 @@ using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar { - public class ToolbarBeatmapListingButton : ToolbarOverlayToggleButton + public partial class ToolbarBeatmapListingButton : ToolbarOverlayToggleButton { protected override Anchor TooltipAnchor => Anchor.TopRight; diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index 96d4da1112..ea5fc5bb38 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -28,7 +28,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Toolbar { - public abstract class ToolbarButton : OsuClickableContainer, IKeyBindingHandler + public abstract partial class ToolbarButton : OsuClickableContainer, IKeyBindingHandler { protected GlobalAction? Hotkey { get; set; } @@ -219,7 +219,7 @@ namespace osu.Game.Overlays.Toolbar } } - public class OpaqueBackground : Container + public partial class OpaqueBackground : Container { public OpaqueBackground() { diff --git a/osu.Game/Overlays/Toolbar/ToolbarChangelogButton.cs b/osu.Game/Overlays/Toolbar/ToolbarChangelogButton.cs index 5ce6387196..30e32d831c 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarChangelogButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarChangelogButton.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics; namespace osu.Game.Overlays.Toolbar { - public class ToolbarChangelogButton : ToolbarOverlayToggleButton + public partial class ToolbarChangelogButton : ToolbarOverlayToggleButton { protected override Anchor TooltipAnchor => Anchor.TopRight; diff --git a/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs b/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs index 86f87deabd..7bb94067ab 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs @@ -9,7 +9,7 @@ using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar { - public class ToolbarChatButton : ToolbarOverlayToggleButton + public partial class ToolbarChatButton : ToolbarOverlayToggleButton { protected override Anchor TooltipAnchor => Anchor.TopRight; diff --git a/osu.Game/Overlays/Toolbar/ToolbarClock.cs b/osu.Game/Overlays/Toolbar/ToolbarClock.cs index 3fd37d9a62..f1310d8535 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarClock.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarClock.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Toolbar { - public class ToolbarClock : OsuClickableContainer + public partial class ToolbarClock : OsuClickableContainer { private Bindable clockDisplayMode; private Bindable prefer24HourTime; diff --git a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs index f170ec84ac..5a1fe40fbf 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs @@ -8,7 +8,7 @@ using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar { - public class ToolbarHomeButton : ToolbarButton + public partial class ToolbarHomeButton : ToolbarButton { public ToolbarHomeButton() { diff --git a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs index bd56c60582..69597c6b46 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs @@ -19,7 +19,7 @@ using osuTK.Input; namespace osu.Game.Overlays.Toolbar { - public class ToolbarMusicButton : ToolbarOverlayToggleButton + public partial class ToolbarMusicButton : ToolbarOverlayToggleButton { private Circle volumeBar; diff --git a/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs index 286cfa20f0..bdcf6c3fec 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarNewsButton.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics; namespace osu.Game.Overlays.Toolbar { - public class ToolbarNewsButton : ToolbarOverlayToggleButton + public partial class ToolbarNewsButton : ToolbarOverlayToggleButton { protected override Anchor TooltipAnchor => Anchor.TopRight; diff --git a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs index 265eb044e0..3dfec2cba0 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Toolbar { - public class ToolbarNotificationButton : ToolbarOverlayToggleButton + public partial class ToolbarNotificationButton : ToolbarOverlayToggleButton { protected override Anchor TooltipAnchor => Anchor.TopRight; @@ -58,7 +58,7 @@ namespace osu.Game.Overlays.Toolbar }; } - private class CountCircle : CompositeDrawable + private partial class CountCircle : CompositeDrawable { private readonly OsuSpriteText countText; private readonly Circle circle; diff --git a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs index 03c365e49e..7bd48174db 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics; namespace osu.Game.Overlays.Toolbar { - public class ToolbarOverlayToggleButton : ToolbarButton + public partial class ToolbarOverlayToggleButton : ToolbarButton { private readonly Box stateBackground; diff --git a/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs index 1bda6da419..ddbf4889b6 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics; namespace osu.Game.Overlays.Toolbar { - public class ToolbarRankingsButton : ToolbarOverlayToggleButton + public partial class ToolbarRankingsButton : ToolbarOverlayToggleButton { protected override Anchor TooltipAnchor => Anchor.TopRight; diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index 1ca492f81a..715076b368 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -21,7 +21,7 @@ using osu.Framework.Audio.Sample; namespace osu.Game.Overlays.Toolbar { - public class ToolbarRulesetSelector : RulesetSelector + public partial class ToolbarRulesetSelector : RulesetSelector { protected Drawable ModeButtonLine { get; private set; } diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs index 31c6802fda..8f9930e910 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs @@ -12,7 +12,7 @@ using osu.Framework.Input.Events; namespace osu.Game.Overlays.Toolbar { - public class ToolbarRulesetTabButton : TabItem + public partial class ToolbarRulesetTabButton : TabItem { private readonly RulesetButton ruleset; @@ -37,7 +37,7 @@ namespace osu.Game.Overlays.Toolbar protected override void OnDeactivated() => ruleset.Active = false; - private class RulesetButton : ToolbarButton + private partial class RulesetButton : ToolbarButton { public bool Active { diff --git a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs index c3d48bc60e..6ebf2a4c02 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs @@ -8,7 +8,7 @@ using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar { - public class ToolbarSettingsButton : ToolbarOverlayToggleButton + public partial class ToolbarSettingsButton : ToolbarOverlayToggleButton { public ToolbarSettingsButton() { diff --git a/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs b/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs index f8ee39d56e..a8a88813d2 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs @@ -9,7 +9,7 @@ using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Toolbar { - public class ToolbarSocialButton : ToolbarOverlayToggleButton + public partial class ToolbarSocialButton : ToolbarOverlayToggleButton { protected override Anchor TooltipAnchor => Anchor.TopRight; diff --git a/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs b/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs index 4ebd19a1f7..028decea1e 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarUserButton.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Toolbar { - public class ToolbarUserButton : ToolbarOverlayToggleButton + public partial class ToolbarUserButton : ToolbarOverlayToggleButton { private UpdateableAvatar avatar = null!; diff --git a/osu.Game/Overlays/Toolbar/ToolbarWikiButton.cs b/osu.Game/Overlays/Toolbar/ToolbarWikiButton.cs index 5511902fa8..49e6be7978 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarWikiButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarWikiButton.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics; namespace osu.Game.Overlays.Toolbar { - public class ToolbarWikiButton : ToolbarOverlayToggleButton + public partial class ToolbarWikiButton : ToolbarOverlayToggleButton { protected override Anchor TooltipAnchor => Anchor.TopRight; diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index c0ca63bbd9..b1a9b2096e 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -22,7 +22,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public class UserProfileOverlay : FullscreenOverlay + public partial class UserProfileOverlay : FullscreenOverlay { private ProfileSection lastSection; private ProfileSection[] sections; @@ -152,7 +152,7 @@ namespace osu.Game.Overlays } } - private class ProfileSectionTabControl : OverlayTabControl + private partial class ProfileSectionTabControl : OverlayTabControl { private const float bar_height = 2; @@ -182,7 +182,7 @@ namespace osu.Game.Overlays protected override bool OnHover(HoverEvent e) => true; - private class ProfileSectionTabItem : OverlayTabItem + private partial class ProfileSectionTabItem : OverlayTabItem { public ProfileSectionTabItem(ProfileSection value) : base(value) @@ -196,7 +196,7 @@ namespace osu.Game.Overlays } } - private class ProfileSectionsContainer : SectionsContainer + private partial class ProfileSectionsContainer : SectionsContainer { public ProfileSectionsContainer() { diff --git a/osu.Game/Overlays/VersionManager.cs b/osu.Game/Overlays/VersionManager.cs index a1cfdf4594..0e74cada29 100644 --- a/osu.Game/Overlays/VersionManager.cs +++ b/osu.Game/Overlays/VersionManager.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays { - public class VersionManager : VisibilityContainer + public partial class VersionManager : VisibilityContainer { [BackgroundDependencyLoader] private void load(OsuColour colours, TextureStore textures, OsuGameBase game) diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index 744b2bafbd..3bea1c840e 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Volume { - public class MuteButton : OsuButton, IHasCurrentValue + public partial class MuteButton : OsuButton, IHasCurrentValue { private readonly Bindable current = new Bindable(); diff --git a/osu.Game/Overlays/Volume/VolumeControlReceptor.cs b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs index 624be0b25c..4ddbc9dd48 100644 --- a/osu.Game/Overlays/Volume/VolumeControlReceptor.cs +++ b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs @@ -12,7 +12,7 @@ using osu.Game.Input.Bindings; namespace osu.Game.Overlays.Volume { - public class VolumeControlReceptor : Container, IScrollBindingHandler, IHandleGlobalKeyboardInput + public partial class VolumeControlReceptor : Container, IScrollBindingHandler, IHandleGlobalKeyboardInput { public Func ActionRequested; public Func ScrollActionRequested; diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index e01890ddc2..d366f0bddb 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -29,7 +29,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Volume { - public class VolumeMeter : Container, IStateful + public partial class VolumeMeter : Container, IStateful { private CircularProgress volumeCircle; private CircularProgress volumeCircleGlow; diff --git a/osu.Game/Overlays/VolumeOverlay.cs b/osu.Game/Overlays/VolumeOverlay.cs index 4cedd87eac..5470c70400 100644 --- a/osu.Game/Overlays/VolumeOverlay.cs +++ b/osu.Game/Overlays/VolumeOverlay.cs @@ -23,7 +23,7 @@ using osuTK.Input; namespace osu.Game.Overlays { - public class VolumeOverlay : VisibilityContainer + public partial class VolumeOverlay : VisibilityContainer { private const float offset = 10; diff --git a/osu.Game/Overlays/WaveOverlayContainer.cs b/osu.Game/Overlays/WaveOverlayContainer.cs index faf2cca8cf..d25f6a9ae5 100644 --- a/osu.Game/Overlays/WaveOverlayContainer.cs +++ b/osu.Game/Overlays/WaveOverlayContainer.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Overlays { - public abstract class WaveOverlayContainer : OsuFocusedOverlayContainer + public abstract partial class WaveOverlayContainer : OsuFocusedOverlayContainer { protected readonly WaveContainer Waves; diff --git a/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownContainer.cs b/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownContainer.cs index 15c455416c..4ef9be90c9 100644 --- a/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownContainer.cs +++ b/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownContainer.cs @@ -14,7 +14,7 @@ using osu.Game.Graphics.Containers.Markdown; namespace osu.Game.Overlays.Wiki.Markdown { - public class WikiMarkdownContainer : OsuMarkdownContainer + public partial class WikiMarkdownContainer : OsuMarkdownContainer { protected override bool Footnotes => true; protected override bool CustomContainers => true; @@ -53,7 +53,7 @@ namespace osu.Game.Overlays.Wiki.Markdown public override MarkdownTextFlowContainer CreateTextFlow() => new WikiMarkdownTextFlowContainer(); - private class WikiMarkdownTextFlowContainer : OsuMarkdownTextFlowContainer + private partial class WikiMarkdownTextFlowContainer : OsuMarkdownTextFlowContainer { protected override void AddImage(LinkInline linkInline) => AddDrawable(new WikiMarkdownImage(linkInline)); } diff --git a/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownImage.cs b/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownImage.cs index 1c7a08930b..71c2df538d 100644 --- a/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownImage.cs +++ b/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownImage.cs @@ -8,7 +8,7 @@ using osu.Game.Graphics.Containers.Markdown; namespace osu.Game.Overlays.Wiki.Markdown { - public class WikiMarkdownImage : OsuMarkdownImage + public partial class WikiMarkdownImage : OsuMarkdownImage { public WikiMarkdownImage(LinkInline linkInline) : base(linkInline) diff --git a/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownImageBlock.cs b/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownImageBlock.cs index 5ce3f179a4..641c6242b6 100644 --- a/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownImageBlock.cs +++ b/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownImageBlock.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Overlays.Wiki.Markdown { - public class WikiMarkdownImageBlock : FillFlowContainer + public partial class WikiMarkdownImageBlock : FillFlowContainer { [Resolved] private IMarkdownTextFlowComponent parentFlowComponent { get; set; } @@ -49,7 +49,7 @@ namespace osu.Game.Overlays.Wiki.Markdown textFlow.AddText(linkInline.Title); } - private class BlockMarkdownImage : WikiMarkdownImage + private partial class BlockMarkdownImage : WikiMarkdownImage { public BlockMarkdownImage(LinkInline linkInline) : base(linkInline) @@ -60,7 +60,7 @@ namespace osu.Game.Overlays.Wiki.Markdown protected override ImageContainer CreateImageContainer(string url) => new BlockImageContainer(url); - private class BlockImageContainer : ImageContainer + private partial class BlockImageContainer : ImageContainer { public BlockImageContainer(string url) : base(url) @@ -71,7 +71,7 @@ namespace osu.Game.Overlays.Wiki.Markdown protected override Sprite CreateImageSprite() => new ImageSprite(); - private class ImageSprite : Sprite + private partial class ImageSprite : Sprite { public ImageSprite() { diff --git a/osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs b/osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs index 64d7e20d9b..5f8bee7558 100644 --- a/osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs +++ b/osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs @@ -15,7 +15,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Wiki.Markdown { - public class WikiNoticeContainer : FillFlowContainer + public partial class WikiNoticeContainer : FillFlowContainer { private readonly bool isOutdated; private readonly bool needsCleanup; @@ -62,7 +62,7 @@ namespace osu.Game.Overlays.Wiki.Markdown } } - private class NoticeBox : Container + private partial class NoticeBox : Container { [Resolved] private IMarkdownTextFlowComponent parentFlowComponent { get; set; } diff --git a/osu.Game/Overlays/Wiki/WikiArticlePage.cs b/osu.Game/Overlays/Wiki/WikiArticlePage.cs index f4ba0a4d8d..6c1dbe3181 100644 --- a/osu.Game/Overlays/Wiki/WikiArticlePage.cs +++ b/osu.Game/Overlays/Wiki/WikiArticlePage.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays.Wiki.Markdown; namespace osu.Game.Overlays.Wiki { - public class WikiArticlePage : CompositeDrawable + public partial class WikiArticlePage : CompositeDrawable { public Container SidebarContainer { get; } @@ -65,7 +65,7 @@ namespace osu.Game.Overlays.Wiki }; } - private class ArticleMarkdownContainer : WikiMarkdownContainer + private partial class ArticleMarkdownContainer : WikiMarkdownContainer { public Action OnAddHeading; diff --git a/osu.Game/Overlays/Wiki/WikiHeader.cs b/osu.Game/Overlays/Wiki/WikiHeader.cs index fc8df03892..9317813fc4 100644 --- a/osu.Game/Overlays/Wiki/WikiHeader.cs +++ b/osu.Game/Overlays/Wiki/WikiHeader.cs @@ -14,7 +14,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Wiki { - public class WikiHeader : BreadcrumbControlOverlayHeader + public partial class WikiHeader : BreadcrumbControlOverlayHeader { private const string index_path = "Main_Page"; @@ -75,7 +75,7 @@ namespace osu.Game.Overlays.Wiki protected override OverlayTitle CreateTitle() => new WikiHeaderTitle(); - private class WikiHeaderTitle : OverlayTitle + private partial class WikiHeaderTitle : OverlayTitle { public WikiHeaderTitle() { diff --git a/osu.Game/Overlays/Wiki/WikiMainPage.cs b/osu.Game/Overlays/Wiki/WikiMainPage.cs index 67e4bdf2e5..457309ae44 100644 --- a/osu.Game/Overlays/Wiki/WikiMainPage.cs +++ b/osu.Game/Overlays/Wiki/WikiMainPage.cs @@ -15,7 +15,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Overlays.Wiki { - public class WikiMainPage : FillFlowContainer + public partial class WikiMainPage : FillFlowContainer { public string Markdown; diff --git a/osu.Game/Overlays/Wiki/WikiPanelContainer.cs b/osu.Game/Overlays/Wiki/WikiPanelContainer.cs index 552770f098..ef31e9cfdd 100644 --- a/osu.Game/Overlays/Wiki/WikiPanelContainer.cs +++ b/osu.Game/Overlays/Wiki/WikiPanelContainer.cs @@ -22,7 +22,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Wiki { - public class WikiPanelContainer : Container + public partial class WikiPanelContainer : Container { private WikiPanelMarkdownContainer panelContainer; @@ -78,7 +78,7 @@ namespace osu.Game.Overlays.Wiki Height = Math.Max(panelContainer.Height, Parent.DrawHeight); } - private class WikiPanelMarkdownContainer : WikiMarkdownContainer + private partial class WikiPanelMarkdownContainer : WikiMarkdownContainer { private readonly bool isFullWidth; @@ -104,7 +104,7 @@ namespace osu.Game.Overlays.Wiki }; } - private class WikiPanelHeading : OsuMarkdownHeading + private partial class WikiPanelHeading : OsuMarkdownHeading { public bool IsFullWidth; diff --git a/osu.Game/Overlays/Wiki/WikiSidebar.cs b/osu.Game/Overlays/Wiki/WikiSidebar.cs index 78ce9c8a24..4c8fe83703 100644 --- a/osu.Game/Overlays/Wiki/WikiSidebar.cs +++ b/osu.Game/Overlays/Wiki/WikiSidebar.cs @@ -15,7 +15,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Wiki { - public class WikiSidebar : OverlaySidebar + public partial class WikiSidebar : OverlaySidebar { private WikiTableOfContents tableOfContents; diff --git a/osu.Game/Overlays/Wiki/WikiTableOfContents.cs b/osu.Game/Overlays/Wiki/WikiTableOfContents.cs index d60d728aca..5566233c39 100644 --- a/osu.Game/Overlays/Wiki/WikiTableOfContents.cs +++ b/osu.Game/Overlays/Wiki/WikiTableOfContents.cs @@ -13,7 +13,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Overlays.Wiki { - public class WikiTableOfContents : CompositeDrawable + public partial class WikiTableOfContents : CompositeDrawable { private readonly FillFlowContainer content; @@ -54,7 +54,7 @@ namespace osu.Game.Overlays.Wiki content.Add(lastMainTitle = entry.With(d => d.Margin = new MarginPadding { Bottom = 5 })); } - private class TableOfContentsEntry : OsuHoverContainer + private partial class TableOfContentsEntry : OsuHoverContainer { private readonly MarkdownHeading target; diff --git a/osu.Game/Overlays/WikiOverlay.cs b/osu.Game/Overlays/WikiOverlay.cs index 148d2977c7..a06c180948 100644 --- a/osu.Game/Overlays/WikiOverlay.cs +++ b/osu.Game/Overlays/WikiOverlay.cs @@ -17,7 +17,7 @@ using osu.Game.Overlays.Wiki; namespace osu.Game.Overlays { - public class WikiOverlay : OnlineOverlay + public partial class WikiOverlay : OnlineOverlay { private const string index_path = @"main_page"; diff --git a/osu.Game/PerformFromMenuRunner.cs b/osu.Game/PerformFromMenuRunner.cs index 158350b43d..21beadf366 100644 --- a/osu.Game/PerformFromMenuRunner.cs +++ b/osu.Game/PerformFromMenuRunner.cs @@ -18,7 +18,7 @@ using osu.Game.Screens.Menu; namespace osu.Game { - internal class PerformFromMenuRunner : Component + internal partial class PerformFromMenuRunner : Component { private readonly Action finalAction; private readonly Type[] validScreens; diff --git a/osu.Game/Performance/HighPerformanceSession.cs b/osu.Game/Performance/HighPerformanceSession.cs index dd5de03077..c113e7a342 100644 --- a/osu.Game/Performance/HighPerformanceSession.cs +++ b/osu.Game/Performance/HighPerformanceSession.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Play; namespace osu.Game.Performance { - public class HighPerformanceSession : Component + public partial class HighPerformanceSession : Component { private readonly IBindable localUserPlaying = new Bindable(); diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index b0a2694a0a..0df481737e 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Edit /// Represents a for rulesets with the concept of distances between objects. /// /// The base type of supported objects. - public abstract class DistancedHitObjectComposer : HitObjectComposer, IDistanceSnapProvider, IScrollBindingHandler + public abstract partial class DistancedHitObjectComposer : HitObjectComposer, IDistanceSnapProvider, IScrollBindingHandler where TObject : HitObject { private const float adjust_step = 0.1f; @@ -297,7 +297,7 @@ namespace osu.Game.Rulesets.Edit return DurationToDistance(referenceObject, snappedEndTime - startTime); } - private class DistanceSpacingToast : Toast + private partial class DistanceSpacingToast : Toast { private readonly ValueChangedEvent change; diff --git a/osu.Game/Rulesets/Edit/DrawableEditorRulesetWrapper.cs b/osu.Game/Rulesets/Edit/DrawableEditorRulesetWrapper.cs index 9588a092a8..20ee409937 100644 --- a/osu.Game/Rulesets/Edit/DrawableEditorRulesetWrapper.cs +++ b/osu.Game/Rulesets/Edit/DrawableEditorRulesetWrapper.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Edit /// /// A wrapper for a . Handles adding visual representations of s to the underlying . /// - internal class DrawableEditorRulesetWrapper : CompositeDrawable + internal partial class DrawableEditorRulesetWrapper : CompositeDrawable where TObject : HitObject { public Playfield Playfield => drawableRuleset.Playfield; diff --git a/osu.Game/Rulesets/Edit/EditorToolboxGroup.cs b/osu.Game/Rulesets/Edit/EditorToolboxGroup.cs index 7dcc90b16d..312ba62b61 100644 --- a/osu.Game/Rulesets/Edit/EditorToolboxGroup.cs +++ b/osu.Game/Rulesets/Edit/EditorToolboxGroup.cs @@ -8,7 +8,7 @@ using osu.Game.Overlays; namespace osu.Game.Rulesets.Edit { - public class EditorToolboxGroup : SettingsToolboxGroup + public partial class EditorToolboxGroup : SettingsToolboxGroup { public EditorToolboxGroup(string title) : base(title) diff --git a/osu.Game/Rulesets/Edit/ExpandableButton.cs b/osu.Game/Rulesets/Edit/ExpandableButton.cs index a66600bd58..d512aa287a 100644 --- a/osu.Game/Rulesets/Edit/ExpandableButton.cs +++ b/osu.Game/Rulesets/Edit/ExpandableButton.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Rulesets.Edit { - internal class ExpandableButton : RoundedButton, IExpandable + internal partial class ExpandableButton : RoundedButton, IExpandable { private float actualHeight; diff --git a/osu.Game/Rulesets/Edit/ExpandingToolboxContainer.cs b/osu.Game/Rulesets/Edit/ExpandingToolboxContainer.cs index 26dd5dfa55..7bf10f6beb 100644 --- a/osu.Game/Rulesets/Edit/ExpandingToolboxContainer.cs +++ b/osu.Game/Rulesets/Edit/ExpandingToolboxContainer.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Rulesets.Edit { - public class ExpandingToolboxContainer : ExpandingContainer + public partial class ExpandingToolboxContainer : ExpandingContainer { protected override double HoverExpansionDelay => 250; diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 520fcb0290..aff242d63f 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Edit /// Responsible for providing snapping and generally gluing components together. /// /// The base type of supported objects. - public abstract class HitObjectComposer : HitObjectComposer, IPlacementHandler + public abstract partial class HitObjectComposer : HitObjectComposer, IPlacementHandler where TObject : HitObject { protected IRulesetConfigManager Config { get; private set; } @@ -417,7 +417,7 @@ namespace osu.Game.Rulesets.Edit /// Generally used to access certain methods without requiring a generic type for . /// [Cached] - public abstract class HitObjectComposer : CompositeDrawable, IPositionSnapProvider + public abstract partial class HitObjectComposer : CompositeDrawable, IPositionSnapProvider { protected HitObjectComposer() { diff --git a/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs b/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs index 408fbfc04f..93b889792b 100644 --- a/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Rulesets.Edit { - public abstract class HitObjectSelectionBlueprint : SelectionBlueprint + public abstract partial class HitObjectSelectionBlueprint : SelectionBlueprint { /// /// The which this applies to. @@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Edit public override Quad SelectionQuad => DrawableObject.ScreenSpaceDrawQuad; } - public abstract class HitObjectSelectionBlueprint : HitObjectSelectionBlueprint + public abstract partial class HitObjectSelectionBlueprint : HitObjectSelectionBlueprint where T : HitObject { public T HitObject => (T)Item; diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs index c8196b6865..dd8dd93d66 100644 --- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs +++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Edit /// /// A blueprint which governs the creation of a new to actualisation. /// - public abstract class PlacementBlueprint : CompositeDrawable + public abstract partial class PlacementBlueprint : CompositeDrawable { /// /// Whether the is currently mid-placement, but has not necessarily finished being placed. diff --git a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs index fc24b55d21..4e0e45e0f5 100644 --- a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Edit /// /// A blueprint placed above a displaying item adding editing functionality. /// - public abstract class SelectionBlueprint : CompositeDrawable, IStateful + public abstract partial class SelectionBlueprint : CompositeDrawable, IStateful { public readonly T Item; diff --git a/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs b/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs index c2b27d4ce8..2b8bd08ede 100644 --- a/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs +++ b/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Rulesets.Judgements { - public class DefaultJudgementPiece : CompositeDrawable, IAnimatableJudgement + public partial class DefaultJudgementPiece : CompositeDrawable, IAnimatableJudgement { protected readonly HitResult Result; diff --git a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs index 48955c729f..15434fcc04 100644 --- a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs +++ b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Judgements /// /// A drawable object which visualises the hit result of a . /// - public class DrawableJudgement : PoolableDrawable + public partial class DrawableJudgement : PoolableDrawable { private const float judgement_size = 128; diff --git a/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs b/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs index 599e81f2b8..9d9c10b3ea 100644 --- a/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs +++ b/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs @@ -15,7 +15,7 @@ using osu.Game.Overlays.Settings; namespace osu.Game.Rulesets.Mods { - public class DifficultyAdjustSettingsControl : SettingsItem + public partial class DifficultyAdjustSettingsControl : SettingsItem { [Resolved] private IBindable beatmap { get; set; } @@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.Mods isInternalChange = false; } - private class SliderControl : CompositeDrawable, IHasCurrentValue + private partial class SliderControl : CompositeDrawable, IHasCurrentValue { // This is required as SettingsItem relies heavily on this bindable for internal use. // The actual update flow is done via the bindable provided in the constructor. diff --git a/osu.Game/Rulesets/Mods/MetronomeBeat.cs b/osu.Game/Rulesets/Mods/MetronomeBeat.cs index 149af1e30a..265970ea46 100644 --- a/osu.Game/Rulesets/Mods/MetronomeBeat.cs +++ b/osu.Game/Rulesets/Mods/MetronomeBeat.cs @@ -11,7 +11,7 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Mods { - public class MetronomeBeat : BeatSyncedContainer, IAdjustableAudioComponent + public partial class MetronomeBeat : BeatSyncedContainer, IAdjustableAudioComponent { private readonly double firstHitTime; diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index d58a901154..45fa55c7f2 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Mods public abstract float DefaultFlashlightSize { get; } } - public abstract class ModFlashlight : ModFlashlight, IApplicableToDrawableRuleset, IApplicableToScoreProcessor + public abstract partial class ModFlashlight : ModFlashlight, IApplicableToDrawableRuleset, IApplicableToScoreProcessor where T : HitObject { public const double FLASHLIGHT_FADE_DURATION = 800; @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Mods protected abstract Flashlight CreateFlashlight(); - public abstract class Flashlight : Drawable + public abstract partial class Flashlight : Drawable { public readonly BindableInt Combo = new BindableInt(); diff --git a/osu.Game/Rulesets/Mods/ModMuted.cs b/osu.Game/Rulesets/Mods/ModMuted.cs index 27a777bff7..59c4cfa85b 100644 --- a/osu.Game/Rulesets/Mods/ModMuted.cs +++ b/osu.Game/Rulesets/Mods/ModMuted.cs @@ -94,7 +94,7 @@ namespace osu.Game.Rulesets.Mods public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank; } - public class MuteComboSlider : OsuSliderBar + public partial class MuteComboSlider : OsuSliderBar { public override LocalisableString TooltipText => Current.Value == 0 ? "always muted" : base.TooltipText; } diff --git a/osu.Game/Rulesets/Mods/ModNightcore.cs b/osu.Game/Rulesets/Mods/ModNightcore.cs index 099bf386f3..9b1f7d5cf7 100644 --- a/osu.Game/Rulesets/Mods/ModNightcore.cs +++ b/osu.Game/Rulesets/Mods/ModNightcore.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mods public override LocalisableString Description => "Uguuuuuuuu..."; } - public abstract class ModNightcore : ModNightcore, IApplicableToDrawableRuleset + public abstract partial class ModNightcore : ModNightcore, IApplicableToDrawableRuleset where TObject : HitObject { private readonly BindableNumber tempoAdjust = new BindableDouble(1); @@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Mods drawableRuleset.Overlays.Add(new NightcoreBeatContainer()); } - public class NightcoreBeatContainer : BeatSyncedContainer + public partial class NightcoreBeatContainer : BeatSyncedContainer { private PausableSkinnableSound? hatSample; private PausableSkinnableSound? clapSample; diff --git a/osu.Game/Rulesets/Mods/ModNoScope.cs b/osu.Game/Rulesets/Mods/ModNoScope.cs index 36fbb88943..cfac44066e 100644 --- a/osu.Game/Rulesets/Mods/ModNoScope.cs +++ b/osu.Game/Rulesets/Mods/ModNoScope.cs @@ -62,7 +62,7 @@ namespace osu.Game.Rulesets.Mods } } - public class HiddenComboSlider : OsuSliderBar + public partial class HiddenComboSlider : OsuSliderBar { public override LocalisableString TooltipText => Current.Value == 0 ? "always hidden" : base.TooltipText; } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 60792445cd..d6c151028e 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -30,7 +30,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Objects.Drawables { [Cached(typeof(DrawableHitObject))] - public abstract class DrawableHitObject : PoolableDrawableWithLifetime + public abstract partial class DrawableHitObject : PoolableDrawableWithLifetime { /// /// Invoked after this 's applied has had its defaults applied. @@ -745,7 +745,7 @@ namespace osu.Game.Rulesets.Objects.Drawables } } - public abstract class DrawableHitObject : DrawableHitObject + public abstract partial class DrawableHitObject : DrawableHitObject where TObject : HitObject { public new TObject HitObject => (TObject)base.HitObject; diff --git a/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs b/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs index 8dc588da9e..a06f810cfe 100644 --- a/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs +++ b/osu.Game/Rulesets/Objects/Pooling/PoolableDrawableWithLifetime.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Objects.Pooling /// A that is controlled by to implement drawable pooling and replay rewinding. /// /// The type storing state and controlling this drawable. - public abstract class PoolableDrawableWithLifetime : PoolableDrawable where TEntry : LifetimeEntry + public abstract partial class PoolableDrawableWithLifetime : PoolableDrawable where TEntry : LifetimeEntry { private TEntry? entry; diff --git a/osu.Game/Rulesets/Objects/Pooling/PooledDrawableWithLifetimeContainer.cs b/osu.Game/Rulesets/Objects/Pooling/PooledDrawableWithLifetimeContainer.cs index d5b4390ce8..3b45acc7bb 100644 --- a/osu.Game/Rulesets/Objects/Pooling/PooledDrawableWithLifetimeContainer.cs +++ b/osu.Game/Rulesets/Objects/Pooling/PooledDrawableWithLifetimeContainer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Objects.Pooling /// /// The type of entries managed by this container. /// The type of drawables corresponding to the entries. - public abstract class PooledDrawableWithLifetimeContainer : CompositeDrawable + public abstract partial class PooledDrawableWithLifetimeContainer : CompositeDrawable where TEntry : LifetimeEntry where TDrawable : Drawable { diff --git a/osu.Game/Rulesets/RulesetConfigCache.cs b/osu.Game/Rulesets/RulesetConfigCache.cs index ab44e86048..79dff37280 100644 --- a/osu.Game/Rulesets/RulesetConfigCache.cs +++ b/osu.Game/Rulesets/RulesetConfigCache.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Configuration; namespace osu.Game.Rulesets { - public class RulesetConfigCache : Component, IRulesetConfigCache + public partial class RulesetConfigCache : Component, IRulesetConfigCache { private readonly RealmAccess realm; private readonly RulesetStore rulesets; diff --git a/osu.Game/Rulesets/RulesetSelector.cs b/osu.Game/Rulesets/RulesetSelector.cs index 701e60eec9..062f8d6450 100644 --- a/osu.Game/Rulesets/RulesetSelector.cs +++ b/osu.Game/Rulesets/RulesetSelector.cs @@ -9,7 +9,7 @@ using osu.Framework.Logging; namespace osu.Game.Rulesets { - public abstract class RulesetSelector : TabControl + public abstract partial class RulesetSelector : TabControl { [Resolved] protected RulesetStore Rulesets { get; private set; } diff --git a/osu.Game/Rulesets/Scoring/AccumulatingHealthProcessor.cs b/osu.Game/Rulesets/Scoring/AccumulatingHealthProcessor.cs index c6b9d227af..af6e825b06 100644 --- a/osu.Game/Rulesets/Scoring/AccumulatingHealthProcessor.cs +++ b/osu.Game/Rulesets/Scoring/AccumulatingHealthProcessor.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Scoring /// A that accumulates health and causes a fail if the final health /// is less than a value required to pass the beatmap. /// - public class AccumulatingHealthProcessor : HealthProcessor + public partial class AccumulatingHealthProcessor : HealthProcessor { protected override bool DefaultFailCondition => JudgedHits == MaxHits && Health.Value < requiredHealth; diff --git a/osu.Game/Rulesets/Scoring/DrainingHealthProcessor.cs b/osu.Game/Rulesets/Scoring/DrainingHealthProcessor.cs index 65af161393..d94c6dd2e0 100644 --- a/osu.Game/Rulesets/Scoring/DrainingHealthProcessor.cs +++ b/osu.Game/Rulesets/Scoring/DrainingHealthProcessor.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Scoring /// At HP=5, the minimum health reached for a perfect play is 70%.
/// At HP=10, the minimum health reached for a perfect play is 30%. ///
- public class DrainingHealthProcessor : HealthProcessor + public partial class DrainingHealthProcessor : HealthProcessor { /// /// A reasonable allowable error for the minimum health offset from . A 1% error is unnoticeable. diff --git a/osu.Game/Rulesets/Scoring/HealthProcessor.cs b/osu.Game/Rulesets/Scoring/HealthProcessor.cs index 0a1e6b729f..cdfe71943e 100644 --- a/osu.Game/Rulesets/Scoring/HealthProcessor.cs +++ b/osu.Game/Rulesets/Scoring/HealthProcessor.cs @@ -8,7 +8,7 @@ using osu.Game.Rulesets.Judgements; namespace osu.Game.Rulesets.Scoring { - public abstract class HealthProcessor : JudgementProcessor + public abstract partial class HealthProcessor : JudgementProcessor { /// /// Invoked when the is in a failed state. diff --git a/osu.Game/Rulesets/Scoring/JudgementProcessor.cs b/osu.Game/Rulesets/Scoring/JudgementProcessor.cs index bc8f2c22f3..09b5f0a6bc 100644 --- a/osu.Game/Rulesets/Scoring/JudgementProcessor.cs +++ b/osu.Game/Rulesets/Scoring/JudgementProcessor.cs @@ -13,7 +13,7 @@ using osu.Game.Rulesets.Replays; namespace osu.Game.Rulesets.Scoring { - public abstract class JudgementProcessor : Component + public abstract partial class JudgementProcessor : Component { /// /// Invoked when a new judgement has occurred. This occurs after the judgement has been processed by this . diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 899d149cbc..29c37c31d5 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -21,7 +21,7 @@ using osu.Game.Localisation; namespace osu.Game.Rulesets.Scoring { - public class ScoreProcessor : JudgementProcessor + public partial class ScoreProcessor : JudgementProcessor { private const double max_score = 1000000; diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index dd3a950264..71b452c309 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.UI /// Displays an interactive ruleset gameplay instance. /// /// The type of HitObject contained by this DrawableRuleset. - public abstract class DrawableRuleset : DrawableRuleset, IProvideCursor, ICanAttachHUDPieces + public abstract partial class DrawableRuleset : DrawableRuleset, IProvideCursor, ICanAttachHUDPieces where TObject : HitObject { public override event Action NewResult; @@ -414,7 +414,7 @@ namespace osu.Game.Rulesets.UI /// /// [Cached(typeof(DrawableRuleset))] - public abstract class DrawableRuleset : CompositeDrawable + public abstract partial class DrawableRuleset : CompositeDrawable { /// /// Invoked when a has been applied by a . diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs index 3b35fba122..4bb145973d 100644 --- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs +++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.UI /// [Cached(typeof(IGameplayClock))] [Cached(typeof(IFrameStableClock))] - public sealed class FrameStabilityContainer : Container, IHasReplayHandler, IFrameStableClock + public sealed partial class FrameStabilityContainer : Container, IHasReplayHandler, IFrameStableClock { public ReplayInputHandler? ReplayInputHandler { get; set; } diff --git a/osu.Game/Rulesets/UI/GameplayCursorContainer.cs b/osu.Game/Rulesets/UI/GameplayCursorContainer.cs index 3149b7f890..cbce397d1e 100644 --- a/osu.Game/Rulesets/UI/GameplayCursorContainer.cs +++ b/osu.Game/Rulesets/UI/GameplayCursorContainer.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Cursor; namespace osu.Game.Rulesets.UI { - public class GameplayCursorContainer : CursorContainer + public partial class GameplayCursorContainer : CursorContainer { /// /// Because Show/Hide are executed by a parent, is updated immediately even if the cursor diff --git a/osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs b/osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs index fd8fcfddab..d068f8d016 100644 --- a/osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs +++ b/osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.UI /// /// A component which can trigger the most appropriate hit sound for a given point in time, based on the state of a /// - public class GameplaySampleTriggerSource : CompositeDrawable + public partial class GameplaySampleTriggerSource : CompositeDrawable { /// /// The number of concurrent samples allowed to be played concurrently so that it feels better when spam-pressing a key. diff --git a/osu.Game/Rulesets/UI/HitObjectContainer.cs b/osu.Game/Rulesets/UI/HitObjectContainer.cs index bbced9e58c..7cbf49aa31 100644 --- a/osu.Game/Rulesets/UI/HitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/HitObjectContainer.cs @@ -17,7 +17,7 @@ using osu.Game.Rulesets.Objects.Pooling; namespace osu.Game.Rulesets.UI { - public class HitObjectContainer : PooledDrawableWithLifetimeContainer, IHitObjectContainer + public partial class HitObjectContainer : PooledDrawableWithLifetimeContainer, IHitObjectContainer { public IEnumerable Objects => InternalChildren.Cast().OrderBy(h => h.HitObject.StartTime); diff --git a/osu.Game/Rulesets/UI/JudgementContainer.cs b/osu.Game/Rulesets/UI/JudgementContainer.cs index 471a62cab3..8381e6d6b5 100644 --- a/osu.Game/Rulesets/UI/JudgementContainer.cs +++ b/osu.Game/Rulesets/UI/JudgementContainer.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Judgements; namespace osu.Game.Rulesets.UI { - public class JudgementContainer : Container + public partial class JudgementContainer : Container where T : DrawableJudgement { public override void Add(T judgement) diff --git a/osu.Game/Rulesets/UI/ModIcon.cs b/osu.Game/Rulesets/UI/ModIcon.cs index b1f355a789..bf212ad72f 100644 --- a/osu.Game/Rulesets/UI/ModIcon.cs +++ b/osu.Game/Rulesets/UI/ModIcon.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.UI /// /// Display the specified mod at a fixed size. /// - public class ModIcon : Container, IHasTooltip + public partial class ModIcon : Container, IHasTooltip { public readonly BindableBool Selected = new BindableBool(); diff --git a/osu.Game/Rulesets/UI/ModSwitchSmall.cs b/osu.Game/Rulesets/UI/ModSwitchSmall.cs index 1b777f3e88..b6058c16ce 100644 --- a/osu.Game/Rulesets/UI/ModSwitchSmall.cs +++ b/osu.Game/Rulesets/UI/ModSwitchSmall.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.UI { - public class ModSwitchSmall : CompositeDrawable + public partial class ModSwitchSmall : CompositeDrawable { public BindableBool Active { get; } = new BindableBool(); diff --git a/osu.Game/Rulesets/UI/ModSwitchTiny.cs b/osu.Game/Rulesets/UI/ModSwitchTiny.cs index 1bb0fe535f..a5cf75bd07 100644 --- a/osu.Game/Rulesets/UI/ModSwitchTiny.cs +++ b/osu.Game/Rulesets/UI/ModSwitchTiny.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.UI { - public class ModSwitchTiny : CompositeDrawable + public partial class ModSwitchTiny : CompositeDrawable { public BindableBool Active { get; } = new BindableBool(); diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index e59e45722a..859be6e210 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.UI { [Cached(typeof(IPooledHitObjectProvider))] [Cached(typeof(IPooledSampleProvider))] - public abstract class Playfield : CompositeDrawable, IPooledHitObjectProvider, IPooledSampleProvider + public abstract partial class Playfield : CompositeDrawable, IPooledHitObjectProvider, IPooledSampleProvider { /// /// Invoked when a is judged. @@ -427,7 +427,7 @@ namespace osu.Game.Rulesets.UI return pool; } - private class DrawableSamplePool : DrawablePool + private partial class DrawableSamplePool : DrawablePool { private readonly ISampleInfo sampleInfo; diff --git a/osu.Game/Rulesets/UI/PlayfieldAdjustmentContainer.cs b/osu.Game/Rulesets/UI/PlayfieldAdjustmentContainer.cs index d0e79281a7..0f440adef8 100644 --- a/osu.Game/Rulesets/UI/PlayfieldAdjustmentContainer.cs +++ b/osu.Game/Rulesets/UI/PlayfieldAdjustmentContainer.cs @@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.UI /// /// A container which handles sizing of the and any other components that need to match their size. /// - public class PlayfieldAdjustmentContainer : Container + public partial class PlayfieldAdjustmentContainer : Container { public PlayfieldAdjustmentContainer() { diff --git a/osu.Game/Rulesets/UI/PlayfieldBorder.cs b/osu.Game/Rulesets/UI/PlayfieldBorder.cs index a129760ef3..211a87de84 100644 --- a/osu.Game/Rulesets/UI/PlayfieldBorder.cs +++ b/osu.Game/Rulesets/UI/PlayfieldBorder.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.UI /// /// Provides a border around the playfield. /// - public class PlayfieldBorder : CompositeDrawable + public partial class PlayfieldBorder : CompositeDrawable { public Bindable PlayfieldBorderStyle { get; } = new Bindable(); @@ -108,7 +108,7 @@ namespace osu.Game.Rulesets.UI } } - private class Line : Box + private partial class Line : Box { private readonly Direction direction; diff --git a/osu.Game/Rulesets/UI/ReplayRecorder.cs b/osu.Game/Rulesets/UI/ReplayRecorder.cs index 79da56fc8a..28e25c72e1 100644 --- a/osu.Game/Rulesets/UI/ReplayRecorder.cs +++ b/osu.Game/Rulesets/UI/ReplayRecorder.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Rulesets.UI { - public abstract class ReplayRecorder : ReplayRecorder, IKeyBindingHandler + public abstract partial class ReplayRecorder : ReplayRecorder, IKeyBindingHandler where T : struct { private readonly Score target; @@ -94,7 +94,7 @@ namespace osu.Game.Rulesets.UI protected abstract ReplayFrame HandleFrame(Vector2 mousePosition, List actions, ReplayFrame previousFrame); } - public abstract class ReplayRecorder : Component + public abstract partial class ReplayRecorder : Component { public Func ScreenSpaceToGamefield; } diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index 64ac021204..a5e442b7de 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -25,7 +25,7 @@ using static osu.Game.Input.Handlers.ReplayInputHandler; namespace osu.Game.Rulesets.UI { - public abstract class RulesetInputManager : PassThroughInputManager, ICanAttachHUDPieces, IHasReplayHandler, IHasRecordingHandler + public abstract partial class RulesetInputManager : PassThroughInputManager, ICanAttachHUDPieces, IHasReplayHandler, IHasRecordingHandler where T : struct { public readonly KeyBindingContainer KeyBindingContainer; @@ -169,7 +169,7 @@ namespace osu.Game.Rulesets.UI .Select(action => new KeyCounterAction(action))); } - private class ActionReceptor : KeyCounterDisplay.Receptor, IKeyBindingHandler + private partial class ActionReceptor : KeyCounterDisplay.Receptor, IKeyBindingHandler { public ActionReceptor(KeyCounterDisplay target) : base(target) @@ -196,7 +196,7 @@ namespace osu.Game.Rulesets.UI KeyBindingContainer.Add(listener); } - private class ActionListener : Component, IKeyBindingHandler + private partial class ActionListener : Component, IKeyBindingHandler { private readonly ClicksPerSecondCalculator calculator; @@ -221,7 +221,7 @@ namespace osu.Game.Rulesets.UI protected virtual KeyBindingContainer CreateKeyBindingContainer(RulesetInfo ruleset, int variant, SimultaneousBindingMode unique) => new RulesetKeyBindingContainer(ruleset, variant, unique); - public class RulesetKeyBindingContainer : DatabasedKeyBindingContainer + public partial class RulesetKeyBindingContainer : DatabasedKeyBindingContainer { protected override bool HandleRepeats => false; diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs index 2cb57966e7..52853d3979 100644 --- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.UI.Scrolling /// A type of that supports a . /// s inside this will scroll within the playfield. /// - public abstract class DrawableScrollingRuleset : DrawableRuleset, IDrawableScrollingRuleset, IKeyBindingHandler + public abstract partial class DrawableScrollingRuleset : DrawableRuleset, IDrawableScrollingRuleset, IKeyBindingHandler where TObject : HitObject { /// diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 424fc7c44c..3559a1521c 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Rulesets.UI.Scrolling { - public class ScrollingHitObjectContainer : HitObjectContainer + public partial class ScrollingHitObjectContainer : HitObjectContainer { private readonly IBindable timeRange = new BindableDouble(); private readonly IBindable direction = new Bindable(); diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs index 34e5b7f9de..7d141113df 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.UI.Scrolling /// /// A type of specialized towards scrolling s. /// - public abstract class ScrollingPlayfield : Playfield + public abstract partial class ScrollingPlayfield : Playfield { protected readonly IBindable Direction = new Bindable(); diff --git a/osu.Game/Scoring/Drawables/UnprocessedPerformancePointsPlaceholder.cs b/osu.Game/Scoring/Drawables/UnprocessedPerformancePointsPlaceholder.cs index 6087ca9eb9..99eb7e964d 100644 --- a/osu.Game/Scoring/Drawables/UnprocessedPerformancePointsPlaceholder.cs +++ b/osu.Game/Scoring/Drawables/UnprocessedPerformancePointsPlaceholder.cs @@ -13,7 +13,7 @@ namespace osu.Game.Scoring.Drawables /// /// A placeholder used in PP columns for scores with unprocessed PP value. /// - public class UnprocessedPerformancePointsPlaceholder : SpriteIcon, IHasTooltip + public partial class UnprocessedPerformancePointsPlaceholder : SpriteIcon, IHasTooltip { public LocalisableString TooltipText => ScoresStrings.StatusProcessing; diff --git a/osu.Game/Scoring/ScorePerformanceCache.cs b/osu.Game/Scoring/ScorePerformanceCache.cs index f51fb41497..17a0c0ea6a 100644 --- a/osu.Game/Scoring/ScorePerformanceCache.cs +++ b/osu.Game/Scoring/ScorePerformanceCache.cs @@ -18,7 +18,7 @@ namespace osu.Game.Scoring /// A component which performs and acts as a central cache for performance calculations of locally databased scores. /// Currently not persisted between game sessions. /// - public class ScorePerformanceCache : MemoryCachingComponent + public partial class ScorePerformanceCache : MemoryCachingComponent { [Resolved] private BeatmapDifficultyCache difficultyCache { get; set; } diff --git a/osu.Game/Screens/BackgroundScreen.cs b/osu.Game/Screens/BackgroundScreen.cs index 8e1fd63040..a7502f22d5 100644 --- a/osu.Game/Screens/BackgroundScreen.cs +++ b/osu.Game/Screens/BackgroundScreen.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Screens { - public abstract class BackgroundScreen : Screen, IEquatable + public abstract partial class BackgroundScreen : Screen, IEquatable { protected const float TRANSITION_LENGTH = 500; private const float x_movement_amount = 50; diff --git a/osu.Game/Screens/BackgroundScreenStack.cs b/osu.Game/Screens/BackgroundScreenStack.cs index bafd1ff348..ca0dad83c8 100644 --- a/osu.Game/Screens/BackgroundScreenStack.cs +++ b/osu.Game/Screens/BackgroundScreenStack.cs @@ -9,7 +9,7 @@ using osu.Framework.Screens; namespace osu.Game.Screens { - public class BackgroundScreenStack : ScreenStack + public partial class BackgroundScreenStack : ScreenStack { public BackgroundScreenStack() : base(false) diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs index 4d84a8194d..42a81ad3fa 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Screens.Backgrounds { - public class BackgroundScreenBeatmap : BackgroundScreen + public partial class BackgroundScreenBeatmap : BackgroundScreen { /// /// The amount of blur to apply when full user blur is requested. @@ -122,7 +122,7 @@ namespace osu.Game.Screens.Backgrounds return base.Equals(other) && beatmap == otherBeatmapBackground.Beatmap; } - public class DimmableBackground : UserDimContainer + public partial class DimmableBackground : UserDimContainer { /// /// The amount of blur to be applied to the background in addition to user-specified blur. diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenBlack.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenBlack.cs index 4b0f262ab1..09778c5cdf 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenBlack.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenBlack.cs @@ -10,7 +10,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Backgrounds { - public class BackgroundScreenBlack : BackgroundScreen + public partial class BackgroundScreenBlack : BackgroundScreen { public BackgroundScreenBlack() { diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenCustom.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenCustom.cs index 3dd72685e9..3c8ed6fe76 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenCustom.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenCustom.cs @@ -7,7 +7,7 @@ using osu.Game.Graphics.Backgrounds; namespace osu.Game.Screens.Backgrounds { - public class BackgroundScreenCustom : BackgroundScreen + public partial class BackgroundScreenCustom : BackgroundScreen { private readonly string textureName; diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs index 44b6fcce4a..0d9b39f099 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs @@ -19,7 +19,7 @@ using osu.Game.Skinning; namespace osu.Game.Screens.Backgrounds { - public class BackgroundScreenDefault : BackgroundScreen + public partial class BackgroundScreenDefault : BackgroundScreen { private Background background; diff --git a/osu.Game/Screens/Edit/BottomBar.cs b/osu.Game/Screens/Edit/BottomBar.cs index 444911cf2d..b8fed4b935 100644 --- a/osu.Game/Screens/Edit/BottomBar.cs +++ b/osu.Game/Screens/Edit/BottomBar.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Edit { - internal class BottomBar : CompositeDrawable + internal partial class BottomBar : CompositeDrawable { public TestGameplayButton TestGameplayButton { get; private set; } diff --git a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs index 482a0bbe5f..32ec3b6833 100644 --- a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs +++ b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Edit.Components { - public class BottomBarContainer : Container + public partial class BottomBarContainer : Container { private const float contents_padding = 15; diff --git a/osu.Game/Screens/Edit/Components/EditorSidebar.cs b/osu.Game/Screens/Edit/Components/EditorSidebar.cs index da15512cdc..cfcfcd75e6 100644 --- a/osu.Game/Screens/Edit/Components/EditorSidebar.cs +++ b/osu.Game/Screens/Edit/Components/EditorSidebar.cs @@ -16,7 +16,7 @@ namespace osu.Game.Screens.Edit.Components /// A sidebar area that can be attached to the left or right edge of the screen. /// Houses scrolling sectionised content. /// - internal class EditorSidebar : Container + internal partial class EditorSidebar : Container { public const float WIDTH = 250; diff --git a/osu.Game/Screens/Edit/Components/EditorSidebarSection.cs b/osu.Game/Screens/Edit/Components/EditorSidebarSection.cs index 6782b2f357..4e8c55efa1 100644 --- a/osu.Game/Screens/Edit/Components/EditorSidebarSection.cs +++ b/osu.Game/Screens/Edit/Components/EditorSidebarSection.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Components { - public class EditorSidebarSection : Container + public partial class EditorSidebarSection : Container { protected override Container Content { get; } @@ -41,7 +41,7 @@ namespace osu.Game.Screens.Edit.Components }; } - public class SectionHeader : CompositeDrawable + public partial class SectionHeader : CompositeDrawable { private readonly LocalisableString text; diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs b/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs index 20b8bba6da..a911b4e1d8 100644 --- a/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs +++ b/osu.Game/Screens/Edit/Components/Menus/EditorMenuBar.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Components.Menus { - public class EditorMenuBar : OsuMenu + public partial class EditorMenuBar : OsuMenu { public EditorMenuBar() : base(Direction.Horizontal, true) @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Edit.Components.Menus protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableEditorBarMenuItem(item); - private class DrawableEditorBarMenuItem : DrawableOsuMenuItem + private partial class DrawableEditorBarMenuItem : DrawableOsuMenuItem { public DrawableEditorBarMenuItem(MenuItem item) : base(item) @@ -75,7 +75,7 @@ namespace osu.Game.Screens.Edit.Components.Menus protected override DrawableOsuMenuItem.TextContainer CreateTextContainer() => new TextContainer(); - private new class TextContainer : DrawableOsuMenuItem.TextContainer + private new partial class TextContainer : DrawableOsuMenuItem.TextContainer { public TextContainer() { @@ -85,7 +85,7 @@ namespace osu.Game.Screens.Edit.Components.Menus } } - private class SubMenu : OsuMenu + private partial class SubMenu : OsuMenu { public SubMenu() : base(Direction.Vertical) @@ -118,7 +118,7 @@ namespace osu.Game.Screens.Edit.Components.Menus } } - private class EditorStatefulMenuItem : DrawableStatefulMenuItem + private partial class EditorStatefulMenuItem : DrawableStatefulMenuItem { public EditorStatefulMenuItem(StatefulMenuItem item) : base(item) @@ -135,7 +135,7 @@ namespace osu.Game.Screens.Edit.Components.Menus } } - private class EditorMenuItem : DrawableOsuMenuItem + private partial class EditorMenuItem : DrawableOsuMenuItem { public EditorMenuItem(MenuItem item) : base(item) @@ -152,7 +152,7 @@ namespace osu.Game.Screens.Edit.Components.Menus } } - private class DrawableSpacer : DrawableOsuMenuItem + private partial class DrawableSpacer : DrawableOsuMenuItem { public DrawableSpacer(MenuItem item) : base(item) diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs b/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs index 0bba5a79ab..e88138def4 100644 --- a/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs +++ b/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Components.Menus { - public class EditorScreenSwitcherControl : OsuTabControl + public partial class EditorScreenSwitcherControl : OsuTabControl { public EditorScreenSwitcherControl() { @@ -42,7 +42,7 @@ namespace osu.Game.Screens.Edit.Components.Menus protected override TabItem CreateTabItem(EditorScreenMode value) => new TabItem(value); - private class TabItem : OsuTabItem + private partial class TabItem : OsuTabItem { private const float transition_length = 250; diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs index 30316cb12c..f403551a62 100644 --- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs +++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs @@ -23,7 +23,7 @@ using osuTK.Input; namespace osu.Game.Screens.Edit.Components { - public class PlaybackControl : BottomBarContainer + public partial class PlaybackControl : BottomBarContainer { private IconButton playButton; @@ -102,7 +102,7 @@ namespace osu.Game.Screens.Edit.Components playButton.Icon = editorClock.IsRunning ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle; } - private class PlaybackTabControl : OsuTabControl + private partial class PlaybackTabControl : OsuTabControl { private static readonly double[] tempo_values = { 0.25, 0.5, 0.75, 1 }; @@ -120,7 +120,7 @@ namespace osu.Game.Screens.Edit.Components Current.Value = tempo_values.Last(); } - public class PlaybackTabItem : TabItem + public partial class PlaybackTabItem : TabItem { private const float fade_duration = 200; diff --git a/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButton.cs b/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButton.cs index 071bb9fdcb..bfcc0084bd 100644 --- a/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButton.cs +++ b/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButton.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Edit.Components.RadioButtons { - public class EditorRadioButton : OsuButton, IHasTooltip + public partial class EditorRadioButton : OsuButton, IHasTooltip { /// /// Invoked when this has been selected. diff --git a/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButtonCollection.cs b/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButtonCollection.cs index b8d1cca061..92dd47dc81 100644 --- a/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButtonCollection.cs +++ b/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButtonCollection.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Components.RadioButtons { - public class EditorRadioButtonCollection : CompositeDrawable + public partial class EditorRadioButtonCollection : CompositeDrawable { private IReadOnlyList items; diff --git a/osu.Game/Screens/Edit/Components/TernaryButtons/DrawableTernaryButton.cs b/osu.Game/Screens/Edit/Components/TernaryButtons/DrawableTernaryButton.cs index 1fb5c0285d..45b7cd1b7c 100644 --- a/osu.Game/Screens/Edit/Components/TernaryButtons/DrawableTernaryButton.cs +++ b/osu.Game/Screens/Edit/Components/TernaryButtons/DrawableTernaryButton.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Edit.Components.TernaryButtons { - internal class DrawableTernaryButton : OsuButton + internal partial class DrawableTernaryButton : OsuButton { private Color4 defaultBackgroundColour; private Color4 defaultIconColour; diff --git a/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs b/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs index 7051dd226c..1c16671ce4 100644 --- a/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs +++ b/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Components { - public class TimeInfoContainer : BottomBarContainer + public partial class TimeInfoContainer : BottomBarContainer { private OsuSpriteText trackTimer; private OsuSpriteText bpm; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs index 058aa83b97..f1023ade8c 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs @@ -12,7 +12,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts /// /// The part of the timeline that displays bookmarks. /// - public class BookmarkPart : TimelinePart + public partial class BookmarkPart : TimelinePart { protected override void LoadBeatmap(EditorBeatmap beatmap) { @@ -21,7 +21,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts Add(new BookmarkVisualisation(bookmark)); } - private class BookmarkVisualisation : PointVisualisation + private partial class BookmarkVisualisation : PointVisualisation { public BookmarkVisualisation(double startTime) : base(startTime) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs index 4dbec880dc..de5d074c51 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs @@ -13,7 +13,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts /// /// The part of the timeline that displays breaks in the song. /// - public class BreakPart : TimelinePart + public partial class BreakPart : TimelinePart { protected override void LoadBeatmap(EditorBeatmap beatmap) { @@ -22,7 +22,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts Add(new BreakVisualisation(breakPeriod)); } - private class BreakVisualisation : DurationVisualisation + private partial class BreakVisualisation : DurationVisualisation { public BreakVisualisation(BreakPeriod breakPeriod) : base(breakPeriod.StartTime, breakPeriod.EndTime) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs index 54ef5a2bd7..2d26e6f90b 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs @@ -14,7 +14,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts /// /// The part of the timeline that displays the control points. /// - public class ControlPointPart : TimelinePart + public partial class ControlPointPart : TimelinePart { private readonly IBindableList controlPointGroups = new BindableList(); diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointVisualisation.cs index 89c0309222..aa494271f8 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointVisualisation.cs @@ -11,7 +11,7 @@ using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations; namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { - public class ControlPointVisualisation : PointVisualisation, IControlPointVisualisation + public partial class ControlPointVisualisation : PointVisualisation, IControlPointVisualisation { protected readonly ControlPoint Point; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/EffectPointVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/EffectPointVisualisation.cs index b61fcf4482..d92beba38a 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/EffectPointVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/EffectPointVisualisation.cs @@ -13,7 +13,7 @@ using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations; namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { - public class EffectPointVisualisation : CompositeDrawable, IControlPointVisualisation + public partial class EffectPointVisualisation : CompositeDrawable, IControlPointVisualisation { private readonly EffectControlPoint effect; private Bindable kiai = null!; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/GroupVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/GroupVisualisation.cs index e058cae191..64c0745596 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/GroupVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/GroupVisualisation.cs @@ -11,7 +11,7 @@ using osu.Game.Beatmaps.ControlPoints; namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { - public class GroupVisualisation : CompositeDrawable + public partial class GroupVisualisation : CompositeDrawable { public readonly ControlPointGroup Group; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs index c00ebb32bc..5be6db55a4 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts /// /// The part of the timeline that displays the current position of the song. /// - public class MarkerPart : TimelinePart + public partial class MarkerPart : TimelinePart { private Drawable marker; @@ -71,7 +71,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts // block base call so we don't clear our marker (can be reused on beatmap change). } - private class MarkerVisualisation : CompositeDrawable + private partial class MarkerVisualisation : CompositeDrawable { public MarkerVisualisation() { diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index bb5b4a6cea..e380a2063b 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -14,14 +14,14 @@ using osu.Game.Beatmaps; namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { - public class TimelinePart : TimelinePart + public partial class TimelinePart : TimelinePart { } /// /// Represents a part of the summary timeline.. /// - public class TimelinePart : Container where T : Drawable + public partial class TimelinePart : Container where T : Drawable { private readonly IBindable beatmap = new Bindable(); diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs index afaedee0a9..7f762b9d50 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs @@ -16,7 +16,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary /// /// The timeline that sits at the bottom of the editor. /// - public class SummaryTimeline : BottomBarContainer + public partial class SummaryTimeline : BottomBarContainer { [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs index d38596b9be..a3a003947c 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs @@ -13,7 +13,7 @@ using osu.Game.Overlays; namespace osu.Game.Screens.Edit.Components.Timelines.Summary { - public class TestGameplayButton : OsuButton + public partial class TestGameplayButton : OsuButton { protected override SpriteText CreateText() => new OsuSpriteText { diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs index 88e40cb305..6fc994b8b1 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs @@ -11,7 +11,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations /// /// Represents a spanning point on a timeline part. /// - public class DurationVisualisation : Circle + public partial class DurationVisualisation : Circle { protected DurationVisualisation(double startTime, double endTime) { diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs index b8e55c8db8..75dacdf3e7 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs @@ -11,7 +11,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations /// /// Represents a singular point on a timeline part. /// - public class PointVisualisation : Circle + public partial class PointVisualisation : Circle { public const float MAX_WIDTH = 4; diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs index 6dca799549..903c117422 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs @@ -29,7 +29,7 @@ using osuTK.Input; namespace osu.Game.Screens.Edit.Compose.Components { - public class BeatDivisorControl : CompositeDrawable + public partial class BeatDivisorControl : CompositeDrawable { private readonly BindableBeatDivisor beatDivisor = new BindableBeatDivisor(); @@ -220,7 +220,7 @@ namespace osu.Game.Screens.Edit.Compose.Components return base.OnKeyDown(e); } - internal class DivisorDisplay : OsuAnimatedButton, IHasPopover + internal partial class DivisorDisplay : OsuAnimatedButton, IHasPopover { public BindableBeatDivisor BeatDivisor { get; } = new BindableBeatDivisor(); @@ -270,7 +270,7 @@ namespace osu.Game.Screens.Edit.Compose.Components }; } - internal class CustomDivisorPopover : OsuPopover + internal partial class CustomDivisorPopover : OsuPopover { public BindableBeatDivisor BeatDivisor { get; } = new BindableBeatDivisor(); @@ -328,7 +328,7 @@ namespace osu.Game.Screens.Edit.Compose.Components } } - private class DivisorTypeText : OsuSpriteText + private partial class DivisorTypeText : OsuSpriteText { public BindableBeatDivisor BeatDivisor { get; } = new BindableBeatDivisor(); @@ -347,7 +347,7 @@ namespace osu.Game.Screens.Edit.Compose.Components } } - internal class ChevronButton : IconButton + internal partial class ChevronButton : IconButton { public ChevronButton() { @@ -370,7 +370,7 @@ namespace osu.Game.Screens.Edit.Compose.Components } } - private class TickSliderBar : SliderBar + private partial class TickSliderBar : SliderBar { private Marker marker; @@ -485,7 +485,7 @@ namespace osu.Game.Screens.Edit.Compose.Components private float getMappedPosition(float divisor) => MathF.Pow((divisor - 1) / (beatDivisor.ValidDivisors.Value.Presets.Last() - 1), 0.90f); - private class Tick : Circle + private partial class Tick : Circle { public Tick(int divisor) { @@ -494,7 +494,7 @@ namespace osu.Game.Screens.Edit.Compose.Components } } - private class Marker : CompositeDrawable + private partial class Marker : CompositeDrawable { [Resolved] private OverlayColourProvider colourProvider { get; set; } diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 43ad270c16..60fec5bcc6 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// A container which provides a "blueprint" display of items. /// Includes selection and manipulation support via a . /// - public abstract class BlueprintContainer : CompositeDrawable, IKeyBindingHandler + public abstract partial class BlueprintContainer : CompositeDrawable, IKeyBindingHandler where T : class { protected DragBox DragBox { get; private set; } diff --git a/osu.Game/Screens/Edit/Compose/Components/CircularDistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/CircularDistanceSnapGrid.cs index 6e54e98740..d6e4e1f030 100644 --- a/osu.Game/Screens/Edit/Compose/Components/CircularDistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/CircularDistanceSnapGrid.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Edit.Compose.Components { - public abstract class CircularDistanceSnapGrid : DistanceSnapGrid + public abstract partial class CircularDistanceSnapGrid : DistanceSnapGrid { protected CircularDistanceSnapGrid(HitObject referenceObject, Vector2 startPosition, double startTime, double? endTime = null) : base(referenceObject, startPosition, startTime, endTime) @@ -117,7 +117,7 @@ namespace osu.Game.Screens.Edit.Compose.Components return (snappedPosition, snappedTime); } - private class Ring : CircularProgress + private partial class Ring : CircularProgress { [Resolved] private IDistanceSnapProvider snapProvider { get; set; } diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index ec07da43a0..f955ae9cd6 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -29,7 +29,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// A blueprint container generally displayed as an overlay to a ruleset's playfield. /// - public class ComposeBlueprintContainer : EditorBlueprintContainer + public partial class ComposeBlueprintContainer : EditorBlueprintContainer { private readonly Container placementBlueprintContainer; diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs index c179e7f0c2..6092ebc08f 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs @@ -21,7 +21,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// A grid which takes user input and returns a quantized ("snapped") position and time. /// - public abstract class DistanceSnapGrid : CompositeDrawable + public abstract partial class DistanceSnapGrid : CompositeDrawable { /// /// The spacing between each tick of the beat snapping grid. diff --git a/osu.Game/Screens/Edit/Compose/Components/DragBox.cs b/osu.Game/Screens/Edit/Compose/Components/DragBox.cs index 905d47533a..4d1f81228e 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DragBox.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DragBox.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// A box that displays the drag selection and provides selection events for users to handle. /// - public class DragBox : CompositeDrawable, IStateful + public partial class DragBox : CompositeDrawable, IStateful { public Drawable Box { get; private set; } @@ -71,7 +71,7 @@ namespace osu.Game.Screens.Edit.Compose.Components public event Action StateChanged; - public class BoxWithBorders : CompositeDrawable + public partial class BoxWithBorders : CompositeDrawable { private readonly LayoutValue cache = new LayoutValue(Invalidation.RequiredParentSizeToFit); diff --git a/osu.Game/Screens/Edit/Compose/Components/EditorBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/EditorBlueprintContainer.cs index 7423b368b4..65797a968d 100644 --- a/osu.Game/Screens/Edit/Compose/Components/EditorBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/EditorBlueprintContainer.cs @@ -16,7 +16,7 @@ using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Screens.Edit.Compose.Components { - public class EditorBlueprintContainer : BlueprintContainer + public partial class EditorBlueprintContainer : BlueprintContainer { [Resolved] protected EditorClock EditorClock { get; private set; } diff --git a/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs index 0bdfc5b0a0..357cc940f2 100644 --- a/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs @@ -18,7 +18,7 @@ using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Screens.Edit.Compose.Components { - public class EditorSelectionHandler : SelectionHandler + public partial class EditorSelectionHandler : SelectionHandler { [Resolved] protected EditorBeatmap EditorBeatmap { get; private set; } diff --git a/osu.Game/Screens/Edit/Compose/Components/HitObjectOrderedSelectionContainer.cs b/osu.Game/Screens/Edit/Compose/Components/HitObjectOrderedSelectionContainer.cs index 18bb6284b8..849a526556 100644 --- a/osu.Game/Screens/Edit/Compose/Components/HitObjectOrderedSelectionContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/HitObjectOrderedSelectionContainer.cs @@ -15,7 +15,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// A container for ordered by their start times. /// - public sealed class HitObjectOrderedSelectionContainer : Container> + public sealed partial class HitObjectOrderedSelectionContainer : Container> { [Resolved] private EditorBeatmap editorBeatmap { get; set; } diff --git a/osu.Game/Screens/Edit/Compose/Components/RectangularPositionSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/RectangularPositionSnapGrid.cs index 64fb2ccaba..06b73c8af4 100644 --- a/osu.Game/Screens/Edit/Compose/Components/RectangularPositionSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/RectangularPositionSnapGrid.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Compose.Components { - public class RectangularPositionSnapGrid : CompositeDrawable + public partial class RectangularPositionSnapGrid : CompositeDrawable { /// /// The position of the origin of this in local coordinates. diff --git a/osu.Game/Screens/Edit/Compose/Components/ScrollingDragBox.cs b/osu.Game/Screens/Edit/Compose/Components/ScrollingDragBox.cs index 58bfaf56ff..599e64760d 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ScrollingDragBox.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ScrollingDragBox.cs @@ -11,7 +11,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// A that scrolls along with the scrolling playfield. /// - public class ScrollingDragBox : DragBox + public partial class ScrollingDragBox : DragBox { public double MinTime { get; private set; } diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs index 2c4c220ad0..17790547ed 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBox.cs @@ -18,7 +18,7 @@ using osuTK.Input; namespace osu.Game.Screens.Edit.Compose.Components { [Cached] - public class SelectionBox : CompositeDrawable + public partial class SelectionBox : CompositeDrawable { public const float BORDER_RADIUS = 3; diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxButton.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxButton.cs index 3d6dacc95e..832d8b65e5 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxButton.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxButton.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Edit.Compose.Components { - public sealed class SelectionBoxButton : SelectionBoxControl, IHasTooltip + public sealed partial class SelectionBoxButton : SelectionBoxControl, IHasTooltip { private SpriteIcon icon; diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxControl.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxControl.cs index c4675685f6..35c67a1c67 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxControl.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxControl.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// Represents the base appearance for UI controls of the , /// such as scale handles, rotation handles, buttons, etc... /// - public abstract class SelectionBoxControl : CompositeDrawable + public abstract partial class SelectionBoxControl : CompositeDrawable { public const double TRANSFORM_DURATION = 100; diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxDragHandle.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxDragHandle.cs index 308d0cc893..757ff655f5 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxDragHandle.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxDragHandle.cs @@ -8,7 +8,7 @@ using osu.Framework.Input.Events; namespace osu.Game.Screens.Edit.Compose.Components { - public abstract class SelectionBoxDragHandle : SelectionBoxControl + public abstract partial class SelectionBoxDragHandle : SelectionBoxControl { protected override bool OnDragStart(DragStartEvent e) { diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxDragHandleContainer.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxDragHandleContainer.cs index 5c7debf57e..5c87271493 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxDragHandleContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxDragHandleContainer.cs @@ -15,7 +15,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// Represents a display composite containing and managing the visibility state of the selection box's drag handles. /// - public class SelectionBoxDragHandleContainer : CompositeDrawable + public partial class SelectionBoxDragHandleContainer : CompositeDrawable { private Container scaleHandles; private Container rotationHandles; diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs index 761cd118bf..0f702e1c49 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Edit.Compose.Components { - public class SelectionBoxRotationHandle : SelectionBoxDragHandle, IHasTooltip + public partial class SelectionBoxRotationHandle : SelectionBoxDragHandle, IHasTooltip { public Action HandleRotate { get; set; } diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxScaleHandle.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxScaleHandle.cs index bd1e2f4649..7943065c82 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxScaleHandle.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxScaleHandle.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Compose.Components { - public class SelectionBoxScaleHandle : SelectionBoxDragHandle + public partial class SelectionBoxScaleHandle : SelectionBoxDragHandle { public Action HandleScale { get; set; } diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs index 269c19f846..a0ac99fec2 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs @@ -30,7 +30,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// A component which outlines items and handles movement of selections. /// - public abstract class SelectionHandler : CompositeDrawable, IKeyBindingHandler, IKeyBindingHandler, IHasContextMenu + public abstract partial class SelectionHandler : CompositeDrawable, IKeyBindingHandler, IKeyBindingHandler, IHasContextMenu { /// /// The currently selected blueprints. diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/CentreMarker.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/CentreMarker.cs index 6c545f8f78..44daf70577 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/CentreMarker.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/CentreMarker.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - public class CentreMarker : CompositeDrawable + public partial class CentreMarker : CompositeDrawable { private const float triangle_width = 15; private const float triangle_height = 10; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs index b028f67ba1..d3cdd461ea 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs @@ -22,7 +22,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - public class DifficultyPointPiece : HitObjectPointPiece, IHasPopover + public partial class DifficultyPointPiece : HitObjectPointPiece, IHasPopover { public readonly HitObject HitObject; @@ -51,7 +51,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline public Popover GetPopover() => new DifficultyEditPopover(HitObject); - public class DifficultyEditPopover : OsuPopover + public partial class DifficultyEditPopover : OsuPopover { private readonly HitObject hitObject; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs index 1091afe226..5b0a5729c8 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - public class HitObjectPointPiece : CircularContainer + public partial class HitObjectPointPiece : CircularContainer { private readonly ControlPoint point; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs index 648ffd9609..314137a565 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - public class SamplePointPiece : HitObjectPointPiece, IHasPopover + public partial class SamplePointPiece : HitObjectPointPiece, IHasPopover { public readonly HitObject HitObject; @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline public Popover GetPopover() => new SampleEditPopover(HitObject); - public class SampleEditPopover : OsuPopover + public partial class SampleEditPopover : OsuPopover { private readonly HitObject hitObject; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 8befda82e8..45f902d0de 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -22,7 +22,7 @@ using osuTK.Input; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { [Cached] - public class Timeline : ZoomableScrollContainer, IPositionSnapProvider + public partial class Timeline : ZoomableScrollContainer, IPositionSnapProvider { private const float timeline_height = 72; private const float timeline_expanded_height = 94; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs index 58d378154a..615925ff91 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - public class TimelineArea : CompositeDrawable + public partial class TimelineArea : CompositeDrawable { public Timeline Timeline; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs index b79c2675c8..f93fb0679f 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs @@ -24,7 +24,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - internal class TimelineBlueprintContainer : EditorBlueprintContainer + internal partial class TimelineBlueprintContainer : EditorBlueprintContainer { [Resolved(CanBeNull = true)] private Timeline timeline { get; set; } @@ -198,7 +198,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline timeline.ScrollBy((float)((mouseX - timelineQuad.TopLeft.X) / 10 * Clock.ElapsedFrameTime)); } - private class SelectableAreaBackground : CompositeDrawable + private partial class SelectableAreaBackground : CompositeDrawable { [Resolved] private OsuColour colours { get; set; } @@ -246,7 +246,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline } } - protected class TimelineSelectionBlueprintContainer : Container> + protected partial class TimelineSelectionBlueprintContainer : Container> { protected override Container> Content { get; } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineButton.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineButton.cs index 0832dc02a9..c94de0fe67 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineButton.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineButton.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Edit.Timing; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - public class TimelineButton : IconButton + public partial class TimelineButton : IconButton { [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineControlPointDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineControlPointDisplay.cs index cfc71256e8..9783c4184a 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineControlPointDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineControlPointDisplay.cs @@ -14,7 +14,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline /// /// The part of the timeline that displays the control points. /// - public class TimelineControlPointDisplay : TimelinePart + public partial class TimelineControlPointDisplay : TimelinePart { private readonly IBindableList controlPointGroups = new BindableList(); diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineControlPointGroup.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineControlPointGroup.cs index 10355045be..257cc9e635 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineControlPointGroup.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineControlPointGroup.cs @@ -10,7 +10,7 @@ using osu.Game.Beatmaps.ControlPoints; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - public class TimelineControlPointGroup : CompositeDrawable + public partial class TimelineControlPointGroup : CompositeDrawable { public readonly ControlPointGroup Group; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineDragBox.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineDragBox.cs index 65d9293b7e..a1dfd0718b 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineDragBox.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineDragBox.cs @@ -11,7 +11,7 @@ using osu.Framework.Input.Events; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - public class TimelineDragBox : DragBox + public partial class TimelineDragBox : DragBox { public double MinTime { get; private set; } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index 20ef128ee9..3e49c31b1e 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -27,7 +27,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - public class TimelineHitObjectBlueprint : SelectionBlueprint + public partial class TimelineHitObjectBlueprint : SelectionBlueprint { private const float circle_size = 38; @@ -262,7 +262,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline public override Vector2 ScreenSpaceSelectionPoint => ScreenSpaceDrawQuad.TopLeft; - private class Tick : Circle + private partial class Tick : Circle { public Tick() { @@ -273,7 +273,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline } } - public class DragArea : Circle + public partial class DragArea : Circle { private readonly HitObject? hitObject; @@ -444,7 +444,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline } } - public class Border : ExtendableCircle + public partial class Border : ExtendableCircle { [BackgroundDependencyLoader] private void load(OsuColour colours) @@ -460,7 +460,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline /// /// A circle with externalised end caps so it can take up the full width of a relative width area. /// - public class ExtendableCircle : CompositeDrawable + public partial class ExtendableCircle : CompositeDrawable { protected readonly Circle Content; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineSelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineSelectionHandler.cs index d91b95888b..0a5a0e99ac 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineSelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineSelectionHandler.cs @@ -16,7 +16,7 @@ using osuTK.Input; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - internal class TimelineSelectionHandler : EditorSelectionHandler + internal partial class TimelineSelectionHandler : EditorSelectionHandler { // for now we always allow movement. snapping is provided by the Timeline's "distance" snap implementation public override bool HandleMovement(MoveSelectionEvent moveEvent) => true; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs index c1c9b2493b..6a0688e19c 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - public class TimelineTickDisplay : TimelinePart + public partial class TimelineTickDisplay : TimelinePart { [Resolved] private EditorBeatmap beatmap { get; set; } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimingPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimingPointPiece.cs index cf62707839..4191864e5c 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimingPointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimingPointPiece.cs @@ -9,7 +9,7 @@ using osu.Game.Beatmaps.ControlPoints; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - public class TimingPointPiece : TopPointPiece + public partial class TimingPointPiece : TopPointPiece { private readonly BindableNumber beatLength; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TopPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TopPointPiece.cs index 28ae77c931..69fb001a66 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TopPointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TopPointPiece.cs @@ -13,7 +13,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - public class TopPointPiece : CompositeDrawable + public partial class TopPointPiece : CompositeDrawable { private readonly ControlPoint point; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs index 839b2b5bad..28f7731354 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - public class ZoomableScrollContainer : OsuScrollContainer + public partial class ZoomableScrollContainer : OsuScrollContainer { /// /// The time to zoom into/out of a point. diff --git a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs index d3c330c6d7..3af7a400e2 100644 --- a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs +++ b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs @@ -20,7 +20,7 @@ using osu.Game.Screens.Edit.Compose.Components.Timeline; namespace osu.Game.Screens.Edit.Compose { - public class ComposeScreen : EditorScreenWithTimeline, IGameplaySettings + public partial class ComposeScreen : EditorScreenWithTimeline, IGameplaySettings { [Resolved] private GameHost host { get; set; } diff --git a/osu.Game/Screens/Edit/CreateNewDifficultyDialog.cs b/osu.Game/Screens/Edit/CreateNewDifficultyDialog.cs index 36c4e397a7..85466c5056 100644 --- a/osu.Game/Screens/Edit/CreateNewDifficultyDialog.cs +++ b/osu.Game/Screens/Edit/CreateNewDifficultyDialog.cs @@ -8,7 +8,7 @@ using osu.Game.Overlays.Dialog; namespace osu.Game.Screens.Edit { - public class CreateNewDifficultyDialog : PopupDialog + public partial class CreateNewDifficultyDialog : PopupDialog { /// /// Delegate used to create new difficulties. diff --git a/osu.Game/Screens/Edit/DeleteDifficultyConfirmationDialog.cs b/osu.Game/Screens/Edit/DeleteDifficultyConfirmationDialog.cs index 594042b426..68a0ef4250 100644 --- a/osu.Game/Screens/Edit/DeleteDifficultyConfirmationDialog.cs +++ b/osu.Game/Screens/Edit/DeleteDifficultyConfirmationDialog.cs @@ -7,7 +7,7 @@ using osu.Game.Overlays.Dialog; namespace osu.Game.Screens.Edit { - public class DeleteDifficultyConfirmationDialog : DeleteConfirmationDialog + public partial class DeleteDifficultyConfirmationDialog : DeleteConfirmationDialog { public DeleteDifficultyConfirmationDialog(BeatmapInfo beatmapInfo, Action deleteAction) { diff --git a/osu.Game/Screens/Edit/Design/DesignScreen.cs b/osu.Game/Screens/Edit/Design/DesignScreen.cs index 546a07f17d..10b351ded1 100644 --- a/osu.Game/Screens/Edit/Design/DesignScreen.cs +++ b/osu.Game/Screens/Edit/Design/DesignScreen.cs @@ -5,7 +5,7 @@ namespace osu.Game.Screens.Edit.Design { - public class DesignScreen : EditorScreen + public partial class DesignScreen : EditorScreen { public DesignScreen() : base(EditorScreenMode.Design) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 4c44117581..0676c372a8 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -58,7 +58,7 @@ namespace osu.Game.Screens.Edit { [Cached(typeof(IBeatSnapProvider))] [Cached] - public class Editor : ScreenWithBeatmapBackground, IKeyBindingHandler, IKeyBindingHandler, IBeatSnapProvider, ISamplePlaybackDisabler, IBeatSyncProvider + public partial class Editor : ScreenWithBeatmapBackground, IKeyBindingHandler, IKeyBindingHandler, IBeatSnapProvider, ISamplePlaybackDisabler, IBeatSyncProvider { public override float BackgroundParallaxAmount => 0.1f; @@ -1034,7 +1034,7 @@ namespace osu.Game.Screens.Edit IClock IBeatSyncProvider.Clock => clock; ChannelAmplitudes IHasAmplitudes.CurrentAmplitudes => Beatmap.Value.TrackLoaded ? Beatmap.Value.Track.CurrentAmplitudes : ChannelAmplitudes.Empty; - private class BeatmapEditorToast : Toast + private partial class BeatmapEditorToast : Toast { public BeatmapEditorToast(LocalisableString value, string beatmapDisplayName) : base(InputSettingsStrings.EditorSection, value, beatmapDisplayName) diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 839535b99f..e204b44db3 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -20,7 +20,7 @@ using osu.Game.Skinning; namespace osu.Game.Screens.Edit { - public class EditorBeatmap : TransactionalCommitComponent, IBeatmap, IBeatSnapProvider + public partial class EditorBeatmap : TransactionalCommitComponent, IBeatmap, IBeatSnapProvider { /// /// Will become true when a new update is queued, and false when all updates have been applied. diff --git a/osu.Game/Screens/Edit/EditorChangeHandler.cs b/osu.Game/Screens/Edit/EditorChangeHandler.cs index 1a93f3f101..964b86cad3 100644 --- a/osu.Game/Screens/Edit/EditorChangeHandler.cs +++ b/osu.Game/Screens/Edit/EditorChangeHandler.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Edit /// /// Tracks changes to the . /// - public class EditorChangeHandler : TransactionalCommitComponent, IEditorChangeHandler + public partial class EditorChangeHandler : TransactionalCommitComponent, IEditorChangeHandler { public readonly Bindable CanUndo = new Bindable(); public readonly Bindable CanRedo = new Bindable(); diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index f83874e4a0..e5e88a04d9 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -21,7 +21,7 @@ namespace osu.Game.Screens.Edit /// /// A decoupled clock which adds editor-specific functionality, such as snapping to a user-defined beat divisor. /// - public class EditorClock : CompositeComponent, IFrameBasedClock, IAdjustableClock, ISourceChangeableClock + public partial class EditorClock : CompositeComponent, IFrameBasedClock, IAdjustableClock, ISourceChangeableClock { public IBindable Track => track; diff --git a/osu.Game/Screens/Edit/EditorLoader.cs b/osu.Game/Screens/Edit/EditorLoader.cs index d6af990b52..f665b7c511 100644 --- a/osu.Game/Screens/Edit/EditorLoader.cs +++ b/osu.Game/Screens/Edit/EditorLoader.cs @@ -25,7 +25,7 @@ namespace osu.Game.Screens.Edit /// Transition screen for the editor. /// Used to avoid backing out to main menu/song select when switching difficulties from within the editor. /// - public class EditorLoader : ScreenWithBeatmapBackground + public partial class EditorLoader : ScreenWithBeatmapBackground { /// /// The stored state from the last editor opened. diff --git a/osu.Game/Screens/Edit/EditorRoundedScreenSettings.cs b/osu.Game/Screens/Edit/EditorRoundedScreenSettings.cs index 013971960b..1c083b4fab 100644 --- a/osu.Game/Screens/Edit/EditorRoundedScreenSettings.cs +++ b/osu.Game/Screens/Edit/EditorRoundedScreenSettings.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Screens.Edit { - public abstract class EditorRoundedScreenSettings : CompositeDrawable + public abstract partial class EditorRoundedScreenSettings : CompositeDrawable { [BackgroundDependencyLoader] private void load(OverlayColourProvider colours) diff --git a/osu.Game/Screens/Edit/EditorRoundedScreenSettingsSection.cs b/osu.Game/Screens/Edit/EditorRoundedScreenSettingsSection.cs index be1545cac8..751b6f61d1 100644 --- a/osu.Game/Screens/Edit/EditorRoundedScreenSettingsSection.cs +++ b/osu.Game/Screens/Edit/EditorRoundedScreenSettingsSection.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Screens.Edit { - public abstract class EditorRoundedScreenSettingsSection : CompositeDrawable + public abstract partial class EditorRoundedScreenSettingsSection : CompositeDrawable { private const int header_height = 50; diff --git a/osu.Game/Screens/Edit/EditorScreen.cs b/osu.Game/Screens/Edit/EditorScreen.cs index 92709484ff..069a5490bb 100644 --- a/osu.Game/Screens/Edit/EditorScreen.cs +++ b/osu.Game/Screens/Edit/EditorScreen.cs @@ -14,7 +14,7 @@ namespace osu.Game.Screens.Edit /// /// TODO: eventually make this inherit Screen and add a local screen stack inside the Editor. /// - public abstract class EditorScreen : VisibilityContainer + public abstract partial class EditorScreen : VisibilityContainer { [Resolved] protected EditorBeatmap EditorBeatmap { get; private set; } diff --git a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs index b3aafb9730..84cfac8f65 100644 --- a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs +++ b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs @@ -15,7 +15,7 @@ using osu.Game.Screens.Edit.Compose.Components.Timeline; namespace osu.Game.Screens.Edit { - public abstract class EditorScreenWithTimeline : EditorScreen + public abstract partial class EditorScreenWithTimeline : EditorScreen { private const float padding = 10; diff --git a/osu.Game/Screens/Edit/EditorSkinProvidingContainer.cs b/osu.Game/Screens/Edit/EditorSkinProvidingContainer.cs index d4387a0263..814b5dc18e 100644 --- a/osu.Game/Screens/Edit/EditorSkinProvidingContainer.cs +++ b/osu.Game/Screens/Edit/EditorSkinProvidingContainer.cs @@ -9,7 +9,7 @@ namespace osu.Game.Screens.Edit /// A that fires when users have made a change to the beatmap skin /// of the map being edited. /// - public class EditorSkinProvidingContainer : RulesetSkinProvidingContainer + public partial class EditorSkinProvidingContainer : RulesetSkinProvidingContainer { private readonly EditorBeatmapSkin? beatmapSkin; diff --git a/osu.Game/Screens/Edit/EditorTable.cs b/osu.Game/Screens/Edit/EditorTable.cs index a290cce708..f97a8c5572 100644 --- a/osu.Game/Screens/Edit/EditorTable.cs +++ b/osu.Game/Screens/Edit/EditorTable.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Edit { - public abstract class EditorTable : TableContainer + public abstract partial class EditorTable : TableContainer { private const float horizontal_inset = 20; @@ -47,7 +47,7 @@ namespace osu.Game.Screens.Edit protected override Drawable CreateHeader(int index, TableColumn column) => new HeaderText(column?.Header ?? default); - private class HeaderText : OsuSpriteText + private partial class HeaderText : OsuSpriteText { public HeaderText(LocalisableString text) { @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Edit } } - public class RowBackground : OsuClickableContainer + public partial class RowBackground : OsuClickableContainer { public readonly object Item; diff --git a/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs b/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs index ad09618279..e7db1c105b 100644 --- a/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs +++ b/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Play; namespace osu.Game.Screens.Edit.GameplayTest { - public class EditorPlayer : Player + public partial class EditorPlayer : Player { private readonly Editor editor; private readonly EditorState editorState; diff --git a/osu.Game/Screens/Edit/GameplayTest/EditorPlayerLoader.cs b/osu.Game/Screens/Edit/GameplayTest/EditorPlayerLoader.cs index d3260f1e7d..a74d97cdc7 100644 --- a/osu.Game/Screens/Edit/GameplayTest/EditorPlayerLoader.cs +++ b/osu.Game/Screens/Edit/GameplayTest/EditorPlayerLoader.cs @@ -11,7 +11,7 @@ using osu.Game.Screens.Play; namespace osu.Game.Screens.Edit.GameplayTest { - public class EditorPlayerLoader : PlayerLoader + public partial class EditorPlayerLoader : PlayerLoader { [Resolved] private OsuLogo osuLogo { get; set; } diff --git a/osu.Game/Screens/Edit/GameplayTest/SaveBeforeGameplayTestDialog.cs b/osu.Game/Screens/Edit/GameplayTest/SaveBeforeGameplayTestDialog.cs index 37e1c99d98..5a5572b508 100644 --- a/osu.Game/Screens/Edit/GameplayTest/SaveBeforeGameplayTestDialog.cs +++ b/osu.Game/Screens/Edit/GameplayTest/SaveBeforeGameplayTestDialog.cs @@ -9,7 +9,7 @@ using osu.Game.Overlays.Dialog; namespace osu.Game.Screens.Edit.GameplayTest { - public class SaveBeforeGameplayTestDialog : PopupDialog + public partial class SaveBeforeGameplayTestDialog : PopupDialog { public SaveBeforeGameplayTestDialog(Action saveAndPreview) { diff --git a/osu.Game/Screens/Edit/PromptForSaveDialog.cs b/osu.Game/Screens/Edit/PromptForSaveDialog.cs index 59a697d91c..2a2cd019ea 100644 --- a/osu.Game/Screens/Edit/PromptForSaveDialog.cs +++ b/osu.Game/Screens/Edit/PromptForSaveDialog.cs @@ -9,7 +9,7 @@ using osu.Game.Overlays.Dialog; namespace osu.Game.Screens.Edit { - public class PromptForSaveDialog : PopupDialog + public partial class PromptForSaveDialog : PopupDialog { public PromptForSaveDialog(Action exit, Action saveAndExit, Action cancel) { diff --git a/osu.Game/Screens/Edit/Setup/ColoursSection.cs b/osu.Game/Screens/Edit/Setup/ColoursSection.cs index e3fcdedd1b..10ab272a87 100644 --- a/osu.Game/Screens/Edit/Setup/ColoursSection.cs +++ b/osu.Game/Screens/Edit/Setup/ColoursSection.cs @@ -11,7 +11,7 @@ using osu.Game.Localisation; namespace osu.Game.Screens.Edit.Setup { - internal class ColoursSection : SetupSection + internal partial class ColoursSection : SetupSection { public override LocalisableString Title => EditorSetupStrings.ColoursHeader; diff --git a/osu.Game/Screens/Edit/Setup/DesignSection.cs b/osu.Game/Screens/Edit/Setup/DesignSection.cs index cc3e9b91ab..3428366510 100644 --- a/osu.Game/Screens/Edit/Setup/DesignSection.cs +++ b/osu.Game/Screens/Edit/Setup/DesignSection.cs @@ -17,7 +17,7 @@ using osu.Game.Localisation; namespace osu.Game.Screens.Edit.Setup { - internal class DesignSection : SetupSection + internal partial class DesignSection : SetupSection { protected LabelledSwitchButton EnableCountdown; diff --git a/osu.Game/Screens/Edit/Setup/DifficultySection.cs b/osu.Game/Screens/Edit/Setup/DifficultySection.cs index 01e31bd688..afe6b36cba 100644 --- a/osu.Game/Screens/Edit/Setup/DifficultySection.cs +++ b/osu.Game/Screens/Edit/Setup/DifficultySection.cs @@ -15,7 +15,7 @@ using osu.Game.Localisation; namespace osu.Game.Screens.Edit.Setup { - internal class DifficultySection : SetupSection + internal partial class DifficultySection : SetupSection { private LabelledSliderBar circleSizeSlider; private LabelledSliderBar healthDrainSlider; diff --git a/osu.Game/Screens/Edit/Setup/LabelledFileChooser.cs b/osu.Game/Screens/Edit/Setup/LabelledFileChooser.cs index efc8b6978e..57d28824b1 100644 --- a/osu.Game/Screens/Edit/Setup/LabelledFileChooser.cs +++ b/osu.Game/Screens/Edit/Setup/LabelledFileChooser.cs @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Edit.Setup /// A labelled drawable displaying file chooser on click, with placeholder text support. /// todo: this should probably not use PopoverTextBox just to display placeholder text, but is the best way for now. /// - internal class LabelledFileChooser : LabelledDrawable, IHasCurrentValue, ICanAcceptFiles, IHasPopover + internal partial class LabelledFileChooser : LabelledDrawable, IHasCurrentValue, ICanAcceptFiles, IHasPopover { private readonly string[] handledExtensions; @@ -112,7 +112,7 @@ namespace osu.Game.Screens.Edit.Setup public Popover GetPopover() => new FileChooserPopover(handledExtensions, Current, initialChooserPath); - private class FileChooserPopover : OsuPopover + private partial class FileChooserPopover : OsuPopover { public FileChooserPopover(string[] handledExtensions, Bindable currentFile, string? chooserPath) { diff --git a/osu.Game/Screens/Edit/Setup/LabelledRomanisedTextBox.cs b/osu.Game/Screens/Edit/Setup/LabelledRomanisedTextBox.cs index a9cf5357c8..43c20b5e40 100644 --- a/osu.Game/Screens/Edit/Setup/LabelledRomanisedTextBox.cs +++ b/osu.Game/Screens/Edit/Setup/LabelledRomanisedTextBox.cs @@ -9,11 +9,11 @@ using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Screens.Edit.Setup { - internal class LabelledRomanisedTextBox : LabelledTextBox + internal partial class LabelledRomanisedTextBox : LabelledTextBox { protected override OsuTextBox CreateTextBox() => new RomanisedTextBox(); - private class RomanisedTextBox : OsuTextBox + private partial class RomanisedTextBox : OsuTextBox { protected override bool AllowIme => false; diff --git a/osu.Game/Screens/Edit/Setup/LabelledTextBoxWithPopover.cs b/osu.Game/Screens/Edit/Setup/LabelledTextBoxWithPopover.cs index 0eb74df575..05c8f88444 100644 --- a/osu.Game/Screens/Edit/Setup/LabelledTextBoxWithPopover.cs +++ b/osu.Game/Screens/Edit/Setup/LabelledTextBoxWithPopover.cs @@ -14,7 +14,7 @@ using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Screens.Edit.Setup { - internal abstract class LabelledTextBoxWithPopover : LabelledTextBox, IHasPopover + internal abstract partial class LabelledTextBoxWithPopover : LabelledTextBox, IHasPopover { public abstract Popover GetPopover(); @@ -28,7 +28,7 @@ namespace osu.Game.Screens.Edit.Setup OnFocused = this.ShowPopover }; - internal class PopoverTextBox : OsuTextBox + internal partial class PopoverTextBox : OsuTextBox { public Action OnFocused; diff --git a/osu.Game/Screens/Edit/Setup/MetadataSection.cs b/osu.Game/Screens/Edit/Setup/MetadataSection.cs index 1da7a87f83..c2c853f7b2 100644 --- a/osu.Game/Screens/Edit/Setup/MetadataSection.cs +++ b/osu.Game/Screens/Edit/Setup/MetadataSection.cs @@ -14,7 +14,7 @@ using osu.Game.Localisation; namespace osu.Game.Screens.Edit.Setup { - public class MetadataSection : SetupSection + public partial class MetadataSection : SetupSection { protected LabelledTextBox ArtistTextBox; protected LabelledTextBox RomanisedArtistTextBox; diff --git a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs index cbaa2d8b42..ca0f50cd34 100644 --- a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs +++ b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs @@ -14,7 +14,7 @@ using osu.Game.Localisation; namespace osu.Game.Screens.Edit.Setup { - internal class ResourcesSection : SetupSection + internal partial class ResourcesSection : SetupSection { private LabelledFileChooser audioTrackChooser; private LabelledFileChooser backgroundChooser; diff --git a/osu.Game/Screens/Edit/Setup/RulesetSetupSection.cs b/osu.Game/Screens/Edit/Setup/RulesetSetupSection.cs index d6664e860b..0914bd47bc 100644 --- a/osu.Game/Screens/Edit/Setup/RulesetSetupSection.cs +++ b/osu.Game/Screens/Edit/Setup/RulesetSetupSection.cs @@ -9,7 +9,7 @@ using osu.Game.Localisation; namespace osu.Game.Screens.Edit.Setup { - public abstract class RulesetSetupSection : SetupSection + public abstract partial class RulesetSetupSection : SetupSection { public sealed override LocalisableString Title => EditorSetupStrings.RulesetHeader(rulesetInfo.Name); diff --git a/osu.Game/Screens/Edit/Setup/SetupScreen.cs b/osu.Game/Screens/Edit/Setup/SetupScreen.cs index 036202a503..cc705547de 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreen.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreen.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays; namespace osu.Game.Screens.Edit.Setup { - public class SetupScreen : EditorScreen + public partial class SetupScreen : EditorScreen { [Cached] private SectionsContainer sections { get; } = new SetupScreenSectionsContainer(); @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Edit.Setup })); } - private class SetupScreenSectionsContainer : SectionsContainer + private partial class SetupScreenSectionsContainer : SectionsContainer { protected override UserTrackingScrollContainer CreateScrollContainer() { diff --git a/osu.Game/Screens/Edit/Setup/SetupScreenHeader.cs b/osu.Game/Screens/Edit/Setup/SetupScreenHeader.cs index 9486b3728b..0a6643efeb 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreenHeader.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreenHeader.cs @@ -16,7 +16,7 @@ using osu.Game.Localisation; namespace osu.Game.Screens.Edit.Setup { - internal class SetupScreenHeader : OverlayHeader + internal partial class SetupScreenHeader : OverlayHeader { public SetupScreenHeaderBackground Background { get; private set; } @@ -75,7 +75,7 @@ namespace osu.Game.Screens.Edit.Setup }); } - private class SetupScreenTitle : OverlayTitle + private partial class SetupScreenTitle : OverlayTitle { public SetupScreenTitle() { @@ -85,7 +85,7 @@ namespace osu.Game.Screens.Edit.Setup } } - internal class SetupScreenTabControl : OverlayTabControl + internal partial class SetupScreenTabControl : OverlayTabControl { private readonly Box background; @@ -111,7 +111,7 @@ namespace osu.Game.Screens.Edit.Setup AccentColour = AccentColour }; - private class SetupScreenTabItem : OverlayTabItem + private partial class SetupScreenTabItem : OverlayTabItem { public SetupScreenTabItem(SetupSection value) : base(value) diff --git a/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs b/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs index 5680d75f4e..50743476bf 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs @@ -15,7 +15,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Screens.Edit.Setup { - public class SetupScreenHeaderBackground : CompositeDrawable + public partial class SetupScreenHeaderBackground : CompositeDrawable { [Resolved] private OsuColour colours { get; set; } diff --git a/osu.Game/Screens/Edit/Setup/SetupSection.cs b/osu.Game/Screens/Edit/Setup/SetupSection.cs index 727a94a590..c7690623ad 100644 --- a/osu.Game/Screens/Edit/Setup/SetupSection.cs +++ b/osu.Game/Screens/Edit/Setup/SetupSection.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Setup { - public abstract class SetupSection : Container + public abstract partial class SetupSection : Container { private FillFlowContainer flow; diff --git a/osu.Game/Screens/Edit/Timing/ControlPointSettings.cs b/osu.Game/Screens/Edit/Timing/ControlPointSettings.cs index 1f95156aba..97bd84b1b6 100644 --- a/osu.Game/Screens/Edit/Timing/ControlPointSettings.cs +++ b/osu.Game/Screens/Edit/Timing/ControlPointSettings.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics; namespace osu.Game.Screens.Edit.Timing { - public class ControlPointSettings : EditorRoundedScreenSettings + public partial class ControlPointSettings : EditorRoundedScreenSettings { protected override IReadOnlyList CreateSections() => new Drawable[] { diff --git a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs index b51da2c53d..5c131c0b6d 100644 --- a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs +++ b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Timing { - public class ControlPointTable : EditorTable + public partial class ControlPointTable : EditorTable { [Resolved] private Bindable selectedGroup { get; set; } @@ -118,7 +118,7 @@ namespace osu.Game.Screens.Edit.Timing }; } - private class ControlGroupAttributes : CompositeDrawable + private partial class ControlGroupAttributes : CompositeDrawable { private readonly Func matchFunction; diff --git a/osu.Game/Screens/Edit/Timing/EffectSection.cs b/osu.Game/Screens/Edit/Timing/EffectSection.cs index 9be663bb26..1f5400c03b 100644 --- a/osu.Game/Screens/Edit/Timing/EffectSection.cs +++ b/osu.Game/Screens/Edit/Timing/EffectSection.cs @@ -13,7 +13,7 @@ using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Screens.Edit.Timing { - internal class EffectSection : Section + internal partial class EffectSection : Section { private LabelledSwitchButton kiai; private LabelledSwitchButton omitBarLine; diff --git a/osu.Game/Screens/Edit/Timing/GroupSection.cs b/osu.Game/Screens/Edit/Timing/GroupSection.cs index e78cd18024..f36989cf32 100644 --- a/osu.Game/Screens/Edit/Timing/GroupSection.cs +++ b/osu.Game/Screens/Edit/Timing/GroupSection.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Timing { - internal class GroupSection : CompositeDrawable + internal partial class GroupSection : CompositeDrawable { private LabelledTextBox textBox; diff --git a/osu.Game/Screens/Edit/Timing/IndeterminateSliderWithTextBoxInput.cs b/osu.Game/Screens/Edit/Timing/IndeterminateSliderWithTextBoxInput.cs index ea6c6f31e4..36186353f8 100644 --- a/osu.Game/Screens/Edit/Timing/IndeterminateSliderWithTextBoxInput.cs +++ b/osu.Game/Screens/Edit/Timing/IndeterminateSliderWithTextBoxInput.cs @@ -23,7 +23,7 @@ namespace osu.Game.Screens.Edit.Timing /// where multiple objects with multiple different property values are selected /// by providing an "indeterminate state". /// - public class IndeterminateSliderWithTextBoxInput : CompositeDrawable, IHasCurrentValue + public partial class IndeterminateSliderWithTextBoxInput : CompositeDrawable, IHasCurrentValue where T : struct, IEquatable, IComparable, IConvertible { /// diff --git a/osu.Game/Screens/Edit/Timing/LabelledTimeSignature.cs b/osu.Game/Screens/Edit/Timing/LabelledTimeSignature.cs index 998e49a6ab..217aa46c3f 100644 --- a/osu.Game/Screens/Edit/Timing/LabelledTimeSignature.cs +++ b/osu.Game/Screens/Edit/Timing/LabelledTimeSignature.cs @@ -16,7 +16,7 @@ using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Screens.Edit.Timing { - public class LabelledTimeSignature : LabelledComponent + public partial class LabelledTimeSignature : LabelledComponent { public LabelledTimeSignature() : base(false) @@ -25,7 +25,7 @@ namespace osu.Game.Screens.Edit.Timing protected override TimeSignatureBox CreateComponent() => new TimeSignatureBox(); - public class TimeSignatureBox : CompositeDrawable, IHasCurrentValue + public partial class TimeSignatureBox : CompositeDrawable, IHasCurrentValue { private readonly BindableWithCurrent current = new BindableWithCurrent(TimeSignature.SimpleQuadruple); diff --git a/osu.Game/Screens/Edit/Timing/MetronomeDisplay.cs b/osu.Game/Screens/Edit/Timing/MetronomeDisplay.cs index 3895959982..dfe2ec1f17 100644 --- a/osu.Game/Screens/Edit/Timing/MetronomeDisplay.cs +++ b/osu.Game/Screens/Edit/Timing/MetronomeDisplay.cs @@ -26,7 +26,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Timing { - public class MetronomeDisplay : BeatSyncedContainer + public partial class MetronomeDisplay : BeatSyncedContainer { private Container swing; diff --git a/osu.Game/Screens/Edit/Timing/RepeatingButtonBehaviour.cs b/osu.Game/Screens/Edit/Timing/RepeatingButtonBehaviour.cs index cd3ced53da..0b442fe5da 100644 --- a/osu.Game/Screens/Edit/Timing/RepeatingButtonBehaviour.cs +++ b/osu.Game/Screens/Edit/Timing/RepeatingButtonBehaviour.cs @@ -16,7 +16,7 @@ namespace osu.Game.Screens.Edit.Timing /// /// Represents a component that provides the behaviour of triggering button clicks repeatedly while holding with mouse. /// - public class RepeatingButtonBehaviour : Component + public partial class RepeatingButtonBehaviour : Component { private const double initial_delay = 300; private const double minimum_delay = 80; diff --git a/osu.Game/Screens/Edit/Timing/RowAttribute.cs b/osu.Game/Screens/Edit/Timing/RowAttribute.cs index e73a343583..6f0553c771 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttribute.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttribute.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Timing { - public class RowAttribute : CompositeDrawable + public partial class RowAttribute : CompositeDrawable { protected readonly ControlPoint Point; diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeProgressBar.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeProgressBar.cs index a8d2172f58..49791bd99a 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeProgressBar.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeProgressBar.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Timing.RowAttributes { - public class AttributeProgressBar : ProgressBar + public partial class AttributeProgressBar : ProgressBar { private readonly ControlPoint controlPoint; diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeText.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeText.cs index d65ef1799a..c9d7aab5d8 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeText.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeText.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Screens.Edit.Timing.RowAttributes { - public class AttributeText : OsuSpriteText + public partial class AttributeText : OsuSpriteText { private readonly ControlPoint controlPoint; diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/DifficultyRowAttribute.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/DifficultyRowAttribute.cs index 17f8b01d07..4d3704d44a 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/DifficultyRowAttribute.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/DifficultyRowAttribute.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Screens.Edit.Timing.RowAttributes { - public class DifficultyRowAttribute : RowAttribute + public partial class DifficultyRowAttribute : RowAttribute { private readonly BindableNumber speedMultiplier; diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/EffectRowAttribute.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/EffectRowAttribute.cs index ef682dd3ad..88943e5578 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/EffectRowAttribute.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/EffectRowAttribute.cs @@ -10,7 +10,7 @@ using osu.Game.Beatmaps.ControlPoints; namespace osu.Game.Screens.Edit.Timing.RowAttributes { - public class EffectRowAttribute : RowAttribute + public partial class EffectRowAttribute : RowAttribute { private readonly Bindable kiaiMode; private readonly Bindable omitBarLine; diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/SampleRowAttribute.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/SampleRowAttribute.cs index e06f6b7bfb..915cf63baa 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/SampleRowAttribute.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/SampleRowAttribute.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Screens.Edit.Timing.RowAttributes { - public class SampleRowAttribute : RowAttribute + public partial class SampleRowAttribute : RowAttribute { private AttributeText sampleText; private OsuSpriteText volumeText; diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/TimingRowAttribute.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/TimingRowAttribute.cs index 0b498650d4..3887282c6a 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/TimingRowAttribute.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/TimingRowAttribute.cs @@ -13,7 +13,7 @@ using osu.Game.Overlays; namespace osu.Game.Screens.Edit.Timing.RowAttributes { - public class TimingRowAttribute : RowAttribute + public partial class TimingRowAttribute : RowAttribute { private readonly BindableNumber beatLength; private readonly Bindable timeSignature; diff --git a/osu.Game/Screens/Edit/Timing/Section.cs b/osu.Game/Screens/Edit/Timing/Section.cs index 02789c0cbf..ebba481099 100644 --- a/osu.Game/Screens/Edit/Timing/Section.cs +++ b/osu.Game/Screens/Edit/Timing/Section.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Timing { - internal abstract class Section : CompositeDrawable + internal abstract partial class Section : CompositeDrawable where T : ControlPoint { private OsuCheckbox checkbox; diff --git a/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs b/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs index 4dcb5ad2ba..e1a5c3b23c 100644 --- a/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs +++ b/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Timing { - public class SliderWithTextBoxInput : CompositeDrawable, IHasCurrentValue + public partial class SliderWithTextBoxInput : CompositeDrawable, IHasCurrentValue where T : struct, IEquatable, IComparable, IConvertible { private readonly SettingsSlider slider; diff --git a/osu.Game/Screens/Edit/Timing/TapButton.cs b/osu.Game/Screens/Edit/Timing/TapButton.cs index 2944eea4fe..af5e6aa180 100644 --- a/osu.Game/Screens/Edit/Timing/TapButton.cs +++ b/osu.Game/Screens/Edit/Timing/TapButton.cs @@ -28,7 +28,7 @@ using osuTK.Input; namespace osu.Game.Screens.Edit.Timing { - internal class TapButton : CircularContainer, IKeyBindingHandler + internal partial class TapButton : CircularContainer, IKeyBindingHandler { public const float SIZE = 140; @@ -343,7 +343,7 @@ namespace osu.Game.Screens.Edit.Timing IsHandlingTapping.Value = false; } - private class Light : CompositeDrawable + private partial class Light : CompositeDrawable { public Drawable Glow { get; private set; } = null!; diff --git a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs index 3b26e335d9..09b3851333 100644 --- a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs +++ b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Timing { - public class TapTimingControl : CompositeDrawable + public partial class TapTimingControl : CompositeDrawable { [Resolved] private EditorClock editorClock { get; set; } = null!; @@ -233,7 +233,7 @@ namespace osu.Game.Screens.Edit.Timing timing.BeatLength = 60000 / (timing.BPM + adjust); } - private class InlineButton : OsuButton + private partial class InlineButton : OsuButton { private readonly IconUsage icon; private readonly Anchor anchor; diff --git a/osu.Game/Screens/Edit/Timing/TimingAdjustButton.cs b/osu.Game/Screens/Edit/Timing/TimingAdjustButton.cs index 16dea328da..4018eff5d6 100644 --- a/osu.Game/Screens/Edit/Timing/TimingAdjustButton.cs +++ b/osu.Game/Screens/Edit/Timing/TimingAdjustButton.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.Edit.Timing /// /// A button with variable constant output based on hold position and length. /// - public class TimingAdjustButton : CompositeDrawable + public partial class TimingAdjustButton : CompositeDrawable { public Action Action; @@ -112,7 +112,7 @@ namespace osu.Game.Screens.Edit.Timing return true; } - private class IncrementBox : CompositeDrawable + private partial class IncrementBox : CompositeDrawable { public readonly float Multiplier; diff --git a/osu.Game/Screens/Edit/Timing/TimingScreen.cs b/osu.Game/Screens/Edit/Timing/TimingScreen.cs index fd218209d4..43fca40526 100644 --- a/osu.Game/Screens/Edit/Timing/TimingScreen.cs +++ b/osu.Game/Screens/Edit/Timing/TimingScreen.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Timing { - public class TimingScreen : EditorScreenWithTimeline + public partial class TimingScreen : EditorScreenWithTimeline { [Cached] public readonly Bindable SelectedGroup = new Bindable(); @@ -48,7 +48,7 @@ namespace osu.Game.Screens.Edit.Timing } }; - public class ControlPointList : CompositeDrawable + public partial class ControlPointList : CompositeDrawable { private OsuButton deleteButton; private ControlPointTable table; diff --git a/osu.Game/Screens/Edit/Timing/TimingSection.cs b/osu.Game/Screens/Edit/Timing/TimingSection.cs index 9b86969db1..81abb266d4 100644 --- a/osu.Game/Screens/Edit/Timing/TimingSection.cs +++ b/osu.Game/Screens/Edit/Timing/TimingSection.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Screens.Edit.Timing { - internal class TimingSection : Section + internal partial class TimingSection : Section { private LabelledTimeSignature timeSignature; private BPMTextBox bpmTextEntry; @@ -69,7 +69,7 @@ namespace osu.Game.Screens.Edit.Timing }; } - private class BPMTextBox : LabelledTextBox + private partial class BPMTextBox : LabelledTextBox { private readonly BindableNumber beatLengthBindable = new TimingControlPoint().BeatLengthBindable; diff --git a/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs b/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs index 2956a28547..6c17aeed54 100644 --- a/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs +++ b/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs @@ -21,7 +21,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Edit.Timing { - internal class WaveformComparisonDisplay : CompositeDrawable + internal partial class WaveformComparisonDisplay : CompositeDrawable { private const int total_waveforms = 8; @@ -222,7 +222,7 @@ namespace osu.Game.Screens.Edit.Timing } } - internal class LockedOverlay : CompositeDrawable + internal partial class LockedOverlay : CompositeDrawable { private OsuSpriteText text = null!; @@ -285,7 +285,7 @@ namespace osu.Game.Screens.Edit.Timing } } - internal class WaveformRow : CompositeDrawable + internal partial class WaveformRow : CompositeDrawable { private readonly bool isMainRow; private OsuSpriteText beatIndexText = null!; diff --git a/osu.Game/Screens/Edit/TransactionalCommitComponent.cs b/osu.Game/Screens/Edit/TransactionalCommitComponent.cs index 78d052702a..55c9cf86c3 100644 --- a/osu.Game/Screens/Edit/TransactionalCommitComponent.cs +++ b/osu.Game/Screens/Edit/TransactionalCommitComponent.cs @@ -11,7 +11,7 @@ namespace osu.Game.Screens.Edit /// /// A component that tracks a batch change, only applying after all active changes are completed. /// - public abstract class TransactionalCommitComponent : Component + public abstract partial class TransactionalCommitComponent : Component { /// /// Fires whenever a transaction begins. Will not fire on nested transactions. diff --git a/osu.Game/Screens/Edit/Verify/InterpretationSection.cs b/osu.Game/Screens/Edit/Verify/InterpretationSection.cs index 276c2a3ea9..5b6eea098c 100644 --- a/osu.Game/Screens/Edit/Verify/InterpretationSection.cs +++ b/osu.Game/Screens/Edit/Verify/InterpretationSection.cs @@ -10,7 +10,7 @@ using osu.Game.Overlays.Settings; namespace osu.Game.Screens.Edit.Verify { - internal class InterpretationSection : EditorRoundedScreenSettingsSection + internal partial class InterpretationSection : EditorRoundedScreenSettingsSection { protected override string HeaderText => "Interpretation"; diff --git a/osu.Game/Screens/Edit/Verify/IssueList.cs b/osu.Game/Screens/Edit/Verify/IssueList.cs index bffda4ec41..907949aee8 100644 --- a/osu.Game/Screens/Edit/Verify/IssueList.cs +++ b/osu.Game/Screens/Edit/Verify/IssueList.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Screens.Edit.Verify { [Cached] - public class IssueList : CompositeDrawable + public partial class IssueList : CompositeDrawable { private IssueTable table; diff --git a/osu.Game/Screens/Edit/Verify/IssueSettings.cs b/osu.Game/Screens/Edit/Verify/IssueSettings.cs index 70065f6f0d..e8275c3684 100644 --- a/osu.Game/Screens/Edit/Verify/IssueSettings.cs +++ b/osu.Game/Screens/Edit/Verify/IssueSettings.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics; namespace osu.Game.Screens.Edit.Verify { - public class IssueSettings : EditorRoundedScreenSettings + public partial class IssueSettings : EditorRoundedScreenSettings { protected override IReadOnlyList CreateSections() => new Drawable[] { diff --git a/osu.Game/Screens/Edit/Verify/IssueTable.cs b/osu.Game/Screens/Edit/Verify/IssueTable.cs index f1a76dcbf5..6fdf9c76e2 100644 --- a/osu.Game/Screens/Edit/Verify/IssueTable.cs +++ b/osu.Game/Screens/Edit/Verify/IssueTable.cs @@ -18,7 +18,7 @@ using osu.Game.Rulesets.Edit.Checks.Components; namespace osu.Game.Screens.Edit.Verify { - public class IssueTable : EditorTable + public partial class IssueTable : EditorTable { [Resolved] private VerifyScreen verify { get; set; } diff --git a/osu.Game/Screens/Edit/Verify/VerifyScreen.cs b/osu.Game/Screens/Edit/Verify/VerifyScreen.cs index 3030018138..b17cf3379e 100644 --- a/osu.Game/Screens/Edit/Verify/VerifyScreen.cs +++ b/osu.Game/Screens/Edit/Verify/VerifyScreen.cs @@ -13,7 +13,7 @@ using osu.Game.Rulesets.Edit.Checks.Components; namespace osu.Game.Screens.Edit.Verify { [Cached] - public class VerifyScreen : EditorScreen + public partial class VerifyScreen : EditorScreen { public readonly Bindable SelectedIssue = new Bindable(); diff --git a/osu.Game/Screens/Edit/Verify/VisibilitySection.cs b/osu.Game/Screens/Edit/Verify/VisibilitySection.cs index fbf6982984..e2e2e518ae 100644 --- a/osu.Game/Screens/Edit/Verify/VisibilitySection.cs +++ b/osu.Game/Screens/Edit/Verify/VisibilitySection.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Edit.Checks.Components; namespace osu.Game.Screens.Edit.Verify { - internal class VisibilitySection : EditorRoundedScreenSettingsSection + internal partial class VisibilitySection : EditorRoundedScreenSettingsSection { private readonly IssueType[] configurableIssueTypes = { diff --git a/osu.Game/Screens/Import/FileImportScreen.cs b/osu.Game/Screens/Import/FileImportScreen.cs index e3d8de2dfd..dde4e9c326 100644 --- a/osu.Game/Screens/Import/FileImportScreen.cs +++ b/osu.Game/Screens/Import/FileImportScreen.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Screens.Import { - public class FileImportScreen : OsuScreen + public partial class FileImportScreen : OsuScreen { public override bool HideOverlaysOnEnter => true; diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index ac22fdce71..b70c1f7ddf 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -19,7 +19,7 @@ using IntroSequence = osu.Game.Configuration.IntroSequence; namespace osu.Game.Screens { - public class Loader : StartupScreen + public partial class Loader : StartupScreen { private bool showDisclaimer; @@ -116,7 +116,7 @@ namespace osu.Game.Screens /// /// Compiles a set of shaders before continuing. Attempts to draw some frames between compilation by limiting to one compile per draw frame. /// - public class ShaderPrecompiler : Drawable + public partial class ShaderPrecompiler : Drawable { private readonly List loadTargets = new List(); diff --git a/osu.Game/Screens/Menu/ButtonArea.cs b/osu.Game/Screens/Menu/ButtonArea.cs index bf6e0cee83..69ba68442f 100644 --- a/osu.Game/Screens/Menu/ButtonArea.cs +++ b/osu.Game/Screens/Menu/ButtonArea.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Screens.Menu { - public class ButtonArea : Container, IStateful + public partial class ButtonArea : Container, IStateful { public FlowContainerWithOrigin Flow; @@ -90,7 +90,7 @@ namespace osu.Game.Screens.Menu public event Action StateChanged; - private class ButtonAreaBackground : Box, IStateful + private partial class ButtonAreaBackground : Box, IStateful { private ButtonAreaBackgroundState state; diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 04bffda81b..2ead18c3d6 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -34,7 +34,7 @@ using osuTK.Input; namespace osu.Game.Screens.Menu { - public class ButtonSystem : Container, IStateful, IKeyBindingHandler + public partial class ButtonSystem : Container, IStateful, IKeyBindingHandler { public event Action StateChanged; diff --git a/osu.Game/Screens/Menu/ConfirmDiscardChangesDialog.cs b/osu.Game/Screens/Menu/ConfirmDiscardChangesDialog.cs index 450c559450..0cd3e9ce71 100644 --- a/osu.Game/Screens/Menu/ConfirmDiscardChangesDialog.cs +++ b/osu.Game/Screens/Menu/ConfirmDiscardChangesDialog.cs @@ -7,7 +7,7 @@ using osu.Game.Overlays.Dialog; namespace osu.Game.Screens.Menu { - public class ConfirmDiscardChangesDialog : PopupDialog + public partial class ConfirmDiscardChangesDialog : PopupDialog { /// /// Construct a new discard changes confirmation dialog. diff --git a/osu.Game/Screens/Menu/ConfirmExitDialog.cs b/osu.Game/Screens/Menu/ConfirmExitDialog.cs index 20fa889986..4906232d21 100644 --- a/osu.Game/Screens/Menu/ConfirmExitDialog.cs +++ b/osu.Game/Screens/Menu/ConfirmExitDialog.cs @@ -7,7 +7,7 @@ using osu.Game.Overlays.Dialog; namespace osu.Game.Screens.Menu { - public class ConfirmExitDialog : PopupDialog + public partial class ConfirmExitDialog : PopupDialog { /// /// Construct a new exit confirmation dialog. diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index a81658a4b6..e30be72704 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -22,7 +22,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Menu { - public class Disclaimer : StartupScreen + public partial class Disclaimer : StartupScreen { private SpriteIcon icon; private Color4 iconColour; diff --git a/osu.Game/Screens/Menu/ExitConfirmOverlay.cs b/osu.Game/Screens/Menu/ExitConfirmOverlay.cs index f82a6c9736..bc2f6ea00f 100644 --- a/osu.Game/Screens/Menu/ExitConfirmOverlay.cs +++ b/osu.Game/Screens/Menu/ExitConfirmOverlay.cs @@ -10,7 +10,7 @@ using osu.Game.Overlays; namespace osu.Game.Screens.Menu { - public class ExitConfirmOverlay : HoldToConfirmOverlay, IKeyBindingHandler + public partial class ExitConfirmOverlay : HoldToConfirmOverlay, IKeyBindingHandler { protected override bool AllowMultipleFires => true; diff --git a/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs b/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs index 24a365ffd1..e36cc4a152 100644 --- a/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs +++ b/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs @@ -12,7 +12,7 @@ namespace osu.Game.Screens.Menu /// /// A flow container with an origin based on one of its contained drawables. /// - public class FlowContainerWithOrigin : FillFlowContainer + public partial class FlowContainerWithOrigin : FillFlowContainer { /// /// A target drawable which this flowcontainer should be centered around. diff --git a/osu.Game/Screens/Menu/IntroCircles.cs b/osu.Game/Screens/Menu/IntroCircles.cs index 7a4bdb231f..57a3fd9c38 100644 --- a/osu.Game/Screens/Menu/IntroCircles.cs +++ b/osu.Game/Screens/Menu/IntroCircles.cs @@ -13,7 +13,7 @@ using osu.Framework.Graphics; namespace osu.Game.Screens.Menu { - public class IntroCircles : IntroScreen + public partial class IntroCircles : IntroScreen { protected override string BeatmapHash => "3c8b1fcc9434dbb29e2fb613d3b9eada9d7bb6c125ceb32396c3b53437280c83"; diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index dcead4a3a8..f632d9ee73 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -32,7 +32,7 @@ using Realms; namespace osu.Game.Screens.Menu { - public abstract class IntroScreen : StartupScreen + public abstract partial class IntroScreen : StartupScreen { /// /// Whether we have loaded the menu previously. diff --git a/osu.Game/Screens/Menu/IntroSequence.cs b/osu.Game/Screens/Menu/IntroSequence.cs index bc5aa83503..722f884ac5 100644 --- a/osu.Game/Screens/Menu/IntroSequence.cs +++ b/osu.Game/Screens/Menu/IntroSequence.cs @@ -16,7 +16,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Screens.Menu { - public class IntroSequence : Container + public partial class IntroSequence : Container { private const float logo_size = 460; //todo: this should probably be 480 @@ -266,7 +266,7 @@ namespace osu.Game.Screens.Menu } } - private class Ring : Container + private partial class Ring : Container { public readonly Circle Foreground; diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index 4ec877b85a..a9c86b10c4 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -25,7 +25,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Menu { - public class IntroTriangles : IntroScreen + public partial class IntroTriangles : IntroScreen { protected override string BeatmapHash => "a1556d0801b3a6b175dda32ef546f0ec812b400499f575c44fccbe9c67f9b1e5"; @@ -107,7 +107,7 @@ namespace osu.Game.Screens.Menu intro.Expire(); } - private class TrianglesIntroSequence : CompositeDrawable + private partial class TrianglesIntroSequence : CompositeDrawable { private readonly OsuLogo logo; private readonly Action showBackgroundAction; @@ -269,7 +269,7 @@ namespace osu.Game.Screens.Menu } } - private class GameWideFlash : Box + private partial class GameWideFlash : Box { private const double flash_length = 1000; @@ -287,7 +287,7 @@ namespace osu.Game.Screens.Menu } } - private class LazerLogo : CompositeDrawable + private partial class LazerLogo : CompositeDrawable { private LogoAnimation highlight, background; @@ -327,7 +327,7 @@ namespace osu.Game.Screens.Menu } } - private class RulesetFlow : FillFlowContainer + private partial class RulesetFlow : FillFlowContainer { [BackgroundDependencyLoader] private void load(RulesetStore rulesets) @@ -357,7 +357,7 @@ namespace osu.Game.Screens.Menu } } - private class GlitchingTriangles : CompositeDrawable + private partial class GlitchingTriangles : CompositeDrawable { public GlitchingTriangles() { @@ -391,7 +391,7 @@ namespace osu.Game.Screens.Menu /// /// Represents a sprite that is drawn in a triangle shape, instead of a rectangle shape. /// - public class OutlineTriangle : BufferedContainer + public partial class OutlineTriangle : BufferedContainer { public OutlineTriangle(bool outlineOnly, float size) : base(cachedFrameBuffer: true) diff --git a/osu.Game/Screens/Menu/IntroWelcome.cs b/osu.Game/Screens/Menu/IntroWelcome.cs index 5ae2158172..da44161507 100644 --- a/osu.Game/Screens/Menu/IntroWelcome.cs +++ b/osu.Game/Screens/Menu/IntroWelcome.cs @@ -21,7 +21,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Menu { - public class IntroWelcome : IntroScreen + public partial class IntroWelcome : IntroScreen { protected override string BeatmapHash => "64e00d7022195959bfa3109d09c2e2276c8f12f486b91fcf6175583e973b48f2"; protected override string BeatmapFile => "welcome.osz"; @@ -103,7 +103,7 @@ namespace osu.Game.Screens.Menu } } - private class WelcomeIntroSequence : Container + private partial class WelcomeIntroSequence : Container { private Drawable welcomeText; private Container scaleContainer; diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 4a20d7cb2b..c67850bdf6 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -24,7 +24,7 @@ namespace osu.Game.Screens.Menu /// /// A visualiser that reacts to music coming from beatmaps. /// - public class LogoVisualisation : Drawable + public partial class LogoVisualisation : Drawable { /// /// The number of bars to jump each update iteration. diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 0071ada05a..69b8596474 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -32,7 +32,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Menu { - public class MainMenu : OsuScreen, IHandlePresentBeatmap, IKeyBindingHandler + public partial class MainMenu : OsuScreen, IHandlePresentBeatmap, IKeyBindingHandler { public const float FADE_IN_DURATION = 300; diff --git a/osu.Game/Screens/Menu/MainMenuButton.cs b/osu.Game/Screens/Menu/MainMenuButton.cs index f2b57b185e..cd3795711e 100644 --- a/osu.Game/Screens/Menu/MainMenuButton.cs +++ b/osu.Game/Screens/Menu/MainMenuButton.cs @@ -30,7 +30,7 @@ namespace osu.Game.Screens.Menu /// Button designed specifically for the osu!next main menu. /// In order to correctly flow, we have to use a negative margin on the parent container (due to the parallelogram shape). /// - public class MainMenuButton : BeatSyncedContainer, IStateful + public partial class MainMenuButton : BeatSyncedContainer, IStateful { public event Action StateChanged; diff --git a/osu.Game/Screens/Menu/MenuLogoVisualisation.cs b/osu.Game/Screens/Menu/MenuLogoVisualisation.cs index 4324f02c84..f4e992be9a 100644 --- a/osu.Game/Screens/Menu/MenuLogoVisualisation.cs +++ b/osu.Game/Screens/Menu/MenuLogoVisualisation.cs @@ -12,7 +12,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Screens.Menu { - internal class MenuLogoVisualisation : LogoVisualisation + internal partial class MenuLogoVisualisation : LogoVisualisation { private IBindable user; private Bindable skin; diff --git a/osu.Game/Screens/Menu/MenuSideFlashes.cs b/osu.Game/Screens/Menu/MenuSideFlashes.cs index 5214d87ee9..533c39826c 100644 --- a/osu.Game/Screens/Menu/MenuSideFlashes.cs +++ b/osu.Game/Screens/Menu/MenuSideFlashes.cs @@ -22,7 +22,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Screens.Menu { - public class MenuSideFlashes : BeatSyncedContainer + public partial class MenuSideFlashes : BeatSyncedContainer { private readonly IBindable beatmap = new Bindable(); diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 3efd74d2c8..2d6a0736e9 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -29,7 +29,7 @@ namespace osu.Game.Screens.Menu /// /// osu! logo and its attachments (pulsing, visualiser etc.) /// - public class OsuLogo : BeatSyncedContainer + public partial class OsuLogo : BeatSyncedContainer { public readonly Color4 OsuPink = Color4Extensions.FromHex(@"e967a1"); diff --git a/osu.Game/Screens/Menu/SongTicker.cs b/osu.Game/Screens/Menu/SongTicker.cs index 6574c9a696..bac7e15461 100644 --- a/osu.Game/Screens/Menu/SongTicker.cs +++ b/osu.Game/Screens/Menu/SongTicker.cs @@ -15,7 +15,7 @@ using osu.Game.Beatmaps; namespace osu.Game.Screens.Menu { - public class SongTicker : Container + public partial class SongTicker : Container { private const int fade_duration = 800; diff --git a/osu.Game/Screens/Menu/StorageErrorDialog.cs b/osu.Game/Screens/Menu/StorageErrorDialog.cs index 28ef413179..ba05ad8b76 100644 --- a/osu.Game/Screens/Menu/StorageErrorDialog.cs +++ b/osu.Game/Screens/Menu/StorageErrorDialog.cs @@ -12,7 +12,7 @@ using osu.Game.Overlays.Dialog; namespace osu.Game.Screens.Menu { - public class StorageErrorDialog : PopupDialog + public partial class StorageErrorDialog : PopupDialog { [Resolved] private IDialogOverlay dialogOverlay { get; set; } diff --git a/osu.Game/Screens/OnlinePlay/Components/BeatmapTitle.cs b/osu.Game/Screens/OnlinePlay/Components/BeatmapTitle.cs index 39a887f820..ebcc08360e 100644 --- a/osu.Game/Screens/OnlinePlay/Components/BeatmapTitle.cs +++ b/osu.Game/Screens/OnlinePlay/Components/BeatmapTitle.cs @@ -13,7 +13,7 @@ using osu.Game.Online.Chat; namespace osu.Game.Screens.OnlinePlay.Components { - public class BeatmapTitle : OnlinePlayComposite + public partial class BeatmapTitle : OnlinePlayComposite { private readonly LinkFlowContainer textFlow; diff --git a/osu.Game/Screens/OnlinePlay/Components/DisableableTabControl.cs b/osu.Game/Screens/OnlinePlay/Components/DisableableTabControl.cs index 22839ab4d4..3f7f38f3bc 100644 --- a/osu.Game/Screens/OnlinePlay/Components/DisableableTabControl.cs +++ b/osu.Game/Screens/OnlinePlay/Components/DisableableTabControl.cs @@ -9,7 +9,7 @@ using osu.Framework.Input.Events; namespace osu.Game.Screens.OnlinePlay.Components { - public abstract class DisableableTabControl : TabControl + public abstract partial class DisableableTabControl : TabControl { public readonly BindableBool Enabled = new BindableBool(true); @@ -20,7 +20,7 @@ namespace osu.Game.Screens.OnlinePlay.Components base.AddTabItem(tab, addToDropdown); } - protected abstract class DisableableTabItem : TabItem + protected abstract partial class DisableableTabItem : TabItem { protected DisableableTabItem(T value) : base(value) diff --git a/osu.Game/Screens/OnlinePlay/Components/DrawableGameType.cs b/osu.Game/Screens/OnlinePlay/Components/DrawableGameType.cs index c97e52c247..77e461ce41 100644 --- a/osu.Game/Screens/OnlinePlay/Components/DrawableGameType.cs +++ b/osu.Game/Screens/OnlinePlay/Components/DrawableGameType.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.OnlinePlay.Components { - public class DrawableGameType : CircularContainer, IHasTooltip + public partial class DrawableGameType : CircularContainer, IHasTooltip { private readonly MatchType type; @@ -132,7 +132,7 @@ namespace osu.Game.Screens.OnlinePlay.Components } } - private class VersusRow : FillFlowContainer + private partial class VersusRow : FillFlowContainer { public VersusRow(Color4 first, Color4 second, float size) { diff --git a/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs b/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs index 1ea84b60b9..c296e2a86b 100644 --- a/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs +++ b/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs @@ -15,7 +15,7 @@ namespace osu.Game.Screens.OnlinePlay.Components /// /// A that polls for the lounge listing. /// - public class ListingPollingComponent : RoomPollingComponent + public partial class ListingPollingComponent : RoomPollingComponent { public IBindable InitialRoomsReceived => initialRoomsReceived; private readonly Bindable initialRoomsReceived = new Bindable(); diff --git a/osu.Game/Screens/OnlinePlay/Components/MatchBeatmapDetailArea.cs b/osu.Game/Screens/OnlinePlay/Components/MatchBeatmapDetailArea.cs index 9a48769405..b2a8575c3d 100644 --- a/osu.Game/Screens/OnlinePlay/Components/MatchBeatmapDetailArea.cs +++ b/osu.Game/Screens/OnlinePlay/Components/MatchBeatmapDetailArea.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Components { - public class MatchBeatmapDetailArea : BeatmapDetailArea + public partial class MatchBeatmapDetailArea : BeatmapDetailArea { public Action CreateNewItem; diff --git a/osu.Game/Screens/OnlinePlay/Components/OnlinePlayBackgroundScreen.cs b/osu.Game/Screens/OnlinePlay/Components/OnlinePlayBackgroundScreen.cs index 8c65649cc6..014473dfee 100644 --- a/osu.Game/Screens/OnlinePlay/Components/OnlinePlayBackgroundScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Components/OnlinePlayBackgroundScreen.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.OnlinePlay.Components { - public abstract class OnlinePlayBackgroundScreen : BackgroundScreen + public abstract partial class OnlinePlayBackgroundScreen : BackgroundScreen { private CancellationTokenSource? cancellationSource; private PlaylistItemBackground? background; diff --git a/osu.Game/Screens/OnlinePlay/Components/OnlinePlayBackgroundSprite.cs b/osu.Game/Screens/OnlinePlay/Components/OnlinePlayBackgroundSprite.cs index fe89eaf591..0d4cd30090 100644 --- a/osu.Game/Screens/OnlinePlay/Components/OnlinePlayBackgroundSprite.cs +++ b/osu.Game/Screens/OnlinePlay/Components/OnlinePlayBackgroundSprite.cs @@ -10,7 +10,7 @@ using osu.Game.Online.Rooms; namespace osu.Game.Screens.OnlinePlay.Components { - public class OnlinePlayBackgroundSprite : OnlinePlayComposite + public partial class OnlinePlayBackgroundSprite : OnlinePlayComposite { protected readonly BeatmapSetCoverType BeatmapSetCoverType; private UpdateableBeatmapBackgroundSprite sprite; diff --git a/osu.Game/Screens/OnlinePlay/Components/OverlinedHeader.cs b/osu.Game/Screens/OnlinePlay/Components/OverlinedHeader.cs index b953136fdd..0e2ce6703f 100644 --- a/osu.Game/Screens/OnlinePlay/Components/OverlinedHeader.cs +++ b/osu.Game/Screens/OnlinePlay/Components/OverlinedHeader.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.OnlinePlay.Components /// /// A header used in the multiplayer interface which shows text / details beneath a line. /// - public class OverlinedHeader : OnlinePlayComposite + public partial class OverlinedHeader : OnlinePlayComposite { private bool showLine = true; diff --git a/osu.Game/Screens/OnlinePlay/Components/OverlinedPlaylistHeader.cs b/osu.Game/Screens/OnlinePlay/Components/OverlinedPlaylistHeader.cs index a268d4d917..f8dcd7b75d 100644 --- a/osu.Game/Screens/OnlinePlay/Components/OverlinedPlaylistHeader.cs +++ b/osu.Game/Screens/OnlinePlay/Components/OverlinedPlaylistHeader.cs @@ -7,7 +7,7 @@ using osu.Game.Online.Rooms; namespace osu.Game.Screens.OnlinePlay.Components { - public class OverlinedPlaylistHeader : OverlinedHeader + public partial class OverlinedPlaylistHeader : OverlinedHeader { public OverlinedPlaylistHeader() : base("Playlist") diff --git a/osu.Game/Screens/OnlinePlay/Components/ParticipantCountDisplay.cs b/osu.Game/Screens/OnlinePlay/Components/ParticipantCountDisplay.cs index 71b33bf247..9f7e700ab3 100644 --- a/osu.Game/Screens/OnlinePlay/Components/ParticipantCountDisplay.cs +++ b/osu.Game/Screens/OnlinePlay/Components/ParticipantCountDisplay.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Screens.OnlinePlay.Components { - public class ParticipantCountDisplay : OnlinePlayComposite + public partial class ParticipantCountDisplay : OnlinePlayComposite { private const float text_size = 30; private const float transition_duration = 100; diff --git a/osu.Game/Screens/OnlinePlay/Components/ParticipantsDisplay.cs b/osu.Game/Screens/OnlinePlay/Components/ParticipantsDisplay.cs index c66ae8b6d5..4fdf41d0f7 100644 --- a/osu.Game/Screens/OnlinePlay/Components/ParticipantsDisplay.cs +++ b/osu.Game/Screens/OnlinePlay/Components/ParticipantsDisplay.cs @@ -10,7 +10,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Screens.OnlinePlay.Components { - public class ParticipantsDisplay : OnlinePlayComposite + public partial class ParticipantsDisplay : OnlinePlayComposite { public Bindable Details = new Bindable(); diff --git a/osu.Game/Screens/OnlinePlay/Components/ParticipantsList.cs b/osu.Game/Screens/OnlinePlay/Components/ParticipantsList.cs index 2f38321e13..00f0889cc8 100644 --- a/osu.Game/Screens/OnlinePlay/Components/ParticipantsList.cs +++ b/osu.Game/Screens/OnlinePlay/Components/ParticipantsList.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Components { - public class ParticipantsList : OnlinePlayComposite + public partial class ParticipantsList : OnlinePlayComposite { public const float TILE_SIZE = 35; @@ -92,7 +92,7 @@ namespace osu.Game.Screens.OnlinePlay.Components }); } - private class UserTile : CompositeDrawable + private partial class UserTile : CompositeDrawable { public APIUser User { diff --git a/osu.Game/Screens/OnlinePlay/Components/PlaylistItemBackground.cs b/osu.Game/Screens/OnlinePlay/Components/PlaylistItemBackground.cs index d882b3d97f..997ba6b639 100644 --- a/osu.Game/Screens/OnlinePlay/Components/PlaylistItemBackground.cs +++ b/osu.Game/Screens/OnlinePlay/Components/PlaylistItemBackground.cs @@ -9,7 +9,7 @@ using osu.Game.Online.Rooms; namespace osu.Game.Screens.OnlinePlay.Components { - public class PlaylistItemBackground : Background + public partial class PlaylistItemBackground : Background { public readonly IBeatmapInfo? Beatmap; diff --git a/osu.Game/Screens/OnlinePlay/Components/ReadyButton.cs b/osu.Game/Screens/OnlinePlay/Components/ReadyButton.cs index 0871fc9a72..81ed88b8a3 100644 --- a/osu.Game/Screens/OnlinePlay/Components/ReadyButton.cs +++ b/osu.Game/Screens/OnlinePlay/Components/ReadyButton.cs @@ -13,7 +13,7 @@ using osu.Game.Online.Rooms; namespace osu.Game.Screens.OnlinePlay.Components { - public abstract class ReadyButton : TriangleButton, IHasTooltip + public abstract partial class ReadyButton : TriangleButton, IHasTooltip { public new readonly BindableBool Enabled = new BindableBool(); diff --git a/osu.Game/Screens/OnlinePlay/Components/RoomLocalUserInfo.cs b/osu.Game/Screens/OnlinePlay/Components/RoomLocalUserInfo.cs index cc517ca080..0c3b53266c 100644 --- a/osu.Game/Screens/OnlinePlay/Components/RoomLocalUserInfo.cs +++ b/osu.Game/Screens/OnlinePlay/Components/RoomLocalUserInfo.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Screens.OnlinePlay.Components { - public class RoomLocalUserInfo : OnlinePlayComposite + public partial class RoomLocalUserInfo : OnlinePlayComposite { private OsuSpriteText attemptDisplay; diff --git a/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs b/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs index 35dc251e4d..539d5b74b3 100644 --- a/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs +++ b/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs @@ -17,7 +17,7 @@ using osu.Game.Online.Rooms; namespace osu.Game.Screens.OnlinePlay.Components { - public class RoomManager : Component, IRoomManager + public partial class RoomManager : Component, IRoomManager { public event Action RoomsUpdated; diff --git a/osu.Game/Screens/OnlinePlay/Components/RoomPollingComponent.cs b/osu.Game/Screens/OnlinePlay/Components/RoomPollingComponent.cs index 039e1d92b7..395a77b9e6 100644 --- a/osu.Game/Screens/OnlinePlay/Components/RoomPollingComponent.cs +++ b/osu.Game/Screens/OnlinePlay/Components/RoomPollingComponent.cs @@ -9,7 +9,7 @@ using osu.Game.Online.API; namespace osu.Game.Screens.OnlinePlay.Components { - public abstract class RoomPollingComponent : PollingComponent + public abstract partial class RoomPollingComponent : PollingComponent { [Resolved] protected IAPIProvider API { get; private set; } diff --git a/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs b/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs index 3b8ba739d9..780ee29e41 100644 --- a/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs +++ b/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs @@ -11,7 +11,7 @@ namespace osu.Game.Screens.OnlinePlay.Components /// /// A that polls for the currently-selected room. /// - public class SelectionPollingComponent : RoomPollingComponent + public partial class SelectionPollingComponent : RoomPollingComponent { private readonly Room room; diff --git a/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs b/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs index b6ef080e44..93c8faf0b0 100644 --- a/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs +++ b/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Components { - public class StarRatingRangeDisplay : OnlinePlayComposite + public partial class StarRatingRangeDisplay : OnlinePlayComposite { [Resolved] private OsuColour colours { get; set; } diff --git a/osu.Game/Screens/OnlinePlay/Components/StatusColouredContainer.cs b/osu.Game/Screens/OnlinePlay/Components/StatusColouredContainer.cs index 6122e7ec5e..ed39021a73 100644 --- a/osu.Game/Screens/OnlinePlay/Components/StatusColouredContainer.cs +++ b/osu.Game/Screens/OnlinePlay/Components/StatusColouredContainer.cs @@ -12,7 +12,7 @@ using osu.Game.Online.Rooms; namespace osu.Game.Screens.OnlinePlay.Components { - public class StatusColouredContainer : Container + public partial class StatusColouredContainer : Container { private readonly double transitionDuration; diff --git a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylist.cs b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylist.cs index ed554ebd34..f5477837b0 100644 --- a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylist.cs +++ b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylist.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.OnlinePlay /// /// A scrollable list which displays the s in a . /// - public class DrawableRoomPlaylist : OsuRearrangeableListContainer, IKeyBindingHandler + public partial class DrawableRoomPlaylist : OsuRearrangeableListContainer, IKeyBindingHandler { /// /// The currently-selected item. Selection is visually represented with a border. diff --git a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs index bda616d5c3..3fab0fc180 100644 --- a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs +++ b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs @@ -42,7 +42,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.OnlinePlay { - public class DrawableRoomPlaylistItem : OsuRearrangeableListItem, IHasContextMenu + public partial class DrawableRoomPlaylistItem : OsuRearrangeableListItem, IHasContextMenu { public const float HEIGHT = 50; @@ -512,7 +512,7 @@ namespace osu.Game.Screens.OnlinePlay } } - public class PlaylistEditButton : GrayButton + public partial class PlaylistEditButton : GrayButton { public PlaylistEditButton() : base(FontAwesome.Solid.Edit) @@ -520,7 +520,7 @@ namespace osu.Game.Screens.OnlinePlay } } - public class PlaylistRemoveButton : GrayButton + public partial class PlaylistRemoveButton : GrayButton { public PlaylistRemoveButton() : base(FontAwesome.Solid.MinusSquare) @@ -528,7 +528,7 @@ namespace osu.Game.Screens.OnlinePlay } } - private sealed class PlaylistDownloadButton : BeatmapDownloadButton + private sealed partial class PlaylistDownloadButton : BeatmapDownloadButton { private readonly IBeatmapInfo beatmap; @@ -586,7 +586,7 @@ namespace osu.Game.Screens.OnlinePlay } // For now, this is the same implementation as in PanelBackground, but supports a beatmap info rather than a working beatmap - private class PanelBackground : Container // todo: should be a buffered container (https://github.com/ppy/osu-framework/issues/3222) + private partial class PanelBackground : Container // todo: should be a buffered container (https://github.com/ppy/osu-framework/issues/3222) { public readonly Bindable Beatmap = new Bindable(); @@ -641,7 +641,7 @@ namespace osu.Game.Screens.OnlinePlay } } - private class OwnerAvatar : UpdateableAvatar, IHasTooltip + private partial class OwnerAvatar : UpdateableAvatar, IHasTooltip { public OwnerAvatar() { @@ -654,7 +654,7 @@ namespace osu.Game.Screens.OnlinePlay public LocalisableString TooltipText => User == null ? string.Empty : $"queued by {User.Username}"; - private class TooltipArea : Component, IHasTooltip + private partial class TooltipArea : Component, IHasTooltip { private readonly OwnerAvatar avatar; diff --git a/osu.Game/Screens/OnlinePlay/FooterButtonFreeMods.cs b/osu.Game/Screens/OnlinePlay/FooterButtonFreeMods.cs index 9e589b362b..98f3df525d 100644 --- a/osu.Game/Screens/OnlinePlay/FooterButtonFreeMods.cs +++ b/osu.Game/Screens/OnlinePlay/FooterButtonFreeMods.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay { - public class FooterButtonFreeMods : FooterButton, IHasCurrentValue> + public partial class FooterButtonFreeMods : FooterButton, IHasCurrentValue> { public Bindable> Current { diff --git a/osu.Game/Screens/OnlinePlay/FreeModSelectOverlay.cs b/osu.Game/Screens/OnlinePlay/FreeModSelectOverlay.cs index 0f02692eda..6313d907a5 100644 --- a/osu.Game/Screens/OnlinePlay/FreeModSelectOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/FreeModSelectOverlay.cs @@ -14,7 +14,7 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Screens.OnlinePlay { - public class FreeModSelectOverlay : ModSelectOverlay + public partial class FreeModSelectOverlay : ModSelectOverlay { protected override bool ShowTotalMultiplier => false; diff --git a/osu.Game/Screens/OnlinePlay/Header.cs b/osu.Game/Screens/OnlinePlay/Header.cs index a9e9f046e2..4c4851c3ac 100644 --- a/osu.Game/Screens/OnlinePlay/Header.cs +++ b/osu.Game/Screens/OnlinePlay/Header.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay { - public class Header : Container + public partial class Header : Container { public const float HEIGHT = 80; @@ -44,7 +44,7 @@ namespace osu.Game.Screens.OnlinePlay private void updateSubScreenTitle() => title.Screen = stack.CurrentScreen as IOnlinePlaySubScreen; - private class MultiHeaderTitle : CompositeDrawable + private partial class MultiHeaderTitle : CompositeDrawable { private const float spacing = 6; diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs index 7e39a52c0a..8c85a8235c 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs @@ -29,7 +29,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.OnlinePlay.Lounge.Components { - public class DrawableRoom : CompositeDrawable + public partial class DrawableRoom : CompositeDrawable { protected const float CORNER_RADIUS = 10; private const float height = 100; @@ -311,7 +311,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components return pills; } - private class RoomNameText : OsuSpriteText + private partial class RoomNameText : OsuSpriteText { [Resolved(typeof(Room), nameof(Online.Rooms.Room.Name))] private Bindable name { get; set; } @@ -328,7 +328,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components } } - private class RoomStatusText : OnlinePlayComposite + private partial class RoomStatusText : OnlinePlayComposite { [Resolved] private OsuColour colours { get; set; } @@ -434,7 +434,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components } } - public class PasswordProtectedIcon : CompositeDrawable + public partial class PasswordProtectedIcon : CompositeDrawable { [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoomParticipantsList.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoomParticipantsList.cs index 9e2bd41fd0..3b66355dab 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoomParticipantsList.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoomParticipantsList.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Lounge.Components { - public class DrawableRoomParticipantsList : OnlinePlayComposite + public partial class DrawableRoomParticipantsList : OnlinePlayComposite { private const float avatar_size = 36; @@ -270,7 +270,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components } } - private class CircularAvatar : CompositeDrawable + private partial class CircularAvatar : CompositeDrawable { public APIUser User { @@ -302,7 +302,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components } } - public class HiddenUserCount : CompositeDrawable + public partial class HiddenUserCount : CompositeDrawable { public int Count { diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/EndDateInfo.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/EndDateInfo.cs index d951b42854..c25dd6f158 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/EndDateInfo.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/EndDateInfo.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics; namespace osu.Game.Screens.OnlinePlay.Lounge.Components { - public class EndDateInfo : OnlinePlayComposite + public partial class EndDateInfo : OnlinePlayComposite { public EndDateInfo() { @@ -30,7 +30,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components }; } - private class EndDatePart : DrawableDate + private partial class EndDatePart : DrawableDate { public readonly IBindable EndDate = new Bindable(); diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/MatchTypePill.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/MatchTypePill.cs index b2e527766a..f96d547747 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/MatchTypePill.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/MatchTypePill.cs @@ -13,7 +13,7 @@ using osu.Game.Online.Rooms; namespace osu.Game.Screens.OnlinePlay.Lounge.Components { - public class MatchTypePill : OnlinePlayComposite + public partial class MatchTypePill : OnlinePlayComposite { private OsuTextFlowContainer textFlow; diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/PillContainer.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/PillContainer.cs index b17873b1c8..263261143d 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/PillContainer.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/PillContainer.cs @@ -13,7 +13,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components /// /// Displays contents in a "pill". /// - public class PillContainer : Container + public partial class PillContainer : Container { private const float padding = 8; diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/PlaylistCountPill.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/PlaylistCountPill.cs index 474463d5f1..81ba48d135 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/PlaylistCountPill.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/PlaylistCountPill.cs @@ -16,7 +16,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components /// /// A pill that displays the playlist item count. /// - public class PlaylistCountPill : OnlinePlayComposite + public partial class PlaylistCountPill : OnlinePlayComposite { private OsuTextFlowContainer count; diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/QueueModePill.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/QueueModePill.cs index 85177ee32c..0175418a96 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/QueueModePill.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/QueueModePill.cs @@ -13,7 +13,7 @@ using osu.Game.Online.Multiplayer; namespace osu.Game.Screens.OnlinePlay.Lounge.Components { - public class QueueModePill : OnlinePlayComposite + public partial class QueueModePill : OnlinePlayComposite { private OsuTextFlowContainer textFlow; diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/RankRangePill.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/RankRangePill.cs index fa531a0d14..adfc44fbd4 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/RankRangePill.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/RankRangePill.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Lounge.Components { - public class RankRangePill : MultiplayerRoomComposite + public partial class RankRangePill : MultiplayerRoomComposite { private OsuTextFlowContainer rankFlow; diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomSpecialCategoryPill.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomSpecialCategoryPill.cs index 0f9bfb22e8..5d67a18d1f 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomSpecialCategoryPill.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomSpecialCategoryPill.cs @@ -13,7 +13,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.OnlinePlay.Lounge.Components { - public class RoomSpecialCategoryPill : OnlinePlayComposite + public partial class RoomSpecialCategoryPill : OnlinePlayComposite { private SpriteText text; private PillContainer pill; diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomStatusPill.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomStatusPill.cs index f37ec9d9d4..201314851e 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomStatusPill.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomStatusPill.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components /// /// A pill that displays the room's current status. /// - public class RoomStatusPill : OnlinePlayComposite + public partial class RoomStatusPill : OnlinePlayComposite { [Resolved] private OsuColour colours { get; set; } diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs index e6b1942506..e723dfe3e6 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs @@ -21,7 +21,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Lounge.Components { - public class RoomsContainer : CompositeDrawable, IKeyBindingHandler + public partial class RoomsContainer : CompositeDrawable, IKeyBindingHandler { public readonly Bindable SelectedRoom = new Bindable(); public readonly Bindable Filter = new Bindable(); diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index 8a2aeb9e5e..79ffa5f666 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -34,7 +34,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge /// /// A with lounge-specific interactions such as selection and hover sounds. /// - public class DrawableLoungeRoom : DrawableRoom, IFilterable, IHasContextMenu, IHasPopover, IKeyBindingHandler + public partial class DrawableLoungeRoom : DrawableRoom, IFilterable, IHasContextMenu, IHasPopover, IKeyBindingHandler { private const float transition_duration = 60; private const float selection_border_width = 4; @@ -180,7 +180,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge return true; } - public class PasswordEntryPopover : OsuPopover + public partial class PasswordEntryPopover : OsuPopover { private readonly Room room; diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeBackgroundScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeBackgroundScreen.cs index d2a57f21db..b31c351b82 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeBackgroundScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeBackgroundScreen.cs @@ -8,7 +8,7 @@ using osu.Game.Screens.OnlinePlay.Components; namespace osu.Game.Screens.OnlinePlay.Lounge { - public class LoungeBackgroundScreen : OnlinePlayBackgroundScreen + public partial class LoungeBackgroundScreen : OnlinePlayBackgroundScreen { public readonly Bindable SelectedRoom = new Bindable(); private readonly BindableList playlist = new BindableList(); diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index 09bc496da5..fc4a5357c6 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -35,7 +35,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Lounge { [Cached] - public abstract class LoungeSubScreen : OnlinePlaySubScreen + public abstract partial class LoungeSubScreen : OnlinePlaySubScreen { public override string Title => "Lounge"; diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/CreateRoomButton.cs b/osu.Game/Screens/OnlinePlay/Match/Components/CreateRoomButton.cs index 3d0c181d9d..0e865b8a09 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/CreateRoomButton.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/CreateRoomButton.cs @@ -10,7 +10,7 @@ using osu.Framework.Input.Events; namespace osu.Game.Screens.OnlinePlay.Match.Components { - public abstract class CreateRoomButton : PurpleTriangleButton, IKeyBindingHandler + public abstract partial class CreateRoomButton : PurpleTriangleButton, IKeyBindingHandler { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/MatchChatDisplay.cs b/osu.Game/Screens/OnlinePlay/Match/Components/MatchChatDisplay.cs index 880bba895a..55d39407b0 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/MatchChatDisplay.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/MatchChatDisplay.cs @@ -10,7 +10,7 @@ using osu.Game.Online.Rooms; namespace osu.Game.Screens.OnlinePlay.Match.Components { - public class MatchChatDisplay : StandAloneChatDisplay + public partial class MatchChatDisplay : StandAloneChatDisplay { private readonly IBindable channelId = new Bindable(); diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/MatchLeaderboard.cs b/osu.Game/Screens/OnlinePlay/Match/Components/MatchLeaderboard.cs index ee5ee576d8..4627cd4072 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/MatchLeaderboard.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/MatchLeaderboard.cs @@ -11,7 +11,7 @@ using osu.Game.Online.Rooms; namespace osu.Game.Screens.OnlinePlay.Match.Components { - public class MatchLeaderboard : Leaderboard + public partial class MatchLeaderboard : Leaderboard { [Resolved(typeof(Room), nameof(Room.RoomID))] private Bindable roomId { get; set; } = null!; diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/MatchLeaderboardScore.cs b/osu.Game/Screens/OnlinePlay/Match/Components/MatchLeaderboardScore.cs index 5bd8f9e066..fabebc3859 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/MatchLeaderboardScore.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/MatchLeaderboardScore.cs @@ -13,7 +13,7 @@ using osu.Game.Scoring; namespace osu.Game.Screens.OnlinePlay.Match.Components { - public class MatchLeaderboardScore : LeaderboardScore + public partial class MatchLeaderboardScore : LeaderboardScore { private readonly APIUserScoreAggregate score; diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/MatchTypePicker.cs b/osu.Game/Screens/OnlinePlay/Match/Components/MatchTypePicker.cs index 91477879c6..995fce085e 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/MatchTypePicker.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/MatchTypePicker.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Match.Components { - public class MatchTypePicker : DisableableTabControl + public partial class MatchTypePicker : DisableableTabControl { private const float height = 40; private const float selection_width = 3; @@ -35,7 +35,7 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components AddItem(MatchType.TeamVersus); } - private class GameTypePickerItem : DisableableTabItem + private partial class GameTypePickerItem : DisableableTabItem { private const float transition_duration = 200; diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/PurpleTriangleButton.cs b/osu.Game/Screens/OnlinePlay/Match/Components/PurpleTriangleButton.cs index 5c751f238f..a444d9ee1c 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/PurpleTriangleButton.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/PurpleTriangleButton.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Screens.OnlinePlay.Match.Components { - public class PurpleTriangleButton : TriangleButton + public partial class PurpleTriangleButton : TriangleButton { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/RoomAvailabilityPicker.cs b/osu.Game/Screens/OnlinePlay/Match/Components/RoomAvailabilityPicker.cs index 408742d8e1..85fac9228b 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/RoomAvailabilityPicker.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/RoomAvailabilityPicker.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.OnlinePlay.Match.Components { - public class RoomAvailabilityPicker : DisableableTabControl + public partial class RoomAvailabilityPicker : DisableableTabControl { protected override TabItem CreateTabItem(RoomAvailability value) => new RoomAvailabilityPickerItem(value); protected override Dropdown CreateDropdown() => null; @@ -36,7 +36,7 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components AddItem(RoomAvailability.InviteOnly); } - private class RoomAvailabilityPickerItem : DisableableTabItem + private partial class RoomAvailabilityPickerItem : DisableableTabItem { private const float transition_duration = 200; diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs index 71447b15e2..4d4fe4ea56 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Match.Components { - public abstract class RoomSettingsOverlay : FocusedOverlayContainer, IKeyBindingHandler + public abstract partial class RoomSettingsOverlay : FocusedOverlayContainer, IKeyBindingHandler { protected const float TRANSITION_DURATION = 350; protected const float FIELD_PADDING = 25; @@ -101,7 +101,7 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components /// use expanded overhanging content (like an 's dropdown), /// then the overhanging content will be correctly Z-ordered. /// - protected class SectionContainer : ReverseChildIDFillFlowContainer
+ protected partial class SectionContainer : ReverseChildIDFillFlowContainer
{ public SectionContainer() { @@ -113,7 +113,7 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components } } - protected class Section : Container + protected partial class Section : Container { private readonly Container content; diff --git a/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs b/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs index 7c444b9bbd..38f3d54837 100644 --- a/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs @@ -19,7 +19,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Match { - public class DrawableMatchRoom : DrawableRoom + public partial class DrawableMatchRoom : DrawableRoom { public readonly IBindable SelectedItem = new Bindable(); public Action OnEdit; @@ -70,7 +70,7 @@ namespace osu.Game.Screens.OnlinePlay.Match protected override Drawable CreateBackground() => background = new BackgroundSprite(); - private class BackgroundSprite : UpdateableBeatmapBackgroundSprite + private partial class BackgroundSprite : UpdateableBeatmapBackgroundSprite { protected override double LoadDelay => 0; } diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomBackgroundScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomBackgroundScreen.cs index 74c37b865c..c9e51d376c 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomBackgroundScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomBackgroundScreen.cs @@ -9,7 +9,7 @@ using osu.Game.Screens.OnlinePlay.Components; namespace osu.Game.Screens.OnlinePlay.Match { - public class RoomBackgroundScreen : OnlinePlayBackgroundScreen + public partial class RoomBackgroundScreen : OnlinePlayBackgroundScreen { public readonly Bindable SelectedItem = new Bindable(); diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index 00c819e5e4..e3f31fc1ad 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -35,7 +35,7 @@ using osu.Game.Screens.OnlinePlay.Multiplayer; namespace osu.Game.Screens.OnlinePlay.Match { [Cached(typeof(IPreviewTrackOwner))] - public abstract class RoomSubScreen : OnlinePlaySubScreen, IPreviewTrackOwner + public abstract partial class RoomSubScreen : OnlinePlaySubScreen, IPreviewTrackOwner { [Cached(typeof(IBindable))] public readonly Bindable SelectedItem = new Bindable(); @@ -517,7 +517,7 @@ namespace osu.Game.Screens.OnlinePlay.Match /// The room to change the settings of. protected abstract RoomSettingsOverlay CreateRoomSettingsOverlay(Room room); - public class UserModSelectButton : PurpleTriangleButton, IKeyBindingHandler + public partial class UserModSelectButton : PurpleTriangleButton, IKeyBindingHandler { public bool OnPressed(KeyBindingPressEvent e) { diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/CreateMultiplayerMatchButton.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/CreateMultiplayerMatchButton.cs index fd535f979d..7975597beb 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/CreateMultiplayerMatchButton.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/CreateMultiplayerMatchButton.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.OnlinePlay.Match.Components; namespace osu.Game.Screens.OnlinePlay.Multiplayer { - public class CreateMultiplayerMatchButton : CreateRoomButton + public partial class CreateMultiplayerMatchButton : CreateRoomButton { private IBindable isConnected; private IBindable operationInProgress; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/GameplayChatDisplay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/GameplayChatDisplay.cs index 270f15a98d..d003110039 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/GameplayChatDisplay.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/GameplayChatDisplay.cs @@ -16,7 +16,7 @@ using osu.Game.Screens.Play; namespace osu.Game.Screens.OnlinePlay.Multiplayer { - public class GameplayChatDisplay : MatchChatDisplay, IKeyBindingHandler + public partial class GameplayChatDisplay : MatchChatDisplay, IKeyBindingHandler { [Resolved(CanBeNull = true)] [CanBeNull] diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/GameplayMatchScoreDisplay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/GameplayMatchScoreDisplay.cs index c7fb6a82d5..8c08390c73 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/GameplayMatchScoreDisplay.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/GameplayMatchScoreDisplay.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Multiplayer { - public class GameplayMatchScoreDisplay : MatchScoreDisplay + public partial class GameplayMatchScoreDisplay : MatchScoreDisplay { public Bindable Expanded = new Bindable(); diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MatchStartControl.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MatchStartControl.cs index f048ae59cd..44e18dd2bb 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MatchStartControl.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MatchStartControl.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match { - public class MatchStartControl : MultiplayerRoomComposite + public partial class MatchStartControl : MultiplayerRoomComposite { [Resolved] private OngoingOperationTracker ongoingOperationTracker { get; set; } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerCountdownButton.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerCountdownButton.cs index cd94b47d9e..a13315edd2 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerCountdownButton.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerCountdownButton.cs @@ -22,7 +22,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match { - public class MultiplayerCountdownButton : IconButton, IHasPopover + public partial class MultiplayerCountdownButton : IconButton, IHasPopover { private static readonly TimeSpan[] available_delays = { diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchFooter.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchFooter.cs index c28bd4892a..fcb6480b58 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchFooter.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchFooter.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match { - public class MultiplayerMatchFooter : CompositeDrawable + public partial class MultiplayerMatchFooter : CompositeDrawable { private const float ready_button_width = 600; private const float spectate_button_width = 200; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs index bbdfed0a00..be1f4d121d 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs @@ -25,7 +25,7 @@ using Container = osu.Framework.Graphics.Containers.Container; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match { - public class MultiplayerMatchSettingsOverlay : RoomSettingsOverlay + public partial class MultiplayerMatchSettingsOverlay : RoomSettingsOverlay { private MatchSettings settings = null!; @@ -50,7 +50,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match SettingsApplied = Hide }; - protected class MatchSettings : OnlinePlayComposite + protected partial class MatchSettings : OnlinePlayComposite { private const float disabled_alpha = 0.2f; @@ -460,7 +460,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match }); } - public class CreateOrUpdateButton : TriangleButton + public partial class CreateOrUpdateButton : TriangleButton { [Resolved(typeof(Room), nameof(Room.RoomID))] private Bindable roomId { get; set; } = null!; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerReadyButton.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerReadyButton.cs index b4ff34cbc2..d794163a9e 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerReadyButton.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerReadyButton.cs @@ -18,7 +18,7 @@ using osu.Game.Screens.OnlinePlay.Components; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match { - public class MultiplayerReadyButton : ReadyButton + public partial class MultiplayerReadyButton : ReadyButton { public new Triangles Triangles => base.Triangles; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerSpectateButton.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerSpectateButton.cs index b55a7d0731..a9233f091a 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerSpectateButton.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerSpectateButton.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match { - public class MultiplayerSpectateButton : MultiplayerRoomComposite + public partial class MultiplayerSpectateButton : MultiplayerRoomComposite { [Resolved] private OngoingOperationTracker ongoingOperationTracker { get; set; } @@ -84,7 +84,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match && !operationInProgress.Value; } - private class ButtonWithTrianglesExposed : TriangleButton + private partial class ButtonWithTrianglesExposed : TriangleButton { public new Triangles Triangles => base.Triangles; } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerHistoryList.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerHistoryList.cs index 3def73accb..a19f61787b 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerHistoryList.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerHistoryList.cs @@ -15,7 +15,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist /// /// A historically-ordered list of s. /// - public class MultiplayerHistoryList : DrawableRoomPlaylist + public partial class MultiplayerHistoryList : DrawableRoomPlaylist { public MultiplayerHistoryList() { @@ -27,7 +27,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist Spacing = new Vector2(0, 2) }; - private class HistoryFillFlowContainer : FillFlowContainer> + private partial class HistoryFillFlowContainer : FillFlowContainer> { public override IEnumerable FlowingChildren => base.FlowingChildren.OfType>().OrderByDescending(item => item.Model.PlayedAt); } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerPlaylist.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerPlaylist.cs index bc96bd61d7..2d08d8ecf6 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerPlaylist.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerPlaylist.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist /// /// The multiplayer playlist, containing lists to show the items from a in both gameplay-order and historical-order. /// - public class MultiplayerPlaylist : MultiplayerRoomComposite + public partial class MultiplayerPlaylist : MultiplayerRoomComposite { public readonly Bindable DisplayMode = new Bindable(); diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerPlaylistTabControl.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerPlaylistTabControl.cs index f7abc91227..a5589c48b9 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerPlaylistTabControl.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerPlaylistTabControl.cs @@ -10,7 +10,7 @@ using osu.Game.Online.Rooms; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist { - public class MultiplayerPlaylistTabControl : OsuTabControl + public partial class MultiplayerPlaylistTabControl : OsuTabControl { public readonly IBindableList QueueItems = new BindableList(); @@ -22,7 +22,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist return base.CreateTabItem(value); } - private class QueueTabItem : OsuTabItem + private partial class QueueTabItem : OsuTabItem { public readonly IBindableList QueueItems = new BindableList(); diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerQueueList.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerQueueList.cs index ba6b482729..77d82c4347 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerQueueList.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/Playlist/MultiplayerQueueList.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist /// /// A gameplay-ordered list of s. /// - public class MultiplayerQueueList : DrawableRoomPlaylist + public partial class MultiplayerQueueList : DrawableRoomPlaylist { public MultiplayerQueueList() { @@ -33,7 +33,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist protected override DrawableRoomPlaylistItem CreateDrawablePlaylistItem(PlaylistItem item) => new QueuePlaylistItem(item); - private class QueueFillFlowContainer : FillFlowContainer> + private partial class QueueFillFlowContainer : FillFlowContainer> { [Resolved(typeof(Room), nameof(Room.Playlist))] private BindableList roomPlaylist { get; set; } @@ -47,7 +47,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist public override IEnumerable FlowingChildren => base.FlowingChildren.OfType>().OrderBy(item => item.Model.PlaylistOrder); } - private class QueuePlaylistItem : DrawableRoomPlaylistItem + private partial class QueuePlaylistItem : DrawableRoomPlaylistItem { [Resolved] private IAPIProvider api { get; set; } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs index 03a2f00c0d..164d1c9a4b 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs @@ -13,7 +13,7 @@ using osu.Game.Screens.OnlinePlay.Lounge; namespace osu.Game.Screens.OnlinePlay.Multiplayer { - public class Multiplayer : OnlinePlayScreen + public partial class Multiplayer : OnlinePlayScreen { [Resolved] private MultiplayerClient client { get; set; } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs index 8206d4b64d..dd4f35cdd4 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs @@ -23,7 +23,7 @@ using osu.Game.Screens.OnlinePlay.Match; namespace osu.Game.Screens.OnlinePlay.Multiplayer { - public class MultiplayerLoungeSubScreen : LoungeSubScreen + public partial class MultiplayerLoungeSubScreen : LoungeSubScreen { [Resolved] private IAPIProvider api { get; set; } @@ -90,7 +90,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer base.OpenNewRoom(room); } - private class MultiplayerListingPollingComponent : ListingPollingComponent + private partial class MultiplayerListingPollingComponent : ListingPollingComponent { [Resolved] private MultiplayerClient client { get; set; } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs index 3fe236bd7a..873a1b0d50 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs @@ -16,7 +16,7 @@ using osu.Game.Screens.Select; namespace osu.Game.Screens.OnlinePlay.Multiplayer { - public class MultiplayerMatchSongSelect : OnlinePlaySongSelect + public partial class MultiplayerMatchSongSelect : OnlinePlaySongSelect { [Resolved] private MultiplayerClient client { get; set; } = null!; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index db752f2b42..c08410f43a 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -38,7 +38,7 @@ using ParticipantsList = osu.Game.Screens.OnlinePlay.Multiplayer.Participants.Pa namespace osu.Game.Screens.OnlinePlay.Multiplayer { [Cached] - public class MultiplayerMatchSubScreen : RoomSubScreen, IHandlePresentBeatmap + public partial class MultiplayerMatchSubScreen : RoomSubScreen, IHandlePresentBeatmap { public override string Title { get; } @@ -430,7 +430,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer modSettingChangeTracker?.Dispose(); } - public class AddItemButton : PurpleTriangleButton + public partial class AddItemButton : PurpleTriangleButton { } } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayer.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayer.cs index a2c43898f7..7b448e4b5c 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayer.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayer.cs @@ -22,7 +22,7 @@ using osu.Game.Users; namespace osu.Game.Screens.OnlinePlay.Multiplayer { - public class MultiplayerPlayer : RoomSubmittingPlayer + public partial class MultiplayerPlayer : RoomSubmittingPlayer { protected override bool PauseOnFocusLost => false; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayerLoader.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayerLoader.cs index f79af664d8..f682508319 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayerLoader.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerPlayerLoader.cs @@ -13,7 +13,7 @@ using osu.Game.Screens.Play; namespace osu.Game.Screens.OnlinePlay.Multiplayer { - public class MultiplayerPlayerLoader : PlayerLoader + public partial class MultiplayerPlayerLoader : PlayerLoader { public bool GameplayPassed => player?.GameplayState.HasPassed == true; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerResultsScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerResultsScreen.cs index d98b837883..de19d3a0e9 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerResultsScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerResultsScreen.cs @@ -9,7 +9,7 @@ using osu.Game.Screens.OnlinePlay.Playlists; namespace osu.Game.Screens.OnlinePlay.Multiplayer { - public class MultiplayerResultsScreen : PlaylistsResultsScreen + public partial class MultiplayerResultsScreen : PlaylistsResultsScreen { public MultiplayerResultsScreen(ScoreInfo score, long roomId, PlaylistItem playlistItem) : base(score, roomId, playlistItem, false, false) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomComposite.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomComposite.cs index 5a297f18db..ee5c84bf40 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomComposite.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomComposite.cs @@ -10,7 +10,7 @@ using osu.Game.Online.Rooms; namespace osu.Game.Screens.OnlinePlay.Multiplayer { - public abstract class MultiplayerRoomComposite : OnlinePlayComposite + public abstract partial class MultiplayerRoomComposite : OnlinePlayComposite { [CanBeNull] protected MultiplayerRoom Room => Client.Room; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs index 7e83d72c77..5f51ccc8d4 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs @@ -15,7 +15,7 @@ using osu.Game.Screens.OnlinePlay.Components; namespace osu.Game.Screens.OnlinePlay.Multiplayer { - public class MultiplayerRoomManager : RoomManager + public partial class MultiplayerRoomManager : RoomManager { [Resolved] private MultiplayerClient multiplayerClient { get; set; } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomSounds.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomSounds.cs index 1aafcea20c..90595bc33b 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomSounds.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomSounds.cs @@ -12,7 +12,7 @@ using osu.Game.Online.Multiplayer; namespace osu.Game.Screens.OnlinePlay.Multiplayer { - public class MultiplayerRoomSounds : MultiplayerRoomComposite + public partial class MultiplayerRoomSounds : MultiplayerRoomComposite { private Sample hostChangedSample; private Sample userJoinedSample; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerTeamResultsScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerTeamResultsScreen.cs index 6fbed03e44..a8c513603c 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerTeamResultsScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerTeamResultsScreen.cs @@ -24,7 +24,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Multiplayer { - public class MultiplayerTeamResultsScreen : MultiplayerResultsScreen + public partial class MultiplayerTeamResultsScreen : MultiplayerResultsScreen { private readonly SortedDictionary teamScores; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs index 3ef2f033b0..c79c210e30 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantPanel.cs @@ -30,7 +30,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants { - public class ParticipantPanel : MultiplayerRoomComposite, IHasContextMenu + public partial class ParticipantPanel : MultiplayerRoomComposite, IHasContextMenu { public readonly MultiplayerRoomUser User; @@ -250,7 +250,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants } } - public class KickButton : IconButton + public partial class KickButton : IconButton { public KickButton() { diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs index 7c93c6084e..6a7a3758c3 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants { - public class ParticipantsList : MultiplayerRoomComposite + public partial class ParticipantsList : MultiplayerRoomComposite { private FillFlowContainer panels; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsListHeader.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsListHeader.cs index b0acda03df..7f4e3360e4 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsListHeader.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsListHeader.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.OnlinePlay.Components; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants { - public class ParticipantsListHeader : OverlinedHeader + public partial class ParticipantsListHeader : OverlinedHeader { [Resolved] private MultiplayerClient client { get; set; } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/StateDisplay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/StateDisplay.cs index ecef7509d9..bfdc0c02ac 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/StateDisplay.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/StateDisplay.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants { - public class StateDisplay : CompositeDrawable + public partial class StateDisplay : CompositeDrawable { private const double fade_time = 50; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/TeamDisplay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/TeamDisplay.cs index 5500d96eea..fe57ad26a5 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/TeamDisplay.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/TeamDisplay.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants { - internal class TeamDisplay : MultiplayerRoomComposite + internal partial class TeamDisplay : MultiplayerRoomComposite { private readonly MultiplayerRoomUser user; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorLeaderboard.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorLeaderboard.cs index 4e9ab07e4c..ed92b719fc 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorLeaderboard.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorLeaderboard.cs @@ -8,7 +8,7 @@ using osu.Game.Screens.Play.HUD; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate { - public class MultiSpectatorLeaderboard : MultiplayerGameplayLeaderboard + public partial class MultiSpectatorLeaderboard : MultiplayerGameplayLeaderboard { public MultiSpectatorLeaderboard(MultiplayerRoomUser[] users) : base(users) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs index 6e939c3916..5a686ffa72 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs @@ -13,7 +13,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate /// /// A single spectated player within a . /// - public class MultiSpectatorPlayer : SpectatorPlayer + public partial class MultiSpectatorPlayer : SpectatorPlayer { /// /// All adjustments applied to the clock of this which come from mods. diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs index 36a6487289..eb55b0d18a 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs @@ -15,7 +15,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate /// /// Used to load a single in a . /// - public class MultiSpectatorPlayerLoader : SpectatorPlayerLoader + public partial class MultiSpectatorPlayerLoader : SpectatorPlayerLoader { public MultiSpectatorPlayerLoader([NotNull] Score score, [NotNull] Func createPlayer) : base(score, createPlayer) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs index 1fd04d35f8..fe27e2cf20 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs @@ -23,7 +23,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate /// /// A that spectates multiple users in a match. /// - public class MultiSpectatorScreen : SpectatorScreen + public partial class MultiSpectatorScreen : SpectatorScreen { // Isolates beatmap/ruleset to this screen. public override bool DisallowExternalBeatmapRulesetChanges => true; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerArea.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerArea.cs index 96f134568d..dc4a2df9d8 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerArea.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerArea.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate /// /// Provides an area for and manages the hierarchy of a spectated player within a . /// - public class PlayerArea : CompositeDrawable + public partial class PlayerArea : CompositeDrawable { /// /// Raised after is called on . @@ -131,7 +131,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate /// /// Isolates each player instance from the game-wide ruleset/beatmap/mods (to allow for different players having different settings). /// - private class PlayerIsolationContainer : Container + private partial class PlayerIsolationContainer : Container { [Cached] private readonly Bindable ruleset = new Bindable(); diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerGrid_Cell.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerGrid_Cell.cs index ee213f7be1..4a8b8f49e1 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerGrid_Cell.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerGrid_Cell.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate /// /// A cell of the grid. Contains the content and tracks to the linked facade. /// - private class Cell : CompositeDrawable + private partial class Cell : CompositeDrawable { /// /// The index of the original facade of this cell. diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerGrid_Facade.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerGrid_Facade.cs index f7b8d48d0a..2f4ed35392 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerGrid_Facade.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/PlayerGrid_Facade.cs @@ -12,7 +12,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate /// /// A facade of the grid which is used as a dummy object to store the required position/size of cells. /// - private class Facade : Drawable + private partial class Facade : Drawable { public Facade() { diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/SpectatorSyncManager.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/SpectatorSyncManager.cs index 8d087aa25c..615c0d7c2b 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/SpectatorSyncManager.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/SpectatorSyncManager.cs @@ -13,7 +13,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate /// /// Manages the synchronisation between one or more s in relation to a master clock. /// - public class SpectatorSyncManager : Component + public partial class SpectatorSyncManager : Component { /// /// The offset from the master clock to which player clocks should remain within to be considered in-sync. diff --git a/osu.Game/Screens/OnlinePlay/OngoingOperationTracker.cs b/osu.Game/Screens/OnlinePlay/OngoingOperationTracker.cs index c87cf32c73..7f73d6655f 100644 --- a/osu.Game/Screens/OnlinePlay/OngoingOperationTracker.cs +++ b/osu.Game/Screens/OnlinePlay/OngoingOperationTracker.cs @@ -13,7 +13,7 @@ namespace osu.Game.Screens.OnlinePlay /// Utility class to track ongoing online operations' progress. /// Can be used to disable interactivity while waiting for a response from online sources. /// - public class OngoingOperationTracker : Component + public partial class OngoingOperationTracker : Component { /// /// Whether there is an online operation in progress. diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayComposite.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayComposite.cs index 50ad3228e5..ff536a65c4 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayComposite.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayComposite.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens.OnlinePlay /// /// A that exposes bindables for properties. /// - public class OnlinePlayComposite : CompositeDrawable + public partial class OnlinePlayComposite : CompositeDrawable { [Resolved(typeof(Room))] protected Bindable RoomID { get; private set; } diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs index 7e5d90bd4f..ccf6cebb12 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs @@ -21,7 +21,7 @@ using osu.Game.Users; namespace osu.Game.Screens.OnlinePlay { [Cached] - public abstract class OnlinePlayScreen : OsuScreen, IHasSubScreenStack + public abstract partial class OnlinePlayScreen : OsuScreen, IHasSubScreenStack { [Cached] protected readonly OverlayColourProvider ColourProvider = new OverlayColourProvider(OverlayColourScheme.Plum); @@ -217,7 +217,7 @@ namespace osu.Game.Screens.OnlinePlay protected abstract LoungeSubScreen CreateLounge(); - private class MultiplayerWaveContainer : WaveContainer + private partial class MultiplayerWaveContainer : WaveContainer { protected override bool StartHidden => true; diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs b/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs index ea20270c1e..b9d8912170 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs @@ -24,7 +24,7 @@ using osu.Game.Utils; namespace osu.Game.Screens.OnlinePlay { - public abstract class OnlinePlaySongSelect : SongSelect, IOnlinePlaySubScreen + public abstract partial class OnlinePlaySongSelect : SongSelect, IOnlinePlaySubScreen { public string ShortTitle => "song selection"; diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlaySubScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlaySubScreen.cs index 5c0a158c97..c7b32131cf 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlaySubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlaySubScreen.cs @@ -9,7 +9,7 @@ using osu.Framework.Screens; namespace osu.Game.Screens.OnlinePlay { - public abstract class OnlinePlaySubScreen : OsuScreen, IOnlinePlaySubScreen + public abstract partial class OnlinePlaySubScreen : OsuScreen, IOnlinePlaySubScreen { public override bool DisallowExternalBeatmapRulesetChanges => false; diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlaySubScreenStack.cs b/osu.Game/Screens/OnlinePlay/OnlinePlaySubScreenStack.cs index ae6988f0d6..7ecb7d954e 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlaySubScreenStack.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlaySubScreenStack.cs @@ -7,7 +7,7 @@ using osu.Framework.Screens; namespace osu.Game.Screens.OnlinePlay { - public class OnlinePlaySubScreenStack : OsuScreenStack + public partial class OnlinePlaySubScreenStack : OsuScreenStack { protected override void ScreenChanged(IScreen prev, IScreen next) { diff --git a/osu.Game/Screens/OnlinePlay/Playlists/CreatePlaylistsRoomButton.cs b/osu.Game/Screens/OnlinePlay/Playlists/CreatePlaylistsRoomButton.cs index 8cdae954ce..9507169e0f 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/CreatePlaylistsRoomButton.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/CreatePlaylistsRoomButton.cs @@ -8,7 +8,7 @@ using osu.Game.Screens.OnlinePlay.Match.Components; namespace osu.Game.Screens.OnlinePlay.Playlists { - public class CreatePlaylistsRoomButton : CreateRoomButton + public partial class CreatePlaylistsRoomButton : CreateRoomButton { [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Screens/OnlinePlay/Playlists/Playlists.cs b/osu.Game/Screens/OnlinePlay/Playlists/Playlists.cs index b84079b955..f9324840dc 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/Playlists.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/Playlists.cs @@ -7,7 +7,7 @@ using osu.Game.Screens.OnlinePlay.Lounge; namespace osu.Game.Screens.OnlinePlay.Playlists { - public class Playlists : OnlinePlayScreen + public partial class Playlists : OnlinePlayScreen { protected override string ScreenTitle => "Playlists"; diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsLoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsLoungeSubScreen.cs index 0827e2031d..e1d747c3b0 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsLoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsLoungeSubScreen.cs @@ -19,7 +19,7 @@ using osu.Game.Screens.OnlinePlay.Match; namespace osu.Game.Screens.OnlinePlay.Playlists { - public class PlaylistsLoungeSubScreen : LoungeSubScreen + public partial class PlaylistsLoungeSubScreen : LoungeSubScreen { [Resolved] private IAPIProvider api { get; set; } diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsPlayer.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsPlayer.cs index 2444729118..0c25a32259 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsPlayer.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsPlayer.cs @@ -21,7 +21,7 @@ using osu.Game.Users; namespace osu.Game.Screens.OnlinePlay.Playlists { - public class PlaylistsPlayer : RoomSubmittingPlayer + public partial class PlaylistsPlayer : RoomSubmittingPlayer { public Action Exited; diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs index b8ab514721..5cc2d9b5da 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs @@ -15,7 +15,7 @@ using osu.Game.Screens.OnlinePlay.Components; namespace osu.Game.Screens.OnlinePlay.Playlists { - public class PlaylistsReadyButton : ReadyButton + public partial class PlaylistsReadyButton : ReadyButton { [Resolved(typeof(Room), nameof(Room.EndDate))] private Bindable endDate { get; set; } diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsResultsScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsResultsScreen.cs index 27193d3cb6..d40d43cd54 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsResultsScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsResultsScreen.cs @@ -20,7 +20,7 @@ using osu.Game.Screens.Ranking; namespace osu.Game.Screens.OnlinePlay.Playlists { - public class PlaylistsResultsScreen : ResultsScreen + public partial class PlaylistsResultsScreen : ResultsScreen { private readonly long roomId; private readonly PlaylistItem playlistItem; @@ -235,7 +235,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists } } - private class PanelListLoadingSpinner : LoadingSpinner + private partial class PanelListLoadingSpinner : LoadingSpinner { private readonly ScorePanelList list; diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomFooter.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomFooter.cs index b1b400713f..5161de5f64 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomFooter.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomFooter.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Playlists { - public class PlaylistsRoomFooter : CompositeDrawable + public partial class PlaylistsRoomFooter : CompositeDrawable { public Action OnStart; diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs index cd52981528..ee6c07e3ca 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs @@ -25,7 +25,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Playlists { - public class PlaylistsRoomSettingsOverlay : RoomSettingsOverlay + public partial class PlaylistsRoomSettingsOverlay : RoomSettingsOverlay { public Action? EditPlaylist; @@ -49,7 +49,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists EditPlaylist = () => EditPlaylist?.Invoke() }; - protected class MatchSettings : OnlinePlayComposite + protected partial class MatchSettings : OnlinePlayComposite { private const float disabled_alpha = 0.2f; @@ -414,7 +414,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists } } - public class CreateRoomButton : TriangleButton + public partial class CreateRoomButton : TriangleButton { public CreateRoomButton() { @@ -430,7 +430,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists } } - private class DurationDropdown : OsuDropdown + private partial class DurationDropdown : OsuDropdown { public DurationDropdown() { diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsPlaylist.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsPlaylist.cs index 80f38d0cd8..df502ae09c 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsPlaylist.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsPlaylist.cs @@ -11,7 +11,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists /// /// A which is displayed during the setup stage of a playlists room. /// - public class PlaylistsRoomSettingsPlaylist : DrawableRoomPlaylist + public partial class PlaylistsRoomSettingsPlaylist : DrawableRoomPlaylist { public PlaylistsRoomSettingsPlaylist() { diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs index 228ecd4bf3..cf5a8e1985 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs @@ -25,7 +25,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Playlists { - public class PlaylistsRoomSubScreen : RoomSubScreen + public partial class PlaylistsRoomSubScreen : RoomSubScreen { public override string Title { get; } diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsSongSelect.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsSongSelect.cs index e3f7b5dfc4..cedea4af70 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsSongSelect.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsSongSelect.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Select; namespace osu.Game.Screens.OnlinePlay.Playlists { - public class PlaylistsSongSelect : OnlinePlaySongSelect + public partial class PlaylistsSongSelect : OnlinePlaySongSelect { public PlaylistsSongSelect(Room room) : base(room) diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 6be13bbda3..bc4cc2b00f 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -21,7 +21,7 @@ using osu.Game.Users; namespace osu.Game.Screens { - public abstract class OsuScreen : Screen, IOsuScreen, IHasDescription + public abstract partial class OsuScreen : Screen, IOsuScreen, IHasDescription { /// /// The amount of negative padding that should be applied to game background content which touches both the left and right sides of the screen. diff --git a/osu.Game/Screens/OsuScreenStack.cs b/osu.Game/Screens/OsuScreenStack.cs index 49f1255ec7..dffbbdbc55 100644 --- a/osu.Game/Screens/OsuScreenStack.cs +++ b/osu.Game/Screens/OsuScreenStack.cs @@ -10,7 +10,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Screens { - public class OsuScreenStack : ScreenStack + public partial class OsuScreenStack : ScreenStack { [Cached] private BackgroundScreenStack backgroundScreenStack; diff --git a/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs b/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs index 0e56cafaaa..06509b6465 100644 --- a/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs +++ b/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Play /// /// Displays beatmap metadata inside /// - public class BeatmapMetadataDisplay : Container + public partial class BeatmapMetadataDisplay : Container { private readonly IWorkingBeatmap beatmap; private readonly Bindable> mods; @@ -212,7 +212,7 @@ namespace osu.Game.Screens.Play }; } - private class MetadataLineLabel : OsuSpriteText + private partial class MetadataLineLabel : OsuSpriteText { public MetadataLineLabel(LocalisableString text) { @@ -224,7 +224,7 @@ namespace osu.Game.Screens.Play } } - private class MetadataLineInfo : OsuSpriteText + private partial class MetadataLineInfo : OsuSpriteText { public MetadataLineInfo(string text) { diff --git a/osu.Game/Screens/Play/Break/BlurredIcon.cs b/osu.Game/Screens/Play/Break/BlurredIcon.cs index 97eafa01fa..cd38390324 100644 --- a/osu.Game/Screens/Play/Break/BlurredIcon.cs +++ b/osu.Game/Screens/Play/Break/BlurredIcon.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Screens.Play.Break { - public class BlurredIcon : BufferedContainer + public partial class BlurredIcon : BufferedContainer { private readonly SpriteIcon icon; diff --git a/osu.Game/Screens/Play/Break/BreakArrows.cs b/osu.Game/Screens/Play/Break/BreakArrows.cs index f2feda4d76..f0f1e8cc3d 100644 --- a/osu.Game/Screens/Play/Break/BreakArrows.cs +++ b/osu.Game/Screens/Play/Break/BreakArrows.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Screens.Play.Break { - public class BreakArrows : CompositeDrawable + public partial class BreakArrows : CompositeDrawable { private const int glow_icon_size = 60; private const int glow_icon_blur_sigma = 10; diff --git a/osu.Game/Screens/Play/Break/BreakInfo.cs b/osu.Game/Screens/Play/Break/BreakInfo.cs index 5aed8b7df1..f99c1d1817 100644 --- a/osu.Game/Screens/Play/Break/BreakInfo.cs +++ b/osu.Game/Screens/Play/Break/BreakInfo.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Screens.Play.Break { - public class BreakInfo : Container + public partial class BreakInfo : Container { public PercentageBreakInfoLine AccuracyDisplay; diff --git a/osu.Game/Screens/Play/Break/BreakInfoLine.cs b/osu.Game/Screens/Play/Break/BreakInfoLine.cs index 690d7c7e63..7261155c94 100644 --- a/osu.Game/Screens/Play/Break/BreakInfoLine.cs +++ b/osu.Game/Screens/Play/Break/BreakInfoLine.cs @@ -16,7 +16,7 @@ using osu.Game.Utils; namespace osu.Game.Screens.Play.Break { - public class BreakInfoLine : Container + public partial class BreakInfoLine : Container where T : struct { private const int margin = 2; @@ -82,7 +82,7 @@ namespace osu.Game.Screens.Play.Break } } - public class PercentageBreakInfoLine : BreakInfoLine + public partial class PercentageBreakInfoLine : BreakInfoLine { public PercentageBreakInfoLine(LocalisableString name, string prefix = "") : base(name, prefix) diff --git a/osu.Game/Screens/Play/Break/GlowIcon.cs b/osu.Game/Screens/Play/Break/GlowIcon.cs index 9222e8f890..595c4dd494 100644 --- a/osu.Game/Screens/Play/Break/GlowIcon.cs +++ b/osu.Game/Screens/Play/Break/GlowIcon.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Screens.Play.Break { - public class GlowIcon : Container + public partial class GlowIcon : Container { private readonly SpriteIcon spriteIcon; private readonly BlurredIcon blurredIcon; diff --git a/osu.Game/Screens/Play/Break/LetterboxOverlay.cs b/osu.Game/Screens/Play/Break/LetterboxOverlay.cs index 3eb58da469..92b432831d 100644 --- a/osu.Game/Screens/Play/Break/LetterboxOverlay.cs +++ b/osu.Game/Screens/Play/Break/LetterboxOverlay.cs @@ -11,7 +11,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play.Break { - public class LetterboxOverlay : CompositeDrawable + public partial class LetterboxOverlay : CompositeDrawable { private const int height = 350; diff --git a/osu.Game/Screens/Play/Break/RemainingTimeCounter.cs b/osu.Game/Screens/Play/Break/RemainingTimeCounter.cs index 4b84f7c69e..da83f8c29f 100644 --- a/osu.Game/Screens/Play/Break/RemainingTimeCounter.cs +++ b/osu.Game/Screens/Play/Break/RemainingTimeCounter.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Screens.Play.Break { - public class RemainingTimeCounter : Counter + public partial class RemainingTimeCounter : Counter { private readonly OsuSpriteText counter; diff --git a/osu.Game/Screens/Play/BreakOverlay.cs b/osu.Game/Screens/Play/BreakOverlay.cs index 492c9c27ff..4927800059 100644 --- a/osu.Game/Screens/Play/BreakOverlay.cs +++ b/osu.Game/Screens/Play/BreakOverlay.cs @@ -14,7 +14,7 @@ using osu.Game.Screens.Play.Break; namespace osu.Game.Screens.Play { - public class BreakOverlay : Container + public partial class BreakOverlay : Container { /// /// The duration of the break overlay fading. diff --git a/osu.Game/Screens/Play/BreakTracker.cs b/osu.Game/Screens/Play/BreakTracker.cs index 8679db01a0..20ef1dc4bf 100644 --- a/osu.Game/Screens/Play/BreakTracker.cs +++ b/osu.Game/Screens/Play/BreakTracker.cs @@ -13,7 +13,7 @@ using osu.Game.Utils; namespace osu.Game.Screens.Play { - public class BreakTracker : Component + public partial class BreakTracker : Component { private readonly ScoreProcessor scoreProcessor; private readonly double gameplayStartTime; diff --git a/osu.Game/Screens/Play/ComboEffects.cs b/osu.Game/Screens/Play/ComboEffects.cs index 442b061af7..09c94a8f1d 100644 --- a/osu.Game/Screens/Play/ComboEffects.cs +++ b/osu.Game/Screens/Play/ComboEffects.cs @@ -13,7 +13,7 @@ using osu.Game.Skinning; namespace osu.Game.Screens.Play { - public class ComboEffects : CompositeDrawable + public partial class ComboEffects : CompositeDrawable { private readonly ScoreProcessor processor; diff --git a/osu.Game/Screens/Play/DimmableStoryboard.cs b/osu.Game/Screens/Play/DimmableStoryboard.cs index ae43d3d70d..40cc0f66ad 100644 --- a/osu.Game/Screens/Play/DimmableStoryboard.cs +++ b/osu.Game/Screens/Play/DimmableStoryboard.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens.Play /// /// A container that handles loading, as well as applies user-specified visual settings to it. /// - public class DimmableStoryboard : UserDimContainer + public partial class DimmableStoryboard : UserDimContainer { public Container OverlayLayerContainer { get; private set; } diff --git a/osu.Game/Screens/Play/EpilepsyWarning.cs b/osu.Game/Screens/Play/EpilepsyWarning.cs index 4f87853158..6316bbdb4e 100644 --- a/osu.Game/Screens/Play/EpilepsyWarning.cs +++ b/osu.Game/Screens/Play/EpilepsyWarning.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Screens.Play { - public class EpilepsyWarning : VisibilityContainer + public partial class EpilepsyWarning : VisibilityContainer { public const double FADE_DURATION = 250; diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index a4b4bf4d2b..24171c25a8 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -29,7 +29,7 @@ namespace osu.Game.Screens.Play /// Manage the animation to be applied when a player fails. /// Single use and automatically disposed after use. /// - public class FailAnimation : Container + public partial class FailAnimation : Container { public Action? OnComplete; diff --git a/osu.Game/Screens/Play/FailOverlay.cs b/osu.Game/Screens/Play/FailOverlay.cs index 2af5102369..4fbc937b59 100644 --- a/osu.Game/Screens/Play/FailOverlay.cs +++ b/osu.Game/Screens/Play/FailOverlay.cs @@ -18,7 +18,7 @@ using osu.Framework.Graphics.Shapes; namespace osu.Game.Screens.Play { - public class FailOverlay : GameplayMenuOverlay + public partial class FailOverlay : GameplayMenuOverlay { public Func> SaveReplay; diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 35b79fd628..c42f607908 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens.Play /// Encapsulates gameplay timing logic and provides a via DI for gameplay components to use. /// [Cached(typeof(IGameplayClock))] - public class GameplayClockContainer : Container, IAdjustableClock, IGameplayClock + public partial class GameplayClockContainer : Container, IAdjustableClock, IGameplayClock { /// /// Whether gameplay is paused. diff --git a/osu.Game/Screens/Play/GameplayMenuOverlay.cs b/osu.Game/Screens/Play/GameplayMenuOverlay.cs index c2652e9212..c681ef8f96 100644 --- a/osu.Game/Screens/Play/GameplayMenuOverlay.cs +++ b/osu.Game/Screens/Play/GameplayMenuOverlay.cs @@ -25,7 +25,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play { - public abstract class GameplayMenuOverlay : OverlayContainer, IKeyBindingHandler + public abstract partial class GameplayMenuOverlay : OverlayContainer, IKeyBindingHandler { protected const int TRANSITION_DURATION = 200; @@ -248,7 +248,7 @@ namespace osu.Game.Screens.Play }; } - private class Button : DialogButton + private partial class Button : DialogButton { // required to ensure keyboard navigation always starts from an extremity (unless the cursor is moved) protected override bool OnHover(HoverEvent e) => true; diff --git a/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs b/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs index 04774b974f..bf1f508d7b 100644 --- a/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs +++ b/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs @@ -8,7 +8,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Screens.Play.HUD.ClicksPerSecond { - public class ClicksPerSecondCalculator : Component + public partial class ClicksPerSecondCalculator : Component { private readonly List timestamps = new List(); diff --git a/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCounter.cs b/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCounter.cs index 243d8ed1e8..cb72bb5f6f 100644 --- a/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCounter.cs +++ b/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCounter.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Screens.Play.HUD.ClicksPerSecond { - public class ClicksPerSecondCounter : RollingCounter, ISkinnableDrawable + public partial class ClicksPerSecondCounter : RollingCounter, ISkinnableDrawable { [Resolved] private ClicksPerSecondCalculator calculator { get; set; } = null!; @@ -43,7 +43,7 @@ namespace osu.Game.Screens.Play.HUD.ClicksPerSecond protected override IHasText CreateText() => new TextComponent(); - private class TextComponent : CompositeDrawable, IHasText + private partial class TextComponent : CompositeDrawable, IHasText { public LocalisableString Text { diff --git a/osu.Game/Screens/Play/HUD/ComboCounter.cs b/osu.Game/Screens/Play/HUD/ComboCounter.cs index 4179d41646..afccbc4ef0 100644 --- a/osu.Game/Screens/Play/HUD/ComboCounter.cs +++ b/osu.Game/Screens/Play/HUD/ComboCounter.cs @@ -7,7 +7,7 @@ using osu.Game.Skinning; namespace osu.Game.Screens.Play.HUD { - public abstract class ComboCounter : RollingCounter, ISkinnableDrawable + public abstract partial class ComboCounter : RollingCounter, ISkinnableDrawable { public bool UsesFixedAnchor { get; set; } diff --git a/osu.Game/Screens/Play/HUD/DefaultAccuracyCounter.cs b/osu.Game/Screens/Play/HUD/DefaultAccuracyCounter.cs index 018720510c..1a082e58b7 100644 --- a/osu.Game/Screens/Play/HUD/DefaultAccuracyCounter.cs +++ b/osu.Game/Screens/Play/HUD/DefaultAccuracyCounter.cs @@ -9,7 +9,7 @@ using osu.Game.Skinning; namespace osu.Game.Screens.Play.HUD { - public class DefaultAccuracyCounter : GameplayAccuracyCounter, ISkinnableDrawable + public partial class DefaultAccuracyCounter : GameplayAccuracyCounter, ISkinnableDrawable { public bool UsesFixedAnchor { get; set; } diff --git a/osu.Game/Screens/Play/HUD/DefaultComboCounter.cs b/osu.Game/Screens/Play/HUD/DefaultComboCounter.cs index 0c9c363280..1377055c30 100644 --- a/osu.Game/Screens/Play/HUD/DefaultComboCounter.cs +++ b/osu.Game/Screens/Play/HUD/DefaultComboCounter.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.HUD { - public class DefaultComboCounter : ComboCounter + public partial class DefaultComboCounter : ComboCounter { [BackgroundDependencyLoader] private void load(OsuColour colours, ScoreProcessor scoreProcessor) diff --git a/osu.Game/Screens/Play/HUD/DefaultHealthDisplay.cs b/osu.Game/Screens/Play/HUD/DefaultHealthDisplay.cs index 37e1d2fb84..76027f9e5d 100644 --- a/osu.Game/Screens/Play/HUD/DefaultHealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/DefaultHealthDisplay.cs @@ -19,7 +19,7 @@ using osu.Game.Skinning; namespace osu.Game.Screens.Play.HUD { - public class DefaultHealthDisplay : HealthDisplay, IHasAccentColour, ISkinnableDrawable + public partial class DefaultHealthDisplay : HealthDisplay, IHasAccentColour, ISkinnableDrawable { /// /// The base opacity of the glow. diff --git a/osu.Game/Screens/Play/HUD/DefaultScoreCounter.cs b/osu.Game/Screens/Play/HUD/DefaultScoreCounter.cs index 4450ad53d8..f116617271 100644 --- a/osu.Game/Screens/Play/HUD/DefaultScoreCounter.cs +++ b/osu.Game/Screens/Play/HUD/DefaultScoreCounter.cs @@ -10,7 +10,7 @@ using osu.Game.Skinning; namespace osu.Game.Screens.Play.HUD { - public class DefaultScoreCounter : GameplayScoreCounter, ISkinnableDrawable + public partial class DefaultScoreCounter : GameplayScoreCounter, ISkinnableDrawable { public DefaultScoreCounter() { diff --git a/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs b/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs index 45d0cf8462..53866312a0 100644 --- a/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs +++ b/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Screens.Play.HUD { - public class DefaultSongProgress : SongProgress + public partial class DefaultSongProgress : SongProgress { private const float bottom_bar_height = 5; private const float graph_height = SquareGraph.Column.WIDTH * 6; diff --git a/osu.Game/Screens/Play/HUD/FailingLayer.cs b/osu.Game/Screens/Play/HUD/FailingLayer.cs index 10c1d418ee..67e7ae8f3f 100644 --- a/osu.Game/Screens/Play/HUD/FailingLayer.cs +++ b/osu.Game/Screens/Play/HUD/FailingLayer.cs @@ -22,7 +22,7 @@ namespace osu.Game.Screens.Play.HUD /// /// An overlay layer on top of the playfield which fades to red when the current player health falls below a certain threshold defined by . /// - public class FailingLayer : HealthDisplay + public partial class FailingLayer : HealthDisplay { /// /// Whether the current player health should be shown on screen. diff --git a/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs index afb6749436..1933193515 100644 --- a/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs +++ b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.HUD { - public abstract class GameplayAccuracyCounter : PercentageCounter + public abstract partial class GameplayAccuracyCounter : PercentageCounter { [BackgroundDependencyLoader] private void load(ScoreProcessor scoreProcessor) diff --git a/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs index 47b67fba00..f6f289db55 100644 --- a/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play.HUD { - public abstract class GameplayLeaderboard : CompositeDrawable + public abstract partial class GameplayLeaderboard : CompositeDrawable { private readonly Cached sorting = new Cached(); @@ -179,7 +179,7 @@ namespace osu.Game.Screens.Play.HUD protected virtual bool CheckValidScorePosition(int i) => true; - private class InputDisabledScrollContainer : OsuScrollContainer + private partial class InputDisabledScrollContainer : OsuScrollContainer { public InputDisabledScrollContainer() { diff --git a/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs b/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs index 0d03d8d090..07b80feb3e 100644 --- a/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs +++ b/osu.Game/Screens/Play/HUD/GameplayLeaderboardScore.cs @@ -21,7 +21,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play.HUD { - public class GameplayLeaderboardScore : CompositeDrawable, ILeaderboardScore + public partial class GameplayLeaderboardScore : CompositeDrawable, ILeaderboardScore { public const float EXTENDED_WIDTH = regular_width + top_player_left_width_extension; diff --git a/osu.Game/Screens/Play/HUD/GameplayScoreCounter.cs b/osu.Game/Screens/Play/HUD/GameplayScoreCounter.cs index 7a6292ccbf..a11cccd97c 100644 --- a/osu.Game/Screens/Play/HUD/GameplayScoreCounter.cs +++ b/osu.Game/Screens/Play/HUD/GameplayScoreCounter.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.HUD { - public abstract class GameplayScoreCounter : ScoreCounter + public abstract partial class GameplayScoreCounter : ScoreCounter { private Bindable scoreDisplayMode; diff --git a/osu.Game/Screens/Play/HUD/HealthDisplay.cs b/osu.Game/Screens/Play/HUD/HealthDisplay.cs index 569b37aea5..7a73eb1657 100644 --- a/osu.Game/Screens/Play/HUD/HealthDisplay.cs +++ b/osu.Game/Screens/Play/HUD/HealthDisplay.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens.Play.HUD /// A container for components displaying the current player health. /// Gets bound automatically to the when inserted to hierarchy. /// - public abstract class HealthDisplay : CompositeDrawable + public abstract partial class HealthDisplay : CompositeDrawable { private readonly Bindable showHealthBar = new Bindable(true); diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index c9f1571dfe..eeca2be7cd 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -23,7 +23,7 @@ using osuTK; namespace osu.Game.Screens.Play.HUD.HitErrorMeters { [Cached] - public class BarHitErrorMeter : HitErrorMeter + public partial class BarHitErrorMeter : HitErrorMeter { [SettingSource("Judgement line thickness", "How thick the individual lines should be.")] public BindableNumber JudgementLineThickness { get; } = new BindableNumber(4) @@ -422,7 +422,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters private float getRelativeJudgementPosition(double value) => Math.Clamp((float)((value / maxHitWindow) + 1) / 2, 0, 1); - internal class JudgementLine : PoolableDrawable + internal partial class JudgementLine : PoolableDrawable { public readonly BindableNumber JudgementLineThickness = new BindableFloat(); diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs index 86ba85168f..ec5dc5f52f 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/ColourHitErrorMeter.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play.HUD.HitErrorMeters { [Cached] - public class ColourHitErrorMeter : HitErrorMeter + public partial class ColourHitErrorMeter : HitErrorMeter { private const int animation_duration = 200; private const int drawable_judgement_size = 8; @@ -63,7 +63,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters public override void Clear() => judgementsFlow.Clear(); - private class JudgementFlow : FillFlowContainer + private partial class JudgementFlow : FillFlowContainer { public override IEnumerable FlowingChildren => base.FlowingChildren.Reverse(); @@ -122,7 +122,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters } } - public class HitErrorShape : PoolableDrawable + public partial class HitErrorShape : PoolableDrawable { public bool IsRemoved { get; private set; } diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs index dda17c25e6..191f63e97d 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/HitErrorMeter.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play.HUD.HitErrorMeters { - public abstract class HitErrorMeter : CompositeDrawable, ISkinnableDrawable + public abstract partial class HitErrorMeter : CompositeDrawable, ISkinnableDrawable { protected HitWindows HitWindows { get; private set; } diff --git a/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs b/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs index 39a8f1e783..f902e0903d 100644 --- a/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs +++ b/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs @@ -25,7 +25,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play.HUD { - public class HoldForMenuButton : FillFlowContainer + public partial class HoldForMenuButton : FillFlowContainer { public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; @@ -102,7 +102,7 @@ namespace osu.Game.Screens.Play.HUD } } - private class HoldButton : HoldToConfirmContainer, IKeyBindingHandler + private partial class HoldButton : HoldToConfirmContainer, IKeyBindingHandler { private SpriteIcon icon; private CircularProgress circularProgress; diff --git a/osu.Game/Screens/Play/HUD/LongestComboCounter.cs b/osu.Game/Screens/Play/HUD/LongestComboCounter.cs index 0e7af69af2..fdc3768aab 100644 --- a/osu.Game/Screens/Play/HUD/LongestComboCounter.cs +++ b/osu.Game/Screens/Play/HUD/LongestComboCounter.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Screens.Play.HUD { - public class LongestComboCounter : ComboCounter + public partial class LongestComboCounter : ComboCounter { [BackgroundDependencyLoader] private void load(OsuColour colours, ScoreProcessor scoreProcessor) @@ -24,7 +24,7 @@ namespace osu.Game.Screens.Play.HUD protected override IHasText CreateText() => new TextComponent(); - private class TextComponent : CompositeDrawable, IHasText + private partial class TextComponent : CompositeDrawable, IHasText { public LocalisableString Text { diff --git a/osu.Game/Screens/Play/HUD/MatchScoreDisplay.cs b/osu.Game/Screens/Play/HUD/MatchScoreDisplay.cs index 00dc586448..58bf4eea4b 100644 --- a/osu.Game/Screens/Play/HUD/MatchScoreDisplay.cs +++ b/osu.Game/Screens/Play/HUD/MatchScoreDisplay.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Screens.Play.HUD { - public class MatchScoreDisplay : CompositeDrawable + public partial class MatchScoreDisplay : CompositeDrawable { private const float bar_height = 18; private const float font_size = 50; @@ -148,7 +148,7 @@ namespace osu.Game.Screens.Play.HUD Score2Text.X = Math.Max(5 + Score2Text.DrawWidth / 2, score2Bar.DrawWidth); } - protected class MatchScoreCounter : CommaSeparatedScoreCounter + protected partial class MatchScoreCounter : CommaSeparatedScoreCounter { private OsuSpriteText displayedSpriteText; diff --git a/osu.Game/Screens/Play/HUD/ModDisplay.cs b/osu.Game/Screens/Play/HUD/ModDisplay.cs index 0badc063ce..3b50a22e3c 100644 --- a/osu.Game/Screens/Play/HUD/ModDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ModDisplay.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.Play.HUD /// /// Displays a single-line horizontal auto-sized flow of mods. For cases where wrapping is required, use instead. /// - public class ModDisplay : CompositeDrawable, IHasCurrentValue> + public partial class ModDisplay : CompositeDrawable, IHasCurrentValue> { private const int fade_duration = 1000; diff --git a/osu.Game/Screens/Play/HUD/ModFlowDisplay.cs b/osu.Game/Screens/Play/HUD/ModFlowDisplay.cs index 86fece84fa..23030e640b 100644 --- a/osu.Game/Screens/Play/HUD/ModFlowDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ModFlowDisplay.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.Play.HUD /// /// A horizontally wrapping display of mods. For cases where wrapping is not required, use instead. /// - public class ModFlowDisplay : ReverseChildIDFillFlowContainer, IHasCurrentValue> + public partial class ModFlowDisplay : ReverseChildIDFillFlowContainer, IHasCurrentValue> { private const int fade_duration = 1000; diff --git a/osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.cs index 4ac92056ef..2743173a6d 100644 --- a/osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/MultiplayerGameplayLeaderboard.cs @@ -25,7 +25,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play.HUD { [LongRunningLoad] - public class MultiplayerGameplayLeaderboard : GameplayLeaderboard + public partial class MultiplayerGameplayLeaderboard : GameplayLeaderboard { protected readonly Dictionary UserScores = new Dictionary(); diff --git a/osu.Game/Screens/Play/HUD/PerformancePointsCounter.cs b/osu.Game/Screens/Play/HUD/PerformancePointsCounter.cs index 97a120f9bd..15484f2965 100644 --- a/osu.Game/Screens/Play/HUD/PerformancePointsCounter.cs +++ b/osu.Game/Screens/Play/HUD/PerformancePointsCounter.cs @@ -35,7 +35,7 @@ using osuTK; namespace osu.Game.Screens.Play.HUD { - public class PerformancePointsCounter : RollingCounter, ISkinnableDrawable + public partial class PerformancePointsCounter : RollingCounter, ISkinnableDrawable { public bool UsesFixedAnchor { get; set; } @@ -171,7 +171,7 @@ namespace osu.Game.Screens.Play.HUD loadCancellationSource?.Cancel(); } - private class TextComponent : CompositeDrawable, IHasText + private partial class TextComponent : CompositeDrawable, IHasText { public LocalisableString Text { diff --git a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs index 5f6f040959..a885336a3a 100644 --- a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs +++ b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs @@ -12,7 +12,7 @@ using osuTK.Input; namespace osu.Game.Screens.Play.HUD { - public class PlayerSettingsOverlay : VisibilityContainer + public partial class PlayerSettingsOverlay : VisibilityContainer { private const int fade_duration = 200; diff --git a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs index 0df3200adb..0f3e54ecdd 100644 --- a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs @@ -15,7 +15,7 @@ using osu.Game.Users; namespace osu.Game.Screens.Play.HUD { - public class SoloGameplayLeaderboard : GameplayLeaderboard + public partial class SoloGameplayLeaderboard : GameplayLeaderboard { private const int duration = 100; diff --git a/osu.Game/Screens/Play/HUD/SongProgress.cs b/osu.Game/Screens/Play/HUD/SongProgress.cs index 0b6494bd8a..4504745eb9 100644 --- a/osu.Game/Screens/Play/HUD/SongProgress.cs +++ b/osu.Game/Screens/Play/HUD/SongProgress.cs @@ -12,7 +12,7 @@ using osu.Game.Skinning; namespace osu.Game.Screens.Play.HUD { - public abstract class SongProgress : OverlayContainer, ISkinnableDrawable + public abstract partial class SongProgress : OverlayContainer, ISkinnableDrawable { // Some implementations of this element allow seeking during gameplay playback. // Set a sane default of never handling input to override the behaviour provided by OverlayContainer. diff --git a/osu.Game/Screens/Play/HUD/SongProgressBar.cs b/osu.Game/Screens/Play/HUD/SongProgressBar.cs index db4e200724..28059d4911 100644 --- a/osu.Game/Screens/Play/HUD/SongProgressBar.cs +++ b/osu.Game/Screens/Play/HUD/SongProgressBar.cs @@ -15,7 +15,7 @@ using osu.Framework.Threading; namespace osu.Game.Screens.Play.HUD { - public class SongProgressBar : SliderBar + public partial class SongProgressBar : SliderBar { public Action OnSeek; diff --git a/osu.Game/Screens/Play/HUD/SongProgressGraph.cs b/osu.Game/Screens/Play/HUD/SongProgressGraph.cs index f234b45922..f69a1eccd6 100644 --- a/osu.Game/Screens/Play/HUD/SongProgressGraph.cs +++ b/osu.Game/Screens/Play/HUD/SongProgressGraph.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Objects; namespace osu.Game.Screens.Play.HUD { - public class SongProgressGraph : SquareGraph + public partial class SongProgressGraph : SquareGraph { private IEnumerable objects; diff --git a/osu.Game/Screens/Play/HUD/SongProgressInfo.cs b/osu.Game/Screens/Play/HUD/SongProgressInfo.cs index d0eb8f8ca1..fb5f5cc916 100644 --- a/osu.Game/Screens/Play/HUD/SongProgressInfo.cs +++ b/osu.Game/Screens/Play/HUD/SongProgressInfo.cs @@ -13,7 +13,7 @@ using System; namespace osu.Game.Screens.Play.HUD { - public class SongProgressInfo : Container + public partial class SongProgressInfo : Container { private SizePreservingSpriteText timeCurrent; private SizePreservingSpriteText timeLeft; diff --git a/osu.Game/Screens/Play/HUD/UnstableRateCounter.cs b/osu.Game/Screens/Play/HUD/UnstableRateCounter.cs index 0ba88c549e..f450ae799e 100644 --- a/osu.Game/Screens/Play/HUD/UnstableRateCounter.cs +++ b/osu.Game/Screens/Play/HUD/UnstableRateCounter.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Screens.Play.HUD { - public class UnstableRateCounter : RollingCounter, ISkinnableDrawable + public partial class UnstableRateCounter : RollingCounter, ISkinnableDrawable { public bool UsesFixedAnchor { get; set; } @@ -83,7 +83,7 @@ namespace osu.Game.Screens.Play.HUD scoreProcessor.JudgementReverted -= updateDisplay; } - private class TextComponent : CompositeDrawable, IHasText + private partial class TextComponent : CompositeDrawable, IHasText { public LocalisableString Text { diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index fa38eeb9aa..4c2483a0e6 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -28,7 +28,7 @@ using osuTK; namespace osu.Game.Screens.Play { [Cached] - public class HUDOverlay : Container, IKeyBindingHandler + public partial class HUDOverlay : Container, IKeyBindingHandler { public const float FADE_DURATION = 300; @@ -383,7 +383,7 @@ namespace osu.Game.Screens.Play } } - private class MainComponentsContainer : SkinnableTargetContainer + private partial class MainComponentsContainer : SkinnableTargetContainer { private Bindable scoringMode; diff --git a/osu.Game/Screens/Play/HotkeyExitOverlay.cs b/osu.Game/Screens/Play/HotkeyExitOverlay.cs index 07595a43c4..4c1265c699 100644 --- a/osu.Game/Screens/Play/HotkeyExitOverlay.cs +++ b/osu.Game/Screens/Play/HotkeyExitOverlay.cs @@ -10,7 +10,7 @@ using osu.Game.Overlays; namespace osu.Game.Screens.Play { - public class HotkeyExitOverlay : HoldToConfirmOverlay, IKeyBindingHandler + public partial class HotkeyExitOverlay : HoldToConfirmOverlay, IKeyBindingHandler { public bool OnPressed(KeyBindingPressEvent e) { diff --git a/osu.Game/Screens/Play/HotkeyRetryOverlay.cs b/osu.Game/Screens/Play/HotkeyRetryOverlay.cs index 94c0f0a89d..582b5a1691 100644 --- a/osu.Game/Screens/Play/HotkeyRetryOverlay.cs +++ b/osu.Game/Screens/Play/HotkeyRetryOverlay.cs @@ -10,7 +10,7 @@ using osu.Game.Overlays; namespace osu.Game.Screens.Play { - public class HotkeyRetryOverlay : HoldToConfirmOverlay, IKeyBindingHandler + public partial class HotkeyRetryOverlay : HoldToConfirmOverlay, IKeyBindingHandler { public bool OnPressed(KeyBindingPressEvent e) { diff --git a/osu.Game/Screens/Play/KeyCounter.cs b/osu.Game/Screens/Play/KeyCounter.cs index 1e5ada5295..4405542b3b 100644 --- a/osu.Game/Screens/Play/KeyCounter.cs +++ b/osu.Game/Screens/Play/KeyCounter.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play { - public abstract class KeyCounter : Container + public abstract partial class KeyCounter : Container { private Sprite buttonSprite; private Sprite glowSprite; diff --git a/osu.Game/Screens/Play/KeyCounterAction.cs b/osu.Game/Screens/Play/KeyCounterAction.cs index f636796436..900d9bcd0e 100644 --- a/osu.Game/Screens/Play/KeyCounterAction.cs +++ b/osu.Game/Screens/Play/KeyCounterAction.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; namespace osu.Game.Screens.Play { - public class KeyCounterAction : KeyCounter + public partial class KeyCounterAction : KeyCounter where T : struct { public T Action { get; } diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs index 1b726b0f7b..d9ad3cfaf7 100644 --- a/osu.Game/Screens/Play/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs @@ -16,7 +16,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play { - public class KeyCounterDisplay : Container + public partial class KeyCounterDisplay : Container { private const int duration = 100; private const double key_fade_time = 80; @@ -141,7 +141,7 @@ namespace osu.Game.Screens.Play this.receptor = receptor; } - public class Receptor : Drawable + public partial class Receptor : Drawable { protected readonly KeyCounterDisplay Target; diff --git a/osu.Game/Screens/Play/KeyCounterKeyboard.cs b/osu.Game/Screens/Play/KeyCounterKeyboard.cs index 1005de4ea4..c5c8b7eeae 100644 --- a/osu.Game/Screens/Play/KeyCounterKeyboard.cs +++ b/osu.Game/Screens/Play/KeyCounterKeyboard.cs @@ -8,7 +8,7 @@ using osuTK.Input; namespace osu.Game.Screens.Play { - public class KeyCounterKeyboard : KeyCounter + public partial class KeyCounterKeyboard : KeyCounter { public Key Key { get; } diff --git a/osu.Game/Screens/Play/KeyCounterMouse.cs b/osu.Game/Screens/Play/KeyCounterMouse.cs index 0dc2830665..cf9c7c029f 100644 --- a/osu.Game/Screens/Play/KeyCounterMouse.cs +++ b/osu.Game/Screens/Play/KeyCounterMouse.cs @@ -9,7 +9,7 @@ using osuTK; namespace osu.Game.Screens.Play { - public class KeyCounterMouse : KeyCounter + public partial class KeyCounterMouse : KeyCounter { public MouseButton Button { get; } diff --git a/osu.Game/Screens/Play/MasterGameplayClockContainer.cs b/osu.Game/Screens/Play/MasterGameplayClockContainer.cs index c3c351ac36..489a4ef8b3 100644 --- a/osu.Game/Screens/Play/MasterGameplayClockContainer.cs +++ b/osu.Game/Screens/Play/MasterGameplayClockContainer.cs @@ -25,7 +25,7 @@ namespace osu.Game.Screens.Play /// /// This is intended to be used as a single controller for gameplay, or as a reference source for other s. /// - public class MasterGameplayClockContainer : GameplayClockContainer, IBeatSyncProvider + public partial class MasterGameplayClockContainer : GameplayClockContainer, IBeatSyncProvider { /// /// Duration before gameplay start time required before skip button displays. diff --git a/osu.Game/Screens/Play/PauseOverlay.cs b/osu.Game/Screens/Play/PauseOverlay.cs index cb98fefcfe..28044653e6 100644 --- a/osu.Game/Screens/Play/PauseOverlay.cs +++ b/osu.Game/Screens/Play/PauseOverlay.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play { - public class PauseOverlay : GameplayMenuOverlay + public partial class PauseOverlay : GameplayMenuOverlay { public Action OnResume; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 7048f83c09..4306d13ac2 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -44,7 +44,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play { [Cached] - public abstract class Player : ScreenWithBeatmapBackground, ISamplePlaybackDisabler, ILocalUserPlayInfo + public abstract partial class Player : ScreenWithBeatmapBackground, ISamplePlaybackDisabler, ILocalUserPlayInfo { /// /// The delay upon completion of the beatmap before displaying the results screen. diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 4ff5083107..5cedd4f793 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -31,7 +31,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play { - public class PlayerLoader : ScreenWithBeatmapBackground + public partial class PlayerLoader : ScreenWithBeatmapBackground { protected const float BACKGROUND_BLUR = 15; @@ -544,7 +544,7 @@ namespace osu.Game.Screens.Play } } - private class MutedNotification : SimpleNotification + private partial class MutedNotification : SimpleNotification { public override bool IsImportant => true; @@ -599,7 +599,7 @@ namespace osu.Game.Screens.Play } } - private class BatteryWarningNotification : SimpleNotification + private partial class BatteryWarningNotification : SimpleNotification { public override bool IsImportant => true; diff --git a/osu.Game/Screens/Play/PlayerSettings/AudioSettings.cs b/osu.Game/Screens/Play/PlayerSettings/AudioSettings.cs index 606b5c198c..010d8115fa 100644 --- a/osu.Game/Screens/Play/PlayerSettings/AudioSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/AudioSettings.cs @@ -12,7 +12,7 @@ using osu.Game.Scoring; namespace osu.Game.Screens.Play.PlayerSettings { - public class AudioSettings : PlayerSettingsGroup + public partial class AudioSettings : PlayerSettingsGroup { public Bindable ReferenceScore { get; } = new Bindable(); diff --git a/osu.Game/Screens/Play/PlayerSettings/BeatmapOffsetControl.cs b/osu.Game/Screens/Play/PlayerSettings/BeatmapOffsetControl.cs index fc89effe1b..9492614b66 100644 --- a/osu.Game/Screens/Play/PlayerSettings/BeatmapOffsetControl.cs +++ b/osu.Game/Screens/Play/PlayerSettings/BeatmapOffsetControl.cs @@ -25,7 +25,7 @@ using osuTK; namespace osu.Game.Screens.Play.PlayerSettings { - public class BeatmapOffsetControl : CompositeDrawable + public partial class BeatmapOffsetControl : CompositeDrawable { public Bindable ReferenceScore { get; } = new Bindable(); @@ -87,11 +87,11 @@ namespace osu.Game.Screens.Play.PlayerSettings }; } - public class OffsetSliderBar : PlayerSliderBar + public partial class OffsetSliderBar : PlayerSliderBar { protected override Drawable CreateControl() => new CustomSliderBar(); - protected class CustomSliderBar : SliderBar + protected partial class CustomSliderBar : SliderBar { public override LocalisableString TooltipText => Current.Value == 0 diff --git a/osu.Game/Screens/Play/PlayerSettings/DiscussionSettings.cs b/osu.Game/Screens/Play/PlayerSettings/DiscussionSettings.cs index afbd5caef3..7c76936621 100644 --- a/osu.Game/Screens/Play/PlayerSettings/DiscussionSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/DiscussionSettings.cs @@ -10,7 +10,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Screens.Play.PlayerSettings { - public class DiscussionSettings : PlayerSettingsGroup + public partial class DiscussionSettings : PlayerSettingsGroup { public DiscussionSettings() : base("discussions") diff --git a/osu.Game/Screens/Play/PlayerSettings/InputSettings.cs b/osu.Game/Screens/Play/PlayerSettings/InputSettings.cs index 04cf79873c..13e5b66a70 100644 --- a/osu.Game/Screens/Play/PlayerSettings/InputSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/InputSettings.cs @@ -10,7 +10,7 @@ using osu.Game.Localisation; namespace osu.Game.Screens.Play.PlayerSettings { - public class InputSettings : PlayerSettingsGroup + public partial class InputSettings : PlayerSettingsGroup { private readonly PlayerCheckbox mouseButtonsCheckbox; diff --git a/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs b/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs index 14e3123028..cb6fcb2413 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlaybackSettings.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Screens.Play.PlayerSettings { - public class PlaybackSettings : PlayerSettingsGroup + public partial class PlaybackSettings : PlayerSettingsGroup { private const int padding = 10; diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs index cea03d2155..49c9cbf385 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerCheckbox.cs @@ -9,11 +9,11 @@ using osu.Game.Overlays.Settings; namespace osu.Game.Screens.Play.PlayerSettings { - public class PlayerCheckbox : SettingsCheckbox + public partial class PlayerCheckbox : SettingsCheckbox { protected override Drawable CreateControl() => new PlayerCheckboxControl(); - public class PlayerCheckboxControl : OsuCheckbox + public partial class PlayerCheckboxControl : OsuCheckbox { [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs index 6c6f62a8ac..c930513c70 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs @@ -8,7 +8,7 @@ using osu.Game.Overlays; namespace osu.Game.Screens.Play.PlayerSettings { - public class PlayerSettingsGroup : SettingsToolboxGroup + public partial class PlayerSettingsGroup : SettingsToolboxGroup { public PlayerSettingsGroup(string title) : base(title) diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerSliderBar.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerSliderBar.cs index 063056e83e..45d4995753 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerSliderBar.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerSliderBar.cs @@ -12,14 +12,14 @@ using osu.Game.Overlays.Settings; namespace osu.Game.Screens.Play.PlayerSettings { - public class PlayerSliderBar : SettingsSlider + public partial class PlayerSliderBar : SettingsSlider where T : struct, IEquatable, IComparable, IConvertible { public OsuSliderBar Bar => (OsuSliderBar)Control; protected override Drawable CreateControl() => new SliderBar(); - protected class SliderBar : OsuSliderBar + protected partial class SliderBar : OsuSliderBar { public SliderBar() { diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs index 6a7eabc6a2..ff857ddb12 100644 --- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs @@ -8,7 +8,7 @@ using osu.Game.Localisation; namespace osu.Game.Screens.Play.PlayerSettings { - public class VisualSettings : PlayerSettingsGroup + public partial class VisualSettings : PlayerSettingsGroup { private readonly PlayerSliderBar dimSliderBar; private readonly PlayerSliderBar blurSliderBar; diff --git a/osu.Game/Screens/Play/ReplayPlayer.cs b/osu.Game/Screens/Play/ReplayPlayer.cs index 5382e283e0..4395b96139 100644 --- a/osu.Game/Screens/Play/ReplayPlayer.cs +++ b/osu.Game/Screens/Play/ReplayPlayer.cs @@ -20,7 +20,7 @@ using osu.Game.Screens.Ranking; namespace osu.Game.Screens.Play { - public class ReplayPlayer : Player, IKeyBindingHandler + public partial class ReplayPlayer : Player, IKeyBindingHandler { private readonly Func, Score> createScore; diff --git a/osu.Game/Screens/Play/ReplayPlayerLoader.cs b/osu.Game/Screens/Play/ReplayPlayerLoader.cs index a961f90d00..1c9d694325 100644 --- a/osu.Game/Screens/Play/ReplayPlayerLoader.cs +++ b/osu.Game/Screens/Play/ReplayPlayerLoader.cs @@ -9,7 +9,7 @@ using osu.Game.Scoring; namespace osu.Game.Screens.Play { - public class ReplayPlayerLoader : PlayerLoader + public partial class ReplayPlayerLoader : PlayerLoader { public readonly ScoreInfo Score; diff --git a/osu.Game/Screens/Play/ResumeOverlay.cs b/osu.Game/Screens/Play/ResumeOverlay.cs index 7ed95c4ce3..fae406bd6b 100644 --- a/osu.Game/Screens/Play/ResumeOverlay.cs +++ b/osu.Game/Screens/Play/ResumeOverlay.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.Play /// /// An overlay which can be used to require further user actions before gameplay is resumed. /// - public abstract class ResumeOverlay : VisibilityContainer + public abstract partial class ResumeOverlay : VisibilityContainer { public CursorContainer GameplayCursor { get; set; } diff --git a/osu.Game/Screens/Play/RoomSubmittingPlayer.cs b/osu.Game/Screens/Play/RoomSubmittingPlayer.cs index 3eb659664a..e21daa737e 100644 --- a/osu.Game/Screens/Play/RoomSubmittingPlayer.cs +++ b/osu.Game/Screens/Play/RoomSubmittingPlayer.cs @@ -13,7 +13,7 @@ namespace osu.Game.Screens.Play /// /// A player instance which submits to a room backing. This is generally used by playlists and multiplayer. /// - public abstract class RoomSubmittingPlayer : SubmittingPlayer + public abstract partial class RoomSubmittingPlayer : SubmittingPlayer { protected readonly PlaylistItem PlaylistItem; protected readonly Room Room; diff --git a/osu.Game/Screens/Play/SaveFailedScoreButton.cs b/osu.Game/Screens/Play/SaveFailedScoreButton.cs index 7358ff3de4..20d2130e76 100644 --- a/osu.Game/Screens/Play/SaveFailedScoreButton.cs +++ b/osu.Game/Screens/Play/SaveFailedScoreButton.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Screens.Play { - public class SaveFailedScoreButton : CompositeDrawable + public partial class SaveFailedScoreButton : CompositeDrawable { private readonly Bindable state = new Bindable(); diff --git a/osu.Game/Screens/Play/ScreenSuspensionHandler.cs b/osu.Game/Screens/Play/ScreenSuspensionHandler.cs index cc1254975c..85948ea3f7 100644 --- a/osu.Game/Screens/Play/ScreenSuspensionHandler.cs +++ b/osu.Game/Screens/Play/ScreenSuspensionHandler.cs @@ -15,7 +15,7 @@ namespace osu.Game.Screens.Play /// /// Ensures screen is not suspended / dimmed while gameplay is active. /// - public class ScreenSuspensionHandler : Component + public partial class ScreenSuspensionHandler : Component { private readonly GameplayClockContainer gameplayClockContainer; private IBindable isPaused; diff --git a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs index 7152fb7473..d6c8a0ad6a 100644 --- a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs +++ b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs @@ -8,7 +8,7 @@ using osu.Game.Screens.Backgrounds; namespace osu.Game.Screens.Play { - public abstract class ScreenWithBeatmapBackground : OsuScreen + public abstract partial class ScreenWithBeatmapBackground : OsuScreen { protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value); diff --git a/osu.Game/Screens/Play/SkipOverlay.cs b/osu.Game/Screens/Play/SkipOverlay.cs index 99fe659bf3..7d69f0ca18 100644 --- a/osu.Game/Screens/Play/SkipOverlay.cs +++ b/osu.Game/Screens/Play/SkipOverlay.cs @@ -25,7 +25,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play { - public class SkipOverlay : CompositeDrawable, IKeyBindingHandler + public partial class SkipOverlay : CompositeDrawable, IKeyBindingHandler { /// /// The total number of successful skips performed by this overlay. @@ -209,7 +209,7 @@ namespace osu.Game.Screens.Play { } - public class FadeContainer : Container, IStateful + public partial class FadeContainer : Container, IStateful { public event Action StateChanged; @@ -287,14 +287,14 @@ namespace osu.Game.Screens.Play public override void Show() => State = Visibility.Visible; } - private class ButtonContainer : VisibilityContainer + private partial class ButtonContainer : VisibilityContainer { protected override void PopIn() => this.FadeIn(fade_time); protected override void PopOut() => this.FadeOut(fade_time); } - private class Button : OsuClickableContainer + private partial class Button : OsuClickableContainer { private Color4 colourNormal; private Color4 colourHover; diff --git a/osu.Game/Screens/Play/SoloPlayer.cs b/osu.Game/Screens/Play/SoloPlayer.cs index ee19391b89..dafdf00136 100644 --- a/osu.Game/Screens/Play/SoloPlayer.cs +++ b/osu.Game/Screens/Play/SoloPlayer.cs @@ -17,7 +17,7 @@ using osu.Game.Screens.Play.HUD; namespace osu.Game.Screens.Play { - public class SoloPlayer : SubmittingPlayer + public partial class SoloPlayer : SubmittingPlayer { public SoloPlayer() : this(null) diff --git a/osu.Game/Screens/Play/SoloSpectator.cs b/osu.Game/Screens/Play/SoloSpectator.cs index 9ef05c3a05..e1692af351 100644 --- a/osu.Game/Screens/Play/SoloSpectator.cs +++ b/osu.Game/Screens/Play/SoloSpectator.cs @@ -33,7 +33,7 @@ using osuTK; namespace osu.Game.Screens.Play { [Cached(typeof(IPreviewTrackOwner))] - public class SoloSpectator : SpectatorScreen, IPreviewTrackOwner + public partial class SoloSpectator : SpectatorScreen, IPreviewTrackOwner { [NotNull] private readonly APIUser targetUser; diff --git a/osu.Game/Screens/Play/SoloSpectatorPlayer.cs b/osu.Game/Screens/Play/SoloSpectatorPlayer.cs index 5aa310750b..240fbcf662 100644 --- a/osu.Game/Screens/Play/SoloSpectatorPlayer.cs +++ b/osu.Game/Screens/Play/SoloSpectatorPlayer.cs @@ -10,7 +10,7 @@ using osu.Game.Scoring; namespace osu.Game.Screens.Play { - public class SoloSpectatorPlayer : SpectatorPlayer + public partial class SoloSpectatorPlayer : SpectatorPlayer { private readonly Score score; diff --git a/osu.Game/Screens/Play/SpectatorPlayer.cs b/osu.Game/Screens/Play/SpectatorPlayer.cs index 68cc21fc1c..30a5ac3741 100644 --- a/osu.Game/Screens/Play/SpectatorPlayer.cs +++ b/osu.Game/Screens/Play/SpectatorPlayer.cs @@ -18,7 +18,7 @@ using osu.Game.Screens.Ranking; namespace osu.Game.Screens.Play { - public abstract class SpectatorPlayer : Player + public abstract partial class SpectatorPlayer : Player { [Resolved] protected SpectatorClient SpectatorClient { get; private set; } diff --git a/osu.Game/Screens/Play/SpectatorPlayerLoader.cs b/osu.Game/Screens/Play/SpectatorPlayerLoader.cs index 6b664a4f96..3830443ce8 100644 --- a/osu.Game/Screens/Play/SpectatorPlayerLoader.cs +++ b/osu.Game/Screens/Play/SpectatorPlayerLoader.cs @@ -9,7 +9,7 @@ using osu.Game.Scoring; namespace osu.Game.Screens.Play { - public class SpectatorPlayerLoader : PlayerLoader + public partial class SpectatorPlayerLoader : PlayerLoader { public readonly ScoreInfo Score; diff --git a/osu.Game/Screens/Play/SpectatorResultsScreen.cs b/osu.Game/Screens/Play/SpectatorResultsScreen.cs index 3d320bd294..b54dbb387a 100644 --- a/osu.Game/Screens/Play/SpectatorResultsScreen.cs +++ b/osu.Game/Screens/Play/SpectatorResultsScreen.cs @@ -11,7 +11,7 @@ using osu.Game.Screens.Ranking; namespace osu.Game.Screens.Play { - public class SpectatorResultsScreen : SoloResultsScreen + public partial class SpectatorResultsScreen : SoloResultsScreen { public SpectatorResultsScreen(ScoreInfo score) : base(score, false) diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index 9ac673ae52..57b7c84e89 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -19,7 +19,7 @@ using osu.Framework.Threading; namespace osu.Game.Screens.Play { - public class SquareGraph : Container + public partial class SquareGraph : Container { private BufferedContainer columns; @@ -176,7 +176,7 @@ namespace osu.Game.Screens.Play calculatedValues = newValues.ToArray(); } - public class Column : Container, IStateful + public partial class Column : Container, IStateful { protected readonly Color4 EmptyColour = Color4.White.Opacity(20); public Color4 LitColour = Color4.LightBlue; diff --git a/osu.Game/Screens/Play/SubmittingPlayer.cs b/osu.Game/Screens/Play/SubmittingPlayer.cs index fb296d7988..14453c8cbe 100644 --- a/osu.Game/Screens/Play/SubmittingPlayer.cs +++ b/osu.Game/Screens/Play/SubmittingPlayer.cs @@ -23,7 +23,7 @@ namespace osu.Game.Screens.Play /// /// A player instance which supports submitting scores to an online store. /// - public abstract class SubmittingPlayer : Player + public abstract partial class SubmittingPlayer : Player { /// /// The token to be used for the current submission. This is fetched via a request created by . diff --git a/osu.Game/Screens/Ranking/AspectContainer.cs b/osu.Game/Screens/Ranking/AspectContainer.cs index 1c93d08474..9ec2a15044 100644 --- a/osu.Game/Screens/Ranking/AspectContainer.cs +++ b/osu.Game/Screens/Ranking/AspectContainer.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Screens.Ranking { - public class AspectContainer : Container + public partial class AspectContainer : Container { protected override void Update() { diff --git a/osu.Game/Screens/Ranking/Contracted/ContractedPanelMiddleContent.cs b/osu.Game/Screens/Ranking/Contracted/ContractedPanelMiddleContent.cs index 3e67868f34..402322c611 100644 --- a/osu.Game/Screens/Ranking/Contracted/ContractedPanelMiddleContent.cs +++ b/osu.Game/Screens/Ranking/Contracted/ContractedPanelMiddleContent.cs @@ -31,7 +31,7 @@ namespace osu.Game.Screens.Ranking.Contracted /// /// The content that appears in the middle of a contracted . /// - public class ContractedPanelMiddleContent : CompositeDrawable + public partial class ContractedPanelMiddleContent : CompositeDrawable { private readonly ScoreInfo score; diff --git a/osu.Game/Screens/Ranking/Contracted/ContractedPanelTopContent.cs b/osu.Game/Screens/Ranking/Contracted/ContractedPanelTopContent.cs index 74b2f4ef93..93bc7c41e1 100644 --- a/osu.Game/Screens/Ranking/Contracted/ContractedPanelTopContent.cs +++ b/osu.Game/Screens/Ranking/Contracted/ContractedPanelTopContent.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Screens.Ranking.Contracted { - public class ContractedPanelTopContent : CompositeDrawable + public partial class ContractedPanelTopContent : CompositeDrawable { public readonly Bindable ScorePosition = new Bindable(); diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs index a1879c5c9b..3285ebc914 100644 --- a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs +++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs @@ -25,7 +25,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy /// /// The component that displays the player's accuracy on the results screen. /// - public class AccuracyCircle : CompositeDrawable + public partial class AccuracyCircle : CompositeDrawable { /// /// Duration for the transforms causing this component to appear. diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/RankBadge.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/RankBadge.cs index 80415dbbc2..5432b4cbeb 100644 --- a/osu.Game/Screens/Ranking/Expanded/Accuracy/RankBadge.cs +++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/RankBadge.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy /// /// Contains a that is positioned around the . /// - public class RankBadge : CompositeDrawable + public partial class RankBadge : CompositeDrawable { /// /// The accuracy value corresponding to the displayed by this badge. diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/RankNotch.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/RankNotch.cs index 573833932f..7e73767318 100644 --- a/osu.Game/Screens/Ranking/Expanded/Accuracy/RankNotch.cs +++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/RankNotch.cs @@ -15,7 +15,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy /// /// A solid "notch" of the that appears at the ends of the rank circles to add separation. /// - public class RankNotch : CompositeDrawable + public partial class RankNotch : CompositeDrawable { private readonly float position; diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/RankText.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/RankText.cs index 2d9c1f9d07..b7adcb032f 100644 --- a/osu.Game/Screens/Ranking/Expanded/Accuracy/RankText.cs +++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/RankText.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy /// /// The text that appears in the middle of the displaying the user's rank. /// - public class RankText : CompositeDrawable + public partial class RankText : CompositeDrawable { private readonly ScoreRank rank; diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/SmoothCircularProgress.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/SmoothCircularProgress.cs index b4f41e0f39..601c47ea55 100644 --- a/osu.Game/Screens/Ranking/Expanded/Accuracy/SmoothCircularProgress.cs +++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/SmoothCircularProgress.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy /// /// Contains a with smoothened edges. /// - public class SmoothCircularProgress : CompositeDrawable + public partial class SmoothCircularProgress : CompositeDrawable { public Bindable Current { diff --git a/osu.Game/Screens/Ranking/Expanded/ExpandedPanelMiddleContent.cs b/osu.Game/Screens/Ranking/Expanded/ExpandedPanelMiddleContent.cs index 829ba83696..8fe0ae509b 100644 --- a/osu.Game/Screens/Ranking/Expanded/ExpandedPanelMiddleContent.cs +++ b/osu.Game/Screens/Ranking/Expanded/ExpandedPanelMiddleContent.cs @@ -31,7 +31,7 @@ namespace osu.Game.Screens.Ranking.Expanded /// /// The content that appears in the middle section of the . /// - public class ExpandedPanelMiddleContent : CompositeDrawable + public partial class ExpandedPanelMiddleContent : CompositeDrawable { private const float padding = 10; @@ -280,7 +280,7 @@ namespace osu.Game.Screens.Ranking.Expanded }); } - public class PlayedOnText : OsuSpriteText + public partial class PlayedOnText : OsuSpriteText { private readonly DateTimeOffset time; private readonly Bindable prefer24HourTime = new Bindable(); diff --git a/osu.Game/Screens/Ranking/Expanded/ExpandedPanelTopContent.cs b/osu.Game/Screens/Ranking/Expanded/ExpandedPanelTopContent.cs index 2708090855..c834d541eb 100644 --- a/osu.Game/Screens/Ranking/Expanded/ExpandedPanelTopContent.cs +++ b/osu.Game/Screens/Ranking/Expanded/ExpandedPanelTopContent.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.Ranking.Expanded /// /// The content that appears in the middle section of the . /// - public class ExpandedPanelTopContent : CompositeDrawable + public partial class ExpandedPanelTopContent : CompositeDrawable { private readonly APIUser user; diff --git a/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs b/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs index 824156598c..4b8c057235 100644 --- a/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs +++ b/osu.Game/Screens/Ranking/Expanded/Statistics/AccuracyStatistic.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Statistics /// /// A to display the player's accuracy. /// - public class AccuracyStatistic : StatisticDisplay + public partial class AccuracyStatistic : StatisticDisplay { private readonly double accuracy; @@ -42,7 +42,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Statistics protected override Drawable CreateContent() => counter = new Counter(); - private class Counter : RollingCounter + private partial class Counter : RollingCounter { protected override double RollingDuration => AccuracyCircle.ACCURACY_TRANSFORM_DURATION; diff --git a/osu.Game/Screens/Ranking/Expanded/Statistics/ComboStatistic.cs b/osu.Game/Screens/Ranking/Expanded/Statistics/ComboStatistic.cs index 3505786b64..6290cee6da 100644 --- a/osu.Game/Screens/Ranking/Expanded/Statistics/ComboStatistic.cs +++ b/osu.Game/Screens/Ranking/Expanded/Statistics/ComboStatistic.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Statistics /// /// A to display the player's combo. /// - public class ComboStatistic : CounterStatistic + public partial class ComboStatistic : CounterStatistic { private readonly bool isPerfect; diff --git a/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs b/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs index 17a12a76a5..8528dac83b 100644 --- a/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs +++ b/osu.Game/Screens/Ranking/Expanded/Statistics/CounterStatistic.cs @@ -16,7 +16,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Statistics /// /// A to display general numeric values. /// - public class CounterStatistic : StatisticDisplay + public partial class CounterStatistic : StatisticDisplay { private readonly int count; private readonly int? maxCount; diff --git a/osu.Game/Screens/Ranking/Expanded/Statistics/HitResultStatistic.cs b/osu.Game/Screens/Ranking/Expanded/Statistics/HitResultStatistic.cs index c23a5e668d..863c450617 100644 --- a/osu.Game/Screens/Ranking/Expanded/Statistics/HitResultStatistic.cs +++ b/osu.Game/Screens/Ranking/Expanded/Statistics/HitResultStatistic.cs @@ -10,7 +10,7 @@ using osu.Game.Scoring; namespace osu.Game.Screens.Ranking.Expanded.Statistics { - public class HitResultStatistic : CounterStatistic + public partial class HitResultStatistic : CounterStatistic { public readonly HitResult Result; diff --git a/osu.Game/Screens/Ranking/Expanded/Statistics/PerformanceStatistic.cs b/osu.Game/Screens/Ranking/Expanded/Statistics/PerformanceStatistic.cs index 332215e15d..22509b2cea 100644 --- a/osu.Game/Screens/Ranking/Expanded/Statistics/PerformanceStatistic.cs +++ b/osu.Game/Screens/Ranking/Expanded/Statistics/PerformanceStatistic.cs @@ -15,7 +15,7 @@ using osu.Game.Scoring; namespace osu.Game.Screens.Ranking.Expanded.Statistics { - public class PerformanceStatistic : StatisticDisplay + public partial class PerformanceStatistic : StatisticDisplay { private readonly ScoreInfo score; diff --git a/osu.Game/Screens/Ranking/Expanded/Statistics/StatisticCounter.cs b/osu.Game/Screens/Ranking/Expanded/Statistics/StatisticCounter.cs index 36d6d6fa7c..ecadc9eed6 100644 --- a/osu.Game/Screens/Ranking/Expanded/Statistics/StatisticCounter.cs +++ b/osu.Game/Screens/Ranking/Expanded/Statistics/StatisticCounter.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Screens.Ranking.Expanded.Statistics { - public class StatisticCounter : RollingCounter + public partial class StatisticCounter : RollingCounter { protected override double RollingDuration => AccuracyCircle.ACCURACY_TRANSFORM_DURATION; diff --git a/osu.Game/Screens/Ranking/Expanded/Statistics/StatisticDisplay.cs b/osu.Game/Screens/Ranking/Expanded/Statistics/StatisticDisplay.cs index 0d8dcda895..686b6c7d47 100644 --- a/osu.Game/Screens/Ranking/Expanded/Statistics/StatisticDisplay.cs +++ b/osu.Game/Screens/Ranking/Expanded/Statistics/StatisticDisplay.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Statistics /// /// A statistic from the score to be displayed in the . /// - public abstract class StatisticDisplay : CompositeDrawable + public abstract partial class StatisticDisplay : CompositeDrawable { protected SpriteText HeaderText { get; private set; } diff --git a/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs b/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs index c7286a1838..b017a3a63d 100644 --- a/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs +++ b/osu.Game/Screens/Ranking/Expanded/TotalScoreCounter.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.Ranking.Expanded /// /// A counter for the player's total score to be displayed in the . /// - public class TotalScoreCounter : RollingCounter + public partial class TotalScoreCounter : RollingCounter { protected override double RollingDuration => AccuracyCircle.ACCURACY_TRANSFORM_DURATION; diff --git a/osu.Game/Screens/Ranking/ReplayDownloadButton.cs b/osu.Game/Screens/Ranking/ReplayDownloadButton.cs index 7081a0156e..5c5cb61b79 100644 --- a/osu.Game/Screens/Ranking/ReplayDownloadButton.cs +++ b/osu.Game/Screens/Ranking/ReplayDownloadButton.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Screens.Ranking { - public class ReplayDownloadButton : CompositeDrawable + public partial class ReplayDownloadButton : CompositeDrawable { public readonly Bindable Score = new Bindable(); diff --git a/osu.Game/Screens/Ranking/ResultsScreen.cs b/osu.Game/Screens/Ranking/ResultsScreen.cs index 486df8653f..f3aca43a9d 100644 --- a/osu.Game/Screens/Ranking/ResultsScreen.cs +++ b/osu.Game/Screens/Ranking/ResultsScreen.cs @@ -29,7 +29,7 @@ using osuTK; namespace osu.Game.Screens.Ranking { - public abstract class ResultsScreen : ScreenWithBeatmapBackground, IKeyBindingHandler + public abstract partial class ResultsScreen : ScreenWithBeatmapBackground, IKeyBindingHandler { protected const float BACKGROUND_BLUR = 20; private static readonly float screen_height = 768 - TwoLayerButton.SIZE_EXTENDED.Y; @@ -357,7 +357,7 @@ namespace osu.Game.Screens.Ranking { } - protected class VerticalScrollContainer : OsuScrollContainer + protected partial class VerticalScrollContainer : OsuScrollContainer { protected override Container Content => content; diff --git a/osu.Game/Screens/Ranking/RetryButton.cs b/osu.Game/Screens/Ranking/RetryButton.cs index c56f364ae8..c7d2416e29 100644 --- a/osu.Game/Screens/Ranking/RetryButton.cs +++ b/osu.Game/Screens/Ranking/RetryButton.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Screens.Ranking { - public class RetryButton : OsuAnimatedButton + public partial class RetryButton : OsuAnimatedButton { private readonly Box background; diff --git a/osu.Game/Screens/Ranking/ScorePanel.cs b/osu.Game/Screens/Ranking/ScorePanel.cs index cb777de144..5aecf18033 100644 --- a/osu.Game/Screens/Ranking/ScorePanel.cs +++ b/osu.Game/Screens/Ranking/ScorePanel.cs @@ -25,7 +25,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Ranking { - public class ScorePanel : CompositeDrawable, IStateful + public partial class ScorePanel : CompositeDrawable, IStateful { /// /// Width of the panel when contracted. diff --git a/osu.Game/Screens/Ranking/ScorePanelList.cs b/osu.Game/Screens/Ranking/ScorePanelList.cs index 46f9efd126..29dec42083 100644 --- a/osu.Game/Screens/Ranking/ScorePanelList.cs +++ b/osu.Game/Screens/Ranking/ScorePanelList.cs @@ -21,7 +21,7 @@ using osuTK.Input; namespace osu.Game.Screens.Ranking { - public class ScorePanelList : CompositeDrawable + public partial class ScorePanelList : CompositeDrawable { /// /// Normal spacing between all panels. @@ -322,7 +322,7 @@ namespace osu.Game.Screens.Ranking loadCancellationSource?.Cancel(); } - private class Flow : FillFlowContainer + private partial class Flow : FillFlowContainer { public override IEnumerable FlowingChildren => applySorting(AliveInternalChildren); @@ -339,7 +339,7 @@ namespace osu.Game.Screens.Ranking .ThenBy(s => s.Panel.Score.OnlineID); } - private class Scroll : OsuScrollContainer + private partial class Scroll : OsuScrollContainer { public new float Target => base.Target; diff --git a/osu.Game/Screens/Ranking/ScorePanelTrackingContainer.cs b/osu.Game/Screens/Ranking/ScorePanelTrackingContainer.cs index b4d6d481ef..ec153cbd63 100644 --- a/osu.Game/Screens/Ranking/ScorePanelTrackingContainer.cs +++ b/osu.Game/Screens/Ranking/ScorePanelTrackingContainer.cs @@ -11,7 +11,7 @@ namespace osu.Game.Screens.Ranking /// /// A which tracks the size of a , to which the can be added or removed. /// - public class ScorePanelTrackingContainer : CompositeDrawable + public partial class ScorePanelTrackingContainer : CompositeDrawable { /// /// The that created this . diff --git a/osu.Game/Screens/Ranking/SoloResultsScreen.cs b/osu.Game/Screens/Ranking/SoloResultsScreen.cs index 4312c9528f..3774cf16b1 100644 --- a/osu.Game/Screens/Ranking/SoloResultsScreen.cs +++ b/osu.Game/Screens/Ranking/SoloResultsScreen.cs @@ -15,7 +15,7 @@ using osu.Game.Scoring; namespace osu.Game.Screens.Ranking { - public class SoloResultsScreen : ResultsScreen + public partial class SoloResultsScreen : ResultsScreen { private GetScoresRequest getScoreRequest; diff --git a/osu.Game/Screens/Ranking/Statistics/AverageHitError.cs b/osu.Game/Screens/Ranking/Statistics/AverageHitError.cs index a0a9c1c1e2..bb9905d29c 100644 --- a/osu.Game/Screens/Ranking/Statistics/AverageHitError.cs +++ b/osu.Game/Screens/Ranking/Statistics/AverageHitError.cs @@ -12,7 +12,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// /// Displays the unstable rate statistic for a given play. /// - public class AverageHitError : SimpleStatisticItem + public partial class AverageHitError : SimpleStatisticItem { /// /// Creates and computes an statistic. diff --git a/osu.Game/Screens/Ranking/Statistics/HitEventTimingDistributionGraph.cs b/osu.Game/Screens/Ranking/Statistics/HitEventTimingDistributionGraph.cs index 764237ef96..6b1850002d 100644 --- a/osu.Game/Screens/Ranking/Statistics/HitEventTimingDistributionGraph.cs +++ b/osu.Game/Screens/Ranking/Statistics/HitEventTimingDistributionGraph.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// /// A graph which displays the distribution of hit timing in a series of s. /// - public class HitEventTimingDistributionGraph : CompositeDrawable + public partial class HitEventTimingDistributionGraph : CompositeDrawable { /// /// The number of bins on each side of the timing distribution. @@ -204,7 +204,7 @@ namespace osu.Game.Screens.Ranking.Statistics } } - private class Bar : CompositeDrawable + private partial class Bar : CompositeDrawable { private readonly IReadOnlyList> values; private readonly float maxValue; diff --git a/osu.Game/Screens/Ranking/Statistics/PerformanceBreakdownChart.cs b/osu.Game/Screens/Ranking/Statistics/PerformanceBreakdownChart.cs index 3462a85e1c..10cb77fa91 100644 --- a/osu.Game/Screens/Ranking/Statistics/PerformanceBreakdownChart.cs +++ b/osu.Game/Screens/Ranking/Statistics/PerformanceBreakdownChart.cs @@ -26,7 +26,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Ranking.Statistics { - public class PerformanceBreakdownChart : Container + public partial class PerformanceBreakdownChart : Container { private readonly ScoreInfo score; private readonly IBeatmap playableBeatmap; diff --git a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs index ecff631c7e..99f4e1e342 100644 --- a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs +++ b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticItem.cs @@ -14,7 +14,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// Represents a simple statistic item (one that only needs textual display). /// Richer visualisations should be done with s. /// - public abstract class SimpleStatisticItem : Container + public abstract partial class SimpleStatisticItem : Container { /// /// The text to display as the statistic's value. @@ -59,7 +59,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// /// Strongly-typed generic specialisation for . /// - public class SimpleStatisticItem : SimpleStatisticItem + public partial class SimpleStatisticItem : SimpleStatisticItem { private TValue value; diff --git a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticTable.cs b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticTable.cs index f1eb16ca80..d10888be43 100644 --- a/osu.Game/Screens/Ranking/Statistics/SimpleStatisticTable.cs +++ b/osu.Game/Screens/Ranking/Statistics/SimpleStatisticTable.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// Represents a table with simple statistics (ones that only need textual display). /// Richer visualisations should be done with s and s. /// - public class SimpleStatisticTable : CompositeDrawable + public partial class SimpleStatisticTable : CompositeDrawable { private readonly SimpleStatisticItem[] items; private readonly int columnCount; @@ -98,7 +98,7 @@ namespace osu.Game.Screens.Ranking.Statistics Direction = FillDirection.Vertical }; - private class Spacer : CompositeDrawable + private partial class Spacer : CompositeDrawable { public Spacer() { diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticContainer.cs b/osu.Game/Screens/Ranking/Statistics/StatisticContainer.cs index 1505585205..d3327224dc 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticContainer.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticContainer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// /// Wraps a to add a header and suitable layout for use in . /// - internal class StatisticContainer : CompositeDrawable + internal partial class StatisticContainer : CompositeDrawable { /// /// Creates a new . diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs index 79d7b99e51..91102d6647 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs @@ -24,7 +24,7 @@ using osuTK; namespace osu.Game.Screens.Ranking.Statistics { - public class StatisticsPanel : VisibilityContainer + public partial class StatisticsPanel : VisibilityContainer { public const float SIDE_PADDING = 30; diff --git a/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs b/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs index 4ab085fa23..de01668029 100644 --- a/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs +++ b/osu.Game/Screens/Ranking/Statistics/UnstableRate.cs @@ -11,7 +11,7 @@ namespace osu.Game.Screens.Ranking.Statistics /// /// Displays the unstable rate statistic for a given play. /// - public class UnstableRate : SimpleStatisticItem + public partial class UnstableRate : SimpleStatisticItem { /// /// Creates and computes an statistic. diff --git a/osu.Game/Screens/ScreenWhiteBox.cs b/osu.Game/Screens/ScreenWhiteBox.cs index 550fda5480..25afe119be 100644 --- a/osu.Game/Screens/ScreenWhiteBox.cs +++ b/osu.Game/Screens/ScreenWhiteBox.cs @@ -20,7 +20,7 @@ using osu.Framework.Graphics.Sprites; namespace osu.Game.Screens { - public class ScreenWhiteBox : OsuScreen + public partial class ScreenWhiteBox : OsuScreen { private readonly UnderConstructionMessage message; @@ -95,7 +95,7 @@ namespace osu.Game.Screens return new Color4(r, g, b, 255); } - private class ChildModeButton : TwoLayerButton + private partial class ChildModeButton : TwoLayerButton { public ChildModeButton() { @@ -105,7 +105,7 @@ namespace osu.Game.Screens } } - public class UnderConstructionMessage : CompositeDrawable + public partial class UnderConstructionMessage : CompositeDrawable { public FillFlowContainer TextContainer { get; } diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 752a1ede64..6955b8ef56 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -32,7 +32,7 @@ using Realms; namespace osu.Game.Screens.Select { - public class BeatmapCarousel : CompositeDrawable, IKeyBindingHandler + public partial class BeatmapCarousel : CompositeDrawable, IKeyBindingHandler { /// /// Height of the area above the carousel that should be treated as visible due to transparency of elements in front of it. @@ -1075,7 +1075,7 @@ namespace osu.Game.Screens.Select } } - protected class CarouselScrollContainer : UserTrackingScrollContainer + protected partial class CarouselScrollContainer : UserTrackingScrollContainer { private bool rightMouseScrollBlocked; diff --git a/osu.Game/Screens/Select/BeatmapClearScoresDialog.cs b/osu.Game/Screens/Select/BeatmapClearScoresDialog.cs index 0996e3e202..c0f97a05e2 100644 --- a/osu.Game/Screens/Select/BeatmapClearScoresDialog.cs +++ b/osu.Game/Screens/Select/BeatmapClearScoresDialog.cs @@ -10,7 +10,7 @@ using osu.Game.Scoring; namespace osu.Game.Screens.Select { - public class BeatmapClearScoresDialog : DeleteConfirmationDialog + public partial class BeatmapClearScoresDialog : DeleteConfirmationDialog { [Resolved] private ScoreManager scoreManager { get; set; } = null!; diff --git a/osu.Game/Screens/Select/BeatmapDeleteDialog.cs b/osu.Game/Screens/Select/BeatmapDeleteDialog.cs index 3d3e8b6d73..4ab23c3a3a 100644 --- a/osu.Game/Screens/Select/BeatmapDeleteDialog.cs +++ b/osu.Game/Screens/Select/BeatmapDeleteDialog.cs @@ -7,7 +7,7 @@ using osu.Game.Overlays.Dialog; namespace osu.Game.Screens.Select { - public class BeatmapDeleteDialog : DeleteConfirmationDialog + public partial class BeatmapDeleteDialog : DeleteConfirmationDialog { private readonly BeatmapSetInfo beatmapSet; diff --git a/osu.Game/Screens/Select/BeatmapDetailArea.cs b/osu.Game/Screens/Select/BeatmapDetailArea.cs index bf6803f551..595b86924b 100644 --- a/osu.Game/Screens/Select/BeatmapDetailArea.cs +++ b/osu.Game/Screens/Select/BeatmapDetailArea.cs @@ -11,7 +11,7 @@ using osu.Game.Beatmaps; namespace osu.Game.Screens.Select { - public abstract class BeatmapDetailArea : Container + public abstract partial class BeatmapDetailArea : Container { private const float details_padding = 10; diff --git a/osu.Game/Screens/Select/BeatmapDetailAreaTabControl.cs b/osu.Game/Screens/Select/BeatmapDetailAreaTabControl.cs index 3c0d621abe..f9dab2bb1d 100644 --- a/osu.Game/Screens/Select/BeatmapDetailAreaTabControl.cs +++ b/osu.Game/Screens/Select/BeatmapDetailAreaTabControl.cs @@ -17,7 +17,7 @@ using osu.Framework.Graphics.Shapes; namespace osu.Game.Screens.Select { - public class BeatmapDetailAreaTabControl : Container + public partial class BeatmapDetailAreaTabControl : Container { public const float HEIGHT = 24; diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index 90418efe15..0a14df6480 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -23,7 +23,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Select { - public class BeatmapDetails : Container + public partial class BeatmapDetails : Container { private const float spacing = 10; private const float transition_duration = 250; @@ -273,7 +273,7 @@ namespace osu.Game.Screens.Select loading.Hide(); } - private class DetailBox : Container + private partial class DetailBox : Container { private readonly Container content; protected override Container Content => content; diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 3ee9a11b24..2102df1022 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -33,7 +33,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Screens.Select { - public class BeatmapInfoWedge : VisibilityContainer + public partial class BeatmapInfoWedge : VisibilityContainer { public const float BORDER_THICKNESS = 2.5f; private const float shear_width = 36.75f; @@ -148,7 +148,7 @@ namespace osu.Game.Screens.Select } } - public class WedgeInfoText : Container + public partial class WedgeInfoText : Container { public OsuSpriteText VersionLabel { get; private set; } public OsuSpriteText TitleLabel { get; private set; } @@ -456,7 +456,7 @@ namespace osu.Game.Screens.Select cancellationSource?.Cancel(); } - public class InfoLabel : Container, IHasTooltip + public partial class InfoLabel : Container, IHasTooltip { public LocalisableString TooltipText { get; } diff --git a/osu.Game/Screens/Select/BeatmapInfoWedgeBackground.cs b/osu.Game/Screens/Select/BeatmapInfoWedgeBackground.cs index 68f0c92097..d5d258704b 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedgeBackground.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedgeBackground.cs @@ -15,7 +15,7 @@ using osu.Framework.Graphics.Shapes; namespace osu.Game.Screens.Select { - internal class BeatmapInfoWedgeBackground : CompositeDrawable + internal partial class BeatmapInfoWedgeBackground : CompositeDrawable { private readonly IWorkingBeatmap beatmap; diff --git a/osu.Game/Screens/Select/Carousel/CarouselHeader.cs b/osu.Game/Screens/Select/Carousel/CarouselHeader.cs index 5cde5f7d5a..1ae69bc951 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselHeader.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselHeader.cs @@ -21,7 +21,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Select.Carousel { - public class CarouselHeader : Container + public partial class CarouselHeader : Container { public Container BorderContainer; @@ -93,7 +93,7 @@ namespace osu.Game.Screens.Select.Carousel } } - public class HoverLayer : HoverSampleDebounceComponent + public partial class HoverLayer : HoverSampleDebounceComponent { private Sample sampleHover; diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index c3cb04680b..4e10961e55 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -34,7 +34,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Select.Carousel { - public class DrawableCarouselBeatmap : DrawableCarouselItem, IHasContextMenu + public partial class DrawableCarouselBeatmap : DrawableCarouselItem, IHasContextMenu { public const float CAROUSEL_BEATMAP_SPACING = 5; diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 040f954bba..a7fb25bc1b 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -23,7 +23,7 @@ using osu.Game.Overlays; namespace osu.Game.Screens.Select.Carousel { - public class DrawableCarouselBeatmapSet : DrawableCarouselItem, IHasContextMenu + public partial class DrawableCarouselBeatmapSet : DrawableCarouselItem, IHasContextMenu { public const float HEIGHT = MAX_HEIGHT; diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs index 133bf5f9c3..26a32c23dd 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Screens.Select.Carousel { - public abstract class DrawableCarouselItem : PoolableDrawable + public abstract partial class DrawableCarouselItem : PoolableDrawable { public const float MAX_HEIGHT = 80; diff --git a/osu.Game/Screens/Select/Carousel/FilterableDifficultyIcon.cs b/osu.Game/Screens/Select/Carousel/FilterableDifficultyIcon.cs index cc904fc1da..911b8fd4da 100644 --- a/osu.Game/Screens/Select/Carousel/FilterableDifficultyIcon.cs +++ b/osu.Game/Screens/Select/Carousel/FilterableDifficultyIcon.cs @@ -10,7 +10,7 @@ using osu.Game.Beatmaps.Drawables; namespace osu.Game.Screens.Select.Carousel { - public class FilterableDifficultyIcon : DifficultyIcon + public partial class FilterableDifficultyIcon : DifficultyIcon { private readonly BindableBool filtered = new BindableBool(); diff --git a/osu.Game/Screens/Select/Carousel/GroupedDifficultyIcon.cs b/osu.Game/Screens/Select/Carousel/GroupedDifficultyIcon.cs index 8b4140df56..6e01c82a08 100644 --- a/osu.Game/Screens/Select/Carousel/GroupedDifficultyIcon.cs +++ b/osu.Game/Screens/Select/Carousel/GroupedDifficultyIcon.cs @@ -21,7 +21,7 @@ namespace osu.Game.Screens.Select.Carousel /// /// Used in cases when there are too many difficulty icons to show. /// - public class GroupedDifficultyIcon : DifficultyIcon + public partial class GroupedDifficultyIcon : DifficultyIcon { public readonly List Items; diff --git a/osu.Game/Screens/Select/Carousel/SetPanelBackground.cs b/osu.Game/Screens/Select/Carousel/SetPanelBackground.cs index 2a435e084c..a9dc59cc39 100644 --- a/osu.Game/Screens/Select/Carousel/SetPanelBackground.cs +++ b/osu.Game/Screens/Select/Carousel/SetPanelBackground.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Select.Carousel { - public class SetPanelBackground : BufferedContainer + public partial class SetPanelBackground : BufferedContainer { public SetPanelBackground(IWorkingBeatmap working) : base(cachedFrameBuffer: true) diff --git a/osu.Game/Screens/Select/Carousel/SetPanelContent.cs b/osu.Game/Screens/Select/Carousel/SetPanelContent.cs index a95d9078a2..0de507edce 100644 --- a/osu.Game/Screens/Select/Carousel/SetPanelContent.cs +++ b/osu.Game/Screens/Select/Carousel/SetPanelContent.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Screens.Select.Carousel { - public class SetPanelContent : CompositeDrawable + public partial class SetPanelContent : CompositeDrawable { // Disallow interacting with difficulty icons on a panel until the panel has been selected. public override bool PropagatePositionalInputSubTree => carouselSet.State.Value == CarouselItemState.Selected; diff --git a/osu.Game/Screens/Select/Carousel/TopLocalRank.cs b/osu.Game/Screens/Select/Carousel/TopLocalRank.cs index 0f000555d5..f1b773c831 100644 --- a/osu.Game/Screens/Select/Carousel/TopLocalRank.cs +++ b/osu.Game/Screens/Select/Carousel/TopLocalRank.cs @@ -19,7 +19,7 @@ using Realms; namespace osu.Game.Screens.Select.Carousel { - public class TopLocalRank : CompositeDrawable + public partial class TopLocalRank : CompositeDrawable { private readonly BeatmapInfo beatmapInfo; diff --git a/osu.Game/Screens/Select/Carousel/UpdateBeatmapSetButton.cs b/osu.Game/Screens/Select/Carousel/UpdateBeatmapSetButton.cs index 1bb607bcf3..e45583887a 100644 --- a/osu.Game/Screens/Select/Carousel/UpdateBeatmapSetButton.cs +++ b/osu.Game/Screens/Select/Carousel/UpdateBeatmapSetButton.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Select.Carousel { - public class UpdateBeatmapSetButton : OsuAnimatedButton + public partial class UpdateBeatmapSetButton : OsuAnimatedButton { private readonly BeatmapSetInfo beatmapSetInfo; private SpriteIcon icon = null!; diff --git a/osu.Game/Screens/Select/Carousel/UpdateLocalConfirmationDialog.cs b/osu.Game/Screens/Select/Carousel/UpdateLocalConfirmationDialog.cs index f5267e905e..e1aa662942 100644 --- a/osu.Game/Screens/Select/Carousel/UpdateLocalConfirmationDialog.cs +++ b/osu.Game/Screens/Select/Carousel/UpdateLocalConfirmationDialog.cs @@ -8,7 +8,7 @@ using osu.Game.Localisation; namespace osu.Game.Screens.Select.Carousel { - public class UpdateLocalConfirmationDialog : DeleteConfirmationDialog + public partial class UpdateLocalConfirmationDialog : DeleteConfirmationDialog { public UpdateLocalConfirmationDialog(Action onConfirm) { diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index 693f182065..5d0588e67b 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -28,7 +28,7 @@ using osu.Game.Rulesets; namespace osu.Game.Screens.Select.Details { - public class AdvancedStats : Container + public partial class AdvancedStats : Container { [Resolved] private IBindable> mods { get; set; } @@ -173,7 +173,7 @@ namespace osu.Game.Screens.Select.Details starDifficultyCancellationSource?.Cancel(); } - public class StatisticRow : Container, IHasAccentColour + public partial class StatisticRow : Container, IHasAccentColour { private const float value_width = 25; private const float name_width = 70; diff --git a/osu.Game/Screens/Select/Details/FailRetryGraph.cs b/osu.Game/Screens/Select/Details/FailRetryGraph.cs index 6fa6d50217..9891ef6463 100644 --- a/osu.Game/Screens/Select/Details/FailRetryGraph.cs +++ b/osu.Game/Screens/Select/Details/FailRetryGraph.cs @@ -14,7 +14,7 @@ using osu.Game.Beatmaps; namespace osu.Game.Screens.Select.Details { - public class FailRetryGraph : Container + public partial class FailRetryGraph : Container { private readonly BarGraph retryGraph, failGraph; diff --git a/osu.Game/Screens/Select/Details/UserRatings.cs b/osu.Game/Screens/Select/Details/UserRatings.cs index 39cb9c3d15..3664a89394 100644 --- a/osu.Game/Screens/Select/Details/UserRatings.cs +++ b/osu.Game/Screens/Select/Details/UserRatings.cs @@ -15,7 +15,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Screens.Select.Details { - public class UserRatings : Container + public partial class UserRatings : Container { private readonly FillFlowContainer header; private readonly Bar ratingsBar; diff --git a/osu.Game/Screens/Select/DifficultyRangeFilterControl.cs b/osu.Game/Screens/Select/DifficultyRangeFilterControl.cs index 45e7ff4caa..523fdf4628 100644 --- a/osu.Game/Screens/Select/DifficultyRangeFilterControl.cs +++ b/osu.Game/Screens/Select/DifficultyRangeFilterControl.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Select { - internal class DifficultyRangeFilterControl : CompositeDrawable + internal partial class DifficultyRangeFilterControl : CompositeDrawable { private Bindable lowerStars = null!; private Bindable upperStars = null!; @@ -63,7 +63,7 @@ namespace osu.Game.Screens.Select upperStars.ValueChanged += max => lowerStars.Value = Math.Min(max.NewValue - 0.1, lowerStars.Value); } - private class MinimumStarsSlider : StarsSlider + private partial class MinimumStarsSlider : StarsSlider { public MinimumStarsSlider() : base("0") @@ -87,7 +87,7 @@ namespace osu.Game.Screens.Select && screenSpacePos.X <= Nub.ScreenSpaceDrawQuad.TopRight.X; } - private class MaximumStarsSlider : StarsSlider + private partial class MaximumStarsSlider : StarsSlider { public MaximumStarsSlider() : base("∞") @@ -106,7 +106,7 @@ namespace osu.Game.Screens.Select && screenSpacePos.X >= Nub.ScreenSpaceDrawQuad.TopLeft.X; } - private class StarsSlider : OsuSliderBar + private partial class StarsSlider : OsuSliderBar { private readonly string defaultString; diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index ae82285fba..4aebb96e18 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -24,7 +24,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Select { - public class FilterControl : Container + public partial class FilterControl : Container { public const float HEIGHT = 2 * side_margin + 85; private const float side_margin = 20; diff --git a/osu.Game/Screens/Select/Footer.cs b/osu.Game/Screens/Select/Footer.cs index f9fc2890b0..933df2464a 100644 --- a/osu.Game/Screens/Select/Footer.cs +++ b/osu.Game/Screens/Select/Footer.cs @@ -16,7 +16,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Screens.Select { - public class Footer : Container + public partial class Footer : Container { private readonly Box modeLight; diff --git a/osu.Game/Screens/Select/FooterButton.cs b/osu.Game/Screens/Select/FooterButton.cs index 230cdfc13e..128e750dca 100644 --- a/osu.Game/Screens/Select/FooterButton.cs +++ b/osu.Game/Screens/Select/FooterButton.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Select { - public class FooterButton : OsuClickableContainer, IKeyBindingHandler + public partial class FooterButton : OsuClickableContainer, IKeyBindingHandler { public const float SHEAR_WIDTH = 7.5f; diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index 21f81995be..9a84f9a0aa 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -22,7 +22,7 @@ using osu.Game.Input.Bindings; namespace osu.Game.Screens.Select { - public class FooterButtonMods : FooterButton, IHasCurrentValue> + public partial class FooterButtonMods : FooterButton, IHasCurrentValue> { public Bindable> Current { diff --git a/osu.Game/Screens/Select/FooterButtonOptions.cs b/osu.Game/Screens/Select/FooterButtonOptions.cs index 764f56e79c..e56efcb458 100644 --- a/osu.Game/Screens/Select/FooterButtonOptions.cs +++ b/osu.Game/Screens/Select/FooterButtonOptions.cs @@ -10,7 +10,7 @@ using osu.Game.Input.Bindings; namespace osu.Game.Screens.Select { - public class FooterButtonOptions : FooterButton + public partial class FooterButtonOptions : FooterButton { [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game/Screens/Select/FooterButtonRandom.cs b/osu.Game/Screens/Select/FooterButtonRandom.cs index aad7fdff39..8d7463067e 100644 --- a/osu.Game/Screens/Select/FooterButtonRandom.cs +++ b/osu.Game/Screens/Select/FooterButtonRandom.cs @@ -17,7 +17,7 @@ using osuTK.Input; namespace osu.Game.Screens.Select { - public class FooterButtonRandom : FooterButton + public partial class FooterButtonRandom : FooterButton { public Action NextRandom { get; set; } public Action PreviousRandom { get; set; } diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index 4cc3a30a1e..b8a2eec526 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -21,7 +21,7 @@ using Realms; namespace osu.Game.Screens.Select.Leaderboards { - public class BeatmapLeaderboard : Leaderboard + public partial class BeatmapLeaderboard : Leaderboard { public Action? ScoreSelected; diff --git a/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs b/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs index d9312679bc..6349e9e5eb 100644 --- a/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs +++ b/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs @@ -10,7 +10,7 @@ using osu.Game.Beatmaps; namespace osu.Game.Screens.Select { - public class LocalScoreDeleteDialog : DeleteConfirmationDialog + public partial class LocalScoreDeleteDialog : DeleteConfirmationDialog { private readonly ScoreInfo score; diff --git a/osu.Game/Screens/Select/NoResultsPlaceholder.cs b/osu.Game/Screens/Select/NoResultsPlaceholder.cs index 73b53defe0..9f870503d3 100644 --- a/osu.Game/Screens/Select/NoResultsPlaceholder.cs +++ b/osu.Game/Screens/Select/NoResultsPlaceholder.cs @@ -17,7 +17,7 @@ using osuTK; namespace osu.Game.Screens.Select { - public class NoResultsPlaceholder : VisibilityContainer + public partial class NoResultsPlaceholder : VisibilityContainer { private FilterCriteria? filter; diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs index 69800c4e86..0d3e1238f3 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsButton.cs @@ -20,7 +20,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Screens.Select.Options { - public class BeatmapOptionsButton : OsuClickableContainer + public partial class BeatmapOptionsButton : OsuClickableContainer { private const float width = 130; diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs index 8785dac0aa..c92dc2e343 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs @@ -19,7 +19,7 @@ using osu.Framework.Localisation; namespace osu.Game.Screens.Select.Options { - public class BeatmapOptionsOverlay : OsuFocusedOverlayContainer + public partial class BeatmapOptionsOverlay : OsuFocusedOverlayContainer { private const float transition_duration = 500; private const float x_position = 0.2f; diff --git a/osu.Game/Screens/Select/PlayBeatmapDetailArea.cs b/osu.Game/Screens/Select/PlayBeatmapDetailArea.cs index a19acddb48..8a1b9ef3e1 100644 --- a/osu.Game/Screens/Select/PlayBeatmapDetailArea.cs +++ b/osu.Game/Screens/Select/PlayBeatmapDetailArea.cs @@ -14,7 +14,7 @@ using osu.Game.Screens.Select.Leaderboards; namespace osu.Game.Screens.Select { - public class PlayBeatmapDetailArea : BeatmapDetailArea + public partial class PlayBeatmapDetailArea : BeatmapDetailArea { public readonly BeatmapLeaderboard Leaderboard; diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 94e4215175..f73cfe8d55 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -20,7 +20,7 @@ using osuTK.Input; namespace osu.Game.Screens.Select { - public class PlaySongSelect : SongSelect + public partial class PlaySongSelect : SongSelect { private OsuScreen? playerLoader; diff --git a/osu.Game/Screens/Select/SkinDeleteDialog.cs b/osu.Game/Screens/Select/SkinDeleteDialog.cs index c701d9049f..9e11629890 100644 --- a/osu.Game/Screens/Select/SkinDeleteDialog.cs +++ b/osu.Game/Screens/Select/SkinDeleteDialog.cs @@ -7,7 +7,7 @@ using osu.Game.Overlays.Dialog; namespace osu.Game.Screens.Select { - public class SkinDeleteDialog : DeleteConfirmationDialog + public partial class SkinDeleteDialog : DeleteConfirmationDialog { private readonly Skin skin; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 18ea0f69a2..f4804c6a6c 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -42,7 +42,7 @@ using osu.Game.Skinning; namespace osu.Game.Screens.Select { - public abstract class SongSelect : ScreenWithBeatmapBackground, IKeyBindingHandler + public abstract partial class SongSelect : ScreenWithBeatmapBackground, IKeyBindingHandler { public static readonly float WEDGE_HEIGHT = 245; @@ -925,7 +925,7 @@ namespace osu.Game.Screens.Select return base.OnKeyDown(e); } - private class VerticalMaskingContainer : Container + private partial class VerticalMaskingContainer : Container { private const float panel_overflow = 1.2f; @@ -948,7 +948,7 @@ namespace osu.Game.Screens.Select } } - private class ResetScrollContainer : Container + private partial class ResetScrollContainer : Container { private readonly Action onHoverAction; @@ -964,7 +964,7 @@ namespace osu.Game.Screens.Select } } - internal class SoloModSelectOverlay : UserModSelectOverlay + internal partial class SoloModSelectOverlay : UserModSelectOverlay { protected override bool ShowPresets => true; } diff --git a/osu.Game/Screens/Select/WedgeBackground.cs b/osu.Game/Screens/Select/WedgeBackground.cs index 4a5b9d8911..da12c1a67a 100644 --- a/osu.Game/Screens/Select/WedgeBackground.cs +++ b/osu.Game/Screens/Select/WedgeBackground.cs @@ -12,7 +12,7 @@ using osu.Framework.Graphics.Shapes; namespace osu.Game.Screens.Select { - public class WedgeBackground : Container + public partial class WedgeBackground : Container { public WedgeBackground() { diff --git a/osu.Game/Screens/Spectate/SpectatorScreen.cs b/osu.Game/Screens/Spectate/SpectatorScreen.cs index 259ac0160d..2b56767bd0 100644 --- a/osu.Game/Screens/Spectate/SpectatorScreen.cs +++ b/osu.Game/Screens/Spectate/SpectatorScreen.cs @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Spectate /// /// A which spectates one or more users. /// - public abstract class SpectatorScreen : OsuScreen + public abstract partial class SpectatorScreen : OsuScreen { protected IReadOnlyList Users => users; diff --git a/osu.Game/Screens/StartupScreen.cs b/osu.Game/Screens/StartupScreen.cs index 89761d80de..84ef3eac78 100644 --- a/osu.Game/Screens/StartupScreen.cs +++ b/osu.Game/Screens/StartupScreen.cs @@ -10,7 +10,7 @@ namespace osu.Game.Screens /// /// A screen which is shown once as part of the startup procedure. /// - public abstract class StartupScreen : OsuScreen + public abstract partial class StartupScreen : OsuScreen { public override bool AllowBackButton => false; diff --git a/osu.Game/Screens/Utility/ButtonWithKeyBind.cs b/osu.Game/Screens/Utility/ButtonWithKeyBind.cs index 7df9a22ce4..29e9cd2515 100644 --- a/osu.Game/Screens/Utility/ButtonWithKeyBind.cs +++ b/osu.Game/Screens/Utility/ButtonWithKeyBind.cs @@ -11,7 +11,7 @@ using osuTK.Input; namespace osu.Game.Screens.Utility { - public class ButtonWithKeyBind : SettingsButton + public partial class ButtonWithKeyBind : SettingsButton { private readonly Key key; diff --git a/osu.Game/Screens/Utility/CircleGameplay.cs b/osu.Game/Screens/Utility/CircleGameplay.cs index 1ee5567c43..d97812acb4 100644 --- a/osu.Game/Screens/Utility/CircleGameplay.cs +++ b/osu.Game/Screens/Utility/CircleGameplay.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Screens.Utility { - public class CircleGameplay : LatencySampleComponent + public partial class CircleGameplay : LatencySampleComponent { private int nextLocation; @@ -111,7 +111,7 @@ namespace osu.Game.Screens.Utility hitEvents.Add(h); } - public class SampleHitCircle : LatencySampleComponent + public partial class SampleHitCircle : LatencySampleComponent { public HitEvent? HitEvent; diff --git a/osu.Game/Screens/Utility/LatencyArea.cs b/osu.Game/Screens/Utility/LatencyArea.cs index b7d45ba642..b225171f5d 100644 --- a/osu.Game/Screens/Utility/LatencyArea.cs +++ b/osu.Game/Screens/Utility/LatencyArea.cs @@ -17,7 +17,7 @@ using osuTK.Input; namespace osu.Game.Screens.Utility { [Cached] - public class LatencyArea : CompositeDrawable, IProvideCursor + public partial class LatencyArea : CompositeDrawable, IProvideCursor { [Resolved] private OverlayColourProvider overlayColourProvider { get; set; } = null!; diff --git a/osu.Game/Screens/Utility/LatencyCertifierScreen.cs b/osu.Game/Screens/Utility/LatencyCertifierScreen.cs index bacaccd68e..8ff6d3cf4f 100644 --- a/osu.Game/Screens/Utility/LatencyCertifierScreen.cs +++ b/osu.Game/Screens/Utility/LatencyCertifierScreen.cs @@ -30,7 +30,7 @@ using osuTK.Input; namespace osu.Game.Screens.Utility { [Cached] - public class LatencyCertifierScreen : OsuScreen + public partial class LatencyCertifierScreen : OsuScreen { private FrameSync previousFrameSyncMode; private double previousActiveHz; diff --git a/osu.Game/Screens/Utility/SampleComponents/LatencyCursorContainer.cs b/osu.Game/Screens/Utility/SampleComponents/LatencyCursorContainer.cs index aaf837eb60..251d283242 100644 --- a/osu.Game/Screens/Utility/SampleComponents/LatencyCursorContainer.cs +++ b/osu.Game/Screens/Utility/SampleComponents/LatencyCursorContainer.cs @@ -12,7 +12,7 @@ using osuTK.Input; namespace osu.Game.Screens.Utility.SampleComponents { - public class LatencyCursorContainer : CursorContainer + public partial class LatencyCursorContainer : CursorContainer { protected override Drawable CreateCursor() => new LatencyCursor(); @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Utility.SampleComponents return false; } - private class LatencyCursor : LatencySampleComponent + private partial class LatencyCursor : LatencySampleComponent { public LatencyCursor() { diff --git a/osu.Game/Screens/Utility/SampleComponents/LatencyMovableBox.cs b/osu.Game/Screens/Utility/SampleComponents/LatencyMovableBox.cs index 8b6841caf0..dcfcf602bf 100644 --- a/osu.Game/Screens/Utility/SampleComponents/LatencyMovableBox.cs +++ b/osu.Game/Screens/Utility/SampleComponents/LatencyMovableBox.cs @@ -10,7 +10,7 @@ using osuTK.Input; namespace osu.Game.Screens.Utility.SampleComponents { - public class LatencyMovableBox : LatencySampleComponent + public partial class LatencyMovableBox : LatencySampleComponent { private Box box = null!; diff --git a/osu.Game/Screens/Utility/SampleComponents/LatencySampleComponent.cs b/osu.Game/Screens/Utility/SampleComponents/LatencySampleComponent.cs index 834865d237..690376cf52 100644 --- a/osu.Game/Screens/Utility/SampleComponents/LatencySampleComponent.cs +++ b/osu.Game/Screens/Utility/SampleComponents/LatencySampleComponent.cs @@ -10,7 +10,7 @@ using osu.Game.Overlays; namespace osu.Game.Screens.Utility.SampleComponents { - public abstract class LatencySampleComponent : CompositeDrawable + public abstract partial class LatencySampleComponent : CompositeDrawable { protected readonly BindableDouble SampleBPM = new BindableDouble(); protected readonly BindableDouble SampleApproachRate = new BindableDouble(); diff --git a/osu.Game/Screens/Utility/ScrollingGameplay.cs b/osu.Game/Screens/Utility/ScrollingGameplay.cs index 1f40514cd5..f1331d8fb2 100644 --- a/osu.Game/Screens/Utility/ScrollingGameplay.cs +++ b/osu.Game/Screens/Utility/ScrollingGameplay.cs @@ -18,7 +18,7 @@ using osuTK.Input; namespace osu.Game.Screens.Utility { - public class ScrollingGameplay : LatencySampleComponent + public partial class ScrollingGameplay : LatencySampleComponent { private const float judgement_position = 0.8f; private const float bar_height = 20; @@ -100,7 +100,7 @@ namespace osu.Game.Screens.Utility hitEvents.Add(h); } - public class SampleNote : LatencySampleComponent + public partial class SampleNote : LatencySampleComponent { public HitEvent? HitEvent; diff --git a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs index e14287c318..4486c8a9f0 100644 --- a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs +++ b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs @@ -15,7 +15,7 @@ namespace osu.Game.Skinning /// /// A container which overrides existing skin options with beatmap-local values. /// - public class BeatmapSkinProvidingContainer : SkinProvidingContainer + public partial class BeatmapSkinProvidingContainer : SkinProvidingContainer { private Bindable beatmapSkins; private Bindable beatmapColours; diff --git a/osu.Game/Skinning/Components/BigBlackBox.cs b/osu.Game/Skinning/Components/BigBlackBox.cs index 5bdee827ca..4210a70b72 100644 --- a/osu.Game/Skinning/Components/BigBlackBox.cs +++ b/osu.Game/Skinning/Components/BigBlackBox.cs @@ -21,7 +21,7 @@ namespace osu.Game.Skinning.Components /// Intended to be a test bed for skinning. May be removed at some point in the future. /// [UsedImplicitly] - public class BigBlackBox : CompositeDrawable, ISkinnableDrawable + public partial class BigBlackBox : CompositeDrawable, ISkinnableDrawable { public bool UsesFixedAnchor { get; set; } diff --git a/osu.Game/Skinning/Editor/SkinBlueprint.cs b/osu.Game/Skinning/Editor/SkinBlueprint.cs index ecf1de89da..fc7e9e8ef1 100644 --- a/osu.Game/Skinning/Editor/SkinBlueprint.cs +++ b/osu.Game/Skinning/Editor/SkinBlueprint.cs @@ -18,7 +18,7 @@ using osuTK.Graphics; namespace osu.Game.Skinning.Editor { - public class SkinBlueprint : SelectionBlueprint + public partial class SkinBlueprint : SelectionBlueprint { private Container box; @@ -131,7 +131,7 @@ namespace osu.Game.Skinning.Editor public override Quad SelectionQuad => drawable.ScreenSpaceDrawQuad; } - internal class AnchorOriginVisualiser : CompositeDrawable + internal partial class AnchorOriginVisualiser : CompositeDrawable { private readonly Drawable drawable; diff --git a/osu.Game/Skinning/Editor/SkinBlueprintContainer.cs b/osu.Game/Skinning/Editor/SkinBlueprintContainer.cs index 2937b62eec..8e9256214f 100644 --- a/osu.Game/Skinning/Editor/SkinBlueprintContainer.cs +++ b/osu.Game/Skinning/Editor/SkinBlueprintContainer.cs @@ -20,7 +20,7 @@ using osuTK.Input; namespace osu.Game.Skinning.Editor { - public class SkinBlueprintContainer : BlueprintContainer + public partial class SkinBlueprintContainer : BlueprintContainer { private readonly Drawable target; diff --git a/osu.Game/Skinning/Editor/SkinComponentToolbox.cs b/osu.Game/Skinning/Editor/SkinComponentToolbox.cs index 469657c03c..68ac84df48 100644 --- a/osu.Game/Skinning/Editor/SkinComponentToolbox.cs +++ b/osu.Game/Skinning/Editor/SkinComponentToolbox.cs @@ -18,7 +18,7 @@ using osuTK; namespace osu.Game.Skinning.Editor { - public class SkinComponentToolbox : EditorSidebarSection + public partial class SkinComponentToolbox : EditorSidebarSection { public Action? RequestPlacement; @@ -81,7 +81,7 @@ namespace osu.Game.Skinning.Editor } } - public class ToolboxComponentButton : OsuButton + public partial class ToolboxComponentButton : OsuButton { public Action? RequestPlacement; @@ -171,7 +171,7 @@ namespace osu.Game.Skinning.Editor } } - public class DependencyBorrowingContainer : Container + public partial class DependencyBorrowingContainer : Container { protected override bool ShouldBeConsideredForInput(Drawable child) => false; diff --git a/osu.Game/Skinning/Editor/SkinEditor.cs b/osu.Game/Skinning/Editor/SkinEditor.cs index 410f5d9347..1dd9c93845 100644 --- a/osu.Game/Skinning/Editor/SkinEditor.cs +++ b/osu.Game/Skinning/Editor/SkinEditor.cs @@ -32,7 +32,7 @@ using osu.Game.Screens.Edit.Components.Menus; namespace osu.Game.Skinning.Editor { [Cached(typeof(SkinEditor))] - public class SkinEditor : VisibilityContainer, ICanAcceptFiles, IKeyBindingHandler + public partial class SkinEditor : VisibilityContainer, ICanAcceptFiles, IKeyBindingHandler { public const double TRANSITION_DURATION = 500; @@ -424,7 +424,7 @@ namespace osu.Game.Skinning.Editor game?.UnregisterImportHandler(this); } - private class SkinEditorToast : Toast + private partial class SkinEditorToast : Toast { public SkinEditorToast(LocalisableString value, string skinDisplayName) : base(SkinSettingsStrings.SkinLayoutEditor, value, skinDisplayName) diff --git a/osu.Game/Skinning/Editor/SkinEditorOverlay.cs b/osu.Game/Skinning/Editor/SkinEditorOverlay.cs index 000917f728..35e28ee665 100644 --- a/osu.Game/Skinning/Editor/SkinEditorOverlay.cs +++ b/osu.Game/Skinning/Editor/SkinEditorOverlay.cs @@ -23,7 +23,7 @@ namespace osu.Game.Skinning.Editor /// A container which handles loading a skin editor on user request for a specified target. /// This also handles the scaling / positioning adjustment of the target. /// - public class SkinEditorOverlay : OverlayContainer, IKeyBindingHandler + public partial class SkinEditorOverlay : OverlayContainer, IKeyBindingHandler { private readonly ScalingContainer scalingContainer; diff --git a/osu.Game/Skinning/Editor/SkinEditorSceneLibrary.cs b/osu.Game/Skinning/Editor/SkinEditorSceneLibrary.cs index 4efbf58881..c3907ea60d 100644 --- a/osu.Game/Skinning/Editor/SkinEditorSceneLibrary.cs +++ b/osu.Game/Skinning/Editor/SkinEditorSceneLibrary.cs @@ -27,7 +27,7 @@ using osuTK; namespace osu.Game.Skinning.Editor { - public class SkinEditorSceneLibrary : CompositeDrawable + public partial class SkinEditorSceneLibrary : CompositeDrawable { public const float HEIGHT = BUTTON_HEIGHT + padding * 2; @@ -120,7 +120,7 @@ namespace osu.Game.Skinning.Editor }; } - public class SceneButton : OsuButton + public partial class SceneButton : OsuButton { public SceneButton() { diff --git a/osu.Game/Skinning/Editor/SkinSelectionHandler.cs b/osu.Game/Skinning/Editor/SkinSelectionHandler.cs index 2e2122f7c2..2c3f6238ec 100644 --- a/osu.Game/Skinning/Editor/SkinSelectionHandler.cs +++ b/osu.Game/Skinning/Editor/SkinSelectionHandler.cs @@ -20,7 +20,7 @@ using osuTK; namespace osu.Game.Skinning.Editor { - public class SkinSelectionHandler : SelectionHandler + public partial class SkinSelectionHandler : SelectionHandler { [Resolved] private SkinEditor skinEditor { get; set; } diff --git a/osu.Game/Skinning/Editor/SkinSettingsToolbox.cs b/osu.Game/Skinning/Editor/SkinSettingsToolbox.cs index 3e19fc3afe..8c08f40b70 100644 --- a/osu.Game/Skinning/Editor/SkinSettingsToolbox.cs +++ b/osu.Game/Skinning/Editor/SkinSettingsToolbox.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Skinning.Editor { - internal class SkinSettingsToolbox : EditorSidebarSection + internal partial class SkinSettingsToolbox : EditorSidebarSection { protected override Container Content { get; } diff --git a/osu.Game/Skinning/LegacyAccuracyCounter.cs b/osu.Game/Skinning/LegacyAccuracyCounter.cs index bdcb85456a..e75fb1e7e9 100644 --- a/osu.Game/Skinning/LegacyAccuracyCounter.cs +++ b/osu.Game/Skinning/LegacyAccuracyCounter.cs @@ -8,7 +8,7 @@ using osuTK; namespace osu.Game.Skinning { - public class LegacyAccuracyCounter : GameplayAccuracyCounter, ISkinnableDrawable + public partial class LegacyAccuracyCounter : GameplayAccuracyCounter, ISkinnableDrawable { public bool UsesFixedAnchor { get; set; } diff --git a/osu.Game/Skinning/LegacyComboCounter.cs b/osu.Game/Skinning/LegacyComboCounter.cs index f4caef26c2..c132a72001 100644 --- a/osu.Game/Skinning/LegacyComboCounter.cs +++ b/osu.Game/Skinning/LegacyComboCounter.cs @@ -15,7 +15,7 @@ namespace osu.Game.Skinning /// /// Uses the 'x' symbol and has a pop-out effect while rolling over. /// - public class LegacyComboCounter : CompositeDrawable, ISkinnableDrawable + public partial class LegacyComboCounter : CompositeDrawable, ISkinnableDrawable { public Bindable Current { get; } = new BindableInt { MinValue = 0 }; diff --git a/osu.Game/Skinning/LegacyHealthDisplay.cs b/osu.Game/Skinning/LegacyHealthDisplay.cs index 236e9c355e..c3cb9770fa 100644 --- a/osu.Game/Skinning/LegacyHealthDisplay.cs +++ b/osu.Game/Skinning/LegacyHealthDisplay.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Skinning { - public class LegacyHealthDisplay : HealthDisplay, ISkinnableDrawable + public partial class LegacyHealthDisplay : HealthDisplay, ISkinnableDrawable { private const double epic_cutoff = 0.5; @@ -94,7 +94,7 @@ namespace osu.Game.Skinning return Color4.White; } - public class LegacyOldStyleMarker : LegacyMarker + public partial class LegacyOldStyleMarker : LegacyMarker { private readonly Texture normalTexture; private readonly Texture dangerTexture; @@ -129,7 +129,7 @@ namespace osu.Game.Skinning } } - public class LegacyNewStyleMarker : LegacyMarker + public partial class LegacyNewStyleMarker : LegacyMarker { private readonly ISkin skin; @@ -153,7 +153,7 @@ namespace osu.Game.Skinning } } - internal abstract class LegacyFill : LegacyHealthPiece + internal abstract partial class LegacyFill : LegacyHealthPiece { protected LegacyFill(ISkin skin) { @@ -175,7 +175,7 @@ namespace osu.Game.Skinning } } - internal class LegacyOldStyleFill : LegacyFill + internal partial class LegacyOldStyleFill : LegacyFill { public LegacyOldStyleFill(ISkin skin) : base(skin) @@ -184,7 +184,7 @@ namespace osu.Game.Skinning } } - internal class LegacyNewStyleFill : LegacyFill + internal partial class LegacyNewStyleFill : LegacyFill { public LegacyNewStyleFill(ISkin skin) : base(skin) @@ -199,7 +199,7 @@ namespace osu.Game.Skinning } } - public abstract class LegacyMarker : LegacyHealthPiece + public abstract partial class LegacyMarker : LegacyHealthPiece { protected Sprite Main; @@ -252,7 +252,7 @@ namespace osu.Game.Skinning Main.ScaleTo(1.4f).Then().ScaleTo(1, 200, Easing.Out); } - public class LegacyHealthPiece : CompositeDrawable + public partial class LegacyHealthPiece : CompositeDrawable { public Bindable Current { get; } = new Bindable(); diff --git a/osu.Game/Skinning/LegacyJudgementPieceNew.cs b/osu.Game/Skinning/LegacyJudgementPieceNew.cs index 39b266ab9f..2430e511c4 100644 --- a/osu.Game/Skinning/LegacyJudgementPieceNew.cs +++ b/osu.Game/Skinning/LegacyJudgementPieceNew.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Skinning { - public class LegacyJudgementPieceNew : CompositeDrawable, IAnimatableJudgement + public partial class LegacyJudgementPieceNew : CompositeDrawable, IAnimatableJudgement { private readonly HitResult result; diff --git a/osu.Game/Skinning/LegacyJudgementPieceOld.cs b/osu.Game/Skinning/LegacyJudgementPieceOld.cs index 3f4d13c082..0223e7a5a2 100644 --- a/osu.Game/Skinning/LegacyJudgementPieceOld.cs +++ b/osu.Game/Skinning/LegacyJudgementPieceOld.cs @@ -13,7 +13,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Skinning { - public class LegacyJudgementPieceOld : CompositeDrawable, IAnimatableJudgement + public partial class LegacyJudgementPieceOld : CompositeDrawable, IAnimatableJudgement { private readonly HitResult result; diff --git a/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs b/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs index 2bcdd5b5a1..fd9434e02a 100644 --- a/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs +++ b/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Skinning { - public class LegacyKiaiFlashingDrawable : BeatSyncedContainer + public partial class LegacyKiaiFlashingDrawable : BeatSyncedContainer { private readonly Drawable flashingDrawable; diff --git a/osu.Game/Skinning/LegacyRollingCounter.cs b/osu.Game/Skinning/LegacyRollingCounter.cs index fd17b06a21..465f1c3a20 100644 --- a/osu.Game/Skinning/LegacyRollingCounter.cs +++ b/osu.Game/Skinning/LegacyRollingCounter.cs @@ -12,7 +12,7 @@ namespace osu.Game.Skinning /// /// An integer that uses number sprites from a legacy skin. /// - public class LegacyRollingCounter : RollingCounter + public partial class LegacyRollingCounter : RollingCounter { private readonly LegacyFont font; diff --git a/osu.Game/Skinning/LegacyScoreCounter.cs b/osu.Game/Skinning/LegacyScoreCounter.cs index aee594454f..6a14ed93e9 100644 --- a/osu.Game/Skinning/LegacyScoreCounter.cs +++ b/osu.Game/Skinning/LegacyScoreCounter.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Skinning { - public class LegacyScoreCounter : GameplayScoreCounter, ISkinnableDrawable + public partial class LegacyScoreCounter : GameplayScoreCounter, ISkinnableDrawable { protected override double RollingDuration => 1000; protected override Easing RollingEasing => Easing.Out; diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index 8765882af2..0d2461567f 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -15,7 +15,7 @@ using static osu.Game.Skinning.SkinConfiguration; namespace osu.Game.Skinning { - public static class LegacySkinExtensions + public static partial class LegacySkinExtensions { public static Drawable? GetAnimation(this ISkin? source, string componentName, bool animatable, bool looping, bool applyConfigFrameRate = false, string animationSeparator = "-", bool startAtCurrentTime = true, double? frameLength = null) @@ -146,7 +146,7 @@ namespace osu.Game.Skinning } } - public class SkinnableTextureAnimation : TextureAnimation + public partial class SkinnableTextureAnimation : TextureAnimation { [Resolved(canBeNull: true)] private IAnimationTimeReference? timeReference { get; set; } diff --git a/osu.Game/Skinning/LegacySongProgress.cs b/osu.Game/Skinning/LegacySongProgress.cs index f828e301f2..10d1431ed4 100644 --- a/osu.Game/Skinning/LegacySongProgress.cs +++ b/osu.Game/Skinning/LegacySongProgress.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Skinning { - public class LegacySongProgress : SongProgress + public partial class LegacySongProgress : SongProgress { private CircularProgress circularProgress = null!; diff --git a/osu.Game/Skinning/LegacySpriteText.cs b/osu.Game/Skinning/LegacySpriteText.cs index c5d65cb0c7..b89f85778b 100644 --- a/osu.Game/Skinning/LegacySpriteText.cs +++ b/osu.Game/Skinning/LegacySpriteText.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Skinning { - public sealed class LegacySpriteText : OsuSpriteText + public sealed partial class LegacySpriteText : OsuSpriteText { private readonly LegacyFont font; diff --git a/osu.Game/Skinning/PausableSkinnableSound.cs b/osu.Game/Skinning/PausableSkinnableSound.cs index ebcaeaa3ff..e752160984 100644 --- a/osu.Game/Skinning/PausableSkinnableSound.cs +++ b/osu.Game/Skinning/PausableSkinnableSound.cs @@ -13,7 +13,7 @@ using osu.Game.Audio; namespace osu.Game.Skinning { - public class PausableSkinnableSound : SkinnableSound + public partial class PausableSkinnableSound : SkinnableSound { public double Length => !DrawableSamples.Any() ? 0 : DrawableSamples.Max(sample => sample.Length); diff --git a/osu.Game/Skinning/PoolableSkinnableSample.cs b/osu.Game/Skinning/PoolableSkinnableSample.cs index d0a22f9656..0158c47ea3 100644 --- a/osu.Game/Skinning/PoolableSkinnableSample.cs +++ b/osu.Game/Skinning/PoolableSkinnableSample.cs @@ -20,7 +20,7 @@ namespace osu.Game.Skinning /// /// A sample corresponding to an that supports being pooled and responding to skin changes. /// - public class PoolableSkinnableSample : SkinReloadableDrawable, IAdjustableAudioComponent + public partial class PoolableSkinnableSample : SkinReloadableDrawable, IAdjustableAudioComponent { /// /// The currently-loaded . diff --git a/osu.Game/Skinning/RulesetSkinProvidingContainer.cs b/osu.Game/Skinning/RulesetSkinProvidingContainer.cs index 7267ebd92d..07e238243b 100644 --- a/osu.Game/Skinning/RulesetSkinProvidingContainer.cs +++ b/osu.Game/Skinning/RulesetSkinProvidingContainer.cs @@ -23,7 +23,7 @@ namespace osu.Game.Skinning /// A type of specialized for and other gameplay-related components. /// Providing access to parent skin sources and the beatmap skin each surrounded with the ruleset legacy skin transformer. /// - public class RulesetSkinProvidingContainer : SkinProvidingContainer + public partial class RulesetSkinProvidingContainer : SkinProvidingContainer { protected readonly Ruleset Ruleset; protected readonly IBeatmap Beatmap; diff --git a/osu.Game/Skinning/SkinProvidingContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs index e7d0683005..afead7b072 100644 --- a/osu.Game/Skinning/SkinProvidingContainer.cs +++ b/osu.Game/Skinning/SkinProvidingContainer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Skinning /// /// A container which adds a local to the hierarchy. /// - public class SkinProvidingContainer : Container, ISkinSource + public partial class SkinProvidingContainer : Container, ISkinSource { public event Action? SourceChanged; diff --git a/osu.Game/Skinning/SkinReloadableDrawable.cs b/osu.Game/Skinning/SkinReloadableDrawable.cs index f1c8388f71..1c947a4a84 100644 --- a/osu.Game/Skinning/SkinReloadableDrawable.cs +++ b/osu.Game/Skinning/SkinReloadableDrawable.cs @@ -11,7 +11,7 @@ namespace osu.Game.Skinning /// /// A drawable which has a callback when the skin changes. /// - public abstract class SkinReloadableDrawable : PoolableDrawable + public abstract partial class SkinReloadableDrawable : PoolableDrawable { /// /// Invoked when has changed. diff --git a/osu.Game/Skinning/SkinnableDrawable.cs b/osu.Game/Skinning/SkinnableDrawable.cs index 15d371cdd5..255aba94ae 100644 --- a/osu.Game/Skinning/SkinnableDrawable.cs +++ b/osu.Game/Skinning/SkinnableDrawable.cs @@ -12,7 +12,7 @@ namespace osu.Game.Skinning /// /// A drawable which can be skinned via an . /// - public class SkinnableDrawable : SkinReloadableDrawable + public partial class SkinnableDrawable : SkinReloadableDrawable { /// /// The displayed component. diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 8f71b40801..aeced9b517 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -21,7 +21,7 @@ namespace osu.Game.Skinning /// /// A sound consisting of one or more samples to be played. /// - public class SkinnableSound : SkinReloadableDrawable, IAdjustableAudioComponent + public partial class SkinnableSound : SkinReloadableDrawable, IAdjustableAudioComponent { public override bool RemoveWhenNotAlive => false; public override bool RemoveCompletedTransforms => false; diff --git a/osu.Game/Skinning/SkinnableSprite.cs b/osu.Game/Skinning/SkinnableSprite.cs index 7fd0e43562..1a8a3a26c9 100644 --- a/osu.Game/Skinning/SkinnableSprite.cs +++ b/osu.Game/Skinning/SkinnableSprite.cs @@ -20,7 +20,7 @@ namespace osu.Game.Skinning /// /// A skinnable element which uses a single texture backing. /// - public class SkinnableSprite : SkinnableDrawable, ISkinnableDrawable + public partial class SkinnableSprite : SkinnableDrawable, ISkinnableDrawable { protected override bool ApplySizeRestrictionsToDefault => true; @@ -75,7 +75,7 @@ namespace osu.Game.Skinning } } - public class SpriteSelectorControl : SettingsDropdown + public partial class SpriteSelectorControl : SettingsDropdown { protected override void LoadComplete() { @@ -117,7 +117,7 @@ namespace osu.Game.Skinning } } - public class SpriteNotFound : CompositeDrawable + public partial class SpriteNotFound : CompositeDrawable { public SpriteNotFound(string lookup) { diff --git a/osu.Game/Skinning/SkinnableSpriteText.cs b/osu.Game/Skinning/SkinnableSpriteText.cs index c01cec2f0c..7c42449ae7 100644 --- a/osu.Game/Skinning/SkinnableSpriteText.cs +++ b/osu.Game/Skinning/SkinnableSpriteText.cs @@ -7,7 +7,7 @@ using osu.Framework.Localisation; namespace osu.Game.Skinning { - public class SkinnableSpriteText : SkinnableDrawable, IHasText + public partial class SkinnableSpriteText : SkinnableDrawable, IHasText { public SkinnableSpriteText(ISkinComponentLookup lookup, Func defaultImplementation, ConfineMode confineMode = ConfineMode.NoScaling) : base(lookup, defaultImplementation, confineMode) diff --git a/osu.Game/Skinning/SkinnableTargetComponentsContainer.cs b/osu.Game/Skinning/SkinnableTargetComponentsContainer.cs index e38afedeb9..8c6726c3f4 100644 --- a/osu.Game/Skinning/SkinnableTargetComponentsContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetComponentsContainer.cs @@ -13,7 +13,7 @@ namespace osu.Game.Skinning /// Optionally also applies a default layout to the components. /// [Serializable] - public class SkinnableTargetComponentsContainer : Container, ISkinnableDrawable + public partial class SkinnableTargetComponentsContainer : Container, ISkinnableDrawable { public bool IsEditable => false; diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs index a8038f5f5c..794a12da82 100644 --- a/osu.Game/Skinning/SkinnableTargetContainer.cs +++ b/osu.Game/Skinning/SkinnableTargetContainer.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics; namespace osu.Game.Skinning { - public class SkinnableTargetContainer : SkinReloadableDrawable, ISkinnableTarget + public partial class SkinnableTargetContainer : SkinReloadableDrawable, ISkinnableTarget { private SkinnableTargetComponentsContainer? content; diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs index 6295604438..aa264fa719 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs @@ -20,7 +20,7 @@ using osu.Game.Screens.Play; namespace osu.Game.Storyboards.Drawables { - public class DrawableStoryboard : Container + public partial class DrawableStoryboard : Container { [Cached] public Storyboard Storyboard { get; } diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs index 07e1e86617..e86ee9e63d 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Storyboards.Drawables { - public class DrawableStoryboardAnimation : TextureAnimation, IFlippable, IVectorScalable + public partial class DrawableStoryboardAnimation : TextureAnimation, IFlippable, IVectorScalable { public StoryboardAnimation Animation { get; } diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs index 13f116af24..6fc8d124c7 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Storyboards.Drawables { - public class DrawableStoryboardLayer : CompositeDrawable + public partial class DrawableStoryboardLayer : CompositeDrawable { public StoryboardLayer Layer { get; } public bool Enabled; @@ -32,7 +32,7 @@ namespace osu.Game.Storyboards.Drawables InternalChild = ElementContainer = new LayerElementContainer(layer); } - protected class LayerElementContainer : LifetimeManagementContainer + protected partial class LayerElementContainer : LifetimeManagementContainer { private readonly StoryboardLayer storyboardLayer; diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs index 2e7ca31fe9..c281d23804 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSample.cs @@ -12,7 +12,7 @@ using osu.Game.Skinning; namespace osu.Game.Storyboards.Drawables { - public class DrawableStoryboardSample : PausableSkinnableSound + public partial class DrawableStoryboardSample : PausableSkinnableSound { /// /// The amount of time allowable beyond the start time of the sample, for the sample to start. diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs index b86b021d51..f9b09ed57c 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Storyboards.Drawables { - public class DrawableStoryboardSprite : Sprite, IFlippable, IVectorScalable + public partial class DrawableStoryboardSprite : Sprite, IFlippable, IVectorScalable { public StoryboardSprite Sprite { get; } diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardVideo.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardVideo.cs index ebd056ba50..f4b0692619 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardVideo.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardVideo.cs @@ -11,7 +11,7 @@ using osu.Game.Beatmaps; namespace osu.Game.Storyboards.Drawables { - public class DrawableStoryboardVideo : CompositeDrawable + public partial class DrawableStoryboardVideo : CompositeDrawable { public readonly StoryboardVideo Video; diff --git a/osu.Game/Storyboards/StoryboardVideoLayer.cs b/osu.Game/Storyboards/StoryboardVideoLayer.cs index 339e70d677..f08c02cfd2 100644 --- a/osu.Game/Storyboards/StoryboardVideoLayer.cs +++ b/osu.Game/Storyboards/StoryboardVideoLayer.cs @@ -9,7 +9,7 @@ using osuTK; namespace osu.Game.Storyboards { - public class StoryboardVideoLayer : StoryboardLayer + public partial class StoryboardVideoLayer : StoryboardLayer { public StoryboardVideoLayer(string name, int depth, bool masking) : base(name, depth, masking) @@ -19,7 +19,7 @@ namespace osu.Game.Storyboards public override DrawableStoryboardLayer CreateDrawable() => new DrawableStoryboardVideoLayer(this) { Depth = Depth, Name = Name }; - public class DrawableStoryboardVideoLayer : DrawableStoryboardLayer + public partial class DrawableStoryboardVideoLayer : DrawableStoryboardLayer { public DrawableStoryboardVideoLayer(StoryboardVideoLayer layer) : base(layer) diff --git a/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs b/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs index c97eec116c..fbc920f7de 100644 --- a/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs +++ b/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs @@ -33,7 +33,7 @@ using osu.Game.Tests.Visual; namespace osu.Game.Tests.Beatmaps { [HeadlessTest] - public abstract class HitObjectSampleTest : PlayerTestScene, IStorageResourceProvider + public abstract partial class HitObjectSampleTest : PlayerTestScene, IStorageResourceProvider { protected abstract IResourceStore RulesetResources { get; } protected LegacySkin Skin { get; private set; } diff --git a/osu.Game/Tests/Beatmaps/LegacyBeatmapSkinColourTest.cs b/osu.Game/Tests/Beatmaps/LegacyBeatmapSkinColourTest.cs index 06600c4681..2488aecced 100644 --- a/osu.Game/Tests/Beatmaps/LegacyBeatmapSkinColourTest.cs +++ b/osu.Game/Tests/Beatmaps/LegacyBeatmapSkinColourTest.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Beatmaps { - public abstract class LegacyBeatmapSkinColourTest : ScreenTestScene + public abstract partial class LegacyBeatmapSkinColourTest : ScreenTestScene { protected readonly Bindable BeatmapSkins = new Bindable(); protected readonly Bindable BeatmapColours = new Bindable(); @@ -60,7 +60,7 @@ namespace osu.Game.Tests.Beatmaps protected virtual ExposedPlayer CreateTestPlayer(bool userHasCustomColours) => new ExposedPlayer(userHasCustomColours); - protected class ExposedPlayer : TestPlayer + protected partial class ExposedPlayer : TestPlayer { protected readonly bool UserHasCustomColours; diff --git a/osu.Game/Tests/OsuTestBrowser.cs b/osu.Game/Tests/OsuTestBrowser.cs index 064fdeee94..7431679ab9 100644 --- a/osu.Game/Tests/OsuTestBrowser.cs +++ b/osu.Game/Tests/OsuTestBrowser.cs @@ -12,7 +12,7 @@ using osu.Game.Screens.Backgrounds; namespace osu.Game.Tests { - public class OsuTestBrowser : OsuGameBase + public partial class OsuTestBrowser : OsuGameBase { protected override void LoadComplete() { diff --git a/osu.Game/Tests/Visual/DependencyProvidingContainer.cs b/osu.Game/Tests/Visual/DependencyProvidingContainer.cs index 8d9108f376..ae0225d8df 100644 --- a/osu.Game/Tests/Visual/DependencyProvidingContainer.cs +++ b/osu.Game/Tests/Visual/DependencyProvidingContainer.cs @@ -15,7 +15,7 @@ namespace osu.Game.Tests.Visual /// /// The must be set while this is not loaded. /// - public class DependencyProvidingContainer : Container + public partial class DependencyProvidingContainer : Container { /// /// The dependencies provided to the children. diff --git a/osu.Game/Tests/Visual/EditorClockTestScene.cs b/osu.Game/Tests/Visual/EditorClockTestScene.cs index 8f1e7abd9e..204a817b3a 100644 --- a/osu.Game/Tests/Visual/EditorClockTestScene.cs +++ b/osu.Game/Tests/Visual/EditorClockTestScene.cs @@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual /// Provides a clock, beat-divisor, and scrolling capability for test cases of editor components that /// are preferrably tested within the presence of a clock and seek controls. /// - public abstract class EditorClockTestScene : OsuManualInputManagerTestScene + public abstract partial class EditorClockTestScene : OsuManualInputManagerTestScene { [Cached] private readonly OverlayColourProvider overlayColour = new OverlayColourProvider(OverlayColourScheme.Aquamarine); diff --git a/osu.Game/Tests/Visual/EditorSavingTestScene.cs b/osu.Game/Tests/Visual/EditorSavingTestScene.cs index 3b7b6780b1..cd9e9e1d52 100644 --- a/osu.Game/Tests/Visual/EditorSavingTestScene.cs +++ b/osu.Game/Tests/Visual/EditorSavingTestScene.cs @@ -18,7 +18,7 @@ namespace osu.Game.Tests.Visual /// /// Tests the general expected flow of creating a new beatmap, saving it, then loading it back from song select. /// - public abstract class EditorSavingTestScene : OsuGameTestScene + public abstract partial class EditorSavingTestScene : OsuGameTestScene { protected Editor Editor => Game.ChildrenOfType().FirstOrDefault(); diff --git a/osu.Game/Tests/Visual/EditorTestScene.cs b/osu.Game/Tests/Visual/EditorTestScene.cs index 0e7bb72162..833c12ba54 100644 --- a/osu.Game/Tests/Visual/EditorTestScene.cs +++ b/osu.Game/Tests/Visual/EditorTestScene.cs @@ -23,7 +23,7 @@ using osu.Game.Skinning; namespace osu.Game.Tests.Visual { - public abstract class EditorTestScene : ScreenTestScene + public abstract partial class EditorTestScene : ScreenTestScene { private TestEditorLoader editorLoader; @@ -83,7 +83,7 @@ namespace osu.Game.Tests.Visual protected sealed override Ruleset CreateRuleset() => CreateEditorRuleset(); - protected class TestEditorLoader : EditorLoader + protected partial class TestEditorLoader : EditorLoader { public TestEditor Editor { get; private set; } @@ -92,7 +92,7 @@ namespace osu.Game.Tests.Visual protected virtual TestEditor CreateTestEditor(EditorLoader loader) => new TestEditor(loader); } - protected class TestEditor : Editor + protected partial class TestEditor : Editor { [Resolved(canBeNull: true)] [CanBeNull] diff --git a/osu.Game/Tests/Visual/LegacySkinPlayerTestScene.cs b/osu.Game/Tests/Visual/LegacySkinPlayerTestScene.cs index f6b5d861be..c5efdf36b4 100644 --- a/osu.Game/Tests/Visual/LegacySkinPlayerTestScene.cs +++ b/osu.Game/Tests/Visual/LegacySkinPlayerTestScene.cs @@ -14,7 +14,7 @@ using osu.Game.Skinning; namespace osu.Game.Tests.Visual { [TestFixture] - public abstract class LegacySkinPlayerTestScene : PlayerTestScene + public abstract partial class LegacySkinPlayerTestScene : PlayerTestScene { protected LegacySkin LegacySkin { get; private set; } @@ -54,7 +54,7 @@ namespace osu.Game.Tests.Visual AddUntilStep("wait for components to load", () => this.ChildrenOfType().All(t => t.ComponentsLoaded)); } - public class SkinProvidingPlayer : TestPlayer + public partial class SkinProvidingPlayer : TestPlayer { [Cached(typeof(ISkinSource))] private readonly ISkinSource skinSource; diff --git a/osu.Game/Tests/Visual/ModPerfectTestScene.cs b/osu.Game/Tests/Visual/ModPerfectTestScene.cs index f1ad2656cd..167d5450e9 100644 --- a/osu.Game/Tests/Visual/ModPerfectTestScene.cs +++ b/osu.Game/Tests/Visual/ModPerfectTestScene.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Objects; namespace osu.Game.Tests.Visual { - public abstract class ModPerfectTestScene : ModTestScene + public abstract partial class ModPerfectTestScene : ModTestScene { private readonly ModPerfect mod; @@ -33,7 +33,7 @@ namespace osu.Game.Tests.Visual protected override TestPlayer CreateModPlayer(Ruleset ruleset) => new PerfectModTestPlayer(); - private class PerfectModTestPlayer : TestPlayer + private partial class PerfectModTestPlayer : TestPlayer { public PerfectModTestPlayer() : base(showResults: false) diff --git a/osu.Game/Tests/Visual/ModTestScene.cs b/osu.Game/Tests/Visual/ModTestScene.cs index 28778f1ac3..0559d80384 100644 --- a/osu.Game/Tests/Visual/ModTestScene.cs +++ b/osu.Game/Tests/Visual/ModTestScene.cs @@ -16,7 +16,7 @@ using osu.Game.Scoring; namespace osu.Game.Tests.Visual { - public abstract class ModTestScene : PlayerTestScene + public abstract partial class ModTestScene : PlayerTestScene { protected sealed override bool HasCustomSteps => true; @@ -58,7 +58,7 @@ namespace osu.Game.Tests.Visual protected virtual TestPlayer CreateModPlayer(Ruleset ruleset) => new ModTestPlayer(currentTestData, AllowFail); - protected class ModTestPlayer : TestPlayer + protected partial class ModTestPlayer : TestPlayer { private readonly bool allowFail; private readonly ModTestData currentTestData; diff --git a/osu.Game/Tests/Visual/Multiplayer/MultiplayerTestScene.cs b/osu.Game/Tests/Visual/Multiplayer/MultiplayerTestScene.cs index 101a347749..93c6e72aa2 100644 --- a/osu.Game/Tests/Visual/Multiplayer/MultiplayerTestScene.cs +++ b/osu.Game/Tests/Visual/Multiplayer/MultiplayerTestScene.cs @@ -13,7 +13,7 @@ namespace osu.Game.Tests.Visual.Multiplayer /// /// The base test scene for all multiplayer components and screens. /// - public abstract class MultiplayerTestScene : OnlinePlayTestScene, IMultiplayerTestSceneDependencies + public abstract partial class MultiplayerTestScene : OnlinePlayTestScene, IMultiplayerTestSceneDependencies { public const int PLAYER_1_ID = 55; public const int PLAYER_2_ID = 56; diff --git a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs index 84737bce3f..765c665966 100644 --- a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs +++ b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs @@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual.Multiplayer /// /// A for use in multiplayer test scenes. Should generally not be used by itself outside of a . /// - public class TestMultiplayerClient : MultiplayerClient + public partial class TestMultiplayerClient : MultiplayerClient { public override IBindable IsConnected => isConnected; private readonly Bindable isConnected = new Bindable(true); diff --git a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerRoomManager.cs b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerRoomManager.cs index b2283af9e7..8d04c808fd 100644 --- a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerRoomManager.cs +++ b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerRoomManager.cs @@ -17,7 +17,7 @@ namespace osu.Game.Tests.Visual.Multiplayer /// A for use in multiplayer test scenes. /// Should generally not be used by itself outside of a . /// - public class TestMultiplayerRoomManager : MultiplayerRoomManager + public partial class TestMultiplayerRoomManager : MultiplayerRoomManager { private readonly TestRoomRequestsHandler requestsHandler; diff --git a/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestScene.cs b/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestScene.cs index b9c293c3aa..5350030276 100644 --- a/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestScene.cs +++ b/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestScene.cs @@ -20,7 +20,7 @@ namespace osu.Game.Tests.Visual.OnlinePlay /// /// A base test scene for all online play components and screens. /// - public abstract class OnlinePlayTestScene : ScreenTestScene, IOnlinePlayTestSceneDependencies + public abstract partial class OnlinePlayTestScene : ScreenTestScene, IOnlinePlayTestSceneDependencies { public Bindable SelectedRoom => OnlinePlayDependencies?.SelectedRoom; public IRoomManager RoomManager => OnlinePlayDependencies?.RoomManager; diff --git a/osu.Game/Tests/Visual/OnlinePlay/TestRoomManager.cs b/osu.Game/Tests/Visual/OnlinePlay/TestRoomManager.cs index f905eb26d3..e9980e822c 100644 --- a/osu.Game/Tests/Visual/OnlinePlay/TestRoomManager.cs +++ b/osu.Game/Tests/Visual/OnlinePlay/TestRoomManager.cs @@ -15,7 +15,7 @@ namespace osu.Game.Tests.Visual.OnlinePlay /// /// A very simple for use in online play test scenes. /// - public class TestRoomManager : RoomManager + public partial class TestRoomManager : RoomManager { public Action JoinRoomRequested; diff --git a/osu.Game/Tests/Visual/OsuGameTestScene.cs b/osu.Game/Tests/Visual/OsuGameTestScene.cs index 3ca83a4781..1bf1fbf6ab 100644 --- a/osu.Game/Tests/Visual/OsuGameTestScene.cs +++ b/osu.Game/Tests/Visual/OsuGameTestScene.cs @@ -35,7 +35,7 @@ namespace osu.Game.Tests.Visual /// /// A scene which tests full game flow. /// - public abstract class OsuGameTestScene : OsuManualInputManagerTestScene + public abstract partial class OsuGameTestScene : OsuManualInputManagerTestScene { protected TestOsuGame Game; @@ -114,7 +114,7 @@ namespace osu.Game.Tests.Visual /// protected void DismissAnyNotifications() => Game.Notifications.State.Value = Visibility.Hidden; - public class TestOsuGame : OsuGame + public partial class TestOsuGame : OsuGame { public new const float SIDE_OVERLAY_OFFSET_RATIO = OsuGame.SIDE_OVERLAY_OFFSET_RATIO; @@ -189,11 +189,11 @@ namespace osu.Game.Tests.Visual } } - public class TestLoader : Loader + public partial class TestLoader : Loader { protected override ShaderPrecompiler CreateShaderPrecompiler() => new TestShaderPrecompiler(); - private class TestShaderPrecompiler : ShaderPrecompiler + private partial class TestShaderPrecompiler : ShaderPrecompiler { protected override bool AllLoaded => true; } diff --git a/osu.Game/Tests/Visual/OsuGridTestScene.cs b/osu.Game/Tests/Visual/OsuGridTestScene.cs index f9a609f663..9ef3b2a59d 100644 --- a/osu.Game/Tests/Visual/OsuGridTestScene.cs +++ b/osu.Game/Tests/Visual/OsuGridTestScene.cs @@ -13,7 +13,7 @@ namespace osu.Game.Tests.Visual /// An abstract test case which exposes small cells arranged in a grid. /// Useful for displaying multiple configurations of a tested component at a glance. /// - public abstract class OsuGridTestScene : OsuTestScene + public abstract partial class OsuGridTestScene : OsuTestScene { private readonly Drawable[,] cells; diff --git a/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs b/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs index e56c546bac..b4fb29eb11 100644 --- a/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs +++ b/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs @@ -20,7 +20,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual { - public abstract class OsuManualInputManagerTestScene : OsuTestScene + public abstract partial class OsuManualInputManagerTestScene : OsuTestScene { protected override Container Content => content; private readonly Container content; diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index 5055153691..46c7c3a57c 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -37,7 +37,7 @@ using osu.Game.Tests.Rulesets; namespace osu.Game.Tests.Visual { [ExcludeFromDynamicCompile] - public abstract class OsuTestScene : TestScene + public abstract partial class OsuTestScene : TestScene { [Cached] protected Bindable Beatmap { get; } = new Bindable(); @@ -503,7 +503,7 @@ namespace osu.Game.Tests.Visual } } - public class OsuTestSceneTestRunner : OsuGameBase, ITestSceneTestRunner + public partial class OsuTestSceneTestRunner : OsuGameBase, ITestSceneTestRunner { private TestSceneTestRunner.TestRunner runner; diff --git a/osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs b/osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs index 7e5681ee81..0027e03492 100644 --- a/osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs +++ b/osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs @@ -16,7 +16,7 @@ using osu.Game.Screens.Edit.Compose; namespace osu.Game.Tests.Visual { - public abstract class PlacementBlueprintTestScene : OsuManualInputManagerTestScene, IPlacementHandler + public abstract partial class PlacementBlueprintTestScene : OsuManualInputManagerTestScene, IPlacementHandler { protected readonly Container HitObjectContainer; protected PlacementBlueprint CurrentBlueprint { get; private set; } diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs index 9bad867206..3ecc5a3280 100644 --- a/osu.Game/Tests/Visual/PlayerTestScene.cs +++ b/osu.Game/Tests/Visual/PlayerTestScene.cs @@ -14,7 +14,7 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Tests.Visual { - public abstract class PlayerTestScene : RateAdjustedBeatmapTestScene + public abstract partial class PlayerTestScene : RateAdjustedBeatmapTestScene { /// /// Whether custom test steps are provided. Custom tests should invoke to create the test steps. diff --git a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs index a4f768800c..0f3f9f2199 100644 --- a/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs +++ b/osu.Game/Tests/Visual/RateAdjustedBeatmapTestScene.cs @@ -8,7 +8,7 @@ namespace osu.Game.Tests.Visual /// /// Test case which adjusts the beatmap's rate to match any speed adjustments in visual tests. /// - public abstract class RateAdjustedBeatmapTestScene : ScreenTestScene + public abstract partial class RateAdjustedBeatmapTestScene : ScreenTestScene { protected override void Update() { diff --git a/osu.Game/Tests/Visual/ScreenTestScene.cs b/osu.Game/Tests/Visual/ScreenTestScene.cs index 803db07fa0..7d382ca1bc 100644 --- a/osu.Game/Tests/Visual/ScreenTestScene.cs +++ b/osu.Game/Tests/Visual/ScreenTestScene.cs @@ -20,7 +20,7 @@ namespace osu.Game.Tests.Visual /// /// A test case which can be used to test a screen (that relies on OnEntering being called to execute startup instructions). /// - public abstract class ScreenTestScene : OsuManualInputManagerTestScene, IOverlayManager + public abstract partial class ScreenTestScene : OsuManualInputManagerTestScene, IOverlayManager { protected readonly OsuScreenStack Stack; diff --git a/osu.Game/Tests/Visual/ScrollingTestContainer.cs b/osu.Game/Tests/Visual/ScrollingTestContainer.cs index 1817a704b9..b8b39e16b5 100644 --- a/osu.Game/Tests/Visual/ScrollingTestContainer.cs +++ b/osu.Game/Tests/Visual/ScrollingTestContainer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Tests.Visual /// A container which provides a to children. /// This should only be used when testing /// - public class ScrollingTestContainer : Container + public partial class ScrollingTestContainer : Container { public SortedList ControlPoints => scrollingInfo.Algorithm.ControlPoints; diff --git a/osu.Game/Tests/Visual/SelectionBlueprintTestScene.cs b/osu.Game/Tests/Visual/SelectionBlueprintTestScene.cs index ac0d1cd366..350410e7c6 100644 --- a/osu.Game/Tests/Visual/SelectionBlueprintTestScene.cs +++ b/osu.Game/Tests/Visual/SelectionBlueprintTestScene.cs @@ -11,7 +11,7 @@ using osu.Game.Screens.Edit; namespace osu.Game.Tests.Visual { - public abstract class SelectionBlueprintTestScene : OsuManualInputManagerTestScene + public abstract partial class SelectionBlueprintTestScene : OsuManualInputManagerTestScene { [Cached] private readonly EditorClock editorClock = new EditorClock(); diff --git a/osu.Game/Tests/Visual/SkinnableTestScene.cs b/osu.Game/Tests/Visual/SkinnableTestScene.cs index f8f15e2729..e8f51f9afa 100644 --- a/osu.Game/Tests/Visual/SkinnableTestScene.cs +++ b/osu.Game/Tests/Visual/SkinnableTestScene.cs @@ -27,7 +27,7 @@ using osuTK.Graphics; namespace osu.Game.Tests.Visual { - public abstract class SkinnableTestScene : OsuGridTestScene, IStorageResourceProvider + public abstract partial class SkinnableTestScene : OsuGridTestScene, IStorageResourceProvider { private TrianglesSkin trianglesSkin; private Skin metricsSkin; @@ -171,7 +171,7 @@ namespace osu.Game.Tests.Visual #endregion - private class OutlineBox : CompositeDrawable + private partial class OutlineBox : CompositeDrawable { public OutlineBox() { diff --git a/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs b/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs index e6d8e473bb..a76f6c7052 100644 --- a/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs +++ b/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs @@ -17,7 +17,7 @@ using osu.Game.Scoring; namespace osu.Game.Tests.Visual.Spectator { - public class TestSpectatorClient : SpectatorClient + public partial class TestSpectatorClient : SpectatorClient { /// /// Maximum number of frames sent per bundle via . diff --git a/osu.Game/Tests/Visual/TestPlayer.cs b/osu.Game/Tests/Visual/TestPlayer.cs index 93a155e083..81195ebed9 100644 --- a/osu.Game/Tests/Visual/TestPlayer.cs +++ b/osu.Game/Tests/Visual/TestPlayer.cs @@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual /// /// A player that exposes many components that would otherwise not be available, for testing purposes. /// - public class TestPlayer : SoloPlayer + public partial class TestPlayer : SoloPlayer { protected override bool PauseOnFocusLost { get; } diff --git a/osu.Game/Tests/Visual/TestReplayPlayer.cs b/osu.Game/Tests/Visual/TestReplayPlayer.cs index a33a6763af..bc6dc9bb27 100644 --- a/osu.Game/Tests/Visual/TestReplayPlayer.cs +++ b/osu.Game/Tests/Visual/TestReplayPlayer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Tests.Visual /// /// A player that exposes many components that would otherwise not be available, for testing purposes. /// - public class TestReplayPlayer : ReplayPlayer + public partial class TestReplayPlayer : ReplayPlayer { protected override bool PauseOnFocusLost { get; } diff --git a/osu.Game/Tests/Visual/TestUserLookupCache.cs b/osu.Game/Tests/Visual/TestUserLookupCache.cs index 414166fdd8..a3028f1a34 100644 --- a/osu.Game/Tests/Visual/TestUserLookupCache.cs +++ b/osu.Game/Tests/Visual/TestUserLookupCache.cs @@ -10,7 +10,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Tests.Visual { - public class TestUserLookupCache : UserLookupCache + public partial class TestUserLookupCache : UserLookupCache { /// /// A special user ID which would return a for. diff --git a/osu.Game/Updater/NoActionUpdateManager.cs b/osu.Game/Updater/NoActionUpdateManager.cs index 8a96cdb968..97d3275757 100644 --- a/osu.Game/Updater/NoActionUpdateManager.cs +++ b/osu.Game/Updater/NoActionUpdateManager.cs @@ -16,7 +16,7 @@ namespace osu.Game.Updater /// An update manager that shows notifications if a newer release is detected. /// This is a case where updates are handled externally by a package manager or other means, so no action is performed on clicking the notification. /// - public class NoActionUpdateManager : UpdateManager + public partial class NoActionUpdateManager : UpdateManager { private string version; diff --git a/osu.Game/Updater/SimpleUpdateManager.cs b/osu.Game/Updater/SimpleUpdateManager.cs index fb5794d92e..1ecb73a154 100644 --- a/osu.Game/Updater/SimpleUpdateManager.cs +++ b/osu.Game/Updater/SimpleUpdateManager.cs @@ -20,7 +20,7 @@ namespace osu.Game.Updater /// An update manager that shows notifications if a newer release is detected. /// Installation is left up to the user. /// - public class SimpleUpdateManager : UpdateManager + public partial class SimpleUpdateManager : UpdateManager { private string version; diff --git a/osu.Game/Updater/UpdateManager.cs b/osu.Game/Updater/UpdateManager.cs index 7b540cb564..47c2a169ed 100644 --- a/osu.Game/Updater/UpdateManager.cs +++ b/osu.Game/Updater/UpdateManager.cs @@ -17,7 +17,7 @@ namespace osu.Game.Updater /// /// An update manager which only shows notifications after an update completes. /// - public class UpdateManager : CompositeDrawable + public partial class UpdateManager : CompositeDrawable { /// /// Whether this UpdateManager should be or is capable of checking for updates. @@ -85,7 +85,7 @@ namespace osu.Game.Updater /// Whether any update is waiting. May return true if an error occured (there is potentially an update available). protected virtual Task PerformUpdateCheck() => Task.FromResult(false); - private class UpdateCompleteNotification : SimpleNotification + private partial class UpdateCompleteNotification : SimpleNotification { private readonly string version; @@ -110,7 +110,7 @@ namespace osu.Game.Updater } } - public class UpdateApplicationCompleteNotification : ProgressCompletionNotification + public partial class UpdateApplicationCompleteNotification : ProgressCompletionNotification { public UpdateApplicationCompleteNotification() { @@ -118,7 +118,7 @@ namespace osu.Game.Updater } } - public class UpdateProgressNotification : ProgressNotification + public partial class UpdateProgressNotification : ProgressNotification { protected override Notification CreateCompletionNotification() => new UpdateApplicationCompleteNotification { diff --git a/osu.Game/Users/Drawables/ClickableAvatar.cs b/osu.Game/Users/Drawables/ClickableAvatar.cs index 62e966c48f..5a3009dfcd 100644 --- a/osu.Game/Users/Drawables/ClickableAvatar.cs +++ b/osu.Game/Users/Drawables/ClickableAvatar.cs @@ -13,7 +13,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Users.Drawables { - public class ClickableAvatar : Container + public partial class ClickableAvatar : Container { private const string default_tooltip_text = "view profile"; @@ -71,7 +71,7 @@ namespace osu.Game.Users.Drawables game?.ShowUser(user); } - private class ClickableArea : OsuClickableContainer + private partial class ClickableArea : OsuClickableContainer { private LocalisableString tooltip = default_tooltip_text; diff --git a/osu.Game/Users/Drawables/DrawableAvatar.cs b/osu.Game/Users/Drawables/DrawableAvatar.cs index 155f63dc18..bd09b95164 100644 --- a/osu.Game/Users/Drawables/DrawableAvatar.cs +++ b/osu.Game/Users/Drawables/DrawableAvatar.cs @@ -12,7 +12,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Users.Drawables { [LongRunningLoad] - public class DrawableAvatar : Sprite + public partial class DrawableAvatar : Sprite { private readonly IUser user; diff --git a/osu.Game/Users/Drawables/DrawableFlag.cs b/osu.Game/Users/Drawables/DrawableFlag.cs index 253835b415..0d209f47e8 100644 --- a/osu.Game/Users/Drawables/DrawableFlag.cs +++ b/osu.Game/Users/Drawables/DrawableFlag.cs @@ -13,7 +13,7 @@ using osu.Framework.Localisation; namespace osu.Game.Users.Drawables { - public class DrawableFlag : Sprite, IHasTooltip + public partial class DrawableFlag : Sprite, IHasTooltip { private readonly CountryCode countryCode; diff --git a/osu.Game/Users/Drawables/UpdateableAvatar.cs b/osu.Game/Users/Drawables/UpdateableAvatar.cs index dab3dc59f9..9c04eb5706 100644 --- a/osu.Game/Users/Drawables/UpdateableAvatar.cs +++ b/osu.Game/Users/Drawables/UpdateableAvatar.cs @@ -13,7 +13,7 @@ namespace osu.Game.Users.Drawables /// /// An avatar which can update to a new user when needed. /// - public class UpdateableAvatar : ModelBackedDrawable + public partial class UpdateableAvatar : ModelBackedDrawable { public APIUser User { diff --git a/osu.Game/Users/Drawables/UpdateableFlag.cs b/osu.Game/Users/Drawables/UpdateableFlag.cs index 9b101131b3..a208f3c7c4 100644 --- a/osu.Game/Users/Drawables/UpdateableFlag.cs +++ b/osu.Game/Users/Drawables/UpdateableFlag.cs @@ -13,7 +13,7 @@ using osu.Game.Overlays; namespace osu.Game.Users.Drawables { - public class UpdateableFlag : ModelBackedDrawable + public partial class UpdateableFlag : ModelBackedDrawable { public CountryCode CountryCode { diff --git a/osu.Game/Users/ExtendedUserPanel.cs b/osu.Game/Users/ExtendedUserPanel.cs index a4cba8b920..85b71a5bc7 100644 --- a/osu.Game/Users/ExtendedUserPanel.cs +++ b/osu.Game/Users/ExtendedUserPanel.cs @@ -17,7 +17,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Users { - public abstract class ExtendedUserPanel : UserPanel + public abstract partial class ExtendedUserPanel : UserPanel { public readonly Bindable Status = new Bindable(); diff --git a/osu.Game/Users/UserBrickPanel.cs b/osu.Game/Users/UserBrickPanel.cs index a214b72795..69b390b36e 100644 --- a/osu.Game/Users/UserBrickPanel.cs +++ b/osu.Game/Users/UserBrickPanel.cs @@ -14,7 +14,7 @@ using osuTK; namespace osu.Game.Users { - public class UserBrickPanel : UserPanel + public partial class UserBrickPanel : UserPanel { public UserBrickPanel(APIUser user) : base(user) diff --git a/osu.Game/Users/UserCoverBackground.cs b/osu.Game/Users/UserCoverBackground.cs index c799bbb1ea..69a5fba876 100644 --- a/osu.Game/Users/UserCoverBackground.cs +++ b/osu.Game/Users/UserCoverBackground.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Users { - public class UserCoverBackground : ModelBackedDrawable + public partial class UserCoverBackground : ModelBackedDrawable { public APIUser User { @@ -38,7 +38,7 @@ namespace osu.Game.Users => new DelayedLoadUnloadWrapper(createContentFunc, timeBeforeLoad, UnloadDelay); [LongRunningLoad] - private class Cover : CompositeDrawable + private partial class Cover : CompositeDrawable { private readonly APIUser user; diff --git a/osu.Game/Users/UserGridPanel.cs b/osu.Game/Users/UserGridPanel.cs index 38d8f6fb33..90b6c11f0e 100644 --- a/osu.Game/Users/UserGridPanel.cs +++ b/osu.Game/Users/UserGridPanel.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Users { - public class UserGridPanel : ExtendedUserPanel + public partial class UserGridPanel : ExtendedUserPanel { private const int margin = 10; diff --git a/osu.Game/Users/UserListPanel.cs b/osu.Game/Users/UserListPanel.cs index 6d45481dbe..bbd3c60a33 100644 --- a/osu.Game/Users/UserListPanel.cs +++ b/osu.Game/Users/UserListPanel.cs @@ -15,7 +15,7 @@ using osu.Game.Overlays.Profile.Header.Components; namespace osu.Game.Users { - public class UserListPanel : ExtendedUserPanel + public partial class UserListPanel : ExtendedUserPanel { public UserListPanel(APIUser user) : base(user) diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index d150b38c45..e7af127a30 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -19,7 +19,7 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Users { - public abstract class UserPanel : OsuClickableContainer, IHasContextMenu + public abstract partial class UserPanel : OsuClickableContainer, IHasContextMenu { public readonly APIUser User; From 212d78865a6b5f091173a347bad5686834d1d5fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 26 Nov 2022 16:30:10 +0100 Subject: [PATCH 0783/2991] Add a few more missing partial specs --- .../Visual/Background/TestSceneTriangleBorderShader.cs | 4 ++-- .../Visual/Background/TestSceneTrianglesV2Background.cs | 2 +- osu.Game.Tests/Visual/Online/TestSceneDrawableChannel.cs | 2 +- osu.Game/Graphics/Backgrounds/TrianglesV2.cs | 2 +- osu.Game/Skinning/Components/BeatmapAttributeText.cs | 2 +- osu.Game/Skinning/Components/TextElement.cs | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs b/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs index 64512bc651..185b83d1cc 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs @@ -12,7 +12,7 @@ using osu.Framework.Graphics.Rendering; namespace osu.Game.Tests.Visual.Background { - public class TestSceneTriangleBorderShader : OsuTestScene + public partial class TestSceneTriangleBorderShader : OsuTestScene { private readonly TriangleBorder border; @@ -41,7 +41,7 @@ namespace osu.Game.Tests.Visual.Background AddSliderStep("Thickness", 0f, 1f, 0.02f, t => border.Thickness = t); } - private class TriangleBorder : Sprite + private partial class TriangleBorder : Sprite { private float thickness = 0.02f; diff --git a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs index 0c3a21d510..8d6aef99ad 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs @@ -10,7 +10,7 @@ using osu.Game.Graphics.Backgrounds; namespace osu.Game.Tests.Visual.Background { - public class TestSceneTrianglesV2Background : OsuTestScene + public partial class TestSceneTrianglesV2Background : OsuTestScene { private readonly TrianglesV2 triangles; diff --git a/osu.Game.Tests/Visual/Online/TestSceneDrawableChannel.cs b/osu.Game.Tests/Visual/Online/TestSceneDrawableChannel.cs index dc1e00ee8f..4830c7b856 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneDrawableChannel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneDrawableChannel.cs @@ -13,7 +13,7 @@ using osu.Game.Overlays.Chat; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestSceneDrawableChannel : OsuTestScene + public partial class TestSceneDrawableChannel : OsuTestScene { private Channel channel = null!; private DrawableChannel drawableChannel = null!; diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs index 77d30d50d6..70f4981c36 100644 --- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs +++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs @@ -19,7 +19,7 @@ using osu.Framework.Graphics; namespace osu.Game.Graphics.Backgrounds { - public class TrianglesV2 : Drawable + public partial class TrianglesV2 : Drawable { private const float triangle_size = 100; private const float base_velocity = 50; diff --git a/osu.Game/Skinning/Components/BeatmapAttributeText.cs b/osu.Game/Skinning/Components/BeatmapAttributeText.cs index ec84831fb4..0a5f0d22cb 100644 --- a/osu.Game/Skinning/Components/BeatmapAttributeText.cs +++ b/osu.Game/Skinning/Components/BeatmapAttributeText.cs @@ -24,7 +24,7 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Skinning.Components { [UsedImplicitly] - public class BeatmapAttributeText : Container, ISkinnableDrawable + public partial class BeatmapAttributeText : Container, ISkinnableDrawable { public bool UsesFixedAnchor { get; set; } diff --git a/osu.Game/Skinning/Components/TextElement.cs b/osu.Game/Skinning/Components/TextElement.cs index 1e618a7f82..74a0acb979 100644 --- a/osu.Game/Skinning/Components/TextElement.cs +++ b/osu.Game/Skinning/Components/TextElement.cs @@ -12,7 +12,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Skinning.Components { [UsedImplicitly] - public class TextElement : Container, ISkinnableDrawable + public partial class TextElement : Container, ISkinnableDrawable { public bool UsesFixedAnchor { get; set; } From 0abf6ad5b07371c9547819b93984d8ba4a592701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 26 Nov 2022 16:32:42 +0100 Subject: [PATCH 0784/2991] Ignore partial modifier application in blame --- .git-blame-ignore-revs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 8be6479043..e331778e7f 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,2 +1,6 @@ # Normalize all the line endings 32a74f95a5c80a0ed18e693f13a47522099df5c3 +# Partial everything +7bc8908ca9c026fed1d831eb6e58df7624a8d614 +# Add a few more missing partial specs +212d78865a6b5f091173a347bad5686834d1d5fe From 00c11b2b4e389e48f3995d63484a6bc66a7afbdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 26 Nov 2022 17:59:38 +0100 Subject: [PATCH 0785/2991] Add partial specs in mobile projects too --- osu.Android/AndroidJoystickSettings.cs | 2 +- osu.Android/AndroidMouseSettings.cs | 2 +- osu.Android/GameplayScreenRotationLocker.cs | 2 +- osu.Android/OsuGameAndroid.cs | 2 +- osu.iOS/IOSMouseSettings.cs | 2 +- osu.iOS/OsuGameIOS.cs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Android/AndroidJoystickSettings.cs b/osu.Android/AndroidJoystickSettings.cs index 26e921a426..bf69461f0d 100644 --- a/osu.Android/AndroidJoystickSettings.cs +++ b/osu.Android/AndroidJoystickSettings.cs @@ -11,7 +11,7 @@ using osu.Game.Overlays.Settings; namespace osu.Android { - public class AndroidJoystickSettings : SettingsSubsection + public partial class AndroidJoystickSettings : SettingsSubsection { protected override LocalisableString Header => JoystickSettingsStrings.JoystickGamepad; diff --git a/osu.Android/AndroidMouseSettings.cs b/osu.Android/AndroidMouseSettings.cs index 54b787fd17..d6d7750448 100644 --- a/osu.Android/AndroidMouseSettings.cs +++ b/osu.Android/AndroidMouseSettings.cs @@ -14,7 +14,7 @@ using osu.Game.Overlays.Settings.Sections.Input; namespace osu.Android { - public class AndroidMouseSettings : SettingsSubsection + public partial class AndroidMouseSettings : SettingsSubsection { private readonly AndroidMouseHandler mouseHandler; diff --git a/osu.Android/GameplayScreenRotationLocker.cs b/osu.Android/GameplayScreenRotationLocker.cs index 9e849bdc7c..3c39a820cc 100644 --- a/osu.Android/GameplayScreenRotationLocker.cs +++ b/osu.Android/GameplayScreenRotationLocker.cs @@ -11,7 +11,7 @@ using osu.Game; namespace osu.Android { - public class GameplayScreenRotationLocker : Component + public partial class GameplayScreenRotationLocker : Component { private Bindable localUserPlaying; diff --git a/osu.Android/OsuGameAndroid.cs b/osu.Android/OsuGameAndroid.cs index 6b88f21bcd..1c6f41a7ec 100644 --- a/osu.Android/OsuGameAndroid.cs +++ b/osu.Android/OsuGameAndroid.cs @@ -18,7 +18,7 @@ using Xamarin.Essentials; namespace osu.Android { - public class OsuGameAndroid : OsuGame + public partial class OsuGameAndroid : OsuGame { [Cached] private readonly OsuGameActivity gameActivity; diff --git a/osu.iOS/IOSMouseSettings.cs b/osu.iOS/IOSMouseSettings.cs index 1979a881f7..f464bd93b8 100644 --- a/osu.iOS/IOSMouseSettings.cs +++ b/osu.iOS/IOSMouseSettings.cs @@ -10,7 +10,7 @@ using osu.Game.Overlays.Settings; namespace osu.iOS { - public class IOSMouseSettings : SettingsSubsection + public partial class IOSMouseSettings : SettingsSubsection { protected override LocalisableString Header => MouseSettingsStrings.Mouse; diff --git a/osu.iOS/OsuGameIOS.cs b/osu.iOS/OsuGameIOS.cs index ecbea42d74..b3194e497b 100644 --- a/osu.iOS/OsuGameIOS.cs +++ b/osu.iOS/OsuGameIOS.cs @@ -16,7 +16,7 @@ using Xamarin.Essentials; namespace osu.iOS { - public class OsuGameIOS : OsuGame + public partial class OsuGameIOS : OsuGame { public override Version AssemblyVersion => new Version(NSBundle.MainBundle.InfoDictionary["CFBundleVersion"].ToString()); From f6d47f84ad2b2497ee9a690dcde6ebe87610d2aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 26 Nov 2022 18:00:37 +0100 Subject: [PATCH 0786/2991] Add one more partial modifier commit ignore --- .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index e331778e7f..b85862270b 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -4,3 +4,5 @@ 7bc8908ca9c026fed1d831eb6e58df7624a8d614 # Add a few more missing partial specs 212d78865a6b5f091173a347bad5686834d1d5fe +# Add partial specs in mobile projects too +00c11b2b4e389e48f3995d63484a6bc66a7afbdb From c42720acd440f1dec1917ec381d8d50693f02752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 26 Nov 2022 18:05:08 +0100 Subject: [PATCH 0787/2991] Temporarily disable "partial class with one part" inspection --- osu.Game/Online/Rooms/APICreatedRoom.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Online/Rooms/APICreatedRoom.cs b/osu.Game/Online/Rooms/APICreatedRoom.cs index 254a338a60..7f2bd13aec 100644 --- a/osu.Game/Online/Rooms/APICreatedRoom.cs +++ b/osu.Game/Online/Rooms/APICreatedRoom.cs @@ -7,6 +7,8 @@ using Newtonsoft.Json; namespace osu.Game.Online.Rooms { + // TODO: Remove disable below after merging https://github.com/ppy/osu-framework/pull/5548 and applying follow-up changes game-side. + // ReSharper disable once PartialTypeWithSinglePart public partial class APICreatedRoom : Room { [JsonProperty("error")] From 7ab5136e12123124637ea1a7827d29a461a059a5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 26 Nov 2022 20:05:34 +0300 Subject: [PATCH 0788/2991] Compute texel size in the DrawNode --- osu.Game/Graphics/Backgrounds/TrianglesV2.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs index 77d30d50d6..01e7fc7514 100644 --- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs +++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs @@ -229,6 +229,7 @@ namespace osu.Game.Graphics.Backgrounds private readonly List parts = new List(); private Vector2 size; private float thickness; + private float texelSize; private IVertexBatch? vertexBatch; @@ -245,6 +246,7 @@ namespace osu.Game.Graphics.Backgrounds texture = Source.texture; size = Source.DrawSize; thickness = Source.Thickness; + texelSize = Math.Max(1.5f / Source.ScreenSpaceDrawQuad.Size.X, 1.5f / Source.ScreenSpaceDrawQuad.Size.Y); parts.Clear(); parts.AddRange(Source.parts); @@ -265,6 +267,7 @@ namespace osu.Game.Graphics.Backgrounds shader.Bind(); shader.GetUniform("thickness").UpdateValue(ref thickness); + shader.GetUniform("texelSize").UpdateValue(ref texelSize); foreach (TriangleParticle particle in parts) { From d1eedd081cb3b500c168893fbe6c4302748287a0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 27 Nov 2022 02:46:11 +0900 Subject: [PATCH 0789/2991] Update resources --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index b1d6231210..8f4750e831 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -51,7 +51,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9d7ef7fb22..afc80d073f 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index ae0bc2d0c0..4d8c1af28b 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -61,7 +61,7 @@ - + From 8ecb4aa30b35256edbae8b532c7ab9f20216a955 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 27 Nov 2022 09:41:08 +0900 Subject: [PATCH 0790/2991] better method name --- osu.Game/Online/Chat/NowPlayingCommand.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/Chat/NowPlayingCommand.cs b/osu.Game/Online/Chat/NowPlayingCommand.cs index ea44bd93d8..63df052644 100644 --- a/osu.Game/Online/Chat/NowPlayingCommand.cs +++ b/osu.Game/Online/Chat/NowPlayingCommand.cs @@ -67,14 +67,14 @@ namespace osu.Game.Online.Chat break; } - string beatmapString() + string getBeatmapPart() { string beatmapInfoString = localisation.GetLocalisedBindableString(beatmapInfo.GetDisplayTitleRomanisable()).Value; return beatmapInfo.OnlineID > 0 ? $"[{api.WebsiteRootUrl}/b/{beatmapInfo.OnlineID} {beatmapInfoString}]" : beatmapInfoString; } - string modString() + string getModPart() { if (selectedMods.Value.Count == 0) { @@ -91,7 +91,7 @@ namespace osu.Game.Online.Chat return modS.ToString(); } - channelManager.PostMessage($"is {verb} {beatmapString()} {modString()}", true, target); + channelManager.PostMessage($"is {verb} {getBeatmapPart()} {getModPart()}", true, target); Expire(); } } From 653875bbb452e8ac9297fcc345ec7af027518c99 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 27 Nov 2022 09:41:41 +0900 Subject: [PATCH 0791/2991] only post mod when ingame --- osu.Game/Online/Chat/NowPlayingCommand.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Online/Chat/NowPlayingCommand.cs b/osu.Game/Online/Chat/NowPlayingCommand.cs index 63df052644..93ea597afa 100644 --- a/osu.Game/Online/Chat/NowPlayingCommand.cs +++ b/osu.Game/Online/Chat/NowPlayingCommand.cs @@ -76,6 +76,8 @@ namespace osu.Game.Online.Chat string getModPart() { + if (api.Activity.Value is UserActivity.InGame) return string.Empty; + if (selectedMods.Value.Count == 0) { return string.Empty; From 02e3ebe1a01a39fb692ac13d2c37f6c7bdbc138a Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 27 Nov 2022 09:42:55 +0900 Subject: [PATCH 0792/2991] DifficultyIncrease use `+` and other all `-` mod.Name to mod.Acronym --- osu.Game/Online/Chat/NowPlayingCommand.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/Chat/NowPlayingCommand.cs b/osu.Game/Online/Chat/NowPlayingCommand.cs index 93ea597afa..6d3e1ad50c 100644 --- a/osu.Game/Online/Chat/NowPlayingCommand.cs +++ b/osu.Game/Online/Chat/NowPlayingCommand.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.Linq; using System.Text; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -76,7 +77,7 @@ namespace osu.Game.Online.Chat string getModPart() { - if (api.Activity.Value is UserActivity.InGame) return string.Empty; + if (api.Activity.Value is not UserActivity.InGame) return string.Empty; if (selectedMods.Value.Count == 0) { @@ -85,9 +86,14 @@ namespace osu.Game.Online.Chat StringBuilder modS = new StringBuilder(); - foreach (var mod in selectedMods.Value) + foreach (var mod in selectedMods.Value.Where(mod => mod.Type == ModType.DifficultyIncrease)) { - modS.Append($"+{mod.Name} "); + modS.Append($"+{mod.Acronym} "); + } + + foreach (var mod in selectedMods.Value.Where(mod => mod.Type != ModType.DifficultyIncrease)) + { + modS.Append($"-{mod.Acronym} "); } return modS.ToString(); From 6adac853e85f7ebf81f61fa90a3d3afc8f556d0a Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 27 Nov 2022 09:58:54 +0900 Subject: [PATCH 0793/2991] Spite sync method `ExportToStream` `uuid` to `model` --- osu.Game/Database/LegacyModelExporter.cs | 14 ++++++++------ osu.Game/Database/LegacyScoreExporter.cs | 21 ++++++--------------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 3780f2b9cc..3523d18f29 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -74,24 +74,26 @@ namespace osu.Game.Database } /// - /// Export te model corresponding to uuid to given stream. + /// Export te model corresponding to model to given stream. /// - /// The medel which have . + /// The medel which have . /// The stream to export. /// - public virtual async Task ExportToStreamAsync(TModel uuid, Stream stream) + public async Task ExportToStreamAsync(TModel model, Stream stream) { - Guid id = uuid.ID; + Guid id = model.ID; await Task.Run(() => { RealmAccess.Run(r => { - TModel model = r.Find(id); - createZipArchive(model, stream); + TModel refetchModel = r.Find(id); + ExportToStream(refetchModel, stream); }); }).ContinueWith(OnComplete); } + protected virtual void ExportToStream(TModel model, Stream outputStream) => createZipArchive(model, outputStream); + private void createZipArchive(TModel model, Stream outputStream) { using (var archive = ZipArchive.Create()) diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index ae0fbf8d19..eb46bc6db2 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -3,7 +3,6 @@ using System.IO; using System.Linq; -using System.Threading.Tasks; using osu.Framework.Platform; using osu.Game.Extensions; using osu.Game.Overlays; @@ -20,22 +19,14 @@ namespace osu.Game.Database protected override string FileExtension => ".osr"; - public override async Task ExportToStreamAsync(ScoreInfo uuid, Stream stream) + protected override void ExportToStream(ScoreInfo model, Stream stream) { - await Task.Run(() => - { - RealmAccess.Run(r => - { - ScoreInfo model = r.Find(uuid.ID); + var file = model.Files.SingleOrDefault(); + if (file == null) + return; - var file = model.Files.SingleOrDefault(); - if (file == null) - return; - - using (var inputStream = UserFileStorage.GetStream(file.File.GetStoragePath())) - inputStream.CopyTo(stream); - }); - }).ContinueWith(OnComplete); + using (var inputStream = UserFileStorage.GetStream(file.File.GetStoragePath())) + inputStream.CopyTo(stream); } } } From 54681217be3cf85387d2673ce172e2155b01e41b Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 27 Nov 2022 10:44:06 +0900 Subject: [PATCH 0794/2991] fix test --- osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs b/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs index 1bd2118d5a..362ebd1e74 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs @@ -81,11 +81,13 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestModPresence() { + AddStep("Set activity", () => api.Activity.Value = new UserActivity.InSoloGame(new BeatmapInfo(), new RulesetInfo())); + AddStep("Add Hidden mod", () => SelectedMods.Value = new[] { Ruleset.Value.CreateInstance().CreateMod() }); AddStep("Run command", () => Add(new NowPlayingCommand())); - AddAssert("Check mod is present", () => postTarget.LastMessage.Contains("+Hidden")); + AddAssert("Check mod is present", () => postTarget.LastMessage.Contains("+HD")); } public partial class PostTarget : Component, IChannelPostTarget From 1a914d0df7b4e413be152327756b683f117a3d88 Mon Sep 17 00:00:00 2001 From: Jai Sharma Date: Sun, 27 Nov 2022 02:43:22 +0000 Subject: [PATCH 0795/2991] Remove `#nullable disable` from `TimingScreen` --- osu.Game/Screens/Edit/Timing/TimingScreen.cs | 26 +++++++++----------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Edit/Timing/TimingScreen.cs b/osu.Game/Screens/Edit/Timing/TimingScreen.cs index 43fca40526..4a38d64583 100644 --- a/osu.Game/Screens/Edit/Timing/TimingScreen.cs +++ b/osu.Game/Screens/Edit/Timing/TimingScreen.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using osu.Framework.Allocation; @@ -50,24 +48,24 @@ namespace osu.Game.Screens.Edit.Timing public partial class ControlPointList : CompositeDrawable { - private OsuButton deleteButton; - private ControlPointTable table; + private OsuButton deleteButton = null!; + private ControlPointTable table = null!; + private OsuScrollContainer scroll = null!; + private RoundedButton addButton = null!; private readonly IBindableList controlPointGroups = new BindableList(); - private RoundedButton addButton; + [Resolved] + private EditorClock clock { get; set; } = null!; [Resolved] - private EditorClock clock { get; set; } + protected EditorBeatmap Beatmap { get; private set; } = null!; [Resolved] - protected EditorBeatmap Beatmap { get; private set; } + private Bindable selectedGroup { get; set; } = null!; [Resolved] - private Bindable selectedGroup { get; set; } - - [Resolved(canBeNull: true)] - private IEditorChangeHandler changeHandler { get; set; } + private IEditorChangeHandler? changeHandler { get; set; } [BackgroundDependencyLoader] private void load(OverlayColourProvider colours) @@ -132,8 +130,8 @@ namespace osu.Game.Screens.Edit.Timing deleteButton.Enabled.Value = selected.NewValue != null; addButton.Text = selected.NewValue != null - ? "+ Clone to current time" - : "+ Add at current time"; + ? @"+ Clone to current time" + : @"+ Add at current time"; }, true); controlPointGroups.BindTo(Beatmap.ControlPointInfo.Groups); @@ -159,7 +157,7 @@ namespace osu.Game.Screens.Edit.Timing addButton.Enabled.Value = clock.CurrentTimeAccurate != selectedGroup.Value?.Time; } - private Type trackedType; + private Type? trackedType; /// /// Given the user has selected a control point group, we want to track any group which is From b6d7bec2405299d5d7428a40473462671e30b6be Mon Sep 17 00:00:00 2001 From: Jai Sharma Date: Sun, 27 Nov 2022 02:45:56 +0000 Subject: [PATCH 0796/2991] Remove `#nullable disabled` from `EditorTable` and it's derived classes --- osu.Game/Screens/Edit/EditorTable.cs | 8 +------ .../Screens/Edit/Timing/ControlPointTable.cs | 18 +++++++------- osu.Game/Screens/Edit/Verify/IssueTable.cs | 24 +++++++++---------- 3 files changed, 21 insertions(+), 29 deletions(-) diff --git a/osu.Game/Screens/Edit/EditorTable.cs b/osu.Game/Screens/Edit/EditorTable.cs index f97a8c5572..f62106745b 100644 --- a/osu.Game/Screens/Edit/EditorTable.cs +++ b/osu.Game/Screens/Edit/EditorTable.cs @@ -1,8 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - +using System; using osu.Framework.Allocation; using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; @@ -84,11 +83,6 @@ namespace osu.Game.Screens.Edit Alpha = 0, }, }; - - // todo delete - Action = () => - { - }; } private Color4 colourHover; diff --git a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs index 5c131c0b6d..7bc59c77f8 100644 --- a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs +++ b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -23,10 +21,10 @@ namespace osu.Game.Screens.Edit.Timing public partial class ControlPointTable : EditorTable { [Resolved] - private Bindable selectedGroup { get; set; } + private Bindable selectedGroup { get; set; } = null!; [Resolved] - private EditorClock clock { get; set; } + private EditorClock clock { get; set; } = null!; public const float TIMING_COLUMN_WIDTH = 230; @@ -81,8 +79,8 @@ namespace osu.Game.Screens.Edit.Timing { var columns = new List { - new TableColumn("Time", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, TIMING_COLUMN_WIDTH)), - new TableColumn("Attributes", Anchor.CentreLeft), + new TableColumn(@"Time", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, TIMING_COLUMN_WIDTH)), + new TableColumn(@"Attributes", Anchor.CentreLeft), }; return columns.ToArray(); @@ -162,12 +160,13 @@ namespace osu.Game.Screens.Edit.Timing .Where(matchFunction) .Select(createAttribute) .Where(c => c != null) + .Select(c => c!) // arbitrary ordering to make timing points first. // probably want to explicitly define order in the future. .OrderByDescending(c => c.GetType().Name); } - private Drawable createAttribute(ControlPoint controlPoint) + private Drawable? createAttribute(ControlPoint controlPoint) { switch (controlPoint) { @@ -182,9 +181,10 @@ namespace osu.Game.Screens.Edit.Timing case SampleControlPoint sample: return new SampleRowAttribute(sample); - } - return null; + default: + return null; + } } } } diff --git a/osu.Game/Screens/Edit/Verify/IssueTable.cs b/osu.Game/Screens/Edit/Verify/IssueTable.cs index 6fdf9c76e2..3c72815d1f 100644 --- a/osu.Game/Screens/Edit/Verify/IssueTable.cs +++ b/osu.Game/Screens/Edit/Verify/IssueTable.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; @@ -20,19 +18,19 @@ namespace osu.Game.Screens.Edit.Verify { public partial class IssueTable : EditorTable { - [Resolved] - private VerifyScreen verify { get; set; } - - private Bindable selectedIssue; + private Bindable selectedIssue = null!; [Resolved] - private EditorClock clock { get; set; } + private VerifyScreen verify { get; set; } = null!; [Resolved] - private EditorBeatmap editorBeatmap { get; set; } + private EditorClock clock { get; set; } = null!; [Resolved] - private Editor editor { get; set; } + private EditorBeatmap editorBeatmap { get; set; } = null!; + + [Resolved] + private Editor editor { get; set; } = null!; public IEnumerable Issues { @@ -88,10 +86,10 @@ namespace osu.Game.Screens.Edit.Verify var columns = new List { new TableColumn(string.Empty, Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)), - new TableColumn("Type", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize, minSize: 60)), - new TableColumn("Time", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize, minSize: 60)), - new TableColumn("Message", Anchor.CentreLeft), - new TableColumn("Category", Anchor.CentreRight, new Dimension(GridSizeMode.AutoSize)), + new TableColumn(@"Type", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize, minSize: 60)), + new TableColumn(@"Time", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize, minSize: 60)), + new TableColumn(@"Message", Anchor.CentreLeft), + new TableColumn(@"Category", Anchor.CentreRight, new Dimension(GridSizeMode.AutoSize)), }; return columns.ToArray(); From 792334a1902e8ea80a18b0d1a232c1ade5c4638d Mon Sep 17 00:00:00 2001 From: Jai Sharma Date: Sun, 27 Nov 2022 02:47:02 +0000 Subject: [PATCH 0797/2991] Move Control Group timing data into it's own component --- .../Screens/Edit/Timing/ControlPointTable.cs | 53 +++++++++++-------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs index 7bc59c77f8..e8fd71afa3 100644 --- a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs +++ b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs @@ -90,32 +90,38 @@ namespace osu.Game.Screens.Edit.Timing { return new Drawable[] { - new FillFlowContainer - { - RelativeSizeAxes = Axes.Y, - Width = TIMING_COLUMN_WIDTH, - Spacing = new Vector2(5), - Children = new Drawable[] - { - new OsuSpriteText - { - Text = group.Time.ToEditorFormattedString(), - Font = OsuFont.GetFont(size: TEXT_SIZE, weight: FontWeight.Bold), - Width = 70, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - }, - new ControlGroupAttributes(group, c => c is TimingControlPoint) - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - } - } - }, - new ControlGroupAttributes(group, c => !(c is TimingControlPoint)) + new ControlGroupTiming(group), + new ControlGroupAttributes(group, c => c is not TimingControlPoint) }; } + private partial class ControlGroupTiming : FillFlowContainer + { + public ControlGroupTiming(ControlPointGroup group) + { + Name = @"ControlGroupTiming"; + RelativeSizeAxes = Axes.Y; + Width = TIMING_COLUMN_WIDTH; + Spacing = new Vector2(5); + Children = new Drawable[] + { + new OsuSpriteText + { + Text = group.Time.ToEditorFormattedString(), + Font = OsuFont.GetFont(size: TEXT_SIZE, weight: FontWeight.Bold), + Width = 70, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + }, + new ControlGroupAttributes(group, c => c is TimingControlPoint) + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + } + }; + } + } + private partial class ControlGroupAttributes : CompositeDrawable { private readonly Func matchFunction; @@ -130,6 +136,7 @@ namespace osu.Game.Screens.Edit.Timing AutoSizeAxes = Axes.X; RelativeSizeAxes = Axes.Y; + Name = @"ControlGroupAttributes"; InternalChild = fill = new FillFlowContainer { From 3c56b9c93a24638907466361adf45919713bcbfb Mon Sep 17 00:00:00 2001 From: Jai Sharma Date: Sun, 27 Nov 2022 02:47:54 +0000 Subject: [PATCH 0798/2991] Add `OnRowSelected` event to `EditorTable` --- osu.Game/Screens/Edit/EditorTable.cs | 13 +++++++++++++ osu.Game/Screens/Edit/Timing/ControlPointTable.cs | 8 +------- osu.Game/Screens/Edit/Timing/TimingScreen.cs | 4 +++- osu.Game/Screens/Edit/Verify/IssueTable.cs | 2 +- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Edit/EditorTable.cs b/osu.Game/Screens/Edit/EditorTable.cs index f62106745b..7b607e9afc 100644 --- a/osu.Game/Screens/Edit/EditorTable.cs +++ b/osu.Game/Screens/Edit/EditorTable.cs @@ -19,6 +19,8 @@ namespace osu.Game.Screens.Edit { public abstract partial class EditorTable : TableContainer { + public event Action? OnRowSelected; + private const float horizontal_inset = 20; protected const float ROW_HEIGHT = 25; @@ -44,6 +46,17 @@ namespace osu.Game.Screens.Edit }); } + protected void SetRowSelected(object? item) + { + foreach (var b in BackgroundFlow) + { + b.Selected = ReferenceEquals(b.Item, item); + + if (b.Selected) + OnRowSelected?.Invoke(b); + } + } + protected override Drawable CreateHeader(int index, TableColumn column) => new HeaderText(column?.Header ?? default); private partial class HeaderText : OsuSpriteText diff --git a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs index e8fd71afa3..464a8e92ad 100644 --- a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs +++ b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs @@ -63,17 +63,11 @@ namespace osu.Game.Screens.Edit.Timing selectedGroup.BindValueChanged(_ => { - // TODO: This should scroll the selected row into view. updateSelectedGroup(); }, true); } - private void updateSelectedGroup() - { - // TODO: This should scroll the selected row into view. - foreach (var b in BackgroundFlow) - b.Selected = ReferenceEquals(b.Item, selectedGroup?.Value); - } + private void updateSelectedGroup() => SetRowSelected(selectedGroup?.Value); private TableColumn[] createHeaders() { diff --git a/osu.Game/Screens/Edit/Timing/TimingScreen.cs b/osu.Game/Screens/Edit/Timing/TimingScreen.cs index 4a38d64583..2c40add77c 100644 --- a/osu.Game/Screens/Edit/Timing/TimingScreen.cs +++ b/osu.Game/Screens/Edit/Timing/TimingScreen.cs @@ -86,7 +86,7 @@ namespace osu.Game.Screens.Edit.Timing RelativeSizeAxes = Axes.Y, Width = ControlPointTable.TIMING_COLUMN_WIDTH + margins, }, - new OsuScrollContainer + scroll = new OsuScrollContainer { RelativeSizeAxes = Axes.Both, Child = table = new ControlPointTable(), @@ -140,6 +140,8 @@ namespace osu.Game.Screens.Edit.Timing table.ControlGroups = controlPointGroups; changeHandler?.SaveState(); }, true); + + table.OnRowSelected += (drawable) => scroll.ScrollIntoView(drawable); } protected override bool OnClick(ClickEvent e) diff --git a/osu.Game/Screens/Edit/Verify/IssueTable.cs b/osu.Game/Screens/Edit/Verify/IssueTable.cs index 3c72815d1f..75e7c2e43d 100644 --- a/osu.Game/Screens/Edit/Verify/IssueTable.cs +++ b/osu.Game/Screens/Edit/Verify/IssueTable.cs @@ -77,7 +77,7 @@ namespace osu.Game.Screens.Edit.Verify selectedIssue = verify.SelectedIssue.GetBoundCopy(); selectedIssue.BindValueChanged(issue => { - foreach (var b in BackgroundFlow) b.Selected = b.Item == issue.NewValue; + SetRowSelected(issue); }, true); } From 8dcd1a206713f375adde35d6adb80efc9685a29a Mon Sep 17 00:00:00 2001 From: Jai Sharma Date: Sun, 27 Nov 2022 02:48:15 +0000 Subject: [PATCH 0799/2991] Add test to verify selected timing point will be scrolled into view --- .../Visual/Editing/TestSceneTimingScreen.cs | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs b/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs index 86a977fd3f..216c35de65 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneTimingScreen.cs @@ -10,6 +10,8 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Graphics.Containers; using osu.Game.Overlays; using osu.Game.Rulesets.Edit; using osu.Game.Screens.Edit; @@ -26,6 +28,7 @@ namespace osu.Game.Tests.Visual.Editing private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); private TimingScreen timingScreen; + private EditorBeatmap editorBeatmap; protected override bool ScrollUsingMouseWheel => false; @@ -35,8 +38,11 @@ namespace osu.Game.Tests.Visual.Editing Beatmap.Value = CreateWorkingBeatmap(Ruleset.Value); Beatmap.Disabled = true; + } - var editorBeatmap = new EditorBeatmap(Beatmap.Value.GetPlayableBeatmap(Ruleset.Value)); + private void reloadEditorBeatmap() + { + editorBeatmap = new EditorBeatmap(Beatmap.Value.GetPlayableBeatmap(Ruleset.Value)); Child = new DependencyProvidingContainer { @@ -58,7 +64,9 @@ namespace osu.Game.Tests.Visual.Editing { AddStep("Stop clock", () => EditorClock.Stop()); - AddUntilStep("wait for rows to load", () => Child.ChildrenOfType().Any()); + AddStep("Reload Editor Beatmap", reloadEditorBeatmap); + + AddUntilStep("Wait for rows to load", () => Child.ChildrenOfType().Any()); } [Test] @@ -95,6 +103,37 @@ namespace osu.Game.Tests.Visual.Editing AddUntilStep("Selection changed", () => timingScreen.SelectedGroup.Value.Time == 69670); } + [Test] + public void TestScrollControlGroupIntoView() + { + AddStep("Add many control points", () => + { + editorBeatmap.ControlPointInfo.Clear(); + + editorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint()); + + for (int i = 0; i < 100; i++) + { + editorBeatmap.ControlPointInfo.Add((i + 1) * 1000, new EffectControlPoint + { + KiaiMode = Convert.ToBoolean(i % 2), + }); + } + }); + + AddStep("Select first effect point", () => + { + InputManager.MoveMouseTo(Child.ChildrenOfType().First()); + InputManager.Click(MouseButton.Left); + }); + + AddStep("Seek to beginning", () => EditorClock.Seek(0)); + + AddStep("Seek to last point", () => EditorClock.Seek(101 * 1000)); + + AddUntilStep("Scrolled to end", () => timingScreen.ChildrenOfType().First().IsScrolledToEnd()); + } + protected override void Dispose(bool isDisposing) { Beatmap.Disabled = false; From 6000e146681d2feb5423addf7dbbd8edeffa99e6 Mon Sep 17 00:00:00 2001 From: Jai Sharma Date: Sun, 27 Nov 2022 03:08:54 +0000 Subject: [PATCH 0800/2991] Correctly select issue row --- osu.Game/Screens/Edit/Verify/IssueTable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Verify/IssueTable.cs b/osu.Game/Screens/Edit/Verify/IssueTable.cs index 75e7c2e43d..d78108b026 100644 --- a/osu.Game/Screens/Edit/Verify/IssueTable.cs +++ b/osu.Game/Screens/Edit/Verify/IssueTable.cs @@ -77,7 +77,7 @@ namespace osu.Game.Screens.Edit.Verify selectedIssue = verify.SelectedIssue.GetBoundCopy(); selectedIssue.BindValueChanged(issue => { - SetRowSelected(issue); + SetRowSelected(issue.NewValue); }, true); } From 218c04c1749ea4a591bee3ad7b3c1b3fc8ecf57d Mon Sep 17 00:00:00 2001 From: Jai Sharma Date: Sun, 27 Nov 2022 03:23:08 +0000 Subject: [PATCH 0801/2991] Code quality --- osu.Game/Screens/Edit/EditorTable.cs | 2 +- osu.Game/Screens/Edit/Timing/ControlPointTable.cs | 4 ++-- osu.Game/Screens/Edit/Timing/TimingScreen.cs | 2 +- osu.Game/Screens/Edit/Verify/IssueTable.cs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/EditorTable.cs b/osu.Game/Screens/Edit/EditorTable.cs index 7b607e9afc..2443cfcbf0 100644 --- a/osu.Game/Screens/Edit/EditorTable.cs +++ b/osu.Game/Screens/Edit/EditorTable.cs @@ -57,7 +57,7 @@ namespace osu.Game.Screens.Edit } } - protected override Drawable CreateHeader(int index, TableColumn column) => new HeaderText(column?.Header ?? default); + protected override Drawable CreateHeader(int index, TableColumn? column) => new HeaderText(column?.Header ?? default); private partial class HeaderText : OsuSpriteText { diff --git a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs index 464a8e92ad..b3cc41af72 100644 --- a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs +++ b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs @@ -35,7 +35,7 @@ namespace osu.Game.Screens.Edit.Timing Content = null; BackgroundFlow.Clear(); - if (value?.Any() != true) + if (!value.Any()) return; foreach (var group in value) @@ -67,7 +67,7 @@ namespace osu.Game.Screens.Edit.Timing }, true); } - private void updateSelectedGroup() => SetRowSelected(selectedGroup?.Value); + private void updateSelectedGroup() => SetRowSelected(selectedGroup.Value); private TableColumn[] createHeaders() { diff --git a/osu.Game/Screens/Edit/Timing/TimingScreen.cs b/osu.Game/Screens/Edit/Timing/TimingScreen.cs index 2c40add77c..69eff776e6 100644 --- a/osu.Game/Screens/Edit/Timing/TimingScreen.cs +++ b/osu.Game/Screens/Edit/Timing/TimingScreen.cs @@ -141,7 +141,7 @@ namespace osu.Game.Screens.Edit.Timing changeHandler?.SaveState(); }, true); - table.OnRowSelected += (drawable) => scroll.ScrollIntoView(drawable); + table.OnRowSelected += drawable => scroll.ScrollIntoView(drawable); } protected override bool OnClick(ClickEvent e) diff --git a/osu.Game/Screens/Edit/Verify/IssueTable.cs b/osu.Game/Screens/Edit/Verify/IssueTable.cs index d78108b026..b37fb2b72d 100644 --- a/osu.Game/Screens/Edit/Verify/IssueTable.cs +++ b/osu.Game/Screens/Edit/Verify/IssueTable.cs @@ -39,7 +39,7 @@ namespace osu.Game.Screens.Edit.Verify Content = null; BackgroundFlow.Clear(); - if (value == null) + if (!value.Any()) return; foreach (var issue in value) From db7f429e39b892226a30c62cd2635104e14e21af Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 27 Nov 2022 10:44:05 +0100 Subject: [PATCH 0802/2991] Fix partial class issues and adjust test slightly --- .../Visual/UserInterface/TestSceneRangeSlider.cs | 2 +- osu.Game/Graphics/UserInterface/RangeSlider.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs index 189a6b61f5..d0e3ff737c 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneRangeSlider : OsuTestScene + public partial class TestSceneRangeSlider : OsuTestScene { [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Red); diff --git a/osu.Game/Graphics/UserInterface/RangeSlider.cs b/osu.Game/Graphics/UserInterface/RangeSlider.cs index d654adf626..c8306b70fb 100644 --- a/osu.Game/Graphics/UserInterface/RangeSlider.cs +++ b/osu.Game/Graphics/UserInterface/RangeSlider.cs @@ -15,7 +15,7 @@ using osuTK.Graphics; namespace osu.Game.Graphics.UserInterface { - public class RangeSlider : CompositeDrawable + public partial class RangeSlider : CompositeDrawable { /// /// The lower limiting value @@ -125,7 +125,7 @@ namespace osu.Game.Graphics.UserInterface upperBound.Current.ValueChanged += max => lowerBound.Current.Value = Math.Min(max.NewValue - minRange, lowerBound.Current.Value); } - private class LowerBoundSlider : BoundSlider + private partial class LowerBoundSlider : BoundSlider { protected override void LoadComplete() { @@ -142,7 +142,7 @@ namespace osu.Game.Graphics.UserInterface && screenSpacePos.X <= Nub.ScreenSpaceDrawQuad.TopRight.X; } - private class UpperBoundSlider : BoundSlider + private partial class UpperBoundSlider : BoundSlider { protected override void LoadComplete() { @@ -156,7 +156,7 @@ namespace osu.Game.Graphics.UserInterface && screenSpacePos.X >= Nub.ScreenSpaceDrawQuad.TopLeft.X; } - protected class BoundSlider : OsuSliderBar + protected partial class BoundSlider : OsuSliderBar { public string? DefaultString; public LocalisableString? DefaultTooltip; From cff3e06ad6cc68b97e2e80baa5526a7c10ba4746 Mon Sep 17 00:00:00 2001 From: Derrick Timmermans Date: Sun, 27 Nov 2022 20:57:00 +0100 Subject: [PATCH 0803/2991] Update state based on result during LoadComplete --- .../Objects/Drawables/DrawableHitObject.cs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index d6c151028e..4b074f00aa 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -199,7 +199,7 @@ namespace osu.Game.Rulesets.Objects.Drawables comboColourBrightness.BindValueChanged(_ => UpdateComboColour()); // Apply transforms - updateState(State.Value, true); + updateStateBasedOnResults(); } /// @@ -266,12 +266,7 @@ namespace osu.Game.Rulesets.Objects.Drawables // If not loaded, the state update happens in LoadComplete(). if (IsLoaded) { - if (Result.IsHit) - updateState(ArmedState.Hit, true); - else if (Result.HasResult) - updateState(ArmedState.Miss, true); - else - updateState(ArmedState.Idle, true); + updateStateBasedOnResults(); // Combo colour may have been applied via a bindable flow while no object entry was attached. // Update here to ensure we're in a good state. @@ -279,6 +274,16 @@ namespace osu.Game.Rulesets.Objects.Drawables } } + private void updateStateBasedOnResults() + { + if (Result.IsHit) + updateState(ArmedState.Hit, true); + else if (Result.HasResult) + updateState(ArmedState.Miss, true); + else + updateState(ArmedState.Idle, true); + } + protected sealed override void OnFree(HitObjectLifetimeEntry entry) { StartTimeBindable.UnbindFrom(HitObject.StartTimeBindable); From 70c320b2e8efef9ea3775513a547310b2f022440 Mon Sep 17 00:00:00 2001 From: Derrick Timmermans Date: Sun, 27 Nov 2022 21:43:33 +0100 Subject: [PATCH 0804/2991] Provide ruleset dependencies only to Compose Placement Blueprints --- .../Edit/CatchBlueprintContainer.cs | 4 +-- .../Edit/CatchHitObjectComposer.cs | 2 +- .../Edit/ManiaBlueprintContainer.cs | 4 +-- .../Edit/ManiaHitObjectComposer.cs | 2 +- .../Edit/OsuBlueprintContainer.cs | 4 +-- .../Edit/OsuHitObjectComposer.cs | 2 +- .../Edit/TaikoBlueprintContainer.cs | 4 +-- .../Edit/TaikoHitObjectComposer.cs | 2 +- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 13 ++----- ...leRulesetDependenciesProvidingContainer.cs | 34 +++++++++++++++++++ .../Components/ComposeBlueprintContainer.cs | 13 +++++-- 11 files changed, 60 insertions(+), 24 deletions(-) create mode 100644 osu.Game/Rulesets/UI/DrawableRulesetDependenciesProvidingContainer.cs diff --git a/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs b/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs index a0a11424d0..19642c521e 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs @@ -13,8 +13,8 @@ namespace osu.Game.Rulesets.Catch.Edit { public class CatchBlueprintContainer : ComposeBlueprintContainer { - public CatchBlueprintContainer(CatchHitObjectComposer composer) - : base(composer) + public CatchBlueprintContainer(CatchHitObjectComposer composer, Ruleset ruleset) + : base(composer, ruleset) { } diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index 220bc49203..7cc65a834a 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -148,7 +148,7 @@ namespace osu.Game.Rulesets.Catch.Edit return result; } - protected override ComposeBlueprintContainer CreateBlueprintContainer() => new CatchBlueprintContainer(this); + protected override ComposeBlueprintContainer CreateBlueprintContainer() => new CatchBlueprintContainer(this, Ruleset); [CanBeNull] private PalpableCatchHitObject getLastSnappableHitObject(double time) diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs index f438d6497c..597e94396a 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs @@ -13,8 +13,8 @@ namespace osu.Game.Rulesets.Mania.Edit { public class ManiaBlueprintContainer : ComposeBlueprintContainer { - public ManiaBlueprintContainer(HitObjectComposer composer) - : base(composer) + public ManiaBlueprintContainer(HitObjectComposer composer, Ruleset ruleset) + : base(composer, ruleset) { } diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs index 3585fd4e8c..529cf77078 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Mania.Edit } protected override ComposeBlueprintContainer CreateBlueprintContainer() - => new ManiaBlueprintContainer(this); + => new ManiaBlueprintContainer(this, Ruleset); protected override IReadOnlyList CompositionTools => new HitObjectCompositionTool[] { diff --git a/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs index c0fb0ae7db..7330ed6bb9 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs @@ -15,8 +15,8 @@ namespace osu.Game.Rulesets.Osu.Edit { public class OsuBlueprintContainer : ComposeBlueprintContainer { - public OsuBlueprintContainer(HitObjectComposer composer) - : base(composer) + public OsuBlueprintContainer(HitObjectComposer composer, Ruleset ruleset) + : base(composer, ruleset) { } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 1460fae4d7..c044b2cc79 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.Osu.Edit } protected override ComposeBlueprintContainer CreateBlueprintContainer() - => new OsuBlueprintContainer(this); + => new OsuBlueprintContainer(this, Ruleset); public override string ConvertSelectionToString() => string.Join(',', selectedHitObjects.Cast().OrderBy(h => h.StartTime).Select(h => (h.IndexInCurrentCombo + 1).ToString())); diff --git a/osu.Game.Rulesets.Taiko/Edit/TaikoBlueprintContainer.cs b/osu.Game.Rulesets.Taiko/Edit/TaikoBlueprintContainer.cs index 6107c8009a..b149fbcd4b 100644 --- a/osu.Game.Rulesets.Taiko/Edit/TaikoBlueprintContainer.cs +++ b/osu.Game.Rulesets.Taiko/Edit/TaikoBlueprintContainer.cs @@ -12,8 +12,8 @@ namespace osu.Game.Rulesets.Taiko.Edit { public class TaikoBlueprintContainer : ComposeBlueprintContainer { - public TaikoBlueprintContainer(HitObjectComposer composer) - : base(composer) + public TaikoBlueprintContainer(HitObjectComposer composer, Ruleset ruleset) + : base(composer, ruleset) { } diff --git a/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs b/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs index 161799c980..1b6a4a1cdf 100644 --- a/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs +++ b/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs @@ -24,6 +24,6 @@ namespace osu.Game.Rulesets.Taiko.Edit }; protected override ComposeBlueprintContainer CreateBlueprintContainer() - => new TaikoBlueprintContainer(this); + => new TaikoBlueprintContainer(this, Ruleset); } } diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index d0164d0f2e..dea28667c6 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Edit protected readonly Ruleset Ruleset; // Provides `Playfield` - private DrawableRulesetDependencies dependencies; + private DependencyContainer dependencies; [Resolved] protected EditorClock EditorClock { get; private set; } @@ -79,7 +79,7 @@ namespace osu.Game.Rulesets.Edit } protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) => - dependencies = new DrawableRulesetDependencies(Ruleset, base.CreateChildDependencies(parent)); + dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -218,7 +218,7 @@ namespace osu.Game.Rulesets.Edit /// /// Construct a relevant blueprint container. This will manage hitobject selection/placement input handling and display logic. /// - protected virtual ComposeBlueprintContainer CreateBlueprintContainer() => new ComposeBlueprintContainer(this); + protected virtual ComposeBlueprintContainer CreateBlueprintContainer() => new ComposeBlueprintContainer( this, Ruleset); /// /// Construct a drawable ruleset for the provided ruleset. @@ -410,13 +410,6 @@ namespace osu.Game.Rulesets.Edit } #endregion - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - dependencies.Dispose(); - } } /// diff --git a/osu.Game/Rulesets/UI/DrawableRulesetDependenciesProvidingContainer.cs b/osu.Game/Rulesets/UI/DrawableRulesetDependenciesProvidingContainer.cs new file mode 100644 index 0000000000..414cfe3a97 --- /dev/null +++ b/osu.Game/Rulesets/UI/DrawableRulesetDependenciesProvidingContainer.cs @@ -0,0 +1,34 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; + +namespace osu.Game.Rulesets.UI +{ + public class DrawableRulesetDependenciesProvidingContainer : Container + { + private Ruleset ruleset; + + private DrawableRulesetDependencies rulesetDependencies = null!; + + public DrawableRulesetDependenciesProvidingContainer(Ruleset ruleset) + { + this.ruleset = ruleset; + RelativeSizeAxes = Axes.Both; + } + + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) + { + return rulesetDependencies = new DrawableRulesetDependencies(ruleset, base.CreateChildDependencies(parent)); + } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + rulesetDependencies?.Dispose(); + } + } +} diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index ec07da43a0..c1100c3d7f 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -15,11 +15,13 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Audio; using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.UI; using osu.Game.Screens.Edit.Components.TernaryButtons; using osuTK; using osuTK.Input; @@ -37,15 +39,19 @@ namespace osu.Game.Screens.Edit.Compose.Components private PlacementBlueprint currentPlacement; + private readonly Ruleset ruleset; + /// /// Positional input must be received outside the container's bounds, /// in order to handle composer blueprints which are partially offscreen. /// public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; - public ComposeBlueprintContainer(HitObjectComposer composer) + public ComposeBlueprintContainer(HitObjectComposer composer, Ruleset ruleset) : base(composer) { + this.ruleset = ruleset; + placementBlueprintContainer = new Container { RelativeSizeAxes = Axes.Both @@ -57,7 +63,10 @@ namespace osu.Game.Screens.Edit.Compose.Components { TernaryStates = CreateTernaryButtons().ToArray(); - AddInternal(placementBlueprintContainer); + AddInternal(new DrawableRulesetDependenciesProvidingContainer(ruleset) + { + Child = placementBlueprintContainer + }); } protected override void LoadComplete() From 93ba84e5ff187db13f5a368101722f9226ebfed3 Mon Sep 17 00:00:00 2001 From: Derrick Timmermans Date: Sun, 27 Nov 2022 21:48:44 +0100 Subject: [PATCH 0805/2991] Fix code style --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 2 +- .../UI/DrawableRulesetDependenciesProvidingContainer.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index dea28667c6..cf10c9deca 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -218,7 +218,7 @@ namespace osu.Game.Rulesets.Edit /// /// Construct a relevant blueprint container. This will manage hitobject selection/placement input handling and display logic. /// - protected virtual ComposeBlueprintContainer CreateBlueprintContainer() => new ComposeBlueprintContainer( this, Ruleset); + protected virtual ComposeBlueprintContainer CreateBlueprintContainer() => new ComposeBlueprintContainer(this, Ruleset); /// /// Construct a drawable ruleset for the provided ruleset. diff --git a/osu.Game/Rulesets/UI/DrawableRulesetDependenciesProvidingContainer.cs b/osu.Game/Rulesets/UI/DrawableRulesetDependenciesProvidingContainer.cs index 414cfe3a97..1efe72fdf3 100644 --- a/osu.Game/Rulesets/UI/DrawableRulesetDependenciesProvidingContainer.cs +++ b/osu.Game/Rulesets/UI/DrawableRulesetDependenciesProvidingContainer.cs @@ -7,9 +7,9 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Rulesets.UI { - public class DrawableRulesetDependenciesProvidingContainer : Container + public partial class DrawableRulesetDependenciesProvidingContainer : Container { - private Ruleset ruleset; + private readonly Ruleset ruleset; private DrawableRulesetDependencies rulesetDependencies = null!; From ba1717c2ca9710dbaaf4ab146d7c51fd018f3abb Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 29 Nov 2022 02:36:27 +0300 Subject: [PATCH 0806/2991] Don't draw 0 thickness triangles --- osu.Game/Graphics/Backgrounds/TrianglesV2.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs index 6e9e7591a8..ed9b6019f1 100644 --- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs +++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs @@ -256,7 +256,7 @@ namespace osu.Game.Graphics.Backgrounds { base.Draw(renderer); - if (Source.AimCount == 0) + if (Source.AimCount == 0 || thickness == 0) return; if (vertexBatch == null || vertexBatch.Size != Source.AimCount) From 3e277a92e963bb709e22a3625edae25dc9f2f4b5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 29 Nov 2022 03:21:59 +0300 Subject: [PATCH 0807/2991] Fix incorrect texel size calculation --- osu.Game/Graphics/Backgrounds/TrianglesV2.cs | 30 ++++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs index ed9b6019f1..6e6514690d 100644 --- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs +++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs @@ -227,6 +227,9 @@ namespace osu.Game.Graphics.Backgrounds private Texture texture = null!; private readonly List parts = new List(); + + private readonly Vector2 triangleSize = new Vector2(1f, equilateral_triangle_ratio) * triangle_size; + private Vector2 size; private float thickness; private float texelSize; @@ -246,7 +249,15 @@ namespace osu.Game.Graphics.Backgrounds texture = Source.texture; size = Source.DrawSize; thickness = Source.Thickness; - texelSize = Math.Max(1.5f / Source.ScreenSpaceDrawQuad.Size.X, 1.5f / Source.ScreenSpaceDrawQuad.Size.Y); + + Quad triangleQuad = new Quad( + Vector2Extensions.Transform(Vector2.Zero, DrawInfo.Matrix), + Vector2Extensions.Transform(new Vector2(triangle_size, 0f), DrawInfo.Matrix), + Vector2Extensions.Transform(new Vector2(0f, triangleSize.Y), DrawInfo.Matrix), + Vector2Extensions.Transform(triangleSize, DrawInfo.Matrix) + ); + + texelSize = 1.5f / triangleQuad.Height; parts.Clear(); parts.AddRange(Source.parts); @@ -269,14 +280,15 @@ namespace osu.Game.Graphics.Backgrounds shader.GetUniform("thickness").UpdateValue(ref thickness); shader.GetUniform("texelSize").UpdateValue(ref texelSize); + float texturePartWidth = triangleSize.X / size.X; + float texturePartHeight = triangleSize.Y / size.Y * texture_height; + foreach (TriangleParticle particle in parts) { - var offset = triangle_size * new Vector2(0.5f, equilateral_triangle_ratio); - - Vector2 topLeft = particle.Position * size + new Vector2(-offset.X, 0f); - Vector2 topRight = particle.Position * size + new Vector2(offset.X, 0); - Vector2 bottomLeft = particle.Position * size + new Vector2(-offset.X, offset.Y); - Vector2 bottomRight = particle.Position * size + new Vector2(offset.X, offset.Y); + Vector2 topLeft = particle.Position * size - new Vector2(triangleSize.X * 0.5f, 0f); + Vector2 topRight = topLeft + new Vector2(triangleSize.X, 0f); + Vector2 bottomLeft = topLeft + new Vector2(0f, triangleSize.Y); + Vector2 bottomRight = topLeft + triangleSize; var drawQuad = new Quad( Vector2Extensions.Transform(topLeft, DrawInfo.Matrix), @@ -288,8 +300,8 @@ namespace osu.Game.Graphics.Backgrounds var tRect = new Quad( topLeft.X / size.X, topLeft.Y / size.Y * texture_height, - (topRight.X - topLeft.X) / size.X, - (bottomRight.Y - topRight.Y) / size.Y * texture_height + texturePartWidth, + texturePartHeight ).AABBFloat; renderer.DrawQuad(texture, drawQuad, DrawColourInfo.Colour, tRect, vertexBatch.AddAction, textureCoords: tRect); From c2d8ffc225f8a9e8a4cde803f0d03d3927771465 Mon Sep 17 00:00:00 2001 From: Alden Wu Date: Mon, 28 Nov 2022 17:50:12 -0800 Subject: [PATCH 0808/2991] Refactor `ChatLine` username drawable creation --- .../Visual/Online/TestSceneChatLink.cs | 4 +- osu.Game/Online/Chat/StandAloneChatDisplay.cs | 2 +- osu.Game/Overlays/Chat/ChatLine.cs | 367 ++++++++++-------- 3 files changed, 199 insertions(+), 174 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs index de44986001..3bb8b948d0 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs @@ -130,11 +130,11 @@ namespace osu.Game.Tests.Visual.Online Color4 textColour = isAction && hasBackground ? Color4Extensions.FromHex(newLine.Message.Sender.Colour) : Color4.White; - var linkCompilers = newLine.ContentFlow.Where(d => d is DrawableLinkCompiler).ToList(); + var linkCompilers = newLine.DrawableContentFlow.Where(d => d is DrawableLinkCompiler).ToList(); var linkSprites = linkCompilers.SelectMany(comp => ((DrawableLinkCompiler)comp).Parts); return linkSprites.All(d => d.Colour == linkColour) - && newLine.ContentFlow.Except(linkSprites.Concat(linkCompilers)).All(d => d.Colour == textColour); + && newLine.DrawableContentFlow.Except(linkSprites.Concat(linkCompilers)).All(d => d.Colour == textColour); } } } diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs index 81db3f0d53..667ba8c742 100644 --- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs +++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs @@ -189,7 +189,7 @@ namespace osu.Game.Online.Chat protected class StandAloneMessage : ChatLine { - protected override float TextSize => 15; + protected override float FontSize => 15; protected override float Spacing => 5; protected override float UsernameWidth => 75; diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index bfbffabd2b..422dcf63df 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -24,11 +24,15 @@ using osu.Game.Online.Chat; using osuTK; using osuTK.Graphics; using osu.Framework.Input.Events; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; namespace osu.Game.Overlays.Chat { public class ChatLine : CompositeDrawable { + private Message message = null!; + public Message Message { get => message; @@ -45,55 +49,35 @@ namespace osu.Game.Overlays.Chat } } - public LinkFlowContainer ContentFlow { get; private set; } = null!; + public IReadOnlyCollection DrawableContentFlow => drawableContentFlow; - protected virtual float TextSize => 20; + protected virtual float FontSize => 20; protected virtual float Spacing => 15; protected virtual float UsernameWidth => 130; - private Color4 usernameColour; - - private OsuSpriteText timestamp = null!; - - private Message message = null!; - - private OsuSpriteText username = null!; - - private Drawable usernameColouredDrawable = null!; - - private Container? highlight; - - private readonly Bindable prefer24HourTime = new Bindable(); - - private bool senderHasColour => !string.IsNullOrEmpty(message.Sender.Colour); - - private bool messageHasColour => Message.IsAction && senderHasColour; - [Resolved] private ChannelManager? chatManager { get; set; } [Resolved] - private OsuColour colours { get; set; } = null!; + private OverlayColourProvider? colourProvider { get; set; } + + private readonly OsuSpriteText drawableTimestamp; + + private readonly DrawableUsername drawableUsername; + + private readonly LinkFlowContainer drawableContentFlow; + + private readonly Bindable prefer24HourTime = new Bindable(); + + private Container? highlight; public ChatLine(Message message) { Message = message; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - } - - [BackgroundDependencyLoader] - private void load(OverlayColourProvider? colourProvider, OsuConfigManager configManager) - { - usernameColour = senderHasColour - ? Color4Extensions.FromHex(message.Sender.Colour) - : username_colours[message.Sender.Id % username_colours.Length]; - - // this can be either the username sprite text or a container - // around it depending on which branch is taken in createUsername() - var usernameDrawable = createUsername(); InternalChild = new GridContainer { @@ -110,30 +94,24 @@ namespace osu.Game.Overlays.Chat { new Drawable[] { - timestamp = new OsuSpriteText + drawableTimestamp = new OsuSpriteText { Shadow = false, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: TextSize * 0.75f, weight: FontWeight.SemiBold, fixedWidth: true), - Colour = colourProvider?.Background1 ?? Colour4.White, + Font = OsuFont.GetFont(size: FontSize * 0.75f, weight: FontWeight.SemiBold, fixedWidth: true), AlwaysPresent = true, }, - new MessageSender(message.Sender, usernameColouredDrawable) + drawableUsername = new DrawableUsername(message.Sender) { Width = UsernameWidth, + FontSize = FontSize, AutoSizeAxes = Axes.Y, Origin = Anchor.TopRight, Anchor = Anchor.TopRight, - Child = usernameDrawable, Margin = new MarginPadding { Horizontal = Spacing }, }, - ContentFlow = new LinkFlowContainer(t => - { - t.Shadow = false; - t.Font = t.Font.With(size: TextSize, italics: Message.IsAction); - t.Colour = messageHasColour ? Color4Extensions.FromHex(message.Sender.Colour) : colourProvider?.Content1 ?? Colour4.White; - }) + drawableContentFlow = new LinkFlowContainer(styleMessageContent) { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, @@ -141,18 +119,23 @@ namespace osu.Game.Overlays.Chat }, } }; + } + [BackgroundDependencyLoader] + private void load(OsuConfigManager configManager) + { configManager.BindWith(OsuSetting.Prefer24HourTime, prefer24HourTime); + prefer24HourTime.BindValueChanged(_ => updateTimestamp()); } protected override void LoadComplete() { base.LoadComplete(); + drawableTimestamp.Colour = colourProvider?.Background1 ?? Colour4.White; + updateMessageContent(); FinishTransforms(true); - - prefer24HourTime.BindValueChanged(_ => updateTimestamp()); } /// @@ -167,7 +150,7 @@ namespace osu.Game.Overlays.Chat CornerRadius = 2f, Masking = true, RelativeSizeAxes = Axes.Both, - Colour = usernameColour.Darken(1f), + Colour = drawableUsername.Colour.Darken(1f), Depth = float.MaxValue, Child = new Box { RelativeSizeAxes = Axes.Both } }); @@ -177,140 +160,182 @@ namespace osu.Game.Overlays.Chat highlight.Expire(); } + private void styleMessageContent(SpriteText text) + { + text.Shadow = false; + text.Font = text.Font.With(size: FontSize, italics: Message.IsAction); + + bool messageHasColour = Message.IsAction && !string.IsNullOrEmpty(message.Sender.Colour); + text.Colour = messageHasColour ? Color4Extensions.FromHex(message.Sender.Colour) : colourProvider?.Content1 ?? Colour4.White; + } + private void updateMessageContent() { this.FadeTo(message is LocalEchoMessage ? 0.4f : 1.0f, 500, Easing.OutQuint); - timestamp.FadeTo(message is LocalEchoMessage ? 0 : 1, 500, Easing.OutQuint); + drawableTimestamp.FadeTo(message is LocalEchoMessage ? 0 : 1, 500, Easing.OutQuint); updateTimestamp(); - username.Text = $@"{message.Sender.Username}"; + drawableUsername.Text = $@"{message.Sender.Username}"; // remove non-existent channels from the link list message.Links.RemoveAll(link => link.Action == LinkAction.OpenChannel && chatManager?.AvailableChannels.Any(c => c.Name == link.Argument.ToString()) != true); - ContentFlow.Clear(); - ContentFlow.AddLinks(message.DisplayContent, message.Links); + drawableContentFlow.Clear(); + drawableContentFlow.AddLinks(message.DisplayContent, message.Links); } private void updateTimestamp() { - timestamp.Text = prefer24HourTime.Value + drawableTimestamp.Text = prefer24HourTime.Value ? $@"{message.Timestamp.LocalDateTime:HH:mm:ss}" : $@"{message.Timestamp.LocalDateTime:hh:mm:ss tt}"; } - private Drawable createUsername() + private class DrawableUsername : OsuClickableContainer, IHasContextMenu { - username = new OsuSpriteText - { - Shadow = false, - Truncate = true, - EllipsisString = "…", - Font = OsuFont.GetFont(size: TextSize, weight: FontWeight.Bold, italics: true), - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - MaxWidth = UsernameWidth, - }; + public new Color4 Colour { get; private set; } - if (!senderHasColour) + public float FontSize { - usernameColouredDrawable = username; - usernameColouredDrawable.Colour = usernameColour; - return username; + set => drawableText.Font = OsuFont.GetFont(size: value, weight: FontWeight.Bold, italics: true); } - username.Colour = colours.ChatBlue; - - // Background effect - return new Container + public LocalisableString Text { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Both, - Masking = true, - CornerRadius = 4, - EdgeEffect = new EdgeEffectParameters - { - Roundness = 1, - Radius = 1, - Colour = Color4.Black.Opacity(0.3f), - Offset = new Vector2(0, 1), - Type = EdgeEffectType.Shadow, - }, - Child = new Container - { - AutoSizeAxes = Axes.Both, - Masking = true, - CornerRadius = 4, - Children = new Drawable[] - { - usernameColouredDrawable = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = usernameColour, - }, - new Container - { - AutoSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = 4, Right = 4, Bottom = 1, Top = -2 }, - Child = username - } - } - } - }; - } + set => drawableText.Text = value; + } - private class MessageSender : OsuClickableContainer, IHasContextMenu - { - private readonly APIUser sender; - private readonly Drawable colouredDrawable; - private readonly Color4 defaultColour; + public override float Width + { + get => base.Width; + set => base.Width = drawableText.MaxWidth = value; + } - private Action startChatAction = null!; - - [Resolved] + [Resolved(canBeNull: false)] private IAPIProvider api { get; set; } = null!; - public MessageSender(APIUser sender, Drawable colouredDrawable) + [Resolved(canBeNull: false)] + private OsuColour osuColours { get; set; } = null!; + + [Resolved] + private ChannelManager? chatManager { get; set; } + + [Resolved] + private ChatOverlay? chatOverlay { get; set; } + + [Resolved] + private UserProfileOverlay? profileOverlay { get; set; } + + private readonly APIUser user; + private readonly OsuSpriteText drawableText; + + private readonly Drawable colouredDrawable; + + public DrawableUsername(APIUser user) { - this.sender = sender; - this.colouredDrawable = colouredDrawable; - defaultColour = colouredDrawable.Colour; + this.user = user; + + Action = openUserProfile; + + drawableText = new OsuSpriteText + { + Shadow = false, + Truncate = true, + EllipsisString = "…", + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + }; + + if (string.IsNullOrWhiteSpace(user.Colour)) + { + Colour = default_colours[user.Id % default_colours.Length]; + + Child = colouredDrawable = drawableText; + } + else + { + + Colour = Color4Extensions.FromHex(user.Colour); + + Child = new Container + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Masking = true, + CornerRadius = 4, + EdgeEffect = new EdgeEffectParameters + { + Roundness = 1, + Radius = 1, + Colour = Color4.Black.Opacity(0.3f), + Offset = new Vector2(0, 1), + Type = EdgeEffectType.Shadow, + }, + Child = new Container + { + AutoSizeAxes = Axes.Both, + Masking = true, + CornerRadius = 4, + Children = new[] + { + colouredDrawable = new Box + { + RelativeSizeAxes = Axes.Both, + }, + new Container + { + AutoSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = 4, Right = 4, Bottom = 1, Top = -2 }, + Child = drawableText, + } + } + } + }; + } } - [BackgroundDependencyLoader] - private void load(UserProfileOverlay? profile, ChannelManager? chatManager, ChatOverlay? chatOverlay) + protected override void LoadComplete() { - Action = () => profile?.ShowUser(sender); - startChatAction = () => - { - chatManager?.OpenPrivateChannel(sender); - chatOverlay?.Show(); - }; + base.LoadComplete(); + + drawableText.Colour = osuColours.ChatBlue; + colouredDrawable.Colour = Colour; } public MenuItem[] ContextMenuItems { get { - if (sender.Equals(APIUser.SYSTEM_USER)) + if (user.Equals(APIUser.SYSTEM_USER)) return Array.Empty(); List items = new List { - new OsuMenuItem("View Profile", MenuItemType.Highlighted, Action) + new OsuMenuItem("View Profile", MenuItemType.Highlighted, openUserProfile) }; - if (!sender.Equals(api.LocalUser.Value)) - items.Add(new OsuMenuItem("Start Chat", MenuItemType.Standard, startChatAction)); + if (!user.Equals(api.LocalUser.Value)) + items.Add(new OsuMenuItem("Start Chat", MenuItemType.Standard, openUserChannel)); return items.ToArray(); } } + private void openUserChannel() + { + chatManager?.OpenPrivateChannel(user); + chatOverlay?.Show(); + } + + private void openUserProfile() + { + profileOverlay?.ShowUser(user); + } + protected override bool OnHover(HoverEvent e) { - colouredDrawable.FadeColour(defaultColour.Lighten(0.4f), 150, Easing.OutQuint); + colouredDrawable.FadeColour(Colour.Lighten(0.4f), 150, Easing.OutQuint); return base.OnHover(e); } @@ -319,47 +344,47 @@ namespace osu.Game.Overlays.Chat { base.OnHoverLost(e); - colouredDrawable.FadeColour(defaultColour, 250, Easing.OutQuint); + colouredDrawable.FadeColour(Colour, 250, Easing.OutQuint); } + + private static readonly Color4[] default_colours = + { + Color4Extensions.FromHex("588c7e"), + Color4Extensions.FromHex("b2a367"), + Color4Extensions.FromHex("c98f65"), + Color4Extensions.FromHex("bc5151"), + Color4Extensions.FromHex("5c8bd6"), + Color4Extensions.FromHex("7f6ab7"), + Color4Extensions.FromHex("a368ad"), + Color4Extensions.FromHex("aa6880"), + + Color4Extensions.FromHex("6fad9b"), + Color4Extensions.FromHex("f2e394"), + Color4Extensions.FromHex("f2ae72"), + Color4Extensions.FromHex("f98f8a"), + Color4Extensions.FromHex("7daef4"), + Color4Extensions.FromHex("a691f2"), + Color4Extensions.FromHex("c894d3"), + Color4Extensions.FromHex("d895b0"), + + Color4Extensions.FromHex("53c4a1"), + Color4Extensions.FromHex("eace5c"), + Color4Extensions.FromHex("ea8c47"), + Color4Extensions.FromHex("fc4f4f"), + Color4Extensions.FromHex("3d94ea"), + Color4Extensions.FromHex("7760ea"), + Color4Extensions.FromHex("af52c6"), + Color4Extensions.FromHex("e25696"), + + Color4Extensions.FromHex("677c66"), + Color4Extensions.FromHex("9b8732"), + Color4Extensions.FromHex("8c5129"), + Color4Extensions.FromHex("8c3030"), + Color4Extensions.FromHex("1f5d91"), + Color4Extensions.FromHex("4335a5"), + Color4Extensions.FromHex("812a96"), + Color4Extensions.FromHex("992861"), + }; } - - private static readonly Color4[] username_colours = - { - Color4Extensions.FromHex("588c7e"), - Color4Extensions.FromHex("b2a367"), - Color4Extensions.FromHex("c98f65"), - Color4Extensions.FromHex("bc5151"), - Color4Extensions.FromHex("5c8bd6"), - Color4Extensions.FromHex("7f6ab7"), - Color4Extensions.FromHex("a368ad"), - Color4Extensions.FromHex("aa6880"), - - Color4Extensions.FromHex("6fad9b"), - Color4Extensions.FromHex("f2e394"), - Color4Extensions.FromHex("f2ae72"), - Color4Extensions.FromHex("f98f8a"), - Color4Extensions.FromHex("7daef4"), - Color4Extensions.FromHex("a691f2"), - Color4Extensions.FromHex("c894d3"), - Color4Extensions.FromHex("d895b0"), - - Color4Extensions.FromHex("53c4a1"), - Color4Extensions.FromHex("eace5c"), - Color4Extensions.FromHex("ea8c47"), - Color4Extensions.FromHex("fc4f4f"), - Color4Extensions.FromHex("3d94ea"), - Color4Extensions.FromHex("7760ea"), - Color4Extensions.FromHex("af52c6"), - Color4Extensions.FromHex("e25696"), - - Color4Extensions.FromHex("677c66"), - Color4Extensions.FromHex("9b8732"), - Color4Extensions.FromHex("8c5129"), - Color4Extensions.FromHex("8c3030"), - Color4Extensions.FromHex("1f5d91"), - Color4Extensions.FromHex("4335a5"), - Color4Extensions.FromHex("812a96"), - Color4Extensions.FromHex("992861"), - }; } } From 8ec4dd046ee7a18ab59df4c4881815e208a0ff0b Mon Sep 17 00:00:00 2001 From: Alden Wu Date: Mon, 28 Nov 2022 18:06:44 -0800 Subject: [PATCH 0809/2991] Fix InspectCode errors --- osu.Game/Overlays/Chat/ChatLine.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index ad33f54848..e974db9fba 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -254,7 +254,6 @@ namespace osu.Game.Overlays.Chat } else { - Colour = Color4Extensions.FromHex(user.Colour); Child = new Container From 8b033bf9f79e50b6d752e1da867357ae21fe94bb Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 05:13:54 +0300 Subject: [PATCH 0810/2991] Allow localisable strings --- .../Visual/UserInterface/TestSceneCommentEditor.cs | 13 +++++++------ osu.Game/Overlays/Comments/CommentEditor.cs | 11 ++++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index 99e1702870..596518a015 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -8,6 +8,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Localisation; using osu.Game.Overlays; using osu.Game.Overlays.Comments; using osuTK; @@ -121,15 +122,15 @@ namespace osu.Game.Tests.Visual.UserInterface Scheduler.AddDelayed(() => IsLoading = false, 1000); } - protected override string FooterText => @"Footer text. And it is pretty long. Cool."; - protected override string CommitButtonText => @"Commit"; - protected override string TextBoxPlaceholder => @"This text box is empty"; + protected override LocalisableString FooterText => @"Footer text. And it is pretty long. Cool."; + protected override LocalisableString CommitButtonText => @"Commit"; + protected override LocalisableString TextBoxPlaceholder => @"This text box is empty"; } private partial class TestCancellableCommentEditor : CancellableCommentEditor { public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; - protected override string FooterText => @"Wow, another one. Sicc"; + protected override LocalisableString FooterText => @"Wow, another one. Sicc"; public bool Cancelled { get; private set; } @@ -138,8 +139,8 @@ namespace osu.Game.Tests.Visual.UserInterface OnCancel = () => Cancelled = true; } - protected override string CommitButtonText => @"Save"; - protected override string TextBoxPlaceholder => @"Multiline textboxes soon"; + protected override LocalisableString CommitButtonText => @"Save"; + protected override LocalisableString TextBoxPlaceholder => @"Multiline textboxes soon"; } } } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 72edd1877e..f79439452b 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -17,6 +17,7 @@ using System.Collections.Generic; using System; using osuTK; using osu.Framework.Bindables; +using osu.Framework.Localisation; namespace osu.Game.Overlays.Comments { @@ -32,11 +33,11 @@ namespace osu.Game.Overlays.Comments set => commitButton.IsLoading = value; } - protected abstract string FooterText { get; } + protected abstract LocalisableString FooterText { get; } - protected abstract string CommitButtonText { get; } + protected abstract LocalisableString CommitButtonText { get; } - protected abstract string TextBoxPlaceholder { get; } + protected abstract LocalisableString TextBoxPlaceholder { get; } protected FillFlowContainer ButtonsContainer { get; private set; } @@ -177,7 +178,7 @@ namespace osu.Game.Overlays.Comments protected override IEnumerable EffectTargets => new[] { background }; - private readonly string text; + private readonly LocalisableString text; [Resolved] private OverlayColourProvider colourProvider { get; set; } @@ -186,7 +187,7 @@ namespace osu.Game.Overlays.Comments private Box background; private Box blockedBackground; - public CommitButton(string text) + public CommitButton(LocalisableString text) { this.text = text; From d20dc3668ec790d3d0fea7ad85c8a52db60a305b Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 05:17:44 +0300 Subject: [PATCH 0811/2991] Enable nullability --- .../UserInterface/TestSceneCommentEditor.cs | 8 +++---- .../Comments/CancellableCommentEditor.cs | 4 +--- osu.Game/Overlays/Comments/CommentEditor.cs | 22 +++++++++---------- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index 596518a015..e5fbb8c5d0 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -21,8 +19,8 @@ namespace osu.Game.Tests.Visual.UserInterface [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); - private TestCommentEditor commentEditor; - private TestCancellableCommentEditor cancellableCommentEditor; + private TestCommentEditor commentEditor = null!; + private TestCancellableCommentEditor cancellableCommentEditor = null!; [SetUp] public void SetUp() => Schedule(() => @@ -109,7 +107,7 @@ namespace osu.Game.Tests.Visual.UserInterface public new Bindable Current => base.Current; public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; - public string CommittedText { get; private set; } + public string? CommittedText { get; private set; } public TestCommentEditor() { diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs index 2b597d5638..8f6863b949 100644 --- a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using osu.Framework.Allocation; @@ -19,7 +17,7 @@ namespace osu.Game.Overlays.Comments { public abstract partial class CancellableCommentEditor : CommentEditor { - public Action OnCancel; + public Action? OnCancel; [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index f79439452b..b7fc4f097c 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; @@ -25,7 +23,7 @@ namespace osu.Game.Overlays.Comments { private const int side_padding = 8; - public Action OnCommit; + public Action? OnCommit; public bool IsLoading { @@ -39,11 +37,11 @@ namespace osu.Game.Overlays.Comments protected abstract LocalisableString TextBoxPlaceholder { get; } - protected FillFlowContainer ButtonsContainer { get; private set; } + protected FillFlowContainer ButtonsContainer { get; private set; } = null!; protected readonly Bindable Current = new Bindable(); - private CommitButton commitButton; + private CommitButton commitButton = null!; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -80,7 +78,7 @@ namespace osu.Game.Overlays.Comments }, new Container { - Name = "Footer", + Name = @"Footer", RelativeSizeAxes = Axes.X, Height = 35, Padding = new MarginPadding { Horizontal = side_padding }, @@ -95,7 +93,7 @@ namespace osu.Game.Overlays.Comments }, ButtonsContainer = new FillFlowContainer { - Name = "Buttons", + Name = @"Buttons", Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, AutoSizeAxes = Axes.Both, @@ -140,7 +138,7 @@ namespace osu.Game.Overlays.Comments protected override Color4 SelectionColour => Color4.Gray; - private OsuSpriteText placeholder; + private OsuSpriteText placeholder = null!; public EditorTextBox() { @@ -181,11 +179,11 @@ namespace osu.Game.Overlays.Comments private readonly LocalisableString text; [Resolved] - private OverlayColourProvider colourProvider { get; set; } + private OverlayColourProvider colourProvider { get; set; } = null!; - private OsuSpriteText drawableText; - private Box background; - private Box blockedBackground; + private OsuSpriteText drawableText = null!; + private Box background = null!; + private Box blockedBackground = null!; public CommitButton(LocalisableString text) { From 25ddd20b2e2195ae209baa52d83b7a209377a134 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 05:44:40 +0300 Subject: [PATCH 0812/2991] Allow OsuButton be auto-sized --- osu.Game/Graphics/UserInterface/OsuButton.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index fa61b06cff..69e8dfef84 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -175,6 +175,17 @@ namespace osu.Game.Graphics.UserInterface base.OnMouseUp(e); } + public new Axes AutoSizeAxes + { + get => base.AutoSizeAxes; + set + { + base.AutoSizeAxes = value; + Content.RelativeSizeAxes = ~value; + Content.AutoSizeAxes = value; + } + } + protected virtual SpriteText CreateText() => new OsuSpriteText { Depth = -1, From a874345da04f513ba14b17978b3236debf34e32b Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 05:46:30 +0300 Subject: [PATCH 0813/2991] Rebase CancelButton to RoundedButton --- .../Comments/CancellableCommentEditor.cs | 50 +++++-------------- 1 file changed, 12 insertions(+), 38 deletions(-) diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs index 8f6863b949..499c158ccd 100644 --- a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -2,15 +2,12 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; -using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments @@ -30,45 +27,22 @@ namespace osu.Game.Overlays.Comments }); } - private partial class CancelButton : OsuHoverContainer + private sealed partial class CancelButton : RoundedButton { - protected override IEnumerable EffectTargets => new[] { background }; - - private readonly Box background; - public CancelButton() - : base(HoverSampleSet.Button) { - AutoSizeAxes = Axes.Both; - Child = new CircularContainer - { - Masking = true, - Height = 25, - AutoSizeAxes = Axes.X, - Children = new Drawable[] - { - background = new Box - { - RelativeSizeAxes = Axes.Both - }, - new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), - Margin = new MarginPadding { Horizontal = 20 }, - Text = CommonStrings.ButtonsCancel - } - } - }; + Height = 25; + AutoSizeAxes = Axes.X; } - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) + protected override SpriteText CreateText() => new OsuSpriteText { - IdleColour = colourProvider.Light4; - HoverColour = colourProvider.Light3; - } + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Margin = new MarginPadding { Horizontal = 20 }, + Text = CommonStrings.ButtonsCancel + }; } } } From 894fb98fa25092af9e614408090c66e87576287c Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 06:17:02 +0300 Subject: [PATCH 0814/2991] Rebase CommitButton to RoundedButton --- osu.Game/Overlays/Comments/CommentEditor.cs | 124 +++++++++----------- 1 file changed, 57 insertions(+), 67 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index b7fc4f097c..0dbcf0ff03 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -11,11 +11,12 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.Sprites; using osuTK.Graphics; using osu.Game.Graphics.UserInterface; -using System.Collections.Generic; using System; using osuTK; using osu.Framework.Bindables; +using osu.Framework.Input.Events; using osu.Framework.Localisation; +using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Overlays.Comments { @@ -99,8 +100,9 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(5, 0), - Child = commitButton = new CommitButton(CommitButtonText) + Child = commitButton = new CommitButton { + Text = CommitButtonText, Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Action = () => @@ -118,7 +120,7 @@ namespace osu.Game.Overlays.Comments textBox.OnCommit += (_, _) => { - if (commitButton.IsBlocked.Value) + if (commitButton.IsLoading) return; commitButton.TriggerClick(); @@ -166,84 +168,72 @@ namespace osu.Game.Overlays.Comments }; } - private partial class CommitButton : LoadingButton + private sealed partial class CommitButton : RoundedButton { private const int duration = 200; - + private bool isLoading; + private readonly LoadingSpinner spinner; public readonly BindableBool IsBlocked = new BindableBool(); + private OsuSpriteText text = null!; - public override bool PropagatePositionalInputSubTree => !IsBlocked.Value && base.PropagatePositionalInputSubTree; - - protected override IEnumerable EffectTargets => new[] { background }; - - private readonly LocalisableString text; - - [Resolved] - private OverlayColourProvider colourProvider { get; set; } = null!; - - private OsuSpriteText drawableText = null!; - private Box background = null!; - private Box blockedBackground = null!; - - public CommitButton(LocalisableString text) + public CommitButton() { - this.text = text; - - AutoSizeAxes = Axes.Both; - LoadingAnimationSize = new Vector2(10); - } - - [BackgroundDependencyLoader] - private void load() - { - IdleColour = colourProvider.Light4; - HoverColour = colourProvider.Light3; - blockedBackground.Colour = colourProvider.Background5; + Height = 25; + AutoSizeAxes = Axes.X; + Add(spinner = new LoadingSpinner + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(12), + Depth = -2, + }); } protected override void LoadComplete() { base.LoadComplete(); - IsBlocked.BindValueChanged(onBlockedStateChanged, true); - } - - private void onBlockedStateChanged(ValueChangedEvent isBlocked) - { - drawableText.FadeColour(isBlocked.NewValue ? colourProvider.Foreground1 : Color4.White, duration, Easing.OutQuint); - background.FadeTo(isBlocked.NewValue ? 0 : 1, duration, Easing.OutQuint); - } - - protected override Drawable CreateContent() => new CircularContainer - { - Masking = true, - Height = 25, - AutoSizeAxes = Axes.X, - Children = new Drawable[] + IsBlocked.BindValueChanged(e => { - blockedBackground = new Box - { - RelativeSizeAxes = Axes.Both - }, - background = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0 - }, - drawableText = new OsuSpriteText - { - AlwaysPresent = true, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), - Margin = new MarginPadding { Horizontal = 20 }, - Text = text, - } - } + Enabled.Value = !IsLoading && !e.NewValue; + }, true); + } + + protected override SpriteText CreateText() => text = new OsuSpriteText + { + AlwaysPresent = true, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Margin = new MarginPadding { Horizontal = 20 }, }; - protected override void OnLoadStarted() => drawableText.FadeOut(duration, Easing.OutQuint); + public bool IsLoading + { + get => isLoading; + set + { + isLoading = value; + Enabled.Value = !value && !IsBlocked.Value; + spinner.FadeTo(value ? 1f : 0f, duration, Easing.OutQuint); + text.FadeTo(value ? 0f : 1f, duration, Easing.OutQuint); + } + } - protected override void OnLoadFinished() => drawableText.FadeIn(duration, Easing.OutQuint); + protected override bool OnClick(ClickEvent e) + { + if (!Enabled.Value) + return false; + + try + { + return base.OnClick(e); + } + finally + { + // run afterwards as this will disable this button. + IsLoading = true; + } + } } } } From af0ee9dbd65f37fa867bce18395324ce5400f5da Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 06:19:54 +0300 Subject: [PATCH 0815/2991] Make spinner a little bigger --- osu.Game/Overlays/Comments/CommentEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 0dbcf0ff03..862b131cea 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -184,7 +184,7 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(12), + Size = new Vector2(14), Depth = -2, }); } From 472d9274b6d8ccc5846f3f7c91fcffa2ef1f9474 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 06:23:25 +0300 Subject: [PATCH 0816/2991] Reorder members --- osu.Game/Overlays/Comments/CommentEditor.cs | 31 +++++++++++---------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 862b131cea..784aa33ed9 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -171,11 +171,26 @@ namespace osu.Game.Overlays.Comments private sealed partial class CommitButton : RoundedButton { private const int duration = 200; - private bool isLoading; + private readonly LoadingSpinner spinner; - public readonly BindableBool IsBlocked = new BindableBool(); private OsuSpriteText text = null!; + public readonly BindableBool IsBlocked = new BindableBool(); + + private bool isLoading; + + public bool IsLoading + { + get => isLoading; + set + { + isLoading = value; + Enabled.Value = !value && !IsBlocked.Value; + spinner.FadeTo(value ? 1f : 0f, duration, Easing.OutQuint); + text.FadeTo(value ? 0f : 1f, duration, Easing.OutQuint); + } + } + public CommitButton() { Height = 25; @@ -207,18 +222,6 @@ namespace osu.Game.Overlays.Comments Margin = new MarginPadding { Horizontal = 20 }, }; - public bool IsLoading - { - get => isLoading; - set - { - isLoading = value; - Enabled.Value = !value && !IsBlocked.Value; - spinner.FadeTo(value ? 1f : 0f, duration, Easing.OutQuint); - text.FadeTo(value ? 0f : 1f, duration, Easing.OutQuint); - } - } - protected override bool OnClick(ClickEvent e) { if (!Enabled.Value) From a4819e5c9c0b37cadaf50bfdabfb4e763fae70b8 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 07:01:52 +0300 Subject: [PATCH 0817/2991] Localize actions --- osu.Game/Overlays/Comments/DrawableComment.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 6cb5a0fbac..8c01633fe8 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -331,11 +331,11 @@ namespace osu.Game.Overlays.Comments if (WasDeleted) makeDeleted(); - actionsContainer.AddLink("Copy link", copyUrl); + actionsContainer.AddLink(CommonStrings.ButtonsPermalink, copyUrl); actionsContainer.AddArbitraryDrawable(Empty().With(d => d.Width = 10)); if (Comment.UserId.HasValue && Comment.UserId.Value == api.LocalUser.Value.Id) - actionsContainer.AddLink("Delete", deleteComment); + actionsContainer.AddLink(CommonStrings.ButtonsDelete, deleteComment); else actionsContainer.AddArbitraryDrawable(new CommentReportButton(Comment)); From 16962d9a57699d7c610f21d079987b2f8e338887 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 07:02:02 +0300 Subject: [PATCH 0818/2991] Localize deleted string --- osu.Game/Overlays/Comments/DrawableComment.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 8c01633fe8..7bada5ef2a 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -553,12 +553,12 @@ namespace osu.Game.Overlays.Comments }; } - private string getParentMessage() + private LocalisableString getParentMessage() { if (parentComment == null) return string.Empty; - return parentComment.HasMessage ? parentComment.Message : parentComment.IsDeleted ? "deleted" : string.Empty; + return parentComment.HasMessage ? parentComment.Message : parentComment.IsDeleted ? CommentsStrings.Deleted : string.Empty; } } } From 96e19d4d84c97ff952d0271da2ef792be0e8b71e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 29 Nov 2022 14:36:23 +0900 Subject: [PATCH 0819/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 8f4750e831..17237c5ca7 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index afc80d073f..9301670825 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 4d8c1af28b..57e58dc16a 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From 24deb5f5f45f3e3e2c260ed3a08baeff659e3c28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 16 Nov 2022 15:54:52 +0900 Subject: [PATCH 0820/2991] Remove all unnecessary usage of `IHasFilterableChildren` --- osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs | 1 - osu.Game/Overlays/Settings/SettingsSection.cs | 4 +--- osu.Game/Overlays/Settings/SettingsSubsection.cs | 5 +---- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs index 4e295ba665..24c2eee783 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs @@ -62,7 +62,6 @@ namespace osu.Game.Tests.Visual.Settings section.Children.Where(f => f.IsPresent) .OfType() .OfType() - .Where(f => !(f is IHasFilterableChildren)) .All(f => f.FilterTerms.Any(t => t.ToString().Contains("scaling"))) )); diff --git a/osu.Game/Overlays/Settings/SettingsSection.cs b/osu.Game/Overlays/Settings/SettingsSection.cs index dced187035..9602e4373f 100644 --- a/osu.Game/Overlays/Settings/SettingsSection.cs +++ b/osu.Game/Overlays/Settings/SettingsSection.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -19,7 +18,7 @@ using osuTK; namespace osu.Game.Overlays.Settings { - public abstract partial class SettingsSection : Container, IHasFilterableChildren + public abstract partial class SettingsSection : Container, IFilterable { protected FillFlowContainer FlowContent; protected override Container Content => FlowContent; @@ -33,7 +32,6 @@ namespace osu.Game.Overlays.Settings public abstract Drawable CreateIcon(); public abstract LocalisableString Header { get; } - public IEnumerable FilterableChildren => Children.OfType(); public virtual IEnumerable FilterTerms => new[] { Header }; public const int ITEM_SPACING = 14; diff --git a/osu.Game/Overlays/Settings/SettingsSubsection.cs b/osu.Game/Overlays/Settings/SettingsSubsection.cs index 78fb53230e..784f20a6e8 100644 --- a/osu.Game/Overlays/Settings/SettingsSubsection.cs +++ b/osu.Game/Overlays/Settings/SettingsSubsection.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics.Sprites; using System.Collections.Generic; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Localisation; using osu.Framework.Testing; @@ -17,7 +16,7 @@ using osu.Game.Graphics; namespace osu.Game.Overlays.Settings { [ExcludeFromDynamicCompile] - public abstract partial class SettingsSubsection : FillFlowContainer, IHasFilterableChildren + public abstract partial class SettingsSubsection : FillFlowContainer, IFilterable { protected override Container Content => FlowContent; @@ -25,8 +24,6 @@ namespace osu.Game.Overlays.Settings protected abstract LocalisableString Header { get; } - public IEnumerable FilterableChildren => Children.OfType(); - public virtual IEnumerable FilterTerms => new[] { Header }; public bool MatchingFilter From 8f78d6179bf907efe9f442c5a42a2439031a31ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 16 Nov 2022 22:58:32 +0900 Subject: [PATCH 0821/2991] Fix multiple issues with settings items unhiding on search --- .../Sections/Graphics/LayoutSettings.cs | 32 ++++++------------- .../Settings/Sections/Input/TabletSettings.cs | 25 ++++++++++----- osu.Game/Overlays/Settings/SettingsButton.cs | 7 +++- osu.Game/Overlays/Settings/SettingsItem.cs | 5 ++- 4 files changed, 37 insertions(+), 32 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 63689961e6..bad06732d0 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -177,13 +177,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics updateScreenModeWarning(); }, true); - windowModes.BindCollectionChanged((_, _) => - { - if (windowModes.Count > 1) - windowModeDropdown.Show(); - else - windowModeDropdown.Hide(); - }, true); + windowModes.BindCollectionChanged((_, _) => updateDisplaySettingsVisibility()); currentDisplay.BindValueChanged(display => Schedule(() => { @@ -219,7 +213,11 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics scalingSettings.ResizeHeightTo(0, transition_duration, Easing.OutQuint); scalingSettings.AutoSizeAxes = scalingMode.Value != ScalingMode.Off ? Axes.Y : Axes.None; - scalingSettings.ForEach(s => s.TransferValueOnCommit = scalingMode.Value == ScalingMode.Everything); + scalingSettings.ForEach(s => + { + s.TransferValueOnCommit = scalingMode.Value == ScalingMode.Everything; + s.CanBeShown.Value = scalingMode.Value != ScalingMode.Off; + }); } } @@ -234,20 +232,10 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics private void updateDisplaySettingsVisibility() { - if (resolutions.Count > 1 && windowModeDropdown.Current.Value == WindowMode.Fullscreen) - resolutionDropdown.Show(); - else - resolutionDropdown.Hide(); - - if (displayDropdown.Items.Count() > 1) - displayDropdown.Show(); - else - displayDropdown.Hide(); - - if (host.Window?.SafeAreaPadding.Value.Total != Vector2.Zero) - safeAreaConsiderationsCheckbox.Show(); - else - safeAreaConsiderationsCheckbox.Hide(); + windowModeDropdown.CanBeShown.Value = windowModes.Count > 1; + resolutionDropdown.CanBeShown.Value = resolutions.Count > 1 && windowModeDropdown.Current.Value == WindowMode.Fullscreen; + displayDropdown.CanBeShown.Value = displayDropdown.Items.Count() > 1; + safeAreaConsiderationsCheckbox.CanBeShown.Value = host.Window?.SafeAreaPadding.Value.Total != Vector2.Zero; } private void updateScreenModeWarning() diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs index 27612738df..951cf3802f 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs @@ -143,6 +143,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input areaOffset.SetDefault(); areaSize.SetDefault(); }, + CanBeShown = { BindTarget = enabled } }, new SettingsButton { @@ -150,25 +151,29 @@ namespace osu.Game.Overlays.Settings.Sections.Input Action = () => { forceAspectRatio((float)host.Window.ClientSize.Width / host.Window.ClientSize.Height); - } + }, + CanBeShown = { BindTarget = enabled } }, new SettingsSlider { TransferValueOnCommit = true, LabelText = TabletSettingsStrings.XOffset, - Current = offsetX + Current = offsetX, + CanBeShown = { BindTarget = enabled } }, new SettingsSlider { TransferValueOnCommit = true, LabelText = TabletSettingsStrings.YOffset, - Current = offsetY + Current = offsetY, + CanBeShown = { BindTarget = enabled } }, new SettingsSlider { TransferValueOnCommit = true, LabelText = TabletSettingsStrings.Rotation, - Current = rotation + Current = rotation, + CanBeShown = { BindTarget = enabled } }, new RotationPresetButtons(tabletHandler) { @@ -181,24 +186,28 @@ namespace osu.Game.Overlays.Settings.Sections.Input { TransferValueOnCommit = true, LabelText = TabletSettingsStrings.AspectRatio, - Current = aspectRatio + Current = aspectRatio, + CanBeShown = { BindTarget = enabled } }, new SettingsCheckbox { LabelText = TabletSettingsStrings.LockAspectRatio, - Current = aspectLock + Current = aspectLock, + CanBeShown = { BindTarget = enabled } }, new SettingsSlider { TransferValueOnCommit = true, LabelText = CommonStrings.Width, - Current = sizeX + Current = sizeX, + CanBeShown = { BindTarget = enabled } }, new SettingsSlider { TransferValueOnCommit = true, LabelText = CommonStrings.Height, - Current = sizeY + Current = sizeY, + CanBeShown = { BindTarget = enabled } }, } }, diff --git a/osu.Game/Overlays/Settings/SettingsButton.cs b/osu.Game/Overlays/Settings/SettingsButton.cs index dc1be1ce9f..5091ddc2d0 100644 --- a/osu.Game/Overlays/Settings/SettingsButton.cs +++ b/osu.Game/Overlays/Settings/SettingsButton.cs @@ -3,14 +3,16 @@ using System.Collections.Generic; using System.Linq; +using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Overlays.Settings { - public partial class SettingsButton : RoundedButton, IHasTooltip + public partial class SettingsButton : RoundedButton, IHasTooltip, IConditionalFilterable { public SettingsButton() { @@ -20,6 +22,9 @@ namespace osu.Game.Overlays.Settings public LocalisableString TooltipText { get; set; } + public BindableBool CanBeShown { get; } = new BindableBool(true); + IBindable IConditionalFilterable.CanBeShown => CanBeShown; + public override IEnumerable FilterTerms { get diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index 577f1738ba..5f4bb9d57f 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -22,7 +22,7 @@ using osuTK; namespace osu.Game.Overlays.Settings { - public abstract partial class SettingsItem : Container, IFilterable, ISettingsItem, IHasCurrentValue, IHasTooltip + public abstract partial class SettingsItem : Container, IConditionalFilterable, ISettingsItem, IHasCurrentValue, IHasTooltip { protected abstract Drawable CreateControl(); @@ -144,6 +144,9 @@ namespace osu.Game.Overlays.Settings public bool FilteringActive { get; set; } + public BindableBool CanBeShown { get; } = new BindableBool(true); + IBindable IConditionalFilterable.CanBeShown => CanBeShown; + public event Action SettingChanged; private T classicDefault; From b5b79e09e4c9d46fd5bea0da7f7ed664bd7b7afa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 29 Nov 2022 14:45:08 +0900 Subject: [PATCH 0822/2991] Remove unnecessary CQ disable --- osu.Game/Online/Rooms/APICreatedRoom.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Online/Rooms/APICreatedRoom.cs b/osu.Game/Online/Rooms/APICreatedRoom.cs index 7f2bd13aec..254a338a60 100644 --- a/osu.Game/Online/Rooms/APICreatedRoom.cs +++ b/osu.Game/Online/Rooms/APICreatedRoom.cs @@ -7,8 +7,6 @@ using Newtonsoft.Json; namespace osu.Game.Online.Rooms { - // TODO: Remove disable below after merging https://github.com/ppy/osu-framework/pull/5548 and applying follow-up changes game-side. - // ReSharper disable once PartialTypeWithSinglePart public partial class APICreatedRoom : Room { [JsonProperty("error")] From 61c702c02ec94f39aafafb3267665cf207a3a9ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 29 Nov 2022 14:45:26 +0900 Subject: [PATCH 0823/2991] Add new `IDependencyInjectionCandidate` interface to non-drawable cached classes --- osu.Game/Online/Rooms/Room.cs | 2 +- osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs | 2 +- osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs | 2 +- osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestScene.cs | 2 +- .../Tests/Visual/OnlinePlay/OnlinePlayTestSceneDependencies.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Online/Rooms/Room.cs b/osu.Game/Online/Rooms/Room.cs index bdd7d6ce1c..8f346c4057 100644 --- a/osu.Game/Online/Rooms/Room.cs +++ b/osu.Game/Online/Rooms/Room.cs @@ -16,7 +16,7 @@ using osu.Game.Online.Rooms.RoomStatuses; namespace osu.Game.Online.Rooms { [JsonObject(MemberSerialization.OptIn)] - public partial class Room + public partial class Room : IDependencyInjectionCandidate { [Cached] [JsonProperty("id")] diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs b/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs index b28b04f228..63688841d0 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs @@ -233,7 +233,7 @@ namespace osu.Game.Overlays.FirstRunSetup return parentDependencies.Get(type, info); } - public void Inject(T instance) where T : class + public void Inject(T instance) where T : class, IDependencyInjectionCandidate { parentDependencies.Inject(instance); } diff --git a/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs b/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs index fbc920f7de..bb4e06654a 100644 --- a/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs +++ b/osu.Game/Tests/Beatmaps/HitObjectSampleTest.cs @@ -164,7 +164,7 @@ namespace osu.Game.Tests.Beatmaps return fallback.Get(type, info); } - public void Inject(T instance) where T : class + public void Inject(T instance) where T : class, IDependencyInjectionCandidate { // Never used directly } diff --git a/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestScene.cs b/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestScene.cs index 5350030276..87488710a7 100644 --- a/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestScene.cs +++ b/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestScene.cs @@ -128,7 +128,7 @@ namespace osu.Game.Tests.Visual.OnlinePlay => OnlinePlayDependencies?.Get(type, info) ?? parent.Get(type, info); public void Inject(T instance) - where T : class + where T : class, IDependencyInjectionCandidate => injectableDependencies.Inject(instance); } } diff --git a/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestSceneDependencies.cs b/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestSceneDependencies.cs index 35bdba0038..a9acbdcd7e 100644 --- a/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestSceneDependencies.cs +++ b/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestSceneDependencies.cs @@ -65,7 +65,7 @@ namespace osu.Game.Tests.Visual.OnlinePlay => dependencies.Get(type, info); public void Inject(T instance) - where T : class + where T : class, IDependencyInjectionCandidate => dependencies.Inject(instance); protected void Cache(object instance) From 56a694fb04bf200be1183cae1038c41a7ad59cac Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 29 Nov 2022 15:10:21 +0900 Subject: [PATCH 0824/2991] Add automated test coverage of simple scenarios for `RangeSlider` --- .../UserInterface/TestSceneRangeSlider.cs | 26 ++++++++++++++++--- .../Graphics/UserInterface/RangeSlider.cs | 2 ++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs index d0e3ff737c..b780764e7f 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneRangeSlider.cs @@ -5,6 +5,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Testing; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays; using osuTK; @@ -30,10 +31,12 @@ namespace osu.Game.Tests.Visual.UserInterface Precision = 0.1f }; - [Test] - public void TestBasic() + private RangeSlider rangeSlider = null!; + + [SetUpSteps] + public void SetUpSteps() { - AddStep("create Control", () => Child = new RangeSlider + AddStep("create control", () => Child = rangeSlider = new RangeSlider { Width = 200, Anchor = Anchor.Centre, @@ -47,15 +50,30 @@ namespace osu.Game.Tests.Visual.UserInterface DefaultStringUpperBound = "End", MinRange = 10 }); - AddStep("Test Range", () => + } + + [Test] + public void TestAdjustRange() + { + AddAssert("Initial lower bound is correct", () => rangeSlider.LowerBound.Value, () => Is.EqualTo(0).Within(0.1f)); + AddAssert("Initial upper bound is correct", () => rangeSlider.UpperBound.Value, () => Is.EqualTo(100).Within(0.1f)); + + AddStep("Adjust range", () => { customStart.Value = 50; customEnd.Value = 75; }); + + AddAssert("Adjusted lower bound is correct", () => rangeSlider.LowerBound.Value, () => Is.EqualTo(50).Within(0.1f)); + AddAssert("Adjusted upper bound is correct", () => rangeSlider.UpperBound.Value, () => Is.EqualTo(75).Within(0.1f)); + AddStep("Test nub pushing", () => { customStart.Value = 90; }); + + AddAssert("Pushed lower bound is correct", () => rangeSlider.LowerBound.Value, () => Is.EqualTo(90).Within(0.1f)); + AddAssert("Pushed upper bound is correct", () => rangeSlider.UpperBound.Value, () => Is.EqualTo(100).Within(0.1f)); } } } diff --git a/osu.Game/Graphics/UserInterface/RangeSlider.cs b/osu.Game/Graphics/UserInterface/RangeSlider.cs index c8306b70fb..483119cd58 100644 --- a/osu.Game/Graphics/UserInterface/RangeSlider.cs +++ b/osu.Game/Graphics/UserInterface/RangeSlider.cs @@ -22,6 +22,7 @@ namespace osu.Game.Graphics.UserInterface /// public Bindable LowerBound { + get => lowerBound.Current; set => lowerBound.Current = value; } @@ -30,6 +31,7 @@ namespace osu.Game.Graphics.UserInterface /// public Bindable UpperBound { + get => upperBound.Current; set => upperBound.Current = value; } From cfffe5f00272fd453817db9bf20664e669c745c2 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 14:20:38 +0300 Subject: [PATCH 0825/2991] Avoid null string --- osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index e5fbb8c5d0..aa55cf9930 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -66,7 +66,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("press Enter", () => InputManager.Key(Key.Enter)); - AddAssert("no text committed", () => commentEditor.CommittedText == null); + AddAssert("no text committed", () => commentEditor.CommittedText.Length == 0); AddAssert("button is not loading", () => !commentEditor.IsLoading); } @@ -107,7 +107,7 @@ namespace osu.Game.Tests.Visual.UserInterface public new Bindable Current => base.Current; public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; - public string? CommittedText { get; private set; } + public string CommittedText { get; private set; } = string.Empty; public TestCommentEditor() { From 6c126f5223d8a3b523019af48bf0bb6ac92fce18 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 14:25:51 +0300 Subject: [PATCH 0826/2991] Remove useless local actions on click --- .../UserInterface/TestSceneCommentEditor.cs | 1 + osu.Game/Overlays/Comments/CommentEditor.cs | 17 ----------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index aa55cf9930..fd124f676f 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -116,6 +116,7 @@ namespace osu.Game.Tests.Visual.UserInterface private void onCommit(string value) { + IsLoading = true; CommittedText = value; Scheduler.AddDelayed(() => IsLoading = false, 1000); } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 784aa33ed9..ec112b8547 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -14,7 +14,6 @@ using osu.Game.Graphics.UserInterface; using System; using osuTK; using osu.Framework.Bindables; -using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterfaceV2; @@ -221,22 +220,6 @@ namespace osu.Game.Overlays.Comments Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), Margin = new MarginPadding { Horizontal = 20 }, }; - - protected override bool OnClick(ClickEvent e) - { - if (!Enabled.Value) - return false; - - try - { - return base.OnClick(e); - } - finally - { - // run afterwards as this will disable this button. - IsLoading = true; - } - } } } } From 84aaf5fedf9bccc3ee712acffb04f0cc133b33d4 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 14:37:35 +0300 Subject: [PATCH 0827/2991] Change ways to access submit button state --- .../UserInterface/TestSceneCommentEditor.cs | 10 ++++---- osu.Game/Overlays/Comments/CommentEditor.cs | 23 +++++++++---------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index fd124f676f..81cc5c9572 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -52,7 +52,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("press Enter", () => InputManager.Key(Key.Enter)); AddAssert("text committed", () => commentEditor.CommittedText == "text"); - AddAssert("button is loading", () => commentEditor.IsLoading); + AddAssert("button is loading", () => commentEditor.IsSubmitting); } [Test] @@ -67,7 +67,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("press Enter", () => InputManager.Key(Key.Enter)); AddAssert("no text committed", () => commentEditor.CommittedText.Length == 0); - AddAssert("button is not loading", () => !commentEditor.IsLoading); + AddAssert("button is not loading", () => !commentEditor.IsSubmitting); } [Test] @@ -87,7 +87,7 @@ namespace osu.Game.Tests.Visual.UserInterface }); AddAssert("text committed", () => commentEditor.CommittedText == "some other text"); - AddAssert("button is loading", () => commentEditor.IsLoading); + AddAssert("button is loading", () => commentEditor.IsSubmitting); } [Test] @@ -116,9 +116,9 @@ namespace osu.Game.Tests.Visual.UserInterface private void onCommit(string value) { - IsLoading = true; + CommitButton.IsLoading = true; CommittedText = value; - Scheduler.AddDelayed(() => IsLoading = false, 1000); + Scheduler.AddDelayed(() => CommitButton.IsLoading = false, 1000); } protected override LocalisableString FooterText => @"Footer text. And it is pretty long. Cool."; diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index ec112b8547..8e95975139 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -25,11 +25,10 @@ namespace osu.Game.Overlays.Comments public Action? OnCommit; - public bool IsLoading - { - get => commitButton.IsLoading; - set => commitButton.IsLoading = value; - } + /// + /// Is the editor waiting for submit action to complete? + /// + public bool IsSubmitting => CommitButton.IsLoading; protected abstract LocalisableString FooterText { get; } @@ -41,7 +40,7 @@ namespace osu.Game.Overlays.Comments protected readonly Bindable Current = new Bindable(); - private CommitButton commitButton = null!; + protected EditorCommitButton CommitButton = null!; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -99,7 +98,7 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(5, 0), - Child = commitButton = new CommitButton + Child = CommitButton = new EditorCommitButton { Text = CommitButtonText, Anchor = Anchor.CentreRight, @@ -119,10 +118,10 @@ namespace osu.Game.Overlays.Comments textBox.OnCommit += (_, _) => { - if (commitButton.IsLoading) + if (CommitButton.IsLoading) return; - commitButton.TriggerClick(); + CommitButton.TriggerClick(); }; } @@ -130,7 +129,7 @@ namespace osu.Game.Overlays.Comments { base.LoadComplete(); - Current.BindValueChanged(text => commitButton.IsBlocked.Value = string.IsNullOrEmpty(text.NewValue), true); + Current.BindValueChanged(text => CommitButton.IsBlocked.Value = string.IsNullOrEmpty(text.NewValue), true); } private partial class EditorTextBox : BasicTextBox @@ -167,7 +166,7 @@ namespace osu.Game.Overlays.Comments }; } - private sealed partial class CommitButton : RoundedButton + protected sealed partial class EditorCommitButton : RoundedButton { private const int duration = 200; @@ -190,7 +189,7 @@ namespace osu.Game.Overlays.Comments } } - public CommitButton() + public EditorCommitButton() { Height = 25; AutoSizeAxes = Axes.X; From e30d97c94e4bd2c163046cdfbcfc192424cfe149 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 14:39:59 +0300 Subject: [PATCH 0828/2991] Comments --- osu.Game/Overlays/Comments/CommentEditor.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 8e95975139..be196c2085 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Comments public Action? OnCommit; /// - /// Is the editor waiting for submit action to complete? + /// Whether editor is waiting for submit action to complete. /// public bool IsSubmitting => CommitButton.IsLoading; @@ -177,6 +177,9 @@ namespace osu.Game.Overlays.Comments private bool isLoading; + /// + /// Whether loading spinner shown. + /// public bool IsLoading { get => isLoading; From 7dbf3793515ba9dde17ec8b79de95d26006f360e Mon Sep 17 00:00:00 2001 From: Jai Sharma Date: Tue, 29 Nov 2022 18:22:07 +0000 Subject: [PATCH 0829/2991] Don't use verbatim string literals --- osu.Game/Screens/Edit/Timing/ControlPointTable.cs | 4 ++-- osu.Game/Screens/Edit/Timing/TimingScreen.cs | 4 ++-- osu.Game/Screens/Edit/Verify/IssueTable.cs | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs index b3cc41af72..eeae1bcb9a 100644 --- a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs +++ b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs @@ -73,8 +73,8 @@ namespace osu.Game.Screens.Edit.Timing { var columns = new List { - new TableColumn(@"Time", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, TIMING_COLUMN_WIDTH)), - new TableColumn(@"Attributes", Anchor.CentreLeft), + new TableColumn("Time", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, TIMING_COLUMN_WIDTH)), + new TableColumn("Attributes", Anchor.CentreLeft), }; return columns.ToArray(); diff --git a/osu.Game/Screens/Edit/Timing/TimingScreen.cs b/osu.Game/Screens/Edit/Timing/TimingScreen.cs index 69eff776e6..2450909929 100644 --- a/osu.Game/Screens/Edit/Timing/TimingScreen.cs +++ b/osu.Game/Screens/Edit/Timing/TimingScreen.cs @@ -130,8 +130,8 @@ namespace osu.Game.Screens.Edit.Timing deleteButton.Enabled.Value = selected.NewValue != null; addButton.Text = selected.NewValue != null - ? @"+ Clone to current time" - : @"+ Add at current time"; + ? "+ Clone to current time" + : "+ Add at current time"; }, true); controlPointGroups.BindTo(Beatmap.ControlPointInfo.Groups); diff --git a/osu.Game/Screens/Edit/Verify/IssueTable.cs b/osu.Game/Screens/Edit/Verify/IssueTable.cs index b37fb2b72d..dbd007e423 100644 --- a/osu.Game/Screens/Edit/Verify/IssueTable.cs +++ b/osu.Game/Screens/Edit/Verify/IssueTable.cs @@ -86,10 +86,10 @@ namespace osu.Game.Screens.Edit.Verify var columns = new List { new TableColumn(string.Empty, Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)), - new TableColumn(@"Type", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize, minSize: 60)), - new TableColumn(@"Time", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize, minSize: 60)), - new TableColumn(@"Message", Anchor.CentreLeft), - new TableColumn(@"Category", Anchor.CentreRight, new Dimension(GridSizeMode.AutoSize)), + new TableColumn("Type", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize, minSize: 60)), + new TableColumn("Time", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize, minSize: 60)), + new TableColumn("Message", Anchor.CentreLeft), + new TableColumn("Category", Anchor.CentreRight, new Dimension(GridSizeMode.AutoSize)), }; return columns.ToArray(); From f3fa39f2541c640398b2d312d167acd26b647386 Mon Sep 17 00:00:00 2001 From: Joppe27 Date: Wed, 30 Nov 2022 00:44:20 +0100 Subject: [PATCH 0830/2991] Add legacy taiko kiai glow element --- .../Skinning/Legacy/LegacyKiaiGlow.cs | 67 +++++++++++++++++++ .../Legacy/TaikoLegacySkinTransformer.cs | 6 ++ .../TaikoSkinComponents.cs | 1 + osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 4 ++ 4 files changed, 78 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs new file mode 100644 index 0000000000..07eb052b20 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs @@ -0,0 +1,67 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Scoring; +using osu.Game.Skinning; +using osuTK; + +namespace osu.Game.Rulesets.Taiko.Skinning.Legacy +{ + internal partial class LegacyKiaiGlow : Container + { + public LegacyKiaiGlow() + { + AlwaysPresent = true; + Alpha = 0; + } + + [BackgroundDependencyLoader] + private void load(ISkinSource skin) + { + Child = new Sprite + { + Texture = skin.GetTexture("taiko-glow"), + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Scale = new Vector2(0.75f), + }; + } + + [Resolved(CanBeNull = true)] + private IBeatSyncProvider? beatSyncProvider { get; set; } + + [Resolved(CanBeNull = true)] + private HealthProcessor? healthProcessor { get; set; } + + protected override void Update() + { + base.Update(); + + if (healthProcessor != null) + healthProcessor.NewJudgement += onNewJudgement; + + if (beatSyncProvider != null) + { + if (beatSyncProvider.CheckIsKiaiTime()) + this.FadeIn(180); + else + this.FadeOut(180); + } + } + + private void onNewJudgement(JudgementResult result) + { + if (!result.IsHit) + return; + + this.ScaleTo(1.1f, 50) + .Then().ScaleTo(1f, 50); + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs index 7bf99306f0..d61f9ac35d 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs @@ -129,6 +129,12 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy case TaikoSkinComponents.Mascot: return new DrawableTaikoMascot(); + case TaikoSkinComponents.KiaiGlow: + if (GetTexture("taiko-glow") != null) + return new LegacyKiaiGlow(); + + return null; + default: throw new UnsupportedSkinComponentException(lookup); } diff --git a/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs b/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs index bf48898dd2..b8e3313e1b 100644 --- a/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs +++ b/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs @@ -21,5 +21,6 @@ namespace osu.Game.Rulesets.Taiko TaikoExplosionKiai, Scroller, Mascot, + KiaiGlow } } diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 6ce0be5868..9493de624a 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -112,6 +112,10 @@ namespace osu.Game.Rulesets.Taiko.UI FillMode = FillMode.Fit, Children = new[] { + new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.KiaiGlow), _ => Empty()) + { + RelativeSizeAxes = Axes.Both, + }, hitExplosionContainer = new Container { RelativeSizeAxes = Axes.Both, From dc1dfacbb17b8be5106830f5ed456b6c03e427c8 Mon Sep 17 00:00:00 2001 From: Joppe27 Date: Wed, 30 Nov 2022 00:44:39 +0100 Subject: [PATCH 0831/2991] Add very basic test coverage --- .../Skinning/TestSceneTaikoKiaiGlow.cs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoKiaiGlow.cs diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoKiaiGlow.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoKiaiGlow.cs new file mode 100644 index 0000000000..26e2202124 --- /dev/null +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoKiaiGlow.cs @@ -0,0 +1,33 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Taiko.Skinning.Legacy; + +namespace osu.Game.Rulesets.Taiko.Tests.Skinning +{ + public partial class TestSceneTaikoKiaiGlow : TaikoSkinnableTestScene + { + [Test] + public void TestKiaiGlow() + { + AddStep("Create kiai glow", () => SetContents(_ => new LegacyKiaiGlow())); + AddToggleStep("Toggle kiai mode", setUpBeatmap); + } + + private void setUpBeatmap(bool withKiai) + { + var controlPointInfo = new ControlPointInfo(); + + if (withKiai) + controlPointInfo.Add(0, new EffectControlPoint { KiaiMode = true }); + + Beatmap.Value = CreateWorkingBeatmap(new Beatmap + { + ControlPointInfo = controlPointInfo + }); + } + } +} From c3b5b19c327cae91684e02d6825533459743cf23 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 30 Nov 2022 04:02:35 +0300 Subject: [PATCH 0832/2991] Make TrianglesV2 test scene consistent --- .../Visual/Background/TestSceneTrianglesV2Background.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs index 8d6aef99ad..e8e3c80d48 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs @@ -54,7 +54,11 @@ namespace osu.Game.Tests.Visual.Background { base.LoadComplete(); - AddSliderStep("Spawn ratio", 0f, 2f, 1f, s => triangles.SpawnRatio = s); + AddSliderStep("Spawn ratio", 0f, 5f, 1f, s => + { + triangles.SpawnRatio = s; + triangles.Reset(1234); + }); AddSliderStep("Thickness", 0f, 1f, 0.02f, t => triangles.Thickness = t); } } From 3b13ca116719271c197aa5ab1f8dbbf063056ceb Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 30 Nov 2022 04:09:46 +0300 Subject: [PATCH 0833/2991] Remove texture from TrianglesV2 --- .../TestSceneTrianglesV2Background.cs | 4 +- osu.Game/Graphics/Backgrounds/TrianglesV2.cs | 87 ++++++------------- .../Graphics/UserInterfaceV2/RoundedButton.cs | 4 +- 3 files changed, 30 insertions(+), 65 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs index e8e3c80d48..4f37d5e988 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics.Shapes; using osuTK; using osuTK.Graphics; using osu.Game.Graphics.Backgrounds; +using osu.Framework.Graphics.Colour; namespace osu.Game.Tests.Visual.Background { @@ -42,8 +43,7 @@ namespace osu.Game.Tests.Visual.Background Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - ColourTop = Color4.White, - ColourBottom = Color4.Red + Colour = ColourInfo.GradientVertical(Color4.White, Color4.Red) } } } diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs index 6e6514690d..4838c1ec04 100644 --- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs +++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs @@ -11,9 +11,7 @@ using osu.Framework.Allocation; using System.Collections.Generic; using osu.Framework.Graphics.Rendering; using osu.Framework.Graphics.Rendering.Vertices; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp; -using osuTK.Graphics; +using osu.Framework.Graphics.Colour; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -23,28 +21,12 @@ namespace osu.Game.Graphics.Backgrounds { private const float triangle_size = 100; private const float base_velocity = 50; - private const int texture_height = 128; /// /// sqrt(3) / 2 /// private const float equilateral_triangle_ratio = 0.866f; - private readonly Bindable colourTop = new Bindable(Color4.White); - private readonly Bindable colourBottom = new Bindable(Color4.Black); - - public Color4 ColourTop - { - get => colourTop.Value; - set => colourTop.Value = value; - } - - public Color4 ColourBottom - { - get => colourBottom.Value; - set => colourBottom.Value = value; - } - public float Thickness { get; set; } = 0.02f; // No need for invalidation since it's happening in Update() /// @@ -89,42 +71,19 @@ namespace osu.Game.Graphics.Backgrounds } [BackgroundDependencyLoader] - private void load(ShaderManager shaders) + private void load(ShaderManager shaders, IRenderer renderer) { shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, "TriangleBorder"); + texture = renderer.WhitePixel; } protected override void LoadComplete() { base.LoadComplete(); - colourTop.BindValueChanged(_ => updateTexture()); - colourBottom.BindValueChanged(_ => updateTexture(), true); - spawnRatio.BindValueChanged(_ => Reset(), true); } - private void updateTexture() - { - var image = new Image(texture_height, 1); - - texture = renderer.CreateTexture(1, texture_height, true); - - for (int i = 0; i < texture_height; i++) - { - float ratio = (float)i / texture_height; - - image[i, 0] = new Rgba32( - colourBottom.Value.R * ratio + colourTop.Value.R * (1f - ratio), - colourBottom.Value.G * ratio + colourTop.Value.G * (1f - ratio), - colourBottom.Value.B * ratio + colourTop.Value.B * (1f - ratio) - ); - } - - texture.SetData(new TextureUpload(image)); - Invalidate(Invalidation.DrawNode); - } - protected override void Update() { base.Update(); @@ -280,36 +239,42 @@ namespace osu.Game.Graphics.Backgrounds shader.GetUniform("thickness").UpdateValue(ref thickness); shader.GetUniform("texelSize").UpdateValue(ref texelSize); - float texturePartWidth = triangleSize.X / size.X; - float texturePartHeight = triangleSize.Y / size.Y * texture_height; + float relativeHeight = triangleSize.Y / size.Y; + float relativeWidth = triangleSize.X / size.X; foreach (TriangleParticle particle in parts) { - Vector2 topLeft = particle.Position * size - new Vector2(triangleSize.X * 0.5f, 0f); - Vector2 topRight = topLeft + new Vector2(triangleSize.X, 0f); - Vector2 bottomLeft = topLeft + new Vector2(0f, triangleSize.Y); - Vector2 bottomRight = topLeft + triangleSize; + Vector2 topLeft = particle.Position - new Vector2(relativeWidth * 0.5f, 0f); + Vector2 topRight = topLeft + new Vector2(relativeWidth, 0f); + Vector2 bottomLeft = topLeft + new Vector2(0f, relativeHeight); + Vector2 bottomRight = bottomLeft + new Vector2(relativeWidth, 0f); var drawQuad = new Quad( - Vector2Extensions.Transform(topLeft, DrawInfo.Matrix), - Vector2Extensions.Transform(topRight, DrawInfo.Matrix), - Vector2Extensions.Transform(bottomLeft, DrawInfo.Matrix), - Vector2Extensions.Transform(bottomRight, DrawInfo.Matrix) + Vector2Extensions.Transform(topLeft * size, DrawInfo.Matrix), + Vector2Extensions.Transform(topRight * size, DrawInfo.Matrix), + Vector2Extensions.Transform(bottomLeft * size, DrawInfo.Matrix), + Vector2Extensions.Transform(bottomRight * size, DrawInfo.Matrix) ); - var tRect = new Quad( - topLeft.X / size.X, - topLeft.Y / size.Y * texture_height, - texturePartWidth, - texturePartHeight - ).AABBFloat; + ColourInfo colourInfo = triangleColourInfo(DrawColourInfo.Colour, new Quad(topLeft, topRight, bottomLeft, bottomRight)); - renderer.DrawQuad(texture, drawQuad, DrawColourInfo.Colour, tRect, vertexBatch.AddAction, textureCoords: tRect); + renderer.DrawQuad(texture, drawQuad, colourInfo, vertexAction: vertexBatch.AddAction); } shader.Unbind(); } + private static ColourInfo triangleColourInfo(ColourInfo source, Quad quad) + { + return new ColourInfo + { + TopLeft = source.Interpolate(quad.TopLeft), + TopRight = source.Interpolate(quad.TopRight), + BottomLeft = source.Interpolate(quad.BottomLeft), + BottomRight = source.Interpolate(quad.BottomRight) + }; + } + protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); diff --git a/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs b/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs index 6dc99f5269..6aded3fe32 100644 --- a/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs +++ b/osu.Game/Graphics/UserInterfaceV2/RoundedButton.cs @@ -6,6 +6,7 @@ using System.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; using osu.Framework.Localisation; @@ -79,8 +80,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 Debug.Assert(triangleGradientSecondColour != null); - Triangles.ColourTop = triangleGradientSecondColour.Value; - Triangles.ColourBottom = BackgroundColour; + Triangles.Colour = ColourInfo.GradientVertical(triangleGradientSecondColour.Value, BackgroundColour); } protected override bool OnHover(HoverEvent e) From 745cb0b13aea51f224b646bfa7beace70ee836ec Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 30 Nov 2022 04:17:37 +0300 Subject: [PATCH 0834/2991] Improve test scene --- .../Visual/Background/TestSceneTrianglesV2Background.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs index 4f37d5e988..2a4e9a7356 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs @@ -42,8 +42,7 @@ namespace osu.Game.Tests.Visual.Background { Anchor = Anchor.Centre, Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(Color4.White, Color4.Red) + RelativeSizeAxes = Axes.Both } } } @@ -60,6 +59,10 @@ namespace osu.Game.Tests.Visual.Background triangles.Reset(1234); }); AddSliderStep("Thickness", 0f, 1f, 0.02f, t => triangles.Thickness = t); + + AddStep("White colour", () => triangles.Colour = Color4.White); + AddStep("Vertical gradient", () => triangles.Colour = ColourInfo.GradientVertical(Color4.White, Color4.Red)); + AddStep("Horizontal gradient", () => triangles.Colour = ColourInfo.GradientHorizontal(Color4.White, Color4.Red)); } } } From 2eaefcad304c8da2780f5ab5f503f898c9e717f7 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 30 Nov 2022 04:56:07 +0300 Subject: [PATCH 0835/2991] Remove unused renderer --- osu.Game/Graphics/Backgrounds/TrianglesV2.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs index 4838c1ec04..d543f082b4 100644 --- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs +++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs @@ -52,9 +52,6 @@ namespace osu.Game.Graphics.Backgrounds private readonly List parts = new List(); - [Resolved] - private IRenderer renderer { get; set; } = null!; - private Random? stableRandom; private IShader shader = null!; From fa1000777dec3af022757550bf2b9578906c8f03 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 30 Nov 2022 05:12:26 +0300 Subject: [PATCH 0836/2991] Add box for gradient comparison --- .../TestSceneTrianglesV2Background.cs | 50 +++++++++++++------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs index 2a4e9a7356..ae1f3de6bf 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneTrianglesV2Background.cs @@ -14,6 +14,7 @@ namespace osu.Game.Tests.Visual.Background public partial class TestSceneTrianglesV2Background : OsuTestScene { private readonly TrianglesV2 triangles; + private readonly Box box; public TestSceneTrianglesV2Background() { @@ -24,25 +25,44 @@ namespace osu.Game.Tests.Visual.Background RelativeSizeAxes = Axes.Both, Colour = Color4.Gray }, - new Container + new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(500, 100), - Masking = true, - CornerRadius = 40, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 5), Children = new Drawable[] { - new Box + new Container { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Red + Size = new Vector2(500, 100), + Masking = true, + CornerRadius = 40, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Red + }, + triangles = new TrianglesV2 + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both + } + } }, - triangles = new TrianglesV2 + new Container { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both + Size = new Vector2(500, 100), + Masking = true, + CornerRadius = 40, + Child = box = new Box + { + RelativeSizeAxes = Axes.Both + } } } } @@ -53,16 +73,16 @@ namespace osu.Game.Tests.Visual.Background { base.LoadComplete(); - AddSliderStep("Spawn ratio", 0f, 5f, 1f, s => + AddSliderStep("Spawn ratio", 0f, 10f, 1f, s => { triangles.SpawnRatio = s; triangles.Reset(1234); }); AddSliderStep("Thickness", 0f, 1f, 0.02f, t => triangles.Thickness = t); - AddStep("White colour", () => triangles.Colour = Color4.White); - AddStep("Vertical gradient", () => triangles.Colour = ColourInfo.GradientVertical(Color4.White, Color4.Red)); - AddStep("Horizontal gradient", () => triangles.Colour = ColourInfo.GradientHorizontal(Color4.White, Color4.Red)); + AddStep("White colour", () => box.Colour = triangles.Colour = Color4.White); + AddStep("Vertical gradient", () => box.Colour = triangles.Colour = ColourInfo.GradientVertical(Color4.White, Color4.Red)); + AddStep("Horizontal gradient", () => box.Colour = triangles.Colour = ColourInfo.GradientHorizontal(Color4.White, Color4.Red)); } } } From 3f4d8b39caa4acf0a86b0af332c69f2a80308804 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 30 Nov 2022 12:55:45 +0900 Subject: [PATCH 0837/2991] Update package again --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 17237c5ca7..75828147a5 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9301670825..6e75450594 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 57e58dc16a..bb20b0474d 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From 0659c8434156e3f2da41b6abb82317a5cafc8c46 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 14:17:49 +0900 Subject: [PATCH 0838/2991] Rename method to be more in line with project naming --- osu.Game/Screens/Edit/EditorTable.cs | 2 +- osu.Game/Screens/Edit/Timing/ControlPointTable.cs | 7 ++----- osu.Game/Screens/Edit/Verify/IssueTable.cs | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/EditorTable.cs b/osu.Game/Screens/Edit/EditorTable.cs index 2443cfcbf0..b79d71b42b 100644 --- a/osu.Game/Screens/Edit/EditorTable.cs +++ b/osu.Game/Screens/Edit/EditorTable.cs @@ -46,7 +46,7 @@ namespace osu.Game.Screens.Edit }); } - protected void SetRowSelected(object? item) + protected void SetSelectedRow(object? item) { foreach (var b in BackgroundFlow) { diff --git a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs index eeae1bcb9a..b10959d224 100644 --- a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs +++ b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs @@ -61,13 +61,10 @@ namespace osu.Game.Screens.Edit.Timing { base.LoadComplete(); - selectedGroup.BindValueChanged(_ => - { - updateSelectedGroup(); - }, true); + selectedGroup.BindValueChanged(_ => updateSelectedGroup(), true); } - private void updateSelectedGroup() => SetRowSelected(selectedGroup.Value); + private void updateSelectedGroup() => SetSelectedRow(selectedGroup.Value); private TableColumn[] createHeaders() { diff --git a/osu.Game/Screens/Edit/Verify/IssueTable.cs b/osu.Game/Screens/Edit/Verify/IssueTable.cs index dbd007e423..ba5f98a772 100644 --- a/osu.Game/Screens/Edit/Verify/IssueTable.cs +++ b/osu.Game/Screens/Edit/Verify/IssueTable.cs @@ -77,7 +77,7 @@ namespace osu.Game.Screens.Edit.Verify selectedIssue = verify.SelectedIssue.GetBoundCopy(); selectedIssue.BindValueChanged(issue => { - SetRowSelected(issue.NewValue); + SetSelectedRow(issue.NewValue); }, true); } From 2a3b24d058eb1be089c503367bb60bfdf008319d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 14:20:54 +0900 Subject: [PATCH 0839/2991] Avoid need for implicit null casting --- osu.Game/Screens/Edit/Timing/ControlPointTable.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs index b10959d224..08b2ce8562 100644 --- a/osu.Game/Screens/Edit/Timing/ControlPointTable.cs +++ b/osu.Game/Screens/Edit/Timing/ControlPointTable.cs @@ -157,14 +157,12 @@ namespace osu.Game.Screens.Edit.Timing fill.ChildrenEnumerable = controlPoints .Where(matchFunction) .Select(createAttribute) - .Where(c => c != null) - .Select(c => c!) // arbitrary ordering to make timing points first. // probably want to explicitly define order in the future. .OrderByDescending(c => c.GetType().Name); } - private Drawable? createAttribute(ControlPoint controlPoint) + private Drawable createAttribute(ControlPoint controlPoint) { switch (controlPoint) { @@ -179,10 +177,9 @@ namespace osu.Game.Screens.Edit.Timing case SampleControlPoint sample: return new SampleRowAttribute(sample); - - default: - return null; } + + throw new ArgumentOutOfRangeException(nameof(controlPoint), $"Control point type {controlPoint.GetType()} is not supported"); } } } From b5c514a8f0eeb6da346e007d4d0a7a6e932579b2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 14:30:20 +0900 Subject: [PATCH 0840/2991] Make incoming `Channel` target non-nullable --- .../Visual/Online/TestSceneNowPlayingCommand.cs | 10 +++++----- osu.Game/Online/Chat/NowPlayingCommand.cs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs b/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs index 362ebd1e74..4675410164 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneNowPlayingCommand.cs @@ -34,7 +34,7 @@ namespace osu.Game.Tests.Visual.Online { AddStep("Set activity", () => api.Activity.Value = new UserActivity.InLobby(null)); - AddStep("Run command", () => Add(new NowPlayingCommand())); + AddStep("Run command", () => Add(new NowPlayingCommand(new Channel()))); AddAssert("Check correct response", () => postTarget.LastMessage.Contains("is listening")); } @@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual.Online { AddStep("Set activity", () => api.Activity.Value = new UserActivity.Editing(new BeatmapInfo())); - AddStep("Run command", () => Add(new NowPlayingCommand())); + AddStep("Run command", () => Add(new NowPlayingCommand(new Channel()))); AddAssert("Check correct response", () => postTarget.LastMessage.Contains("is editing")); } @@ -54,7 +54,7 @@ namespace osu.Game.Tests.Visual.Online { AddStep("Set activity", () => api.Activity.Value = new UserActivity.InSoloGame(new BeatmapInfo(), new RulesetInfo())); - AddStep("Run command", () => Add(new NowPlayingCommand())); + AddStep("Run command", () => Add(new NowPlayingCommand(new Channel()))); AddAssert("Check correct response", () => postTarget.LastMessage.Contains("is playing")); } @@ -70,7 +70,7 @@ namespace osu.Game.Tests.Visual.Online BeatmapInfo = { OnlineID = hasOnlineId ? 1234 : -1 } }); - AddStep("Run command", () => Add(new NowPlayingCommand())); + AddStep("Run command", () => Add(new NowPlayingCommand(new Channel()))); if (hasOnlineId) AddAssert("Check link presence", () => postTarget.LastMessage.Contains("/b/1234")); @@ -85,7 +85,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("Add Hidden mod", () => SelectedMods.Value = new[] { Ruleset.Value.CreateInstance().CreateMod() }); - AddStep("Run command", () => Add(new NowPlayingCommand())); + AddStep("Run command", () => Add(new NowPlayingCommand(new Channel()))); AddAssert("Check mod is present", () => postTarget.LastMessage.Contains("+HD")); } diff --git a/osu.Game/Online/Chat/NowPlayingCommand.cs b/osu.Game/Online/Chat/NowPlayingCommand.cs index 540e0b0dc1..0e39f5ac91 100644 --- a/osu.Game/Online/Chat/NowPlayingCommand.cs +++ b/osu.Game/Online/Chat/NowPlayingCommand.cs @@ -38,7 +38,7 @@ namespace osu.Game.Online.Chat /// Creates a new to post the currently-playing beatmap to a parenting . /// /// The target channel to post to. If null, the currently-selected channel will be posted to. - public NowPlayingCommand(Channel? target = null) + public NowPlayingCommand(Channel target) { this.target = target; } From 2df6ccf33e2c9b5fa80ebcde33b8c46d126622e4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 14:31:54 +0900 Subject: [PATCH 0841/2991] Tidy up code --- osu.Game/Online/Chat/NowPlayingCommand.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Online/Chat/NowPlayingCommand.cs b/osu.Game/Online/Chat/NowPlayingCommand.cs index 0e39f5ac91..c65b06c6d8 100644 --- a/osu.Game/Online/Chat/NowPlayingCommand.cs +++ b/osu.Game/Online/Chat/NowPlayingCommand.cs @@ -68,6 +68,9 @@ namespace osu.Game.Online.Chat break; } + channelManager.PostMessage($"is {verb} {getBeatmapPart()} {getModPart()}", true, target); + Expire(); + string getBeatmapPart() { string beatmapInfoString = localisation.GetLocalisedBindableString(beatmapInfo.GetDisplayTitleRomanisable()).Value; @@ -84,23 +87,20 @@ namespace osu.Game.Online.Chat return string.Empty; } - StringBuilder modS = new StringBuilder(); + StringBuilder modsString = new StringBuilder(); foreach (var mod in selectedMods.Value.Where(mod => mod.Type == ModType.DifficultyIncrease)) { - modS.Append($"+{mod.Acronym} "); + modsString.Append($"+{mod.Acronym} "); } foreach (var mod in selectedMods.Value.Where(mod => mod.Type != ModType.DifficultyIncrease)) { - modS.Append($"-{mod.Acronym} "); + modsString.Append($"-{mod.Acronym} "); } - return modS.ToString(); + return modsString.ToString().Trim(); } - - channelManager.PostMessage($"is {verb} {getBeatmapPart()} {getModPart()}", true, target); - Expire(); } } } From b453eecebe494acdf95de02feb38536b8f78228e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 14:43:21 +0900 Subject: [PATCH 0842/2991] Ensure empty pieces do not result in whitespace between elements --- osu.Game/Online/Chat/NowPlayingCommand.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/NowPlayingCommand.cs b/osu.Game/Online/Chat/NowPlayingCommand.cs index c65b06c6d8..2734b4e6dd 100644 --- a/osu.Game/Online/Chat/NowPlayingCommand.cs +++ b/osu.Game/Online/Chat/NowPlayingCommand.cs @@ -68,7 +68,15 @@ namespace osu.Game.Online.Chat break; } - channelManager.PostMessage($"is {verb} {getBeatmapPart()} {getModPart()}", true, target); + string[] pieces = + { + "is", + verb, + getBeatmapPart(), + getModPart(), + }; + + channelManager.PostMessage(string.Join(' ', pieces.Where(p => !string.IsNullOrEmpty(p))), true, target); Expire(); string getBeatmapPart() From 8bf5d6884d33ea13c06e72ed716b0fa0a15b089a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 14:47:16 +0900 Subject: [PATCH 0843/2991] Add ruleset to now playing string --- osu.Game/Online/Chat/NowPlayingCommand.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game/Online/Chat/NowPlayingCommand.cs b/osu.Game/Online/Chat/NowPlayingCommand.cs index 2734b4e6dd..9902704883 100644 --- a/osu.Game/Online/Chat/NowPlayingCommand.cs +++ b/osu.Game/Online/Chat/NowPlayingCommand.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Online.API; +using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Users; @@ -29,6 +30,9 @@ namespace osu.Game.Online.Chat [Resolved] private Bindable> selectedMods { get; set; } = null!; + [Resolved] + private IBindable currentRuleset { get; set; } = null!; + [Resolved] private LocalisationManager localisation { get; set; } = null!; @@ -73,6 +77,7 @@ namespace osu.Game.Online.Chat "is", verb, getBeatmapPart(), + getRulesetPart(), getModPart(), }; @@ -86,6 +91,13 @@ namespace osu.Game.Online.Chat return beatmapInfo.OnlineID > 0 ? $"[{api.WebsiteRootUrl}/b/{beatmapInfo.OnlineID} {beatmapInfoString}]" : beatmapInfoString; } + string getRulesetPart() + { + if (api.Activity.Value is not UserActivity.InGame) return string.Empty; + + return $"<{currentRuleset.Value.Name}>"; + } + string getModPart() { if (api.Activity.Value is not UserActivity.InGame) return string.Empty; From b0039c9b1b4898d6bd0211f8391f62fc38a02a5a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 15:27:12 +0900 Subject: [PATCH 0844/2991] Add test coverage of incorrect system message ordering --- .../Online/TestSceneStandAloneChatDisplay.cs | 45 ++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs index 7d2ac90939..b858b4e355 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs @@ -73,6 +73,11 @@ namespace osu.Game.Tests.Visual.Online messageIdSequence = 0; channelManager.CurrentChannel.Value = testChannel = new Channel(); + reinitialiseDrawableDisplay(); + }); + + private void reinitialiseDrawableDisplay() + { Children = new[] { chatDisplay = new TestStandAloneChatDisplay @@ -92,7 +97,7 @@ namespace osu.Game.Tests.Visual.Online Channel = { Value = testChannel }, } }; - }); + } [Test] public void TestSystemMessageOrdering() @@ -106,14 +111,44 @@ namespace osu.Game.Tests.Visual.Online var infoMessage1 = new InfoMessage($"the system is calling {messageIdSequence++}"); var infoMessage2 = new InfoMessage($"the system is calling {messageIdSequence++}"); + var standardMessage2 = new Message(messageIdSequence++) + { + Sender = admin, + Content = "I am a wang!" + }; + AddStep("message from admin", () => testChannel.AddNewMessages(standardMessage)); AddStep("message from system", () => testChannel.AddNewMessages(infoMessage1)); AddStep("message from system", () => testChannel.AddNewMessages(infoMessage2)); + AddStep("message from admin", () => testChannel.AddNewMessages(standardMessage2)); - AddAssert("message order is correct", () => testChannel.Messages.Count == 3 - && testChannel.Messages[0] == standardMessage - && testChannel.Messages[1] == infoMessage1 - && testChannel.Messages[2] == infoMessage2); + AddAssert("count is correct", () => testChannel.Messages.Count, () => Is.EqualTo(4)); + + AddAssert("message order is correct", () => testChannel.Messages, () => Is.EqualTo(new[] + { + standardMessage, + infoMessage1, + infoMessage2, + standardMessage2 + })); + + AddAssert("displayed order is correct", () => chatDisplay.DrawableChannel.ChildrenOfType().Select(c => c.Message), () => Is.EqualTo(new[] + { + standardMessage, + infoMessage1, + infoMessage2, + standardMessage2 + })); + + AddStep("reinit drawable channel", reinitialiseDrawableDisplay); + + AddAssert("displayed order is still correct", () => chatDisplay.DrawableChannel.ChildrenOfType().Select(c => c.Message), () => Is.EqualTo(new[] + { + standardMessage, + infoMessage1, + infoMessage2, + standardMessage2 + })); } [Test] From c84f011bb7d4566fdc6a7a558a55be35687af365 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 15:36:22 +0900 Subject: [PATCH 0845/2991] Improve `ToString` output of `Message` --- osu.Game/Online/Chat/Message.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/Message.cs b/osu.Game/Online/Chat/Message.cs index 9f6f9c8d6b..2569434df7 100644 --- a/osu.Game/Online/Chat/Message.cs +++ b/osu.Game/Online/Chat/Message.cs @@ -85,6 +85,6 @@ namespace osu.Game.Online.Chat // ReSharper disable once ImpureMethodCallOnReadonlyValueField public override int GetHashCode() => Id.GetHashCode(); - public override string ToString() => $"[{ChannelId}] ({Id}) {Sender}: {Content}"; + public override string ToString() => $"({(Id?.ToString() ?? "null")}) {Timestamp} {Sender}: {Content}"; } } From 9e34fe360a081853fbaf61e0021bf63ed6ba3375 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 15:46:36 +0900 Subject: [PATCH 0846/2991] Ensure all `LocalMessage`s get a timestamp --- .../Visual/Online/TestSceneStandAloneChatDisplay.cs | 2 ++ osu.Game/Online/Chat/InfoMessage.cs | 4 ---- osu.Game/Online/Chat/LocalEchoMessage.cs | 2 -- osu.Game/Online/Chat/LocalMessage.cs | 3 ++- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs index b858b4e355..ebd5e12acb 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs @@ -104,6 +104,7 @@ namespace osu.Game.Tests.Visual.Online { var standardMessage = new Message(messageIdSequence++) { + Timestamp = DateTimeOffset.Now, Sender = admin, Content = "I am a wang!" }; @@ -113,6 +114,7 @@ namespace osu.Game.Tests.Visual.Online var standardMessage2 = new Message(messageIdSequence++) { + Timestamp = DateTimeOffset.Now, Sender = admin, Content = "I am a wang!" }; diff --git a/osu.Game/Online/Chat/InfoMessage.cs b/osu.Game/Online/Chat/InfoMessage.cs index d98c67de34..2ade99dcb2 100644 --- a/osu.Game/Online/Chat/InfoMessage.cs +++ b/osu.Game/Online/Chat/InfoMessage.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using System; using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.Chat @@ -13,7 +10,6 @@ namespace osu.Game.Online.Chat public InfoMessage(string message) : base(null) { - Timestamp = DateTimeOffset.Now; Content = message; Sender = APIUser.SYSTEM_USER; diff --git a/osu.Game/Online/Chat/LocalEchoMessage.cs b/osu.Game/Online/Chat/LocalEchoMessage.cs index b226fe6cad..8a39515575 100644 --- a/osu.Game/Online/Chat/LocalEchoMessage.cs +++ b/osu.Game/Online/Chat/LocalEchoMessage.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Online.Chat { public class LocalEchoMessage : LocalMessage diff --git a/osu.Game/Online/Chat/LocalMessage.cs b/osu.Game/Online/Chat/LocalMessage.cs index 5736f5cabf..57caca2287 100644 --- a/osu.Game/Online/Chat/LocalMessage.cs +++ b/osu.Game/Online/Chat/LocalMessage.cs @@ -1,7 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable +using System; namespace osu.Game.Online.Chat { @@ -13,6 +13,7 @@ namespace osu.Game.Online.Chat protected LocalMessage(long? id) : base(id) { + Timestamp = DateTimeOffset.Now; } } } From 2d8854cbac6dbb5f86e965282321e0b8d1270197 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 15:46:58 +0900 Subject: [PATCH 0847/2991] Change message comparator to always use timestamp comparison if either message has a missing `Id` --- osu.Game/Online/Chat/Message.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Online/Chat/Message.cs b/osu.Game/Online/Chat/Message.cs index 2569434df7..4c86c963b7 100644 --- a/osu.Game/Online/Chat/Message.cs +++ b/osu.Game/Online/Chat/Message.cs @@ -66,12 +66,10 @@ namespace osu.Game.Online.Chat public int CompareTo(Message other) { - if (!Id.HasValue) - return other.Id.HasValue ? 1 : Timestamp.CompareTo(other.Timestamp); - if (!other.Id.HasValue) - return -1; + if (Id.HasValue && other.Id.HasValue) + return Id.Value.CompareTo(other.Id.Value); - return Id.Value.CompareTo(other.Id.Value); + return Timestamp.CompareTo(other.Timestamp); } public virtual bool Equals(Message other) From 7fca5ee28dceb89f189232b51937bc541d16979a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 16:04:00 +0900 Subject: [PATCH 0848/2991] Move `DrawableUsername` into own file It's too large at this point to be a nested class. --- osu.Game/Overlays/Chat/ChatLine.cs | 206 ------------------- osu.Game/Overlays/Chat/DrawableUsername.cs | 222 +++++++++++++++++++++ 2 files changed, 222 insertions(+), 206 deletions(-) create mode 100644 osu.Game/Overlays/Chat/DrawableUsername.cs diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index e974db9fba..4d5fbaac42 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.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 System.Collections.Generic; using osu.Framework.Allocation; @@ -9,23 +8,13 @@ using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; -using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.UserInterface; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using osu.Game.Online.API; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; -using osuTK; -using osuTK.Graphics; -using osu.Framework.Input.Events; using osu.Framework.Graphics.Sprites; -using osu.Framework.Localisation; namespace osu.Game.Overlays.Chat { @@ -190,200 +179,5 @@ namespace osu.Game.Overlays.Chat ? $@"{message.Timestamp.LocalDateTime:HH:mm:ss}" : $@"{message.Timestamp.LocalDateTime:hh:mm:ss tt}"; } - - private partial class DrawableUsername : OsuClickableContainer, IHasContextMenu - { - public new Color4 Colour { get; private set; } - - public float FontSize - { - set => drawableText.Font = OsuFont.GetFont(size: value, weight: FontWeight.Bold, italics: true); - } - - public LocalisableString Text - { - set => drawableText.Text = value; - } - - public override float Width - { - get => base.Width; - set => base.Width = drawableText.MaxWidth = value; - } - - [Resolved(canBeNull: false)] - private IAPIProvider api { get; set; } = null!; - - [Resolved(canBeNull: false)] - private OsuColour osuColours { get; set; } = null!; - - [Resolved] - private ChannelManager? chatManager { get; set; } - - [Resolved] - private ChatOverlay? chatOverlay { get; set; } - - [Resolved] - private UserProfileOverlay? profileOverlay { get; set; } - - private readonly APIUser user; - private readonly OsuSpriteText drawableText; - - private readonly Drawable colouredDrawable; - - public DrawableUsername(APIUser user) - { - this.user = user; - - Action = openUserProfile; - - drawableText = new OsuSpriteText - { - Shadow = false, - Truncate = true, - EllipsisString = "…", - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - }; - - if (string.IsNullOrWhiteSpace(user.Colour)) - { - Colour = default_colours[user.Id % default_colours.Length]; - - Child = colouredDrawable = drawableText; - } - else - { - Colour = Color4Extensions.FromHex(user.Colour); - - Child = new Container - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Both, - Masking = true, - CornerRadius = 4, - EdgeEffect = new EdgeEffectParameters - { - Roundness = 1, - Radius = 1, - Colour = Color4.Black.Opacity(0.3f), - Offset = new Vector2(0, 1), - Type = EdgeEffectType.Shadow, - }, - Child = new Container - { - AutoSizeAxes = Axes.Both, - Masking = true, - CornerRadius = 4, - Children = new[] - { - colouredDrawable = new Box - { - RelativeSizeAxes = Axes.Both, - }, - new Container - { - AutoSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = 4, Right = 4, Bottom = 1, Top = -2 }, - Child = drawableText, - } - } - } - }; - } - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - drawableText.Colour = osuColours.ChatBlue; - colouredDrawable.Colour = Colour; - } - - public MenuItem[] ContextMenuItems - { - get - { - if (user.Equals(APIUser.SYSTEM_USER)) - return Array.Empty(); - - List items = new List - { - new OsuMenuItem("View Profile", MenuItemType.Highlighted, openUserProfile) - }; - - if (!user.Equals(api.LocalUser.Value)) - items.Add(new OsuMenuItem("Start Chat", MenuItemType.Standard, openUserChannel)); - - return items.ToArray(); - } - } - - private void openUserChannel() - { - chatManager?.OpenPrivateChannel(user); - chatOverlay?.Show(); - } - - private void openUserProfile() - { - profileOverlay?.ShowUser(user); - } - - protected override bool OnHover(HoverEvent e) - { - colouredDrawable.FadeColour(Colour.Lighten(0.4f), 150, Easing.OutQuint); - - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - base.OnHoverLost(e); - - colouredDrawable.FadeColour(Colour, 250, Easing.OutQuint); - } - - private static readonly Color4[] default_colours = - { - Color4Extensions.FromHex("588c7e"), - Color4Extensions.FromHex("b2a367"), - Color4Extensions.FromHex("c98f65"), - Color4Extensions.FromHex("bc5151"), - Color4Extensions.FromHex("5c8bd6"), - Color4Extensions.FromHex("7f6ab7"), - Color4Extensions.FromHex("a368ad"), - Color4Extensions.FromHex("aa6880"), - - Color4Extensions.FromHex("6fad9b"), - Color4Extensions.FromHex("f2e394"), - Color4Extensions.FromHex("f2ae72"), - Color4Extensions.FromHex("f98f8a"), - Color4Extensions.FromHex("7daef4"), - Color4Extensions.FromHex("a691f2"), - Color4Extensions.FromHex("c894d3"), - Color4Extensions.FromHex("d895b0"), - - Color4Extensions.FromHex("53c4a1"), - Color4Extensions.FromHex("eace5c"), - Color4Extensions.FromHex("ea8c47"), - Color4Extensions.FromHex("fc4f4f"), - Color4Extensions.FromHex("3d94ea"), - Color4Extensions.FromHex("7760ea"), - Color4Extensions.FromHex("af52c6"), - Color4Extensions.FromHex("e25696"), - - Color4Extensions.FromHex("677c66"), - Color4Extensions.FromHex("9b8732"), - Color4Extensions.FromHex("8c5129"), - Color4Extensions.FromHex("8c3030"), - Color4Extensions.FromHex("1f5d91"), - Color4Extensions.FromHex("4335a5"), - Color4Extensions.FromHex("812a96"), - Color4Extensions.FromHex("992861"), - }; - } } } diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs new file mode 100644 index 0000000000..c8c7d38ce6 --- /dev/null +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -0,0 +1,222 @@ +// 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 osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; +using osu.Framework.Localisation; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Chat; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.Chat +{ + public partial class DrawableUsername : OsuClickableContainer, IHasContextMenu + { + public new Color4 Colour { get; private set; } + + public float FontSize + { + set => drawableText.Font = OsuFont.GetFont(size: value, weight: FontWeight.Bold, italics: true); + } + + public LocalisableString Text + { + set => drawableText.Text = value; + } + + public override float Width + { + get => base.Width; + set => base.Width = drawableText.MaxWidth = value; + } + + [Resolved(canBeNull: false)] + private IAPIProvider api { get; set; } = null!; + + [Resolved(canBeNull: false)] + private OsuColour osuColours { get; set; } = null!; + + [Resolved] + private ChannelManager? chatManager { get; set; } + + [Resolved] + private ChatOverlay? chatOverlay { get; set; } + + [Resolved] + private UserProfileOverlay? profileOverlay { get; set; } + + private readonly APIUser user; + private readonly OsuSpriteText drawableText; + + private readonly Drawable colouredDrawable; + + public DrawableUsername(APIUser user) + { + this.user = user; + + Action = openUserProfile; + + drawableText = new OsuSpriteText + { + Shadow = false, + Truncate = true, + EllipsisString = "…", + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + }; + + if (string.IsNullOrWhiteSpace(user.Colour)) + { + Colour = default_colours[user.Id % default_colours.Length]; + + Child = colouredDrawable = drawableText; + } + else + { + Colour = Color4Extensions.FromHex(user.Colour); + + Child = new Container + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Masking = true, + CornerRadius = 4, + EdgeEffect = new EdgeEffectParameters + { + Roundness = 1, + Radius = 1, + Colour = Color4.Black.Opacity(0.3f), + Offset = new Vector2(0, 1), + Type = EdgeEffectType.Shadow, + }, + Child = new Container + { + AutoSizeAxes = Axes.Both, + Masking = true, + CornerRadius = 4, + Children = new[] + { + colouredDrawable = new Box + { + RelativeSizeAxes = Axes.Both, + }, + new Container + { + AutoSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = 4, Right = 4, Bottom = 1, Top = -2 }, + Child = drawableText, + } + } + } + }; + } + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + drawableText.Colour = osuColours.ChatBlue; + colouredDrawable.Colour = Colour; + } + + public MenuItem[] ContextMenuItems + { + get + { + if (user.Equals(APIUser.SYSTEM_USER)) + return Array.Empty(); + + List items = new List + { + new OsuMenuItem("View Profile", MenuItemType.Highlighted, openUserProfile) + }; + + if (!user.Equals(api.LocalUser.Value)) + items.Add(new OsuMenuItem("Start Chat", MenuItemType.Standard, openUserChannel)); + + return items.ToArray(); + } + } + + private void openUserChannel() + { + chatManager?.OpenPrivateChannel(user); + chatOverlay?.Show(); + } + + private void openUserProfile() + { + profileOverlay?.ShowUser(user); + } + + protected override bool OnHover(HoverEvent e) + { + colouredDrawable.FadeColour(Colour.Lighten(0.4f), 150, Easing.OutQuint); + + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + + colouredDrawable.FadeColour(Colour, 250, Easing.OutQuint); + } + + private static readonly Color4[] default_colours = + { + Color4Extensions.FromHex("588c7e"), + Color4Extensions.FromHex("b2a367"), + Color4Extensions.FromHex("c98f65"), + Color4Extensions.FromHex("bc5151"), + Color4Extensions.FromHex("5c8bd6"), + Color4Extensions.FromHex("7f6ab7"), + Color4Extensions.FromHex("a368ad"), + Color4Extensions.FromHex("aa6880"), + + Color4Extensions.FromHex("6fad9b"), + Color4Extensions.FromHex("f2e394"), + Color4Extensions.FromHex("f2ae72"), + Color4Extensions.FromHex("f98f8a"), + Color4Extensions.FromHex("7daef4"), + Color4Extensions.FromHex("a691f2"), + Color4Extensions.FromHex("c894d3"), + Color4Extensions.FromHex("d895b0"), + + Color4Extensions.FromHex("53c4a1"), + Color4Extensions.FromHex("eace5c"), + Color4Extensions.FromHex("ea8c47"), + Color4Extensions.FromHex("fc4f4f"), + Color4Extensions.FromHex("3d94ea"), + Color4Extensions.FromHex("7760ea"), + Color4Extensions.FromHex("af52c6"), + Color4Extensions.FromHex("e25696"), + + Color4Extensions.FromHex("677c66"), + Color4Extensions.FromHex("9b8732"), + Color4Extensions.FromHex("8c5129"), + Color4Extensions.FromHex("8c3030"), + Color4Extensions.FromHex("1f5d91"), + Color4Extensions.FromHex("4335a5"), + Color4Extensions.FromHex("812a96"), + Color4Extensions.FromHex("992861"), + }; + } +} From 80b0e4a99da48122dd4cfbc2224ab3681bda8a45 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 16:07:21 +0900 Subject: [PATCH 0849/2991] Rename `Colour` to avoid conflict with `Drawable.Colour` --- osu.Game/Overlays/Chat/ChatLine.cs | 2 +- osu.Game/Overlays/Chat/DrawableUsername.cs | 26 +++++++++++----------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index 4d5fbaac42..2b8718939e 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -139,7 +139,7 @@ namespace osu.Game.Overlays.Chat CornerRadius = 2f, Masking = true, RelativeSizeAxes = Axes.Both, - Colour = drawableUsername.Colour.Darken(1f), + Colour = drawableUsername.AccentColour.Darken(1f), Depth = float.MaxValue, Child = new Box { RelativeSizeAxes = Axes.Both } }); diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs index c8c7d38ce6..d6dbb76f37 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -27,7 +27,7 @@ namespace osu.Game.Overlays.Chat { public partial class DrawableUsername : OsuClickableContainer, IHasContextMenu { - public new Color4 Colour { get; private set; } + public Color4 AccentColour { get; } public float FontSize { @@ -45,19 +45,19 @@ namespace osu.Game.Overlays.Chat set => base.Width = drawableText.MaxWidth = value; } - [Resolved(canBeNull: false)] + [Resolved] private IAPIProvider api { get; set; } = null!; - [Resolved(canBeNull: false)] - private OsuColour osuColours { get; set; } = null!; - [Resolved] + private OsuColour colours { get; set; } = null!; + + [Resolved(canBeNull: true)] private ChannelManager? chatManager { get; set; } - [Resolved] + [Resolved(canBeNull: true)] private ChatOverlay? chatOverlay { get; set; } - [Resolved] + [Resolved(canBeNull: true)] private UserProfileOverlay? profileOverlay { get; set; } private readonly APIUser user; @@ -82,13 +82,13 @@ namespace osu.Game.Overlays.Chat if (string.IsNullOrWhiteSpace(user.Colour)) { - Colour = default_colours[user.Id % default_colours.Length]; + AccentColour = default_colours[user.Id % default_colours.Length]; Child = colouredDrawable = drawableText; } else { - Colour = Color4Extensions.FromHex(user.Colour); + AccentColour = Color4Extensions.FromHex(user.Colour); Child = new Container { @@ -132,8 +132,8 @@ namespace osu.Game.Overlays.Chat { base.LoadComplete(); - drawableText.Colour = osuColours.ChatBlue; - colouredDrawable.Colour = Colour; + drawableText.Colour = colours.ChatBlue; + colouredDrawable.Colour = AccentColour; } public MenuItem[] ContextMenuItems @@ -168,7 +168,7 @@ namespace osu.Game.Overlays.Chat protected override bool OnHover(HoverEvent e) { - colouredDrawable.FadeColour(Colour.Lighten(0.4f), 150, Easing.OutQuint); + colouredDrawable.FadeColour(AccentColour.Lighten(0.4f), 150, Easing.OutQuint); return base.OnHover(e); } @@ -177,7 +177,7 @@ namespace osu.Game.Overlays.Chat { base.OnHoverLost(e); - colouredDrawable.FadeColour(Colour, 250, Easing.OutQuint); + colouredDrawable.FadeColour(AccentColour, 250, Easing.OutQuint); } private static readonly Color4[] default_colours = From 24ee363563d23cf558011b1bad1e0cacdfa17295 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 16:12:17 +0900 Subject: [PATCH 0850/2991] Only hover when hovering actual text --- osu.Game/Overlays/Chat/DrawableUsername.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs index d6dbb76f37..4a3aa6e53f 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -29,6 +29,9 @@ namespace osu.Game.Overlays.Chat { public Color4 AccentColour { get; } + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => + Child.ReceivePositionalInputAt(screenSpacePos); + public float FontSize { set => drawableText.Font = OsuFont.GetFont(size: value, weight: FontWeight.Bold, italics: true); From f7b7b58718fbff59fdb39a382f5a1c06374245ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 16:20:01 +0900 Subject: [PATCH 0851/2991] Adjust colour and tween to feel better --- osu.Game/Overlays/Chat/DrawableUsername.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs index 4a3aa6e53f..7026d519a5 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -171,7 +171,7 @@ namespace osu.Game.Overlays.Chat protected override bool OnHover(HoverEvent e) { - colouredDrawable.FadeColour(AccentColour.Lighten(0.4f), 150, Easing.OutQuint); + colouredDrawable.FadeColour(AccentColour.Lighten(0.6f), 30, Easing.OutQuint); return base.OnHover(e); } @@ -180,7 +180,7 @@ namespace osu.Game.Overlays.Chat { base.OnHoverLost(e); - colouredDrawable.FadeColour(AccentColour, 250, Easing.OutQuint); + colouredDrawable.FadeColour(AccentColour, 800, Easing.OutQuint); } private static readonly Color4[] default_colours = From b1ce93e7bff368d6852d4cc914b79ee43b574ed9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 16:55:39 +0900 Subject: [PATCH 0852/2991] Add fallback stable sort to avoid any change of misordered local messages --- osu.Game/Online/Chat/Message.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/Message.cs b/osu.Game/Online/Chat/Message.cs index 4c86c963b7..8ea3ca0fc7 100644 --- a/osu.Game/Online/Chat/Message.cs +++ b/osu.Game/Online/Chat/Message.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; +using System.Threading; using Newtonsoft.Json; using osu.Game.Online.API.Requests.Responses; @@ -59,9 +60,14 @@ namespace osu.Game.Online.Chat /// The s' and s are according to public List Links; + private static long constructionOrderStatic; + private readonly long constructionOrder; + public Message(long? id) { Id = id; + + constructionOrder = Interlocked.Increment(ref constructionOrderStatic); } public int CompareTo(Message other) @@ -69,7 +75,13 @@ namespace osu.Game.Online.Chat if (Id.HasValue && other.Id.HasValue) return Id.Value.CompareTo(other.Id.Value); - return Timestamp.CompareTo(other.Timestamp); + int timestampComparison = Timestamp.CompareTo(other.Timestamp); + + if (timestampComparison != 0) + return timestampComparison; + + // Timestamp might not be accurate enough to make a stable sorting decision. + return constructionOrder.CompareTo(other.constructionOrder); } public virtual bool Equals(Message other) From c4b88e4e5a53b09ce62921c57a039cc8de5cdcf2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 17:07:57 +0900 Subject: [PATCH 0853/2991] Fix flaky test conditions in `TestSceneReplayDownloadButton` --- .../Gameplay/TestSceneReplayDownloadButton.cs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs index c473278fdc..6ccf73d8ff 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayDownloadButton.cs @@ -107,7 +107,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for load", () => downloadButton.IsLoaded); - AddAssert("state is available", () => downloadButton.State.Value == DownloadState.NotDownloaded); + checkState(DownloadState.NotDownloaded); AddStep("click button", () => { @@ -133,7 +133,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for load", () => downloadButton.IsLoaded); - AddAssert("state is not downloaded", () => downloadButton.State.Value == DownloadState.NotDownloaded); + checkState(DownloadState.NotDownloaded); AddAssert("button is not enabled", () => !downloadButton.ChildrenOfType().First().Enabled.Value); } @@ -155,7 +155,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for load", () => downloadButton.IsLoaded); - AddUntilStep("state is not downloaded", () => downloadButton.State.Value == DownloadState.NotDownloaded); + checkState(DownloadState.NotDownloaded); AddAssert("button is not enabled", () => !downloadButton.ChildrenOfType().First().Enabled.Value); } @@ -174,17 +174,16 @@ namespace osu.Game.Tests.Visual.Gameplay }); AddUntilStep("wait for load", () => downloadButton.IsLoaded); - - AddUntilStep("state is not downloaded", () => downloadButton.State.Value == DownloadState.NotDownloaded); + checkState(DownloadState.NotDownloaded); AddStep("import score", () => imported = scoreManager.Import(getScoreInfo(true))); - AddUntilStep("state is available", () => downloadButton.State.Value == DownloadState.LocallyAvailable); + checkState(DownloadState.LocallyAvailable); AddAssert("button is enabled", () => downloadButton.ChildrenOfType().First().Enabled.Value); AddStep("delete score", () => scoreManager.Delete(imported.Value)); - AddUntilStep("state is not downloaded", () => downloadButton.State.Value == DownloadState.NotDownloaded); + checkState(DownloadState.NotDownloaded); AddAssert("button is not enabled", () => !downloadButton.ChildrenOfType().First().Enabled.Value); } @@ -202,10 +201,13 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for load", () => downloadButton.IsLoaded); - AddAssert("state is unknown", () => downloadButton.State.Value == DownloadState.Unknown); + checkState(DownloadState.Unknown); AddAssert("button is not enabled", () => !downloadButton.ChildrenOfType().First().Enabled.Value); } + private void checkState(DownloadState expectedState) => + AddUntilStep($"state is {expectedState}", () => downloadButton.State.Value, () => Is.EqualTo(expectedState)); + private ScoreInfo getScoreInfo(bool replayAvailable, bool hasOnlineId = true) => new ScoreInfo { OnlineID = hasOnlineId ? online_score_id : 0, From 1bb32ec24d73681c74690451ce2a513169ec8289 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 17:35:50 +0900 Subject: [PATCH 0854/2991] Attempt to fix flaky `TestHoldForMenuDoesWorkWhenHidden` Seems like the most likely cause. --- osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 94f9b4262d..29fadd151f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Diagnostics; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; @@ -187,18 +188,22 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestInputDoesntWorkWhenHUDHidden() { - SongProgressBar getSongProgress() => hudOverlay.ChildrenOfType().Single(); + SongProgressBar? getSongProgress() => hudOverlay.ChildrenOfType().SingleOrDefault(); bool seeked = false; createNew(); + AddUntilStep("wait for song progress", () => getSongProgress() != null); + AddStep("bind seek", () => { seeked = false; var progress = getSongProgress(); + Debug.Assert(progress != null); + progress.ShowHandle = true; progress.OnSeek += _ => seeked = true; }); From bb0237d4a96a75e17034c5309b0e25269977896e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 17:49:08 +0900 Subject: [PATCH 0855/2991] Fix nullability inspection on disposal path --- .../UI/DrawableRulesetDependenciesProvidingContainer.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/DrawableRulesetDependenciesProvidingContainer.cs b/osu.Game/Rulesets/UI/DrawableRulesetDependenciesProvidingContainer.cs index 1efe72fdf3..6c213497dd 100644 --- a/osu.Game/Rulesets/UI/DrawableRulesetDependenciesProvidingContainer.cs +++ b/osu.Game/Rulesets/UI/DrawableRulesetDependenciesProvidingContainer.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -28,7 +29,8 @@ namespace osu.Game.Rulesets.UI { base.Dispose(isDisposing); - rulesetDependencies?.Dispose(); + if (rulesetDependencies.IsNotNull()) + rulesetDependencies.Dispose(); } } } From 5ce2d6f54a78235bff651cfabce5152207724d81 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 Nov 2022 18:13:53 +0900 Subject: [PATCH 0856/2991] Hide the game mouse cursor when playing osu!catch with relax mod --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 12 ++++++++++++ .../UI/CatchRelaxCursorContainer.cs | 15 +++++++++++++++ osu.Game/Rulesets/UI/Playfield.cs | 10 +++++----- 3 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/UI/CatchRelaxCursorContainer.cs diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 4df297565e..cd8caa43b8 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -3,15 +3,19 @@ #nullable disable +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawables; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI.Scrolling; using osuTK; +using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.UI { @@ -49,6 +53,14 @@ namespace osu.Game.Rulesets.Catch.UI this.difficulty = difficulty; } + protected override GameplayCursorContainer CreateCursor() + { + if (Mods.Any(m => m is ModRelax)) + return new CatchRelaxCursorContainer(); + + return base.CreateCursor(); + } + [BackgroundDependencyLoader] private void load() { diff --git a/osu.Game.Rulesets.Catch/UI/CatchRelaxCursorContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRelaxCursorContainer.cs new file mode 100644 index 0000000000..f30b8f0f36 --- /dev/null +++ b/osu.Game.Rulesets.Catch/UI/CatchRelaxCursorContainer.cs @@ -0,0 +1,15 @@ +// 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.Graphics; +using osu.Game.Rulesets.UI; + +namespace osu.Game.Rulesets.Catch.UI +{ + public partial class CatchRelaxCursorContainer : GameplayCursorContainer + { + // Just hide the cursor in relax. + // The main goal here is to show that we have a cursor so the game never shows the global one. + protected override Drawable CreateCursor() => Empty(); + } +} diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 859be6e210..abb057f9af 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.UI public readonly BindableBool DisplayJudgements = new BindableBool(true); [Resolved(CanBeNull = true)] - private IReadOnlyList mods { get; set; } + protected IReadOnlyList Mods { get; private set; } private readonly HitObjectEntryManager entryManager = new HitObjectEntryManager(); @@ -243,9 +243,9 @@ namespace osu.Game.Rulesets.UI { base.Update(); - if (!IsNested && mods != null) + if (!IsNested && Mods != null) { - foreach (var mod in mods) + foreach (var mod in Mods) { if (mod is IUpdatableByPlayfield updatable) updatable.Update(this); @@ -374,9 +374,9 @@ namespace osu.Game.Rulesets.UI // If this is the first time this DHO is being used, then apply the DHO mods. // This is done before Apply() so that the state is updated once when the hitobject is applied. - if (mods != null) + if (Mods != null) { - foreach (var m in mods.OfType()) + foreach (var m in Mods.OfType()) m.ApplyToDrawableHitObject(dho); } } From f5d85f5774a8de446420434a0d931c5c4f724dd8 Mon Sep 17 00:00:00 2001 From: Piggey Date: Wed, 30 Nov 2022 10:51:42 +0100 Subject: [PATCH 0857/2991] make `ExportStorage` protected --- osu.Game/Database/LegacyExporter.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 16d7441dde..9f440f3728 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -23,11 +23,11 @@ namespace osu.Game.Database protected readonly Storage UserFileStorage; - private readonly Storage exportStorage; + protected readonly Storage ExportStorage; protected LegacyExporter(Storage storage) { - exportStorage = storage.GetStorageForDirectory(@"exports"); + ExportStorage = storage.GetStorageForDirectory(@"exports"); UserFileStorage = storage.GetStorageForDirectory(@"files"); } @@ -35,14 +35,14 @@ namespace osu.Game.Database /// Exports an item to a legacy (.zip based) package. /// /// The item to export. - public void Export(TModel item) + public virtual void Export(TModel item) { string filename = $"{item.GetDisplayString().GetValidFilename()}{FileExtension}"; - using (var stream = exportStorage.CreateFileSafely(filename)) + using (var stream = ExportStorage.CreateFileSafely(filename)) ExportModelTo(item, stream); - exportStorage.PresentFileExternally(filename); + ExportStorage.PresentFileExternally(filename); } /// From 5e74c4e3b7cbf96e7c635bd05739166835f71ce3 Mon Sep 17 00:00:00 2001 From: Piggey Date: Wed, 30 Nov 2022 10:52:41 +0100 Subject: [PATCH 0858/2991] override `LegacyScoreExporter.Export()` to not overwrite files --- osu.Game/Database/LegacyScoreExporter.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index 6fa02b957d..76828ad102 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -8,6 +8,7 @@ using System.Linq; using osu.Framework.Platform; using osu.Game.Extensions; using osu.Game.Scoring; +using osu.Game.Utils; namespace osu.Game.Database { @@ -29,5 +30,22 @@ namespace osu.Game.Database using (var inputStream = UserFileStorage.GetStream(file.File.GetStoragePath())) inputStream.CopyTo(outputStream); } + + public override void Export(ScoreInfo item) + { + var itemFilename = item.GetDisplayString().GetValidFilename(); + + var existingExports = ExportStorage.GetFiles("", $"{itemFilename}*{FileExtension}").ToArray(); + + // trim the file extension + for (int i = 0; i < existingExports.Length; i++) + existingExports[i] = existingExports[i].TrimEnd(FileExtension.ToCharArray()); + + string filename = $"{NamingUtils.GetNextBestName(existingExports, itemFilename)}{FileExtension}"; + using (var stream = ExportStorage.CreateFileSafely(filename)) + ExportModelTo(item, stream); + + ExportStorage.PresentFileExternally(filename); + } } } From 660ad913ec54db3f6192e0e10bd69dca6dc7f049 Mon Sep 17 00:00:00 2001 From: Piggey Date: Wed, 30 Nov 2022 11:06:44 +0100 Subject: [PATCH 0859/2991] oh wait this affects all of the legacy exporters --- osu.Game/Database/LegacyExporter.cs | 21 +++++++++++++++------ osu.Game/Database/LegacyScoreExporter.cs | 18 ------------------ 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 9f440f3728..430505e855 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -4,8 +4,10 @@ #nullable disable using System.IO; +using System.Linq; using osu.Framework.Platform; using osu.Game.Extensions; +using osu.Game.Utils; using SharpCompress.Archives.Zip; namespace osu.Game.Database @@ -23,11 +25,11 @@ namespace osu.Game.Database protected readonly Storage UserFileStorage; - protected readonly Storage ExportStorage; + private readonly Storage exportStorage; protected LegacyExporter(Storage storage) { - ExportStorage = storage.GetStorageForDirectory(@"exports"); + exportStorage = storage.GetStorageForDirectory(@"exports"); UserFileStorage = storage.GetStorageForDirectory(@"files"); } @@ -35,14 +37,21 @@ namespace osu.Game.Database /// Exports an item to a legacy (.zip based) package. /// /// The item to export. - public virtual void Export(TModel item) + public void Export(TModel item) { - string filename = $"{item.GetDisplayString().GetValidFilename()}{FileExtension}"; + var itemFilename = item.GetDisplayString().GetValidFilename(); - using (var stream = ExportStorage.CreateFileSafely(filename)) + var existingExports = exportStorage.GetFiles("", $"{itemFilename}*{FileExtension}").ToArray(); + + // trim the file extension + for (int i = 0; i < existingExports.Length; i++) + existingExports[i] = existingExports[i].TrimEnd(FileExtension.ToCharArray()); + + string filename = $"{NamingUtils.GetNextBestName(existingExports, itemFilename)}{FileExtension}"; + using (var stream = exportStorage.CreateFileSafely(filename)) ExportModelTo(item, stream); - ExportStorage.PresentFileExternally(filename); + exportStorage.PresentFileExternally(filename); } /// diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index 76828ad102..6fa02b957d 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -8,7 +8,6 @@ using System.Linq; using osu.Framework.Platform; using osu.Game.Extensions; using osu.Game.Scoring; -using osu.Game.Utils; namespace osu.Game.Database { @@ -30,22 +29,5 @@ namespace osu.Game.Database using (var inputStream = UserFileStorage.GetStream(file.File.GetStoragePath())) inputStream.CopyTo(outputStream); } - - public override void Export(ScoreInfo item) - { - var itemFilename = item.GetDisplayString().GetValidFilename(); - - var existingExports = ExportStorage.GetFiles("", $"{itemFilename}*{FileExtension}").ToArray(); - - // trim the file extension - for (int i = 0; i < existingExports.Length; i++) - existingExports[i] = existingExports[i].TrimEnd(FileExtension.ToCharArray()); - - string filename = $"{NamingUtils.GetNextBestName(existingExports, itemFilename)}{FileExtension}"; - using (var stream = ExportStorage.CreateFileSafely(filename)) - ExportModelTo(item, stream); - - ExportStorage.PresentFileExternally(filename); - } } } From 956acbc86fd148d73e273f71ff7761b1e1c4bf63 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:11:54 +0300 Subject: [PATCH 0860/2991] Use fixed width --- osu.Game/Overlays/Comments/CancellableCommentEditor.cs | 2 +- osu.Game/Overlays/Comments/CommentEditor.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs index 499c158ccd..b22a9d6c6c 100644 --- a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -31,8 +31,8 @@ namespace osu.Game.Overlays.Comments { public CancelButton() { + Width = 90; Height = 25; - AutoSizeAxes = Axes.X; } protected override SpriteText CreateText() => new OsuSpriteText diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index be196c2085..9755f45036 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -194,8 +194,8 @@ namespace osu.Game.Overlays.Comments public EditorCommitButton() { + Width = 90; Height = 25; - AutoSizeAxes = Axes.X; Add(spinner = new LoadingSpinner { Anchor = Anchor.Centre, From f4a8ac60a8c2643e1008e40477998f8563b44a4d Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:12:10 +0300 Subject: [PATCH 0861/2991] Revert autosizing in OsuButton --- osu.Game/Graphics/UserInterface/OsuButton.cs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index 69e8dfef84..fa61b06cff 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -175,17 +175,6 @@ namespace osu.Game.Graphics.UserInterface base.OnMouseUp(e); } - public new Axes AutoSizeAxes - { - get => base.AutoSizeAxes; - set - { - base.AutoSizeAxes = value; - Content.RelativeSizeAxes = ~value; - Content.AutoSizeAxes = value; - } - } - protected virtual SpriteText CreateText() => new OsuSpriteText { Depth = -1, From 642e0ac718ed41d8400c4b3c53fbf4a15403574f Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:25:18 +0300 Subject: [PATCH 0862/2991] Increase footer height to look better with default buttons --- osu.Game/Overlays/Comments/CommentEditor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 9755f45036..bb2d42b8c2 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -79,7 +79,7 @@ namespace osu.Game.Overlays.Comments { Name = @"Footer", RelativeSizeAxes = Axes.X, - Height = 35, + Height = 40, Padding = new MarginPadding { Horizontal = side_padding }, Children = new Drawable[] { @@ -87,7 +87,7 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold), + Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold), Text = FooterText }, ButtonsContainer = new FillFlowContainer From 5ea824534b9688cb412969acf48e03613fcc738a Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:25:59 +0300 Subject: [PATCH 0863/2991] Use default button --- .../Comments/CancellableCommentEditor.cs | 28 ++++--------------- osu.Game/Overlays/Comments/CommentEditor.cs | 13 ++------- 2 files changed, 7 insertions(+), 34 deletions(-) diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs index b22a9d6c6c..7418ba344b 100644 --- a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -4,9 +4,6 @@ using System; using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Sprites; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Resources.Localisation.Web; @@ -19,30 +16,15 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load() { - ButtonsContainer.Add(new CancelButton + ButtonsContainer.Add(new RoundedButton { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - Action = () => OnCancel?.Invoke() + Action = () => OnCancel?.Invoke(), + Text = CommonStrings.ButtonsCancel, + Width = 100, + Height = 30, }); } - - private sealed partial class CancelButton : RoundedButton - { - public CancelButton() - { - Width = 90; - Height = 25; - } - - protected override SpriteText CreateText() => new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), - Margin = new MarginPadding { Horizontal = 20 }, - Text = CommonStrings.ButtonsCancel - }; - } } } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index bb2d42b8c2..c9e1f6d224 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -194,8 +194,8 @@ namespace osu.Game.Overlays.Comments public EditorCommitButton() { - Width = 90; - Height = 25; + Width = 100; + Height = 30; Add(spinner = new LoadingSpinner { Anchor = Anchor.Centre, @@ -213,15 +213,6 @@ namespace osu.Game.Overlays.Comments Enabled.Value = !IsLoading && !e.NewValue; }, true); } - - protected override SpriteText CreateText() => text = new OsuSpriteText - { - AlwaysPresent = true, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), - Margin = new MarginPadding { Horizontal = 20 }, - }; } } } From f0922d34bb4e1a69df7af0ee34d0a1171f47e2fb Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:30:00 +0300 Subject: [PATCH 0864/2991] Fix cancel test failure --- osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index 81cc5c9572..61c3fc54ad 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -95,7 +95,7 @@ namespace osu.Game.Tests.Visual.UserInterface { AddStep("click cancel button", () => { - InputManager.MoveMouseTo(cancellableCommentEditor.ButtonsContainer); + InputManager.MoveMouseTo(cancellableCommentEditor.ButtonsContainer[1]); InputManager.Click(MouseButton.Left); }); From a8422961dc1ae152bd50ca1583326ba82cd09c20 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:30:57 +0300 Subject: [PATCH 0865/2991] Rename button spinner prop again --- .../UserInterface/TestSceneCommentEditor.cs | 4 ++-- osu.Game/Overlays/Comments/CommentEditor.cs | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index 61c3fc54ad..43dcba99df 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -116,9 +116,9 @@ namespace osu.Game.Tests.Visual.UserInterface private void onCommit(string value) { - CommitButton.IsLoading = true; + CommitButton.IsLoadingSpinnerShown = true; CommittedText = value; - Scheduler.AddDelayed(() => CommitButton.IsLoading = false, 1000); + Scheduler.AddDelayed(() => CommitButton.IsLoadingSpinnerShown = false, 1000); } protected override LocalisableString FooterText => @"Footer text. And it is pretty long. Cool."; diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index c9e1f6d224..458b4b2a2d 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Comments /// /// Whether editor is waiting for submit action to complete. /// - public bool IsSubmitting => CommitButton.IsLoading; + public bool IsSubmitting => CommitButton.IsLoadingSpinnerShown; protected abstract LocalisableString FooterText { get; } @@ -118,7 +118,7 @@ namespace osu.Game.Overlays.Comments textBox.OnCommit += (_, _) => { - if (CommitButton.IsLoading) + if (CommitButton.IsLoadingSpinnerShown) return; CommitButton.TriggerClick(); @@ -171,21 +171,21 @@ namespace osu.Game.Overlays.Comments private const int duration = 200; private readonly LoadingSpinner spinner; - private OsuSpriteText text = null!; + private readonly OsuSpriteText text = null!; public readonly BindableBool IsBlocked = new BindableBool(); - private bool isLoading; + private bool isLoadingSpinnerShown; /// /// Whether loading spinner shown. /// - public bool IsLoading + public bool IsLoadingSpinnerShown { - get => isLoading; + get => isLoadingSpinnerShown; set { - isLoading = value; + isLoadingSpinnerShown = value; Enabled.Value = !value && !IsBlocked.Value; spinner.FadeTo(value ? 1f : 0f, duration, Easing.OutQuint); text.FadeTo(value ? 0f : 1f, duration, Easing.OutQuint); @@ -210,7 +210,7 @@ namespace osu.Game.Overlays.Comments base.LoadComplete(); IsBlocked.BindValueChanged(e => { - Enabled.Value = !IsLoading && !e.NewValue; + Enabled.Value = !IsLoadingSpinnerShown && !e.NewValue; }, true); } } From bedc771e9988584312d1e02356a7d300095c563a Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:32:01 +0300 Subject: [PATCH 0866/2991] Remove useless check --- osu.Game/Overlays/Comments/CommentEditor.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 458b4b2a2d..eb74b7dd38 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -116,13 +116,7 @@ namespace osu.Game.Overlays.Comments } }); - textBox.OnCommit += (_, _) => - { - if (CommitButton.IsLoadingSpinnerShown) - return; - - CommitButton.TriggerClick(); - }; + textBox.OnCommit += (_, _) => CommitButton.TriggerClick(); } protected override void LoadComplete() From 1cc7ffce39e83cf78deeb2e62dd0b77cecd597ad Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:40:47 +0300 Subject: [PATCH 0867/2991] Keep button's text --- osu.Game/Overlays/Comments/CommentEditor.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index eb74b7dd38..b101eaa427 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -165,7 +165,7 @@ namespace osu.Game.Overlays.Comments private const int duration = 200; private readonly LoadingSpinner spinner; - private readonly OsuSpriteText text = null!; + private SpriteText text = null!; public readonly BindableBool IsBlocked = new BindableBool(); @@ -207,6 +207,11 @@ namespace osu.Game.Overlays.Comments Enabled.Value = !IsLoadingSpinnerShown && !e.NewValue; }, true); } + + protected override SpriteText CreateText() + { + return text = base.CreateText(); + } } } } From 43628903a7ec896de1ed47779fee79cfc409e301 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:57:09 +0300 Subject: [PATCH 0868/2991] Make spinner bigger --- osu.Game/Overlays/Comments/CommentEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index b101eaa427..3ca5941e7c 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -194,7 +194,7 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(14), + Size = new Vector2(16), Depth = -2, }); } From 1763618488a0ca76327a3013668db928c87a1c63 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:58:03 +0300 Subject: [PATCH 0869/2991] Fix spinner presense check & field click --- .../UserInterface/TestSceneCommentEditor.cs | 21 +++++++++++++------ osu.Game/Overlays/Comments/CommentEditor.cs | 5 ----- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index 43dcba99df..a0a1c2481f 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -1,12 +1,17 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; +using osu.Framework.Testing; +using osu.Game.Graphics.UserInterface; using osu.Game.Overlays; using osu.Game.Overlays.Comments; using osuTK; @@ -44,15 +49,16 @@ namespace osu.Game.Tests.Visual.UserInterface { AddStep("click on text box", () => { - InputManager.MoveMouseTo(commentEditor); + InputManager.MoveMouseTo(commentEditor.ChildrenOfType().Single()); InputManager.Click(MouseButton.Left); }); AddStep("enter text", () => commentEditor.Current.Value = "text"); AddStep("press Enter", () => InputManager.Key(Key.Enter)); + AddUntilStep("button is loading", () => commentEditor.ButtonLoading); AddAssert("text committed", () => commentEditor.CommittedText == "text"); - AddAssert("button is loading", () => commentEditor.IsSubmitting); + AddUntilStep("button is not loading", () => !commentEditor.ButtonLoading); } [Test] @@ -60,14 +66,14 @@ namespace osu.Game.Tests.Visual.UserInterface { AddStep("click on text box", () => { - InputManager.MoveMouseTo(commentEditor); + InputManager.MoveMouseTo(commentEditor.ChildrenOfType().Single()); InputManager.Click(MouseButton.Left); }); AddStep("press Enter", () => InputManager.Key(Key.Enter)); + AddAssert("button is not loading", () => !commentEditor.ButtonLoading); AddAssert("no text committed", () => commentEditor.CommittedText.Length == 0); - AddAssert("button is not loading", () => !commentEditor.IsSubmitting); } [Test] @@ -75,7 +81,7 @@ namespace osu.Game.Tests.Visual.UserInterface { AddStep("click on text box", () => { - InputManager.MoveMouseTo(commentEditor); + InputManager.MoveMouseTo(commentEditor.ChildrenOfType().Single()); InputManager.Click(MouseButton.Left); }); AddStep("enter text", () => commentEditor.Current.Value = "some other text"); @@ -86,8 +92,9 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.Click(MouseButton.Left); }); + AddUntilStep("button is loading", () => commentEditor.ButtonLoading); AddAssert("text committed", () => commentEditor.CommittedText == "some other text"); - AddAssert("button is loading", () => commentEditor.IsSubmitting); + AddUntilStep("button is not loading", () => !commentEditor.ButtonLoading); } [Test] @@ -109,6 +116,8 @@ namespace osu.Game.Tests.Visual.UserInterface public string CommittedText { get; private set; } = string.Empty; + public bool ButtonLoading => CommitButton.ChildrenOfType().Single().IsPresent && !CommitButton.ChildrenOfType().Single().IsPresent; + public TestCommentEditor() { OnCommit = onCommit; diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 3ca5941e7c..092a92f935 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -25,11 +25,6 @@ namespace osu.Game.Overlays.Comments public Action? OnCommit; - /// - /// Whether editor is waiting for submit action to complete. - /// - public bool IsSubmitting => CommitButton.IsLoadingSpinnerShown; - protected abstract LocalisableString FooterText { get; } protected abstract LocalisableString CommitButtonText { get; } From 6a61e7076628ac7ffddc860c75c0ff352e6d14ee Mon Sep 17 00:00:00 2001 From: Derrick Timmermans Date: Wed, 30 Nov 2022 12:17:58 +0100 Subject: [PATCH 0870/2991] Expose Ruleset from HitObjectComposer instead --- .../Edit/CatchBlueprintContainer.cs | 4 ++-- .../Edit/CatchHitObjectComposer.cs | 2 +- .../Editor/TestSceneManiaBeatSnapGrid.cs | 1 + .../Edit/ManiaBlueprintContainer.cs | 4 ++-- .../Edit/ManiaHitObjectComposer.cs | 2 +- osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs | 4 ++-- osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs | 2 +- .../Edit/TaikoBlueprintContainer.cs | 4 ++-- .../Edit/TaikoHitObjectComposer.cs | 2 +- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 11 ++++++----- .../Compose/Components/ComposeBlueprintContainer.cs | 8 ++------ 11 files changed, 21 insertions(+), 23 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs b/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs index da45e952ab..9408a9f95c 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs @@ -13,8 +13,8 @@ namespace osu.Game.Rulesets.Catch.Edit { public partial class CatchBlueprintContainer : ComposeBlueprintContainer { - public CatchBlueprintContainer(CatchHitObjectComposer composer, Ruleset ruleset) - : base(composer, ruleset) + public CatchBlueprintContainer(CatchHitObjectComposer composer) + : base(composer) { } diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index fec678a4b6..bbdffbf39c 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -148,7 +148,7 @@ namespace osu.Game.Rulesets.Catch.Edit return result; } - protected override ComposeBlueprintContainer CreateBlueprintContainer() => new CatchBlueprintContainer(this, Ruleset); + protected override ComposeBlueprintContainer CreateBlueprintContainer() => new CatchBlueprintContainer(this); [CanBeNull] private PalpableCatchHitObject getLastSnappableHitObject(double time) diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs index 653c75baac..aca555552f 100644 --- a/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs +++ b/osu.Game.Rulesets.Mania.Tests/Editor/TestSceneManiaBeatSnapGrid.cs @@ -90,6 +90,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Editor public override bool CursorInPlacementArea => false; public TestHitObjectComposer(Playfield playfield) + : base(new ManiaRuleset()) { Playfield = playfield; } diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs index 060073889d..05d8ccc73f 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaBlueprintContainer.cs @@ -13,8 +13,8 @@ namespace osu.Game.Rulesets.Mania.Edit { public partial class ManiaBlueprintContainer : ComposeBlueprintContainer { - public ManiaBlueprintContainer(HitObjectComposer composer, Ruleset ruleset) - : base(composer, ruleset) + public ManiaBlueprintContainer(HitObjectComposer composer) + : base(composer) { } diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs index ff59131c8a..5e577a2964 100644 --- a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs +++ b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Mania.Edit } protected override ComposeBlueprintContainer CreateBlueprintContainer() - => new ManiaBlueprintContainer(this, Ruleset); + => new ManiaBlueprintContainer(this); protected override IReadOnlyList CompositionTools => new HitObjectCompositionTool[] { diff --git a/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs index 58bae7e2b2..173a664902 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs @@ -15,8 +15,8 @@ namespace osu.Game.Rulesets.Osu.Edit { public partial class OsuBlueprintContainer : ComposeBlueprintContainer { - public OsuBlueprintContainer(HitObjectComposer composer, Ruleset ruleset) - : base(composer, ruleset) + public OsuBlueprintContainer(HitObjectComposer composer) + : base(composer) { } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index cf22059133..09ddc420a7 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.Osu.Edit } protected override ComposeBlueprintContainer CreateBlueprintContainer() - => new OsuBlueprintContainer(this, Ruleset); + => new OsuBlueprintContainer(this); public override string ConvertSelectionToString() => string.Join(',', selectedHitObjects.Cast().OrderBy(h => h.StartTime).Select(h => (h.IndexInCurrentCombo + 1).ToString())); diff --git a/osu.Game.Rulesets.Taiko/Edit/TaikoBlueprintContainer.cs b/osu.Game.Rulesets.Taiko/Edit/TaikoBlueprintContainer.cs index 0081f89b7c..6be22f3af0 100644 --- a/osu.Game.Rulesets.Taiko/Edit/TaikoBlueprintContainer.cs +++ b/osu.Game.Rulesets.Taiko/Edit/TaikoBlueprintContainer.cs @@ -12,8 +12,8 @@ namespace osu.Game.Rulesets.Taiko.Edit { public partial class TaikoBlueprintContainer : ComposeBlueprintContainer { - public TaikoBlueprintContainer(HitObjectComposer composer, Ruleset ruleset) - : base(composer, ruleset) + public TaikoBlueprintContainer(HitObjectComposer composer) + : base(composer) { } diff --git a/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs b/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs index 4109bc4887..cff5731181 100644 --- a/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs +++ b/osu.Game.Rulesets.Taiko/Edit/TaikoHitObjectComposer.cs @@ -24,6 +24,6 @@ namespace osu.Game.Rulesets.Taiko.Edit }; protected override ComposeBlueprintContainer CreateBlueprintContainer() - => new TaikoBlueprintContainer(this, Ruleset); + => new TaikoBlueprintContainer(this); } } diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 8279150aa8..b5b7400f64 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -45,8 +45,6 @@ namespace osu.Game.Rulesets.Edit { protected IRulesetConfigManager Config { get; private set; } - protected readonly Ruleset Ruleset; - // Provides `Playfield` private DependencyContainer dependencies; @@ -74,8 +72,8 @@ namespace osu.Game.Rulesets.Edit private IBindable hasTiming; protected HitObjectComposer(Ruleset ruleset) + : base(ruleset) { - Ruleset = ruleset; } protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) => @@ -218,7 +216,7 @@ namespace osu.Game.Rulesets.Edit /// /// Construct a relevant blueprint container. This will manage hitobject selection/placement input handling and display logic. /// - protected virtual ComposeBlueprintContainer CreateBlueprintContainer() => new ComposeBlueprintContainer(this, Ruleset); + protected virtual ComposeBlueprintContainer CreateBlueprintContainer() => new ComposeBlueprintContainer(this); /// /// Construct a drawable ruleset for the provided ruleset. @@ -419,8 +417,11 @@ namespace osu.Game.Rulesets.Edit [Cached] public abstract partial class HitObjectComposer : CompositeDrawable, IPositionSnapProvider { - protected HitObjectComposer() + public readonly Ruleset Ruleset; + + protected HitObjectComposer(Ruleset ruleset) { + Ruleset = ruleset; RelativeSizeAxes = Axes.Both; } diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index fc23f1d1b4..cf38cd7261 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -15,7 +15,6 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Game.Audio; using osu.Game.Graphics.UserInterface; -using osu.Game.Rulesets; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Objects; @@ -39,7 +38,6 @@ namespace osu.Game.Screens.Edit.Compose.Components private PlacementBlueprint currentPlacement; - private readonly Ruleset ruleset; /// /// Positional input must be received outside the container's bounds, @@ -47,11 +45,9 @@ namespace osu.Game.Screens.Edit.Compose.Components /// public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; - public ComposeBlueprintContainer(HitObjectComposer composer, Ruleset ruleset) + public ComposeBlueprintContainer(HitObjectComposer composer) : base(composer) { - this.ruleset = ruleset; - placementBlueprintContainer = new Container { RelativeSizeAxes = Axes.Both @@ -63,7 +59,7 @@ namespace osu.Game.Screens.Edit.Compose.Components { TernaryStates = CreateTernaryButtons().ToArray(); - AddInternal(new DrawableRulesetDependenciesProvidingContainer(ruleset) + AddInternal(new DrawableRulesetDependenciesProvidingContainer(Composer.Ruleset) { Child = placementBlueprintContainer }); From 5c8fce1c087cf7ecc8cf642dd8011b3708d15cb5 Mon Sep 17 00:00:00 2001 From: Derrick Timmermans Date: Wed, 30 Nov 2022 13:05:14 +0100 Subject: [PATCH 0871/2991] Remove extra blank line --- .../Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index cf38cd7261..713625c15f 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -38,7 +38,6 @@ namespace osu.Game.Screens.Edit.Compose.Components private PlacementBlueprint currentPlacement; - /// /// Positional input must be received outside the container's bounds, /// in order to handle composer blueprints which are partially offscreen. From b99ddc2acf47f65e2c0c25290dbff44d0d06ec13 Mon Sep 17 00:00:00 2001 From: Piggey Date: Wed, 30 Nov 2022 15:36:08 +0100 Subject: [PATCH 0872/2991] use `.Select()` to trim the file extension from filename --- osu.Game/Database/LegacyExporter.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 430505e855..4b65e26145 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -3,6 +3,7 @@ #nullable disable +using System.Collections.Generic; using System.IO; using System.Linq; using osu.Framework.Platform; @@ -39,13 +40,11 @@ namespace osu.Game.Database /// The item to export. public void Export(TModel item) { - var itemFilename = item.GetDisplayString().GetValidFilename(); + string itemFilename = item.GetDisplayString().GetValidFilename(); - var existingExports = exportStorage.GetFiles("", $"{itemFilename}*{FileExtension}").ToArray(); - - // trim the file extension - for (int i = 0; i < existingExports.Length; i++) - existingExports[i] = existingExports[i].TrimEnd(FileExtension.ToCharArray()); + IEnumerable existingExports = exportStorage + .GetFiles("", $"{itemFilename}*{FileExtension}") + .Select(export => export.Substring(0, export.Length - FileExtension.Length)); string filename = $"{NamingUtils.GetNextBestName(existingExports, itemFilename)}{FileExtension}"; using (var stream = exportStorage.CreateFileSafely(filename)) From 8412a441796b5d8bbea63b9a45b5a727084ab725 Mon Sep 17 00:00:00 2001 From: Piggey Date: Wed, 30 Nov 2022 18:32:14 +0100 Subject: [PATCH 0873/2991] create `NamingUtils.GetNextBestFilename()` --- osu.Game/Utils/NamingUtils.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/osu.Game/Utils/NamingUtils.cs b/osu.Game/Utils/NamingUtils.cs index 482e3d0954..ca4667b82a 100644 --- a/osu.Game/Utils/NamingUtils.cs +++ b/osu.Game/Utils/NamingUtils.cs @@ -1,7 +1,9 @@ // 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 System.Text.RegularExpressions; namespace osu.Game.Utils @@ -57,5 +59,19 @@ namespace osu.Game.Utils ? desiredName : $"{desiredName} ({bestNumber})"; } + + /// + /// Given a set of and a desired target + /// finds a filename closest to that is not in + /// + /// SHOULD NOT CONTAIN the file extension. + /// + /// + public static string GetNextBestFilename(IEnumerable existingFilenames, string desiredName, string fileExtension) + { + var stripped = existingFilenames.Select(filename => filename.Substring(0, filename.Length - fileExtension.Length)); + + return $"{GetNextBestName(stripped, desiredName)}{fileExtension}"; + } } } From 8b856f1c89d9f45d566984e0b4c5319f18ddd346 Mon Sep 17 00:00:00 2001 From: Piggey Date: Wed, 30 Nov 2022 18:32:53 +0100 Subject: [PATCH 0874/2991] make `LegacyExporter` use `NamingUtils.GetNextBestFilename()` --- osu.Game/Database/LegacyExporter.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 4b65e26145..e9789ca777 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -3,9 +3,9 @@ #nullable disable +using System; using System.Collections.Generic; using System.IO; -using System.Linq; using osu.Framework.Platform; using osu.Game.Extensions; using osu.Game.Utils; @@ -42,11 +42,9 @@ namespace osu.Game.Database { string itemFilename = item.GetDisplayString().GetValidFilename(); - IEnumerable existingExports = exportStorage - .GetFiles("", $"{itemFilename}*{FileExtension}") - .Select(export => export.Substring(0, export.Length - FileExtension.Length)); + IEnumerable existingExports = exportStorage.GetFiles("", $"{itemFilename}*{FileExtension}"); - string filename = $"{NamingUtils.GetNextBestName(existingExports, itemFilename)}{FileExtension}"; + string filename = NamingUtils.GetNextBestFilename(existingExports, itemFilename, FileExtension); using (var stream = exportStorage.CreateFileSafely(filename)) ExportModelTo(item, stream); From 8f59aad91c77982d7f99dbf81036bfd2601efa9b Mon Sep 17 00:00:00 2001 From: Piggey Date: Wed, 30 Nov 2022 18:37:50 +0100 Subject: [PATCH 0875/2991] unnecessary includes --- osu.Game/Database/LegacyExporter.cs | 1 - osu.Game/Utils/NamingUtils.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index e9789ca777..0a5f787469 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -3,7 +3,6 @@ #nullable disable -using System; using System.Collections.Generic; using System.IO; using osu.Framework.Platform; diff --git a/osu.Game/Utils/NamingUtils.cs b/osu.Game/Utils/NamingUtils.cs index ca4667b82a..2439d4ba22 100644 --- a/osu.Game/Utils/NamingUtils.cs +++ b/osu.Game/Utils/NamingUtils.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.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; From f9a9ab1d9be3f74a2f90cea0ba8176260d775d7a Mon Sep 17 00:00:00 2001 From: Joppe27 Date: Wed, 30 Nov 2022 19:50:47 +0100 Subject: [PATCH 0876/2991] Use BeatSyncedContainer and adjust values to be in line with stable --- .../Skinning/Legacy/LegacyKiaiGlow.cs | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs index 07eb052b20..955deb7f3a 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs @@ -2,10 +2,11 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Audio.Track; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; -using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Graphics.Containers; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; @@ -13,8 +14,10 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { - internal partial class LegacyKiaiGlow : Container + internal partial class LegacyKiaiGlow : BeatSyncedContainer { + private const float colour_compensation = 1.58f; + public LegacyKiaiGlow() { AlwaysPresent = true; @@ -29,13 +32,11 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy Texture = skin.GetTexture("taiko-glow"), Origin = Anchor.Centre, Anchor = Anchor.Centre, - Scale = new Vector2(0.75f), + Scale = new Vector2(0.7f), + Colour = new Colour4(255, 228, 0, 255), }; } - [Resolved(CanBeNull = true)] - private IBeatSyncProvider? beatSyncProvider { get; set; } - [Resolved(CanBeNull = true)] private HealthProcessor? healthProcessor { get; set; } @@ -45,14 +46,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy if (healthProcessor != null) healthProcessor.NewJudgement += onNewJudgement; - - if (beatSyncProvider != null) - { - if (beatSyncProvider.CheckIsKiaiTime()) - this.FadeIn(180); - else - this.FadeOut(180); - } } private void onNewJudgement(JudgementResult result) @@ -60,8 +53,16 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy if (!result.IsHit) return; - this.ScaleTo(1.1f, 50) - .Then().ScaleTo(1f, 50); + this.ScaleTo(1.2f) + .Then().ScaleTo(1f, 80, Easing.OutQuad); + } + + protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) + { + if (effectPoint.KiaiMode) + this.FadeTo(colour_compensation, 180); + else + this.FadeOut(180); } } } From 6ebde9a7473c3e93a3eee67bb844cbad1f5c0eda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 30 Nov 2022 20:00:25 +0100 Subject: [PATCH 0877/2991] Annotate `Playfield.Mods` as maybe-null --- osu.Game/Rulesets/UI/Playfield.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index abb057f9af..a7881678f1 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -93,6 +93,7 @@ namespace osu.Game.Rulesets.UI public readonly BindableBool DisplayJudgements = new BindableBool(true); [Resolved(CanBeNull = true)] + [CanBeNull] protected IReadOnlyList Mods { get; private set; } private readonly HitObjectEntryManager entryManager = new HitObjectEntryManager(); From 285248d55412c9c26ff3648499c64d455dffc7e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 30 Nov 2022 20:01:11 +0100 Subject: [PATCH 0878/2991] Fix potential null dereference in `CatchPlayfield` --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index cd8caa43b8..3df63bbe30 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Catch.UI protected override GameplayCursorContainer CreateCursor() { - if (Mods.Any(m => m is ModRelax)) + if (Mods != null && Mods.Any(m => m is ModRelax)) return new CatchRelaxCursorContainer(); return base.CreateCursor(); From 7f68fe429f7f3fb5c1d533d9f8731cada420d42f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 30 Nov 2022 20:01:59 +0100 Subject: [PATCH 0879/2991] Remove unused using directive --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 3df63bbe30..184ff38cc6 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -15,7 +15,6 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI.Scrolling; using osuTK; -using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.UI { From 77e282ada9522547b887ee18d386dadebbfa2bf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 30 Nov 2022 20:14:35 +0100 Subject: [PATCH 0880/2991] Add test coverage for catch relax mod hiding cursor --- .../Mods/TestSceneCatchModRelax.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs index 8472b995e8..5835ccaf78 100644 --- a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs +++ b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModRelax.cs @@ -4,8 +4,10 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Game.Beatmaps; +using osu.Game.Graphics.Cursor; using osu.Game.Rulesets.Catch.Mods; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.UI; @@ -55,6 +57,21 @@ namespace osu.Game.Rulesets.Catch.Tests.Mods } }); + [Test] + public void TestGameCursorHidden() + { + CreateModTest(new ModTestData + { + Mod = new CatchModRelax(), + Autoplay = false, + PassCondition = () => + { + InputManager.MoveMouseTo(this.ChildrenOfType().Single()); + return this.ChildrenOfType().Single().State.Value == Visibility.Hidden; + } + }); + } + private bool passCondition() { var playfield = this.ChildrenOfType().Single(); From 830e243d12719f2887ab1b67a3601aaed5186275 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 30 Nov 2022 22:53:56 +0100 Subject: [PATCH 0881/2991] Add test coverage for failure case --- .../Gameplay/TestSceneDrawableHitObject.cs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs b/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs index 62863524fe..04fc4cafbd 100644 --- a/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs +++ b/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; @@ -137,6 +138,31 @@ namespace osu.Game.Tests.Gameplay AddAssert("DHO state is correct", () => dho.State.Value == ArmedState.Miss); } + [Test] + public void TestResultSetBeforeLoadComplete() + { + TestDrawableHitObject dho = null; + HitObjectLifetimeEntry lifetimeEntry = null; + AddStep("Create lifetime entry", () => + { + var hitObject = new HitObject { StartTime = Time.Current }; + lifetimeEntry = new HitObjectLifetimeEntry(hitObject) + { + Result = new JudgementResult(hitObject, hitObject.CreateJudgement()) + { + Type = HitResult.Great + } + }; + }); + AddStep("Create DHO and apply entry", () => + { + dho = new TestDrawableHitObject(); + dho.Apply(lifetimeEntry); + Child = dho; + }); + AddAssert("DHO state is correct", () => dho.State.Value, () => Is.EqualTo(ArmedState.Hit)); + } + private partial class TestDrawableHitObject : DrawableHitObject { public const double INITIAL_LIFETIME_OFFSET = 100; From 2e19e93036baf5ccd2ee73fa5cf824fa08ad36a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 30 Nov 2022 22:54:14 +0100 Subject: [PATCH 0882/2991] Rename method --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 4b074f00aa..096132d024 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -199,7 +199,7 @@ namespace osu.Game.Rulesets.Objects.Drawables comboColourBrightness.BindValueChanged(_ => UpdateComboColour()); // Apply transforms - updateStateBasedOnResults(); + updateStateFromResult(); } /// @@ -266,7 +266,7 @@ namespace osu.Game.Rulesets.Objects.Drawables // If not loaded, the state update happens in LoadComplete(). if (IsLoaded) { - updateStateBasedOnResults(); + updateStateFromResult(); // Combo colour may have been applied via a bindable flow while no object entry was attached. // Update here to ensure we're in a good state. @@ -274,7 +274,7 @@ namespace osu.Game.Rulesets.Objects.Drawables } } - private void updateStateBasedOnResults() + private void updateStateFromResult() { if (Result.IsHit) updateState(ArmedState.Hit, true); From bbf023cf682b95fb6bd00bff8bc5800163b78a3d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 1 Dec 2022 16:08:14 +0900 Subject: [PATCH 0883/2991] Fix incorrect culture used when parsing timeline popup textbox content --- .../Timing/IndeterminateSliderWithTextBoxInput.cs | 15 ++++++++++++++- .../Screens/Edit/Timing/SliderWithTextBoxInput.cs | 15 ++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Timing/IndeterminateSliderWithTextBoxInput.cs b/osu.Game/Screens/Edit/Timing/IndeterminateSliderWithTextBoxInput.cs index 36186353f8..64713c7714 100644 --- a/osu.Game/Screens/Edit/Timing/IndeterminateSliderWithTextBoxInput.cs +++ b/osu.Game/Screens/Edit/Timing/IndeterminateSliderWithTextBoxInput.cs @@ -94,7 +94,20 @@ namespace osu.Game.Screens.Edit.Timing try { - slider.Current.Parse(t.Text); + switch (slider.Current) + { + case Bindable bindableInt: + bindableInt.Value = int.Parse(t.Text); + break; + + case Bindable bindableDouble: + bindableDouble.Value = double.Parse(t.Text); + break; + + default: + slider.Current.Parse(t.Text); + break; + } } catch { diff --git a/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs b/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs index e1a5c3b23c..65c5128438 100644 --- a/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs +++ b/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs @@ -58,7 +58,20 @@ namespace osu.Game.Screens.Edit.Timing try { - slider.Current.Parse(t.Text); + switch (slider.Current) + { + case Bindable bindableInt: + bindableInt.Value = int.Parse(t.Text); + break; + + case Bindable bindableDouble: + bindableDouble.Value = double.Parse(t.Text); + break; + + default: + slider.Current.Parse(t.Text); + break; + } } catch { From f34a79b1a9a986615f691130f5ed3c057e98d1e1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 1 Dec 2022 17:03:53 +0900 Subject: [PATCH 0884/2991] Set a better default colour for timeline blueprints when no colour information is available --- .../Compose/Components/Timeline/TimelineHitObjectBlueprint.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index 3e49c31b1e..d089b1e744 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -165,7 +165,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline break; default: - return; + colour = Color4.Gray; + break; } if (IsSelected) From 896f2d8f74041d279dca91bb9dbe8b47e017d2b3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 1 Dec 2022 17:43:54 +0900 Subject: [PATCH 0885/2991] Fix multiple instances of last hitobject time being calculated incorrectly --- osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs | 5 ++--- osu.Game/Beatmaps/Beatmap.cs | 5 ++++- osu.Game/Beatmaps/IBeatmap.cs | 12 ++++++++++++ osu.Game/Rulesets/Objects/BarLineGenerator.cs | 7 ++----- .../UI/Scrolling/DrawableScrollingRuleset.cs | 2 +- osu.Game/Screens/Edit/Editor.cs | 7 ++----- osu.Game/Screens/Play/ReplayPlayer.cs | 4 +--- 7 files changed, 24 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs b/osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs index 55c20eebe9..77cf340b95 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModTargetPractice.cs @@ -17,7 +17,6 @@ using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Beatmaps; @@ -196,8 +195,8 @@ namespace osu.Game.Rulesets.Osu.Mods private IEnumerable generateBeats(IBeatmap beatmap, IReadOnlyCollection originalHitObjects) { - double startTime = originalHitObjects.First().StartTime; - double endTime = originalHitObjects.Last().GetEndTime(); + double startTime = beatmap.HitObjects.First().StartTime; + double endTime = beatmap.GetLastObjectTime(); var beats = beatmap.ControlPointInfo.TimingPoints // Ignore timing points after endTime diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 2d02fb6200..2ab4fe0c79 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -81,9 +81,12 @@ namespace osu.Game.Beatmaps public double GetMostCommonBeatLength() { + if (!HitObjects.Any()) + return ControlPointInfo.TimingPoints.LastOrDefault()?.Time ?? 0; + // The last playable time in the beatmap - the last timing point extends to this time. // Note: This is more accurate and may present different results because osu-stable didn't have the ability to calculate slider durations in this context. - double lastTime = HitObjects.LastOrDefault()?.GetEndTime() ?? ControlPointInfo.TimingPoints.LastOrDefault()?.Time ?? 0; + double lastTime = this.GetLastObjectTime(); var mostCommon = // Construct a set of (beatLength, duration) tuples for each individual timing point. diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs index 0e892b6581..f6771f7adf 100644 --- a/osu.Game/Beatmaps/IBeatmap.cs +++ b/osu.Game/Beatmaps/IBeatmap.cs @@ -4,6 +4,7 @@ #nullable disable using System.Collections.Generic; +using System.Linq; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Timing; using osu.Game.Rulesets.Objects; @@ -102,5 +103,16 @@ namespace osu.Game.Beatmaps addCombo(nested, ref combo); } } + + /// + /// Find the absolute end time of the latest in a beatmap. Will throw if beatmap contains no objects. + /// + /// + /// This correctly accounts for rulesets which have concurrent hitobjects which may have durations, causing the .Last() object + /// to not necessarily have the latest end time. + /// + /// It's not super efficient so calls should be kept to a minimum. + /// + public static double GetLastObjectTime(this IBeatmap beatmap) => beatmap.HitObjects.Max(h => h.GetEndTime()); } } diff --git a/osu.Game/Rulesets/Objects/BarLineGenerator.cs b/osu.Game/Rulesets/Objects/BarLineGenerator.cs index 5c76c43f20..af32c7def3 100644 --- a/osu.Game/Rulesets/Objects/BarLineGenerator.cs +++ b/osu.Game/Rulesets/Objects/BarLineGenerator.cs @@ -27,11 +27,8 @@ namespace osu.Game.Rulesets.Objects if (beatmap.HitObjects.Count == 0) return; - HitObject firstObject = beatmap.HitObjects.First(); - HitObject lastObject = beatmap.HitObjects.Last(); - - double firstHitTime = firstObject.StartTime; - double lastHitTime = 1 + lastObject.GetEndTime(); + double firstHitTime = beatmap.HitObjects.First().StartTime; + double lastHitTime = 1 + beatmap.GetLastObjectTime(); var timingPoints = beatmap.ControlPointInfo.TimingPoints; diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs index 52853d3979..123be0f117 100644 --- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs @@ -114,7 +114,7 @@ namespace osu.Game.Rulesets.UI.Scrolling break; } - double lastObjectTime = Objects.LastOrDefault()?.GetEndTime() ?? double.MaxValue; + double lastObjectTime = Beatmap.GetLastObjectTime(); double baseBeatLength = TimingControlPoint.DEFAULT_BEAT_LENGTH; if (RelativeScaleBeatLengths) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 02130b9662..b8d308cc7c 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -40,7 +40,6 @@ using osu.Game.Overlays.Notifications; using osu.Game.Overlays.OSD; using osu.Game.Rulesets; using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Objects; using osu.Game.Screens.Edit.Components.Menus; using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Compose.Components.Timeline; @@ -538,12 +537,10 @@ namespace osu.Game.Screens.Edit // Seek to last object time, or track end if already there. // Note that in osu-stable subsequent presses when at track end won't return to last object. // This has intentionally been changed to make it more useful. - double? lastObjectTime = editorBeatmap.HitObjects.LastOrDefault()?.GetEndTime(); - - if (lastObjectTime == null || clock.CurrentTime == lastObjectTime) + if (!editorBeatmap.HitObjects.Any() || clock.CurrentTime == editorBeatmap.GetLastObjectTime()) clock.Seek(clock.TrackLength); else - clock.Seek(lastObjectTime.Value); + clock.Seek(editorBeatmap.GetLastObjectTime()); return true; } diff --git a/osu.Game/Screens/Play/ReplayPlayer.cs b/osu.Game/Screens/Play/ReplayPlayer.cs index 4395b96139..c5ef6b1585 100644 --- a/osu.Game/Screens/Play/ReplayPlayer.cs +++ b/osu.Game/Screens/Play/ReplayPlayer.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using osu.Framework.Bindables; using osu.Framework.Input.Bindings; @@ -13,7 +12,6 @@ using osu.Framework.Input.Events; using osu.Game.Beatmaps; using osu.Game.Input.Bindings; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Objects; using osu.Game.Scoring; using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Ranking; @@ -94,7 +92,7 @@ namespace osu.Game.Screens.Play void keyboardSeek(int direction) { - double target = Math.Clamp(GameplayClockContainer.CurrentTime + direction * keyboard_seek_amount, 0, GameplayState.Beatmap.HitObjects.Last().GetEndTime()); + double target = Math.Clamp(GameplayClockContainer.CurrentTime + direction * keyboard_seek_amount, 0, GameplayState.Beatmap.GetLastObjectTime()); Seek(target); } From d9d48516fce4a8cfda3d8b91fd3f1aa55270ce8f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 1 Dec 2022 18:04:04 +0900 Subject: [PATCH 0886/2991] Add test coverage of getting last object time --- .../Formats/LegacyBeatmapDecoderTest.cs | 18 +++++++++ .../mania-last-object-not-latest.osu | 39 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 osu.Game.Tests/Resources/mania-last-object-not-latest.osu diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index c6bdd25e8b..5787bd6066 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -314,6 +314,24 @@ namespace osu.Game.Tests.Beatmaps.Formats } } + [Test] + public void TestGetLastObjectTime() + { + var decoder = new LegacyBeatmapDecoder(); + + using (var resStream = TestResources.OpenResource("mania-last-object-not-latest.osu")) + using (var stream = new LineBufferedReader(resStream)) + { + var beatmap = decoder.Decode(stream); + + Assert.That(beatmap.HitObjects.Last().StartTime, Is.EqualTo(2494)); + Assert.That(beatmap.HitObjects.Last().GetEndTime(), Is.EqualTo(2494)); + + Assert.That(beatmap.HitObjects.Max(h => h.GetEndTime()), Is.EqualTo(2582)); + Assert.That(beatmap.GetLastObjectTime(), Is.EqualTo(2582)); + } + } + [Test] public void TestDecodeBeatmapComboOffsetsOsu() { diff --git a/osu.Game.Tests/Resources/mania-last-object-not-latest.osu b/osu.Game.Tests/Resources/mania-last-object-not-latest.osu new file mode 100644 index 0000000000..51893383d8 --- /dev/null +++ b/osu.Game.Tests/Resources/mania-last-object-not-latest.osu @@ -0,0 +1,39 @@ +osu file format v14 + +[General] +SampleSet: Normal +StackLeniency: 0.7 +Mode: 3 + +[Difficulty] +HPDrainRate:3 +CircleSize:5 +OverallDifficulty:8 +ApproachRate:8 +SliderMultiplier:3.59999990463257 +SliderTickRate:2 + +[TimingPoints] +24,352.941176470588,4,1,1,100,1,0 +6376,-50,4,1,1,100,0,0 + +[HitObjects] +51,192,24,1,0,0:0:0:0: +153,192,200,1,0,0:0:0:0: +358,192,376,1,0,0:0:0:0: +460,192,553,1,0,0:0:0:0: +460,192,729,128,0,1435:0:0:0:0: +358,192,906,128,0,1612:0:0:0:0: +256,192,1082,128,0,1788:0:0:0:0: +153,192,1259,128,0,1965:0:0:0:0: +51,192,1435,128,0,2141:0:0:0:0: +51,192,2318,1,12,0:0:0:0: +153,192,2318,1,4,0:0:0:0: +256,192,2318,1,6,0:0:0:0: +358,192,2318,1,14,0:0:0:0: +460,192,2318,1,0,0:0:0:0: +51,192,2494,128,0,2582:0:0:0:0: +153,192,2494,128,14,2582:0:0:0:0: +256,192,2494,128,6,2582:0:0:0:0: +358,192,2494,128,4,2582:0:0:0:0: +460,192,2494,1,12,0:0:0:0:0: From 18b4317e99921e133aed5549a00e0b31445a63cf Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Thu, 1 Dec 2022 11:57:50 +0100 Subject: [PATCH 0887/2991] Create Basic V2 footer and test --- .../SongSelect/TestSceneSongSelectFooterV2.cs | 29 ++++++++++++++ osu.Game/Screens/Select/FooterV2/FooterV2.cs | 39 +++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs create mode 100644 osu.Game/Screens/Select/FooterV2/FooterV2.cs diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs new file mode 100644 index 0000000000..d61c86b69b --- /dev/null +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs @@ -0,0 +1,29 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Game.Screens.Select.FooterV2; + +namespace osu.Game.Tests.Visual.SongSelect +{ + public partial class TestSceneSongSelectFooterV2 : OsuManualInputManagerTestScene + { + [SetUp] + public void SetUp() => Schedule(() => + { + FooterV2 footer; + + Child = footer = new FooterV2 + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre + }; + }); + + [Test] + public void TestBasic() + { + } + } +} diff --git a/osu.Game/Screens/Select/FooterV2/FooterV2.cs b/osu.Game/Screens/Select/FooterV2/FooterV2.cs new file mode 100644 index 0000000000..10050e24fc --- /dev/null +++ b/osu.Game/Screens/Select/FooterV2/FooterV2.cs @@ -0,0 +1,39 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Input.Events; +using osu.Game.Graphics; + +namespace osu.Game.Screens.Select.FooterV2 +{ + public partial class FooterV2 : CompositeDrawable + { + //Should be 60, setting to 50 for now for the sake of matching the current BackButton height. + private const int height = 50; + + [BackgroundDependencyLoader] + private void load(OsuColour colour) + { + RelativeSizeAxes = Axes.X; + Height = height; + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colour.B5 + } + }; + } + + protected override bool OnMouseDown(MouseDownEvent e) => true; + + protected override bool OnClick(ClickEvent e) => true; + + protected override bool OnHover(HoverEvent e) => true; + } +} From a7f4325d3c473bb616b7b82cc23ceefe7044d115 Mon Sep 17 00:00:00 2001 From: Joppe27 Date: Thu, 1 Dec 2022 12:16:58 +0100 Subject: [PATCH 0888/2991] Revert hacky fade value and fix test --- .../Skinning/TestSceneTaikoKiaiGlow.cs | 4 ++++ osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoKiaiGlow.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoKiaiGlow.cs index 26e2202124..a5e2eb0dbb 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoKiaiGlow.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoKiaiGlow.cs @@ -21,6 +21,8 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning { var controlPointInfo = new ControlPointInfo(); + controlPointInfo.Add(0, new TimingControlPoint { BeatLength = 500 }); + if (withKiai) controlPointInfo.Add(0, new EffectControlPoint { KiaiMode = true }); @@ -28,6 +30,8 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning { ControlPointInfo = controlPointInfo }); + + Beatmap.Value.Track.Start(); } } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs index 955deb7f3a..80b8bc9b11 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs @@ -16,8 +16,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { internal partial class LegacyKiaiGlow : BeatSyncedContainer { - private const float colour_compensation = 1.58f; - public LegacyKiaiGlow() { AlwaysPresent = true; @@ -60,7 +58,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) { if (effectPoint.KiaiMode) - this.FadeTo(colour_compensation, 180); + this.FadeIn(180); else this.FadeOut(180); } From 774eb178a19ca8689f5eb6f5306d229bbc385bbc Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Thu, 1 Dec 2022 13:13:37 +0100 Subject: [PATCH 0889/2991] Add basic button design and footer button addition flow --- .../SongSelect/TestSceneSongSelectFooterV2.cs | 2 + .../Screens/Select/FooterV2/FooterButtonV2.cs | 65 +++++++++++++++++++ osu.Game/Screens/Select/FooterV2/FooterV2.cs | 51 +++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs index d61c86b69b..5a7797b3da 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs @@ -19,6 +19,8 @@ namespace osu.Game.Tests.Visual.SongSelect Anchor = Anchor.Centre, Origin = Anchor.Centre }; + + footer.AddButton(new FooterButtonV2()); }); [Test] diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs new file mode 100644 index 0000000000..daad52eb5e --- /dev/null +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs @@ -0,0 +1,65 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Input.Bindings; +using osu.Framework.Input.Events; +using osu.Game.Graphics.Containers; +using osu.Game.Input.Bindings; +using osu.Game.Overlays; +using osuTK; + +namespace osu.Game.Screens.Select.FooterV2 +{ + public partial class FooterButtonV2 : OsuClickableContainer, IKeyBindingHandler + { + private const int button_height = 120; + private const int button_width = 140; + private const int corner_radius = 10; + + public const float SHEAR_WIDTH = 16; + + [Cached] + private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Aquamarine); + + protected static readonly Vector2 SHEAR = new Vector2(SHEAR_WIDTH / button_height, 0); + + [BackgroundDependencyLoader] + private void load() + { + Shear = SHEAR; + Size = new Vector2(button_width, button_height); + Masking = true; + CornerRadius = corner_radius; + InternalChildren = new Drawable[] + { + new Box + { + Colour = colourProvider.Background3, + RelativeSizeAxes = Axes.Both + }, + + //For elements that should not be sheared. + new Container + { + Shear = -SHEAR + } + }; + } + + public Action Hovered = null!; + public Action HoverLost = null!; + public GlobalAction? Hotkey; + + public bool OnPressed(KeyBindingPressEvent e) + { + return false; + } + + public void OnReleased(KeyBindingReleaseEvent e) { } + } +} diff --git a/osu.Game/Screens/Select/FooterV2/FooterV2.cs b/osu.Game/Screens/Select/FooterV2/FooterV2.cs index 10050e24fc..54b2f08eda 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterV2.cs @@ -1,12 +1,15 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; +using osuTK; namespace osu.Game.Screens.Select.FooterV2 { @@ -14,6 +17,33 @@ namespace osu.Game.Screens.Select.FooterV2 { //Should be 60, setting to 50 for now for the sake of matching the current BackButton height. private const int height = 50; + private const int padding = 80; + + private readonly List overlays = new List(); + + public void AddButton(FooterButtonV2 button, OverlayContainer? overlay = null) + { + if (overlay != null) + { + overlays.Add(overlay); + button.Action = () => showOverlay(overlay); + } + + buttons.Add(button); + } + + private void showOverlay(OverlayContainer overlay) + { + foreach (var o in overlays) + { + if (o == overlay) + o.ToggleVisibility(); + else + o.Hide(); + } + } + + private FillFlowContainer buttons = null!; [BackgroundDependencyLoader] private void load(OsuColour colour) @@ -26,6 +56,27 @@ namespace osu.Game.Screens.Select.FooterV2 { RelativeSizeAxes = Axes.Both, Colour = colour.B5 + }, + new FillFlowContainer + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Position = new Vector2(TwoLayerButton.SIZE_EXTENDED.X + padding, 40), + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(padding, 0), + Children = new Drawable[] + { + buttons = new FillFlowContainer + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(-FooterButtonV2.SHEAR_WIDTH, 5), + AutoSizeAxes = Axes.Both + } + } } }; } From d8dd7e7e0ff8a9476949d3ab73e27777fa638e83 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 1 Dec 2022 21:42:03 +0900 Subject: [PATCH 0890/2991] Fix test failures when no hitobjects are present in a scrolling ruleset --- osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs index 123be0f117..5218ddfe15 100644 --- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs @@ -114,7 +114,7 @@ namespace osu.Game.Rulesets.UI.Scrolling break; } - double lastObjectTime = Beatmap.GetLastObjectTime(); + double lastObjectTime = Beatmap.HitObjects.Any() ? Beatmap.GetLastObjectTime() : 0; double baseBeatLength = TimingControlPoint.DEFAULT_BEAT_LENGTH; if (RelativeScaleBeatLengths) From 1530495e7c8e86d47f0bb82d914d116c1c3fc847 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Thu, 1 Dec 2022 15:34:09 +0100 Subject: [PATCH 0891/2991] Add button "accent" colour, bottom bar, icon, text --- .../SongSelect/TestSceneSongSelectFooterV2.cs | 4 +- .../Select/FooterV2/FooterButtonFreeModsV2.cs | 21 ++++++ .../Select/FooterV2/FooterButtonModsV2.cs | 20 ++++++ .../Select/FooterV2/FooterButtonOptionsV2.cs | 20 ++++++ .../Select/FooterV2/FooterButtonRandomV2.cs | 20 ++++++ .../Screens/Select/FooterV2/FooterButtonV2.cs | 72 ++++++++++++++++++- osu.Game/Screens/Select/FooterV2/FooterV2.cs | 2 +- 7 files changed, 155 insertions(+), 4 deletions(-) create mode 100644 osu.Game/Screens/Select/FooterV2/FooterButtonFreeModsV2.cs create mode 100644 osu.Game/Screens/Select/FooterV2/FooterButtonModsV2.cs create mode 100644 osu.Game/Screens/Select/FooterV2/FooterButtonOptionsV2.cs create mode 100644 osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs index 5a7797b3da..b23739e0ca 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs @@ -20,7 +20,9 @@ namespace osu.Game.Tests.Visual.SongSelect Origin = Anchor.Centre }; - footer.AddButton(new FooterButtonV2()); + footer.AddButton(new FooterButtonModsV2()); + footer.AddButton(new FooterButtonRandomV2()); + footer.AddButton(new FooterButtonOptionsV2()); }); [Test] diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonFreeModsV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonFreeModsV2.cs new file mode 100644 index 0000000000..523a2afa36 --- /dev/null +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonFreeModsV2.cs @@ -0,0 +1,21 @@ +// 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.Allocation; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; + +namespace osu.Game.Screens.Select.FooterV2 +{ + public partial class FooterButtonFreeModsV2 : FooterButtonV2 + { + [BackgroundDependencyLoader] + private void load(OsuColour colour) + { + //No design exists for this button! + Icon = FontAwesome.Solid.ExpandArrowsAlt; + Text = "Freemods"; + AccentColour = colour.Yellow; + } + } +} diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonModsV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonModsV2.cs new file mode 100644 index 0000000000..fe6ebd5506 --- /dev/null +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonModsV2.cs @@ -0,0 +1,20 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; + +namespace osu.Game.Screens.Select.FooterV2 +{ + public partial class FooterButtonModsV2 : FooterButtonV2 + { + [BackgroundDependencyLoader] + private void load() + { + Text = "Mods"; + Icon = FontAwesome.Solid.ArrowsAlt; + AccentColour = Colour4.FromHex("#B2FF66"); + } + } +} diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonOptionsV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonOptionsV2.cs new file mode 100644 index 0000000000..211feb0b53 --- /dev/null +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonOptionsV2.cs @@ -0,0 +1,20 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; + +namespace osu.Game.Screens.Select.FooterV2 +{ + public partial class FooterButtonOptionsV2 : FooterButtonV2 + { + [BackgroundDependencyLoader] + private void load() + { + Text = "Options"; + Icon = FontAwesome.Solid.Cog; + AccentColour = Colour4.FromHex("#8C66FF"); + } + } +} diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs new file mode 100644 index 0000000000..ccc5caa049 --- /dev/null +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs @@ -0,0 +1,20 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; + +namespace osu.Game.Screens.Select.FooterV2 +{ + public partial class FooterButtonRandomV2 : FooterButtonV2 + { + [BackgroundDependencyLoader] + private void load() + { + Text = "Random"; + Icon = FontAwesome.Solid.Random; + AccentColour = Colour4.FromHex("#66CCFF"); + } + } +} diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs index daad52eb5e..264db1c770 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs @@ -5,10 +5,13 @@ using System; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; using osu.Game.Input.Bindings; using osu.Game.Overlays; using osuTK; @@ -23,14 +26,47 @@ namespace osu.Game.Screens.Select.FooterV2 public const float SHEAR_WIDTH = 16; + protected static readonly Vector2 SHEAR = new Vector2(SHEAR_WIDTH / button_height, 0); + [Cached] private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Aquamarine); - protected static readonly Vector2 SHEAR = new Vector2(SHEAR_WIDTH / button_height, 0); + private Colour4 buttonAccentColour; + + protected Colour4 AccentColour + { + set + { + buttonAccentColour = value; + bar.Colour = buttonAccentColour; + icon.Colour = buttonAccentColour; + } + } + + protected IconUsage Icon + { + set => icon.Icon = value; + } + + protected string Text + { + set => text.Text = value; + } + + private SpriteIcon icon = null!; + private OsuSpriteText text = null!; + private Box bar = null!; [BackgroundDependencyLoader] private void load() { + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Radius = 5, + Roundness = 10, + Colour = Colour4.Black.Opacity(0.25f) + }; Shear = SHEAR; Size = new Vector2(button_width, button_height); Masking = true; @@ -46,7 +82,39 @@ namespace osu.Game.Screens.Select.FooterV2 //For elements that should not be sheared. new Container { - Shear = -SHEAR + Shear = -SHEAR, + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + icon = new SpriteIcon + { + //We want to offset this by the same amount as the text for aesthetic purposes + Position = new Vector2(-SHEAR_WIDTH * (52f / button_height), 12), + Size = new Vector2(20), + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre + }, + text = new OsuSpriteText + { + Position = new Vector2(-SHEAR_WIDTH * (52f / button_height), 42), + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre + }, + new Container + { + //Offset the bar to centre it with consideration for the shearing + Position = new Vector2(-SHEAR_WIDTH * (80f / button_height), -40), + Anchor = Anchor.BottomCentre, + Origin = Anchor.Centre, + Size = new Vector2(120, 6), + Masking = true, + CornerRadius = 3, + Child = bar = new Box + { + RelativeSizeAxes = Axes.Both, + } + } + } } }; } diff --git a/osu.Game/Screens/Select/FooterV2/FooterV2.cs b/osu.Game/Screens/Select/FooterV2/FooterV2.cs index 54b2f08eda..719512b1ab 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterV2.cs @@ -73,7 +73,7 @@ namespace osu.Game.Screens.Select.FooterV2 Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, Direction = FillDirection.Horizontal, - Spacing = new Vector2(-FooterButtonV2.SHEAR_WIDTH, 5), + Spacing = new Vector2(-FooterButtonV2.SHEAR_WIDTH + 7, 0), AutoSizeAxes = Axes.Both } } From d7cea51551e403c606c0c8017589576bb8e234dd Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Thu, 1 Dec 2022 16:29:52 +0100 Subject: [PATCH 0892/2991] Add functionality of Random button --- .../SongSelect/TestSceneSongSelectFooterV2.cs | 78 +++++++++- .../Select/FooterV2/FooterButtonRandomV2.cs | 142 +++++++++++++++++- .../Screens/Select/FooterV2/FooterButtonV2.cs | 59 ++++++-- 3 files changed, 266 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs index b23739e0ca..4ca193a2c6 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs @@ -1,17 +1,29 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; using NUnit.Framework; using osu.Framework.Graphics; +using osu.Framework.Testing; using osu.Game.Screens.Select.FooterV2; +using osuTK; +using osuTK.Input; namespace osu.Game.Tests.Visual.SongSelect { public partial class TestSceneSongSelectFooterV2 : OsuManualInputManagerTestScene { + private FooterButtonRandomV2 randomButton = null!; + + private bool nextRandomCalled; + private bool previousRandomCalled; + [SetUp] public void SetUp() => Schedule(() => { + nextRandomCalled = false; + previousRandomCalled = false; + FooterV2 footer; Child = footer = new FooterV2 @@ -21,13 +33,75 @@ namespace osu.Game.Tests.Visual.SongSelect }; footer.AddButton(new FooterButtonModsV2()); - footer.AddButton(new FooterButtonRandomV2()); + footer.AddButton(randomButton = new FooterButtonRandomV2 + { + NextRandom = () => nextRandomCalled = true, + PreviousRandom = () => previousRandomCalled = true + }); footer.AddButton(new FooterButtonOptionsV2()); + + InputManager.MoveMouseTo(Vector2.Zero); }); [Test] - public void TestBasic() + public void TestState() { + AddRepeatStep("toggle options state", () => this.ChildrenOfType().Last().Enabled.Toggle(), 20); + } + + [Test] + public void TestFooterRandom() + { + AddStep("press F2", () => InputManager.Key(Key.F2)); + AddAssert("next random invoked", () => nextRandomCalled && !previousRandomCalled); + } + + [Test] + public void TestFooterRandomViaMouse() + { + AddStep("click button", () => + { + InputManager.MoveMouseTo(randomButton); + InputManager.Click(MouseButton.Left); + }); + AddAssert("next random invoked", () => nextRandomCalled && !previousRandomCalled); + } + + [Test] + public void TestFooterRewind() + { + AddStep("press Shift+F2", () => + { + InputManager.PressKey(Key.LShift); + InputManager.PressKey(Key.F2); + InputManager.ReleaseKey(Key.F2); + InputManager.ReleaseKey(Key.LShift); + }); + AddAssert("previous random invoked", () => previousRandomCalled && !nextRandomCalled); + } + + [Test] + public void TestFooterRewindViaShiftMouseLeft() + { + AddStep("shift + click button", () => + { + InputManager.PressKey(Key.LShift); + InputManager.MoveMouseTo(randomButton); + InputManager.Click(MouseButton.Left); + InputManager.ReleaseKey(Key.LShift); + }); + AddAssert("previous random invoked", () => previousRandomCalled && !nextRandomCalled); + } + + [Test] + public void TestFooterRewindViaMouseRight() + { + AddStep("right click button", () => + { + InputManager.MoveMouseTo(randomButton); + InputManager.Click(MouseButton.Right); + }); + AddAssert("previous random invoked", () => previousRandomCalled && !nextRandomCalled); } } } diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs index ccc5caa049..7da31c6dad 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs @@ -1,20 +1,160 @@ // 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.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Input.Bindings; +using osuTK; +using osuTK.Input; namespace osu.Game.Screens.Select.FooterV2 { public partial class FooterButtonRandomV2 : FooterButtonV2 { + public Action NextRandom { get; set; } = null!; + public Action PreviousRandom { get; set; } = null!; + + private Container persistentText = null!; + private OsuSpriteText randomSpriteText = null!; + private OsuSpriteText rewindSpriteText = null!; + private bool rewindSearch; + [BackgroundDependencyLoader] private void load() { - Text = "Random"; + //TODO: use https://fontawesome.com/icons/shuffle?s=solid&f=classic when local Fontawesome is updated Icon = FontAwesome.Solid.Random; AccentColour = Colour4.FromHex("#66CCFF"); + TextContainer.Add(persistentText = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AlwaysPresent = true, + AutoSizeAxes = Axes.Both, + Children = new[] + { + randomSpriteText = new OsuSpriteText + { + Font = OsuFont.TorusAlternate.With(size: 16), + AlwaysPresent = true, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = "Random", + }, + rewindSpriteText = new OsuSpriteText + { + Font = OsuFont.TorusAlternate.With(size: 16), + AlwaysPresent = true, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = "Rewind", + Alpha = 0f, + } + } + }); + + Action = () => + { + if (rewindSearch) + { + const double fade_time = 500; + + OsuSpriteText fallingRewind; + + TextContainer.Add(fallingRewind = new OsuSpriteText + { + Alpha = 0, + Text = rewindSpriteText.Text, + AlwaysPresent = true, // make sure the button is sized large enough to always show this + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre + }); + + fallingRewind.FadeOutFromOne(fade_time, Easing.In); + fallingRewind.MoveTo(Vector2.Zero).MoveTo(new Vector2(0, 10), fade_time, Easing.In); + fallingRewind.Expire(); + + persistentText.FadeInFromZero(fade_time, Easing.In); + + PreviousRandom.Invoke(); + } + else + { + NextRandom.Invoke(); + } + }; + } + + protected override bool OnKeyDown(KeyDownEvent e) + { + updateText(e.ShiftPressed); + return base.OnKeyDown(e); + } + + protected override void OnKeyUp(KeyUpEvent e) + { + updateText(e.ShiftPressed); + base.OnKeyUp(e); + } + + protected override bool OnClick(ClickEvent e) + { + try + { + // this uses OR to handle rewinding when clicks are triggered by other sources (i.e. right button in OnMouseUp). + rewindSearch |= e.ShiftPressed; + return base.OnClick(e); + } + finally + { + rewindSearch = false; + } + } + + protected override void OnMouseUp(MouseUpEvent e) + { + if (e.Button == MouseButton.Right) + { + rewindSearch = true; + TriggerClick(); + return; + } + + base.OnMouseUp(e); + } + + public override bool OnPressed(KeyBindingPressEvent e) + { + rewindSearch = e.Action == GlobalAction.SelectPreviousRandom; + + if (e.Action != GlobalAction.SelectNextRandom && e.Action != GlobalAction.SelectPreviousRandom) + { + return false; + } + + if (!e.Repeat) + TriggerClick(); + return true; + } + + public override void OnReleased(KeyBindingReleaseEvent e) + { + if (e.Action == GlobalAction.SelectPreviousRandom) + { + rewindSearch = false; + } + } + + private void updateText(bool rewind = false) + { + randomSpriteText.Alpha = rewind ? 0 : 1; + rewindSpriteText.Alpha = rewind ? 1 : 0; } } } diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs index 264db1c770..5125aaa552 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs @@ -10,6 +10,8 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; +using osu.Framework.Localisation; +using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Input.Bindings; @@ -48,13 +50,14 @@ namespace osu.Game.Screens.Select.FooterV2 set => icon.Icon = value; } - protected string Text + protected LocalisableString Text { set => text.Text = value; } + private SpriteText text = null!; private SpriteIcon icon = null!; - private OsuSpriteText text = null!; + protected Container TextContainer = null!; private Box bar = null!; [BackgroundDependencyLoader] @@ -86,6 +89,18 @@ namespace osu.Game.Screens.Select.FooterV2 RelativeSizeAxes = Axes.Both, Children = new Drawable[] { + TextContainer = new Container + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Position = new Vector2(-SHEAR_WIDTH * (52f / button_height), 42), + AutoSizeAxes = Axes.Both, + Child = text = new OsuSpriteText + { + Font = OsuFont.TorusAlternate.With(size: 16), + AlwaysPresent = true + } + }, icon = new SpriteIcon { //We want to offset this by the same amount as the text for aesthetic purposes @@ -94,12 +109,6 @@ namespace osu.Game.Screens.Select.FooterV2 Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre }, - text = new OsuSpriteText - { - Position = new Vector2(-SHEAR_WIDTH * (52f / button_height), 42), - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre - }, new Container { //Offset the bar to centre it with consideration for the shearing @@ -123,11 +132,41 @@ namespace osu.Game.Screens.Select.FooterV2 public Action HoverLost = null!; public GlobalAction? Hotkey; - public bool OnPressed(KeyBindingPressEvent e) + protected override void UpdateAfterChildren() { + } + + protected override bool OnHover(HoverEvent e) + { + Hovered?.Invoke(); + + return true; + } + + protected override void OnHoverLost(HoverLostEvent e) + { + HoverLost?.Invoke(); + } + + protected override bool OnClick(ClickEvent e) + { + if (!Enabled.Value) + return true; + + return base.OnClick(e); + } + + public virtual bool OnPressed(KeyBindingPressEvent e) + { + if (e.Action == Hotkey && !e.Repeat) + { + TriggerClick(); + return true; + } + return false; } - public void OnReleased(KeyBindingReleaseEvent e) { } + public virtual void OnReleased(KeyBindingReleaseEvent e) { } } } From 5de01686a9d60c80c0f4afb5d6a3a57a9693fce1 Mon Sep 17 00:00:00 2001 From: Piggey Date: Thu, 1 Dec 2022 18:42:52 +0100 Subject: [PATCH 0893/2991] extract `findBestNumber()` from `GetNextBestName()` into private method --- osu.Game/Utils/NamingUtils.cs | 42 +++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/osu.Game/Utils/NamingUtils.cs b/osu.Game/Utils/NamingUtils.cs index 2439d4ba22..0f55c79e84 100644 --- a/osu.Game/Utils/NamingUtils.cs +++ b/osu.Game/Utils/NamingUtils.cs @@ -31,6 +31,30 @@ namespace osu.Game.Utils { string pattern = $@"^(?i){Regex.Escape(desiredName)}(?-i)( \((?[1-9][0-9]*)\))?$"; var regex = new Regex(pattern, RegexOptions.Compiled); + + int bestNumber = findBestNumber(existingNames, regex); + + return bestNumber == 0 + ? desiredName + : $"{desiredName} ({bestNumber.ToString()})"; + } + + /// + /// Given a set of and a desired target + /// finds a filename closest to that is not in + /// + /// SHOULD NOT CONTAIN the file extension. + /// + /// + public static string GetNextBestFilename(IEnumerable existingFilenames, string desiredName, string fileExtension) + { + var stripped = existingFilenames.Select(filename => filename.Substring(0, filename.Length - fileExtension.Length)); + + return $"{GetNextBestName(stripped, desiredName)}{fileExtension}"; + } + + private static int findBestNumber(IEnumerable existingNames, Regex regex) + { var takenNumbers = new HashSet(); foreach (string name in existingNames) @@ -54,23 +78,7 @@ namespace osu.Game.Utils while (takenNumbers.Contains(bestNumber)) bestNumber += 1; - return bestNumber == 0 - ? desiredName - : $"{desiredName} ({bestNumber})"; - } - - /// - /// Given a set of and a desired target - /// finds a filename closest to that is not in - /// - /// SHOULD NOT CONTAIN the file extension. - /// - /// - public static string GetNextBestFilename(IEnumerable existingFilenames, string desiredName, string fileExtension) - { - var stripped = existingFilenames.Select(filename => filename.Substring(0, filename.Length - fileExtension.Length)); - - return $"{GetNextBestName(stripped, desiredName)}{fileExtension}"; + return bestNumber; } } } From 75cf7bd1d2262fd09633f64182e2d5acbe4758bd Mon Sep 17 00:00:00 2001 From: Piggey Date: Thu, 1 Dec 2022 18:43:34 +0100 Subject: [PATCH 0894/2991] change `GetNextBestFilename()`'s parameters --- osu.Game/Database/LegacyExporter.cs | 2 +- osu.Game/Utils/NamingUtils.cs | 23 ++++++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 0a5f787469..374f9f557a 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -43,7 +43,7 @@ namespace osu.Game.Database IEnumerable existingExports = exportStorage.GetFiles("", $"{itemFilename}*{FileExtension}"); - string filename = NamingUtils.GetNextBestFilename(existingExports, itemFilename, FileExtension); + string filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); using (var stream = exportStorage.CreateFileSafely(filename)) ExportModelTo(item, stream); diff --git a/osu.Game/Utils/NamingUtils.cs b/osu.Game/Utils/NamingUtils.cs index 0f55c79e84..fa102ff56f 100644 --- a/osu.Game/Utils/NamingUtils.cs +++ b/osu.Game/Utils/NamingUtils.cs @@ -2,7 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; -using System.Linq; +using System.IO; using System.Text.RegularExpressions; namespace osu.Game.Utils @@ -40,17 +40,22 @@ namespace osu.Game.Utils } /// - /// Given a set of and a desired target - /// finds a filename closest to that is not in - /// - /// SHOULD NOT CONTAIN the file extension. - /// + /// Given a set of and a desired target + /// finds a filename closest to that is not in /// - public static string GetNextBestFilename(IEnumerable existingFilenames, string desiredName, string fileExtension) + public static string GetNextBestFilename(IEnumerable existingFilenames, string desiredFilename) { - var stripped = existingFilenames.Select(filename => filename.Substring(0, filename.Length - fileExtension.Length)); + string name = Path.GetFileNameWithoutExtension(desiredFilename); + string extension = Path.GetExtension(desiredFilename); - return $"{GetNextBestName(stripped, desiredName)}{fileExtension}"; + string pattern = $@"^(?i){Regex.Escape(name)}(?-i)( \((?[1-9][0-9]*)\))?(?i){Regex.Escape(extension)}(?-i)$"; + var regex = new Regex(pattern, RegexOptions.Compiled); + + int bestNumber = findBestNumber(existingFilenames, regex); + + return bestNumber == 0 + ? desiredFilename + : $"{name} ({bestNumber.ToString()}){extension}"; } private static int findBestNumber(IEnumerable existingNames, Regex regex) From 4308120912e995db07dd165b368d039ff3830310 Mon Sep 17 00:00:00 2001 From: Piggey Date: Thu, 1 Dec 2022 18:44:26 +0100 Subject: [PATCH 0895/2991] add tests for `GetNextBestFilename()` --- osu.Game.Tests/Utils/NamingUtilsTest.cs | 166 ++++++++++++++++++++++-- 1 file changed, 157 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Utils/NamingUtilsTest.cs b/osu.Game.Tests/Utils/NamingUtilsTest.cs index 62e688db90..1f7e06f996 100644 --- a/osu.Game.Tests/Utils/NamingUtilsTest.cs +++ b/osu.Game.Tests/Utils/NamingUtilsTest.cs @@ -11,7 +11,7 @@ namespace osu.Game.Tests.Utils public class NamingUtilsTest { [Test] - public void TestEmptySet() + public void TestNextBestNameEmptySet() { string nextBestName = NamingUtils.GetNextBestName(Enumerable.Empty(), "New Difficulty"); @@ -19,7 +19,7 @@ namespace osu.Game.Tests.Utils } [Test] - public void TestNotTaken() + public void TestNextBestNameNotTaken() { string[] existingNames = { @@ -34,7 +34,7 @@ namespace osu.Game.Tests.Utils } [Test] - public void TestNotTakenButClose() + public void TestNextBestNameNotTakenButClose() { string[] existingNames = { @@ -49,7 +49,7 @@ namespace osu.Game.Tests.Utils } [Test] - public void TestAlreadyTaken() + public void TestNextBestNameAlreadyTaken() { string[] existingNames = { @@ -62,7 +62,7 @@ namespace osu.Game.Tests.Utils } [Test] - public void TestAlreadyTakenWithDifferentCase() + public void TestNextBestNameAlreadyTakenWithDifferentCase() { string[] existingNames = { @@ -75,7 +75,7 @@ namespace osu.Game.Tests.Utils } [Test] - public void TestAlreadyTakenWithBrackets() + public void TestNextBestNameAlreadyTakenWithBrackets() { string[] existingNames = { @@ -88,7 +88,7 @@ namespace osu.Game.Tests.Utils } [Test] - public void TestMultipleAlreadyTaken() + public void TestNextBestNameMultipleAlreadyTaken() { string[] existingNames = { @@ -104,7 +104,7 @@ namespace osu.Game.Tests.Utils } [Test] - public void TestEvenMoreAlreadyTaken() + public void TestNextBestNameEvenMoreAlreadyTaken() { string[] existingNames = Enumerable.Range(1, 30).Select(i => $"New Difficulty ({i})").Append("New Difficulty").ToArray(); @@ -114,7 +114,7 @@ namespace osu.Game.Tests.Utils } [Test] - public void TestMultipleAlreadyTakenWithGaps() + public void TestNextBestNameMultipleAlreadyTakenWithGaps() { string[] existingNames = { @@ -128,5 +128,153 @@ namespace osu.Game.Tests.Utils Assert.AreEqual("New Difficulty (2)", nextBestName); } + + [Test] + public void TestNextBestFilenameEmptySet() + { + string nextBestFilename = NamingUtils.GetNextBestFilename(Enumerable.Empty(), "test_file.osr"); + + Assert.AreEqual("test_file.osr", nextBestFilename); + } + + [Test] + public void TestNextBestFilenameNotTaken() + { + string[] existingFiles = + { + "this file exists.zip", + "that file exists.too", + "three.4", + }; + + string nextBestFilename = NamingUtils.GetNextBestFilename(existingFiles, "test_file.osr"); + + Assert.AreEqual("test_file.osr", nextBestFilename); + } + + [Test] + public void TestNextBestFilenameNotTakenButClose() + { + string[] existingFiles = + { + "replay_file(1).osr", + "replay_file (not a number).zip", + "replay_file (1 <- now THAT is a number right here).lol", + }; + + string nextBestFilename = NamingUtils.GetNextBestFilename(existingFiles, "replay_file.osr"); + + Assert.AreEqual("replay_file.osr", nextBestFilename); + } + + [Test] + public void TestNextBestFilenameAlreadyTaken() + { + string[] existingFiles = + { + "replay_file.osr", + }; + + string nextBestFilename = NamingUtils.GetNextBestFilename(existingFiles, "replay_file.osr"); + + Assert.AreEqual("replay_file (1).osr", nextBestFilename); + } + + [Test] + public void TestNextBestFilenameAlreadyTakenDifferentCase() + { + string[] existingFiles = + { + "replay_file.osr", + "RePlAy_FiLe (1).OsR", + "REPLAY_FILE (2).OSR", + }; + + string nextBestFilename = NamingUtils.GetNextBestFilename(existingFiles, "replay_file.osr"); + Assert.AreEqual("replay_file (3).osr", nextBestFilename); + } + + [Test] + public void TestNextBestFilenameAlreadyTakenWithBrackets() + { + string[] existingFiles = + { + "replay_file.osr", + "replay_file (copy).osr", + }; + + string nextBestFilename = NamingUtils.GetNextBestFilename(existingFiles, "replay_file.osr"); + Assert.AreEqual("replay_file (1).osr", nextBestFilename); + + nextBestFilename = NamingUtils.GetNextBestFilename(existingFiles, "replay_file (copy).osr"); + Assert.AreEqual("replay_file (copy) (1).osr", nextBestFilename); + } + + [Test] + public void TestNextBestFilenameMultipleAlreadyTaken() + { + string[] existingFiles = + { + "replay_file.osr", + "replay_file (1).osr", + "replay_file (2).osr", + "replay_file (3).osr", + }; + + string nextBestFilename = NamingUtils.GetNextBestFilename(existingFiles, "replay_file.osr"); + + Assert.AreEqual("replay_file (4).osr", nextBestFilename); + } + + [Test] + public void TestNextBestFilenameMultipleAlreadyTakenWithGaps() + { + string[] existingFiles = + { + "replay_file.osr", + "replay_file (1).osr", + "replay_file (2).osr", + "replay_file (4).osr", + "replay_file (5).osr", + }; + + string nextBestFilename = NamingUtils.GetNextBestFilename(existingFiles, "replay_file.osr"); + + Assert.AreEqual("replay_file (3).osr", nextBestFilename); + } + + [Test] + public void TestNextBestFilenameNoExtensions() + { + string[] existingFiles = + { + "those", + "are definitely", + "files", + }; + + string nextBestFilename = NamingUtils.GetNextBestFilename(existingFiles, "surely"); + Assert.AreEqual("surely", nextBestFilename); + + nextBestFilename = NamingUtils.GetNextBestFilename(existingFiles, "those"); + Assert.AreEqual("those (1)", nextBestFilename); + } + + [Test] + public void TestNextBestFilenameDifferentExtensions() + { + string[] existingFiles = + { + "replay_file.osr", + "replay_file (1).osr", + "replay_file.txt", + }; + + string nextBestFilename = NamingUtils.GetNextBestFilename(existingFiles, "replay_file.osr"); + Assert.AreEqual("replay_file (2).osr", nextBestFilename); + + nextBestFilename = NamingUtils.GetNextBestFilename(existingFiles, "replay_file.txt"); + Assert.AreEqual("replay_file (1).txt", nextBestFilename); + } } } From 55a21a75a4c30e255bf1d98486a16f87526c9cd6 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Thu, 1 Dec 2022 22:07:28 +0100 Subject: [PATCH 0896/2991] Add hover lightening --- .../Screens/Select/FooterV2/FooterButtonV2.cs | 24 +++++++++++++++---- osu.Game/Screens/Select/FooterV2/FooterV2.cs | 2 +- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs index 5125aaa552..81883700bd 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; @@ -59,6 +60,7 @@ namespace osu.Game.Screens.Select.FooterV2 private SpriteIcon icon = null!; protected Container TextContainer = null!; private Box bar = null!; + private Box backGroundBox = null!; [BackgroundDependencyLoader] private void load() @@ -76,7 +78,7 @@ namespace osu.Game.Screens.Select.FooterV2 CornerRadius = corner_radius; InternalChildren = new Drawable[] { - new Box + backGroundBox = new Box { Colour = colourProvider.Background3, RelativeSizeAxes = Axes.Both @@ -138,14 +140,21 @@ namespace osu.Game.Screens.Select.FooterV2 protected override bool OnHover(HoverEvent e) { - Hovered?.Invoke(); - + updateHover(true); return true; } protected override void OnHoverLost(HoverLostEvent e) { - HoverLost?.Invoke(); + updateHover(false); + } + + protected override bool OnMouseDown(MouseDownEvent e) + { + if (!Enabled.Value) + return true; + + return base.OnMouseDown(e); } protected override bool OnClick(ClickEvent e) @@ -168,5 +177,12 @@ namespace osu.Game.Screens.Select.FooterV2 } public virtual void OnReleased(KeyBindingReleaseEvent e) { } + + private void updateHover(bool hovered) + { + Colour4 targetColour = hovered ? colourProvider.Background3.Lighten(.3f) : colourProvider.Background3; + + backGroundBox.FadeColour(targetColour, 500, Easing.OutQuint); + } } } diff --git a/osu.Game/Screens/Select/FooterV2/FooterV2.cs b/osu.Game/Screens/Select/FooterV2/FooterV2.cs index 719512b1ab..82e6323507 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterV2.cs @@ -13,7 +13,7 @@ using osuTK; namespace osu.Game.Screens.Select.FooterV2 { - public partial class FooterV2 : CompositeDrawable + public partial class FooterV2 : Container { //Should be 60, setting to 50 for now for the sake of matching the current BackButton height. private const int height = 50; From ea882f687433beabfe8858ac53f27c2beccdb157 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Thu, 1 Dec 2022 22:31:14 +0100 Subject: [PATCH 0897/2991] Add disabled button dimming. --- .../Screens/Select/FooterV2/FooterButtonV2.cs | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs index 81883700bd..26a0335baf 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.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 osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -130,23 +129,27 @@ namespace osu.Game.Screens.Select.FooterV2 }; } - public Action Hovered = null!; - public Action HoverLost = null!; + protected override void LoadComplete() + { + base.LoadComplete(); + Enabled.BindValueChanged(_ => updateDisplay(), true); + } + public GlobalAction? Hotkey; - protected override void UpdateAfterChildren() - { - } + private bool isHovered; protected override bool OnHover(HoverEvent e) { - updateHover(true); + isHovered = true; + updateDisplay(); return true; } protected override void OnHoverLost(HoverLostEvent e) { - updateHover(false); + isHovered = false; + updateDisplay(); } protected override bool OnMouseDown(MouseDownEvent e) @@ -178,11 +181,16 @@ namespace osu.Game.Screens.Select.FooterV2 public virtual void OnReleased(KeyBindingReleaseEvent e) { } - private void updateHover(bool hovered) + private void updateDisplay() { - Colour4 targetColour = hovered ? colourProvider.Background3.Lighten(.3f) : colourProvider.Background3; + if (!Enabled.Value) + { + backGroundBox.FadeColour(colourProvider.Background3.Darken(.3f)); + return; + } - backGroundBox.FadeColour(targetColour, 500, Easing.OutQuint); + //Hover logic. + backGroundBox.FadeColour(isHovered && Enabled.Value ? colourProvider.Background3.Lighten(.3f) : colourProvider.Background3, 500, Easing.OutQuint); } } } From 8cf89fcb81c663fbaee4b6576e231028bda73cd4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 2 Dec 2022 15:30:47 +0900 Subject: [PATCH 0898/2991] Use `Highlight1` instead of dull grey --- .../Components/Timeline/TimelineHitObjectBlueprint.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index d089b1e744..a7569daf93 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -18,6 +18,7 @@ using osu.Framework.Utils; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Game.Overlays; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; @@ -54,6 +55,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved] private ISkinSource skin { get; set; } = null!; + [Resolved] + private OverlayColourProvider colourProvider { get; set; } = null!; + public TimelineHitObjectBlueprint(HitObject item) : base(item) { @@ -165,7 +169,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline break; default: - colour = Color4.Gray; + colour = colourProvider.Highlight1; break; } From 809d02cda0156032360471aa5bf287c829529ea0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 2 Dec 2022 16:05:14 +0900 Subject: [PATCH 0899/2991] Fix two implementation oversights --- osu.Game/Beatmaps/Beatmap.cs | 8 +++++--- .../Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 2ab4fe0c79..416d655cc3 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -81,12 +81,14 @@ namespace osu.Game.Beatmaps public double GetMostCommonBeatLength() { - if (!HitObjects.Any()) - return ControlPointInfo.TimingPoints.LastOrDefault()?.Time ?? 0; + double lastTime; // The last playable time in the beatmap - the last timing point extends to this time. // Note: This is more accurate and may present different results because osu-stable didn't have the ability to calculate slider durations in this context. - double lastTime = this.GetLastObjectTime(); + if (!HitObjects.Any()) + lastTime = ControlPointInfo.TimingPoints.LastOrDefault()?.Time ?? 0; + else + lastTime = this.GetLastObjectTime(); var mostCommon = // Construct a set of (beatLength, duration) tuples for each individual timing point. diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs index 5218ddfe15..4c7564b791 100644 --- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs @@ -114,7 +114,7 @@ namespace osu.Game.Rulesets.UI.Scrolling break; } - double lastObjectTime = Beatmap.HitObjects.Any() ? Beatmap.GetLastObjectTime() : 0; + double lastObjectTime = Beatmap.HitObjects.Any() ? Beatmap.GetLastObjectTime() : double.MaxValue; double baseBeatLength = TimingControlPoint.DEFAULT_BEAT_LENGTH; if (RelativeScaleBeatLengths) From a2db0afe1922cb1e6a99247b222c4800b9bea36f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 2 Dec 2022 16:07:24 +0900 Subject: [PATCH 0900/2991] Avoid querying `GetLastObjectTime` twice in editor seek flow --- osu.Game/Screens/Edit/Editor.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index b8d308cc7c..f3f2b8ad6b 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -537,10 +537,14 @@ namespace osu.Game.Screens.Edit // Seek to last object time, or track end if already there. // Note that in osu-stable subsequent presses when at track end won't return to last object. // This has intentionally been changed to make it more useful. - if (!editorBeatmap.HitObjects.Any() || clock.CurrentTime == editorBeatmap.GetLastObjectTime()) + if (!editorBeatmap.HitObjects.Any()) + { clock.Seek(clock.TrackLength); - else - clock.Seek(editorBeatmap.GetLastObjectTime()); + return true; + } + + double lastObjectTime = editorBeatmap.GetLastObjectTime(); + clock.Seek(clock.CurrentTime == lastObjectTime ? clock.TrackLength : lastObjectTime); return true; } From 25120060aa16f05d32d80119c1bf1bb0379bd020 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 2 Dec 2022 16:09:26 +0900 Subject: [PATCH 0901/2991] Use new helper method in `ModTimeRamp` --- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index c4cb41fb6a..7285315c3b 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -7,7 +7,6 @@ using osu.Framework.Audio; using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Configuration; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Mods @@ -71,7 +70,7 @@ namespace osu.Game.Rulesets.Mods SpeedChange.SetDefault(); double firstObjectStart = beatmap.HitObjects.FirstOrDefault()?.StartTime ?? 0; - double lastObjectEnd = beatmap.HitObjects.LastOrDefault()?.GetEndTime() ?? 0; + double lastObjectEnd = beatmap.HitObjects.Any() ? beatmap.GetLastObjectTime() : 0; beginRampTime = firstObjectStart; finalRateTime = firstObjectStart + FINAL_RATE_PROGRESS * (lastObjectEnd - firstObjectStart); From 47855de6ab69536bce3fde959db249283acbe069 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 2 Dec 2022 16:54:58 +0900 Subject: [PATCH 0902/2991] Fix multiple issues with transform handling --- .../Skinning/Legacy/LegacyKiaiGlow.cs | 33 ++++++++----------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs index 80b8bc9b11..d06571eba2 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs @@ -16,15 +16,13 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { internal partial class LegacyKiaiGlow : BeatSyncedContainer { - public LegacyKiaiGlow() - { - AlwaysPresent = true; - Alpha = 0; - } + private bool isKiaiActive; - [BackgroundDependencyLoader] - private void load(ISkinSource skin) + [BackgroundDependencyLoader(true)] + private void load(ISkinSource skin, HealthProcessor? healthProcessor) { + Alpha = 0; + Child = new Sprite { Texture = skin.GetTexture("taiko-glow"), @@ -33,14 +31,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy Scale = new Vector2(0.7f), Colour = new Colour4(255, 228, 0, 255), }; - } - - [Resolved(CanBeNull = true)] - private HealthProcessor? healthProcessor { get; set; } - - protected override void Update() - { - base.Update(); if (healthProcessor != null) healthProcessor.NewJudgement += onNewJudgement; @@ -48,16 +38,21 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy private void onNewJudgement(JudgementResult result) { - if (!result.IsHit) + if (!result.IsHit || !isKiaiActive) return; - this.ScaleTo(1.2f) - .Then().ScaleTo(1f, 80, Easing.OutQuad); + this.ScaleTo(1.2f).Then() + .ScaleTo(1f, 80, Easing.OutQuad); } protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) { - if (effectPoint.KiaiMode) + if (effectPoint.KiaiMode == isKiaiActive) + return; + + isKiaiActive = effectPoint.KiaiMode; + + if (isKiaiActive) this.FadeIn(180); else this.FadeOut(180); From ebc75d40d2a7478950ba3e5544ef5dcb19346bdf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 2 Dec 2022 17:32:57 +0900 Subject: [PATCH 0903/2991] Switch to using immediate transforms to make rewind handle better --- .../Skinning/Legacy/LegacyKiaiGlow.cs | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs index d06571eba2..623243e9e1 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyKiaiGlow.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.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Graphics; @@ -18,16 +19,17 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { private bool isKiaiActive; + private Sprite sprite = null!; + [BackgroundDependencyLoader(true)] private void load(ISkinSource skin, HealthProcessor? healthProcessor) { - Alpha = 0; - - Child = new Sprite + Child = sprite = new Sprite { Texture = skin.GetTexture("taiko-glow"), Origin = Anchor.Centre, Anchor = Anchor.Centre, + Alpha = 0, Scale = new Vector2(0.7f), Colour = new Colour4(255, 228, 0, 255), }; @@ -36,26 +38,28 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy healthProcessor.NewJudgement += onNewJudgement; } + protected override void Update() + { + base.Update(); + + if (isKiaiActive) + sprite.Alpha = (float)Math.Min(1, sprite.Alpha + Math.Abs(Clock.ElapsedFrameTime) / 100f); + else + sprite.Alpha = (float)Math.Max(0, sprite.Alpha - Math.Abs(Clock.ElapsedFrameTime) / 600f); + } + + protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) + { + isKiaiActive = effectPoint.KiaiMode; + } + private void onNewJudgement(JudgementResult result) { if (!result.IsHit || !isKiaiActive) return; - this.ScaleTo(1.2f).Then() - .ScaleTo(1f, 80, Easing.OutQuad); - } - - protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) - { - if (effectPoint.KiaiMode == isKiaiActive) - return; - - isKiaiActive = effectPoint.KiaiMode; - - if (isKiaiActive) - this.FadeIn(180); - else - this.FadeOut(180); + sprite.ScaleTo(0.85f).Then() + .ScaleTo(0.7f, 80, Easing.OutQuad); } } } From 2fd535ea2066251a44f07cc4019a5b816067650a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 2 Dec 2022 17:33:18 +0900 Subject: [PATCH 0904/2991] Apply same immediate transform logic to `TaikoLegacyPlayfieldBackgroundRight` to fix it sticking during rewind --- .../TaikoLegacyPlayfieldBackgroundRight.cs | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs index 86175d3bca..85870d0fd6 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.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.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Graphics; @@ -16,7 +17,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy { private Sprite kiai = null!; - private bool kiaiDisplayed; + private bool isKiaiActive; [BackgroundDependencyLoader] private void load(ISkinSource skin) @@ -41,17 +42,19 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy }; } + protected override void Update() + { + base.Update(); + + if (isKiaiActive) + kiai.Alpha = (float)Math.Min(1, kiai.Alpha + Math.Abs(Clock.ElapsedFrameTime) / 200f); + else + kiai.Alpha = (float)Math.Max(0, kiai.Alpha - Math.Abs(Clock.ElapsedFrameTime) / 200f); + } + protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) { - base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes); - - if (effectPoint.KiaiMode != kiaiDisplayed) - { - kiaiDisplayed = effectPoint.KiaiMode; - - kiai.ClearTransforms(); - kiai.FadeTo(kiaiDisplayed ? 1 : 0, 200); - } + isKiaiActive = effectPoint.KiaiMode; } } } From ba99f1288c0be9a727cbcdfcbec90812298dc325 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 2 Dec 2022 17:47:29 +0900 Subject: [PATCH 0905/2991] Update `IBeatSnapProvider` documentation to mention the pre-divided `BeatSnap` --- osu.Game/Rulesets/Edit/IBeatSnapProvider.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs b/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs index dbad407b75..5e45cefe8c 100644 --- a/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs +++ b/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs @@ -1,14 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Edit { public interface IBeatSnapProvider { /// - /// Snaps a duration to the closest beat of a timing point applicable at the reference time. + /// Snaps a duration to the closest beat of a timing point applicable at the reference time, factoring in the current . /// /// The time to snap. /// An optional reference point to use for timing point lookup. @@ -16,10 +14,10 @@ namespace osu.Game.Rulesets.Edit double SnapTime(double time, double? referenceTime = null); /// - /// Get the most appropriate beat length at a given time. + /// Get the most appropriate beat length at a given time, pre-divided by . /// /// A reference time used for lookup. - /// The most appropriate beat length. + /// The most appropriate beat length, divided by . double GetBeatLengthAtTime(double referenceTime); /// From 45ea183cc36bcee3050daec63af63e6f059695df Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 2 Dec 2022 17:56:34 +0900 Subject: [PATCH 0906/2991] Fix being able to place zero-length spinners Also always snap a spinner's end time using beat snap (matches stable). --- .../Blueprints/Spinners/SpinnerPlacementBlueprint.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs index e412c47c09..52f845f358 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs @@ -4,6 +4,7 @@ #nullable disable using System; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Input.Events; using osu.Game.Rulesets.Edit; @@ -22,6 +23,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners private bool isPlacingEnd; + [Resolved] + private IBeatSnapProvider beatSnapProvider { get; set; } + public SpinnerPlacementBlueprint() : base(new Spinner { Position = OsuPlayfield.BASE_SIZE / 2 }) { @@ -33,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners base.Update(); if (isPlacingEnd) - HitObject.EndTime = Math.Max(HitObject.StartTime, EditorClock.CurrentTime); + updateEndTimeFromCurrent(); piece.UpdateFrom(HitObject); } @@ -45,7 +49,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners if (e.Button != MouseButton.Right) return false; - HitObject.EndTime = EditorClock.CurrentTime; + updateEndTimeFromCurrent(); EndPlacement(true); } else @@ -61,5 +65,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners return true; } + + private void updateEndTimeFromCurrent() => + HitObject.EndTime = Math.Max(HitObject.StartTime + beatSnapProvider.GetBeatLengthAtTime(HitObject.StartTime), beatSnapProvider.SnapTime(EditorClock.CurrentTime)); } } From d1296a22ce0e9d61beb39feb02ff8c7adafebdef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 2 Dec 2022 17:57:13 +0900 Subject: [PATCH 0907/2991] Update timeline blueprint's end time logic to better match new blueprint implementation --- .../Compose/Components/Timeline/TimelineHitObjectBlueprint.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index a7569daf93..03e67306df 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -424,9 +424,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline break; case IHasDuration endTimeHitObject: - double snappedTime = Math.Max(hitObject.StartTime, beatSnapProvider.SnapTime(time)); + double snappedTime = Math.Max(hitObject.StartTime + beatSnapProvider.GetBeatLengthAtTime(hitObject.StartTime), beatSnapProvider.SnapTime(time)); - if (endTimeHitObject.EndTime == snappedTime || Precision.AlmostEquals(snappedTime, hitObject.StartTime, beatmap.GetBeatLengthAtTime(snappedTime))) + if (endTimeHitObject.EndTime == snappedTime) return; endTimeHitObject.Duration = snappedTime - hitObject.StartTime; From ee62f3c0d3f061762cf2370b93f9901eab81b171 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 2 Dec 2022 18:32:40 +0900 Subject: [PATCH 0908/2991] Fix test failure Similar to SliderPlacementBlueprint. --- .../Blueprints/Spinners/SpinnerPlacementBlueprint.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs index 52f845f358..73ee5df9dc 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs @@ -4,6 +4,7 @@ #nullable disable using System; +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Input.Events; @@ -23,7 +24,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners private bool isPlacingEnd; - [Resolved] + [Resolved(CanBeNull = true)] + [CanBeNull] private IBeatSnapProvider beatSnapProvider { get; set; } public SpinnerPlacementBlueprint() @@ -66,7 +68,11 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners return true; } - private void updateEndTimeFromCurrent() => - HitObject.EndTime = Math.Max(HitObject.StartTime + beatSnapProvider.GetBeatLengthAtTime(HitObject.StartTime), beatSnapProvider.SnapTime(EditorClock.CurrentTime)); + private void updateEndTimeFromCurrent() + { + HitObject.EndTime = beatSnapProvider == null + ? Math.Max(HitObject.StartTime, EditorClock.CurrentTime) + : Math.Max(HitObject.StartTime + beatSnapProvider.GetBeatLengthAtTime(HitObject.StartTime), beatSnapProvider.SnapTime(EditorClock.CurrentTime)); + } } } From c5bad816db30d851b86aafe33f2ff940789b370b Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Fri, 2 Dec 2022 18:44:21 +0100 Subject: [PATCH 0909/2991] Add button colouring whilst corresponding overlay is present --- .../SongSelect/TestSceneSongSelectFooterV2.cs | 47 +++++++++++++++++-- .../Screens/Select/FooterV2/FooterButtonV2.cs | 20 +++++++- osu.Game/Screens/Select/FooterV2/FooterV2.cs | 1 + 3 files changed, 62 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs index 4ca193a2c6..a1ba8daf8e 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneSongSelectFooterV2.cs @@ -3,8 +3,12 @@ using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Testing; +using osu.Game.Overlays; +using osu.Game.Overlays.Mods; using osu.Game.Screens.Select.FooterV2; using osuTK; using osuTK.Input; @@ -14,10 +18,13 @@ namespace osu.Game.Tests.Visual.SongSelect public partial class TestSceneSongSelectFooterV2 : OsuManualInputManagerTestScene { private FooterButtonRandomV2 randomButton = null!; + private FooterButtonModsV2 modsButton = null!; private bool nextRandomCalled; private bool previousRandomCalled; + private DummyOverlay overlay = null!; + [SetUp] public void SetUp() => Schedule(() => { @@ -26,13 +33,17 @@ namespace osu.Game.Tests.Visual.SongSelect FooterV2 footer; - Child = footer = new FooterV2 + Children = new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre + footer = new FooterV2 + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre + }, + overlay = new DummyOverlay() }; - footer.AddButton(new FooterButtonModsV2()); + footer.AddButton(modsButton = new FooterButtonModsV2(), overlay); footer.AddButton(randomButton = new FooterButtonRandomV2 { NextRandom = () => nextRandomCalled = true, @@ -41,6 +52,8 @@ namespace osu.Game.Tests.Visual.SongSelect footer.AddButton(new FooterButtonOptionsV2()); InputManager.MoveMouseTo(Vector2.Zero); + + overlay.Hide(); }); [Test] @@ -103,5 +116,31 @@ namespace osu.Game.Tests.Visual.SongSelect }); AddAssert("previous random invoked", () => previousRandomCalled && !nextRandomCalled); } + + [Test] + public void TestOverlayPresent() + { + AddStep("Press F1", () => + { + InputManager.MoveMouseTo(modsButton); + InputManager.Click(MouseButton.Left); + }); + AddAssert("Overlay visible", () => overlay.State.Value == Visibility.Visible); + AddStep("Hide", () => overlay.Hide()); + } + + private partial class DummyOverlay : ShearedOverlayContainer + { + public DummyOverlay() + : base(OverlayColourScheme.Green) + { + } + + [BackgroundDependencyLoader] + private void load() + { + Header.Title = "An overlay"; + } + } } } diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs index 26a0335baf..7fb9bf42bd 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -25,9 +26,12 @@ namespace osu.Game.Screens.Select.FooterV2 private const int button_height = 120; private const int button_width = 140; private const int corner_radius = 10; + private const int transition_length = 500; public const float SHEAR_WIDTH = 16; + public Bindable OverlayState = new Bindable(); + protected static readonly Vector2 SHEAR = new Vector2(SHEAR_WIDTH / button_height, 0); [Cached] @@ -133,6 +137,7 @@ namespace osu.Game.Screens.Select.FooterV2 { base.LoadComplete(); Enabled.BindValueChanged(_ => updateDisplay(), true); + OverlayState.BindValueChanged(_ => updateDisplay()); } public GlobalAction? Hotkey; @@ -185,12 +190,23 @@ namespace osu.Game.Screens.Select.FooterV2 { if (!Enabled.Value) { - backGroundBox.FadeColour(colourProvider.Background3.Darken(.3f)); + backGroundBox.FadeColour(colourProvider.Background3.Darken(0.3f), transition_length, Easing.OutQuint); return; } + switch (OverlayState.Value) + { + case Visibility.Visible: + backGroundBox.FadeColour(buttonAccentColour.Darken(0.5f), transition_length, Easing.OutQuint); + return; + + case Visibility.Hidden: + backGroundBox.FadeColour(buttonAccentColour, transition_length, Easing.OutQuint); + break; + } + //Hover logic. - backGroundBox.FadeColour(isHovered && Enabled.Value ? colourProvider.Background3.Lighten(.3f) : colourProvider.Background3, 500, Easing.OutQuint); + backGroundBox.FadeColour(isHovered && Enabled.Value ? colourProvider.Background3.Lighten(.3f) : colourProvider.Background3, transition_length, Easing.OutQuint); } } } diff --git a/osu.Game/Screens/Select/FooterV2/FooterV2.cs b/osu.Game/Screens/Select/FooterV2/FooterV2.cs index 82e6323507..8ac26c2e58 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterV2.cs @@ -27,6 +27,7 @@ namespace osu.Game.Screens.Select.FooterV2 { overlays.Add(overlay); button.Action = () => showOverlay(overlay); + button.OverlayState.BindTo(overlay.State); } buttons.Add(button); From 7373d79ba6bd7e152d0918c0694a67968c74459c Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Fri, 2 Dec 2022 19:16:25 +0100 Subject: [PATCH 0910/2991] Use OsuColour instead of hex for button accent colour --- osu.Game/Screens/Select/FooterV2/FooterButtonModsV2.cs | 6 +++--- osu.Game/Screens/Select/FooterV2/FooterButtonOptionsV2.cs | 6 +++--- osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonModsV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonModsV2.cs index fe6ebd5506..daa1de2e7b 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterButtonModsV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonModsV2.cs @@ -2,19 +2,19 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; namespace osu.Game.Screens.Select.FooterV2 { public partial class FooterButtonModsV2 : FooterButtonV2 { [BackgroundDependencyLoader] - private void load() + private void load(OsuColour colour) { Text = "Mods"; Icon = FontAwesome.Solid.ArrowsAlt; - AccentColour = Colour4.FromHex("#B2FF66"); + AccentColour = colour.Lime1; } } } diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonOptionsV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonOptionsV2.cs index 211feb0b53..be0fdef9db 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterButtonOptionsV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonOptionsV2.cs @@ -2,19 +2,19 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; namespace osu.Game.Screens.Select.FooterV2 { public partial class FooterButtonOptionsV2 : FooterButtonV2 { [BackgroundDependencyLoader] - private void load() + private void load(OsuColour colour) { Text = "Options"; Icon = FontAwesome.Solid.Cog; - AccentColour = Colour4.FromHex("#8C66FF"); + AccentColour = colour.Purple1; } } } diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs index 7da31c6dad..3ecf616a16 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs @@ -26,11 +26,11 @@ namespace osu.Game.Screens.Select.FooterV2 private bool rewindSearch; [BackgroundDependencyLoader] - private void load() + private void load(OsuColour colour) { //TODO: use https://fontawesome.com/icons/shuffle?s=solid&f=classic when local Fontawesome is updated Icon = FontAwesome.Solid.Random; - AccentColour = Colour4.FromHex("#66CCFF"); + AccentColour = colour.Blue1; TextContainer.Add(persistentText = new Container { Anchor = Anchor.Centre, From 49f5ac57b8ab109f7a4b62f20f05a02f94900ead Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 3 Dec 2022 18:48:53 +0900 Subject: [PATCH 0911/2991] Fix first run beatmap screen button colours looking incorrect with new triangle effect Addresses #21500. --- osu.Game/Overlays/FirstRunSetup/ProgressRoundedButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ProgressRoundedButton.cs b/osu.Game/Overlays/FirstRunSetup/ProgressRoundedButton.cs index a4762fdaed..a1e61e66f8 100644 --- a/osu.Game/Overlays/FirstRunSetup/ProgressRoundedButton.cs +++ b/osu.Game/Overlays/FirstRunSetup/ProgressRoundedButton.cs @@ -81,7 +81,7 @@ namespace osu.Game.Overlays.FirstRunSetup loading.Hide(); tick.FadeIn(500, Easing.OutQuint); - Background.FadeColour(colours.Green, 500, Easing.OutQuint); + this.TransformTo(nameof(BackgroundColour), colours.Green, 500, Easing.OutQuint); progressBar.FillColour = colours.Green; this.TransformBindableTo(progressBar.Current, 1, 500, Easing.OutQuint); From 94cfcdb338690f2cdd174bcdf8b789a44929c5be Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 3 Dec 2022 16:16:21 +0300 Subject: [PATCH 0912/2991] Remove SmoothCircularProgress usage in BeatmapCardThumbnail --- osu.Game/Beatmaps/Drawables/Cards/BeatmapCardThumbnail.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardThumbnail.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardThumbnail.cs index 781133aac7..c99d1f0c76 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardThumbnail.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardThumbnail.cs @@ -11,7 +11,7 @@ using osu.Game.Beatmaps.Drawables.Cards.Buttons; using osu.Game.Graphics; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; -using osu.Game.Screens.Ranking.Expanded.Accuracy; +using osu.Framework.Graphics.UserInterface; using osuTK; using osuTK.Graphics; @@ -30,7 +30,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards private readonly UpdateableOnlineBeatmapSetCover cover; private readonly Container foreground; private readonly PlayButton playButton; - private readonly SmoothCircularProgress progress; + private readonly CircularProgress progress; private readonly Container content; protected override Container Content => content; @@ -53,7 +53,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards { RelativeSizeAxes = Axes.Both }, - progress = new SmoothCircularProgress + progress = new CircularProgress { Anchor = Anchor.Centre, Origin = Anchor.Centre, From 97b6d88f003ffa1230ac03da372c0508c467adb6 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 3 Dec 2022 16:39:44 +0300 Subject: [PATCH 0913/2991] Remove SmoothCircularProgress usage in AccuracyCircle --- .../Expanded/Accuracy/AccuracyCircle.cs | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs index 3285ebc914..8e04bb68fb 100644 --- a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs +++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs @@ -12,6 +12,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Utils; using osu.Game.Audio; using osu.Game.Graphics; @@ -79,8 +80,8 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy private readonly ScoreInfo score; - private SmoothCircularProgress accuracyCircle; - private SmoothCircularProgress innerMask; + private CircularProgress accuracyCircle; + private CircularProgress innerMask; private Container badges; private RankText rankText; @@ -109,7 +110,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy { InternalChildren = new Drawable[] { - new SmoothCircularProgress + new CircularProgress { Name = "Background circle", Anchor = Anchor.Centre, @@ -120,7 +121,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy InnerRadius = accuracy_circle_radius + 0.01f, // Extends a little bit into the circle Current = { Value = 1 }, }, - accuracyCircle = new SmoothCircularProgress + accuracyCircle = new CircularProgress { Name = "Accuracy circle", Anchor = Anchor.Centre, @@ -139,42 +140,42 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy Padding = new MarginPadding(2), Children = new Drawable[] { - new SmoothCircularProgress + new CircularProgress { RelativeSizeAxes = Axes.Both, Colour = OsuColour.ForRank(ScoreRank.X), InnerRadius = RANK_CIRCLE_RADIUS, Current = { Value = 1 } }, - new SmoothCircularProgress + new CircularProgress { RelativeSizeAxes = Axes.Both, Colour = OsuColour.ForRank(ScoreRank.S), InnerRadius = RANK_CIRCLE_RADIUS, Current = { Value = 1 - virtual_ss_percentage } }, - new SmoothCircularProgress + new CircularProgress { RelativeSizeAxes = Axes.Both, Colour = OsuColour.ForRank(ScoreRank.A), InnerRadius = RANK_CIRCLE_RADIUS, Current = { Value = 0.95f } }, - new SmoothCircularProgress + new CircularProgress { RelativeSizeAxes = Axes.Both, Colour = OsuColour.ForRank(ScoreRank.B), InnerRadius = RANK_CIRCLE_RADIUS, Current = { Value = 0.9f } }, - new SmoothCircularProgress + new CircularProgress { RelativeSizeAxes = Axes.Both, Colour = OsuColour.ForRank(ScoreRank.C), InnerRadius = RANK_CIRCLE_RADIUS, Current = { Value = 0.8f } }, - new SmoothCircularProgress + new CircularProgress { RelativeSizeAxes = Axes.Both, Colour = OsuColour.ForRank(ScoreRank.D), @@ -195,14 +196,14 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy Blending = new BlendingParameters { Source = BlendingType.DstColor, - Destination = BlendingType.OneMinusSrcAlpha, + Destination = BlendingType.OneMinusSrcColor, SourceAlpha = BlendingType.One, DestinationAlpha = BlendingType.SrcAlpha }, - Child = innerMask = new SmoothCircularProgress + Child = innerMask = new CircularProgress { RelativeSizeAxes = Axes.Both, - InnerRadius = RANK_CIRCLE_RADIUS - 0.01f, + InnerRadius = RANK_CIRCLE_RADIUS - 0.02f, } } } From 41f7dad8e96c3b8135277d4151eb5d0d553c1fd7 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 3 Dec 2022 16:40:41 +0300 Subject: [PATCH 0914/2991] Delete SmoothCircularProgress.cs --- .../Accuracy/SmoothCircularProgress.cs | 128 ------------------ 1 file changed, 128 deletions(-) delete mode 100644 osu.Game/Screens/Ranking/Expanded/Accuracy/SmoothCircularProgress.cs diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/SmoothCircularProgress.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/SmoothCircularProgress.cs deleted file mode 100644 index 601c47ea55..0000000000 --- a/osu.Game/Screens/Ranking/Expanded/Accuracy/SmoothCircularProgress.cs +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -#nullable disable - -using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Transforms; -using osu.Framework.Graphics.UserInterface; -using osu.Game.Graphics; -using osuTK; - -namespace osu.Game.Screens.Ranking.Expanded.Accuracy -{ - /// - /// Contains a with smoothened edges. - /// - public partial class SmoothCircularProgress : CompositeDrawable - { - public Bindable Current - { - get => progress.Current; - set => progress.Current = value; - } - - public float InnerRadius - { - get => progress.InnerRadius; - set - { - progress.InnerRadius = value; - innerSmoothingContainer.Size = new Vector2(1 - value); - smoothingWedge.Height = value / 2; - } - } - - private readonly CircularProgress progress; - private readonly Container innerSmoothingContainer; - private readonly Drawable smoothingWedge; - - public SmoothCircularProgress() - { - Container smoothingWedgeContainer; - - InternalChild = new BufferedContainer - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - progress = new CircularProgress { RelativeSizeAxes = Axes.Both }, - smoothingWedgeContainer = new Container - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Child = smoothingWedge = new Box - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.Y, - Width = 1f, - EdgeSmoothness = new Vector2(2, 0), - } - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding(-1), - Child = new CircularContainer - { - RelativeSizeAxes = Axes.Both, - BorderThickness = 2, - Masking = true, - BorderColour = OsuColour.Gray(0.5f).Opacity(0.75f), - Blending = new BlendingParameters - { - AlphaEquation = BlendingEquation.ReverseSubtract, - }, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - AlwaysPresent = true - } - } - }, - innerSmoothingContainer = new Container - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Size = Vector2.Zero, - Padding = new MarginPadding(-1), - Child = new CircularContainer - { - RelativeSizeAxes = Axes.Both, - BorderThickness = 2, - BorderColour = OsuColour.Gray(0.5f).Opacity(0.75f), - Masking = true, - Blending = new BlendingParameters - { - AlphaEquation = BlendingEquation.ReverseSubtract, - }, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - AlwaysPresent = true - } - } - }, - } - }; - - Current.BindValueChanged(c => - { - smoothingWedgeContainer.Alpha = c.NewValue > 0 ? 1 : 0; - smoothingWedgeContainer.Rotation = (float)(360 * c.NewValue); - }, true); - } - - public TransformSequence FillTo(double newValue, double duration = 0, Easing easing = Easing.None) - => progress.FillTo(newValue, duration, easing); - } -} From 7f0d366d0169521beb33335dadfbd306375096d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 3 Dec 2022 16:59:43 +0100 Subject: [PATCH 0915/2991] Extract common part of regex to separate method --- osu.Game/Utils/NamingUtils.cs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/osu.Game/Utils/NamingUtils.cs b/osu.Game/Utils/NamingUtils.cs index fa102ff56f..97220f4201 100644 --- a/osu.Game/Utils/NamingUtils.cs +++ b/osu.Game/Utils/NamingUtils.cs @@ -29,7 +29,7 @@ namespace osu.Game.Utils /// public static string GetNextBestName(IEnumerable existingNames, string desiredName) { - string pattern = $@"^(?i){Regex.Escape(desiredName)}(?-i)( \((?[1-9][0-9]*)\))?$"; + string pattern = $@"^{getBaselineNameDetectingPattern(desiredName)}$"; var regex = new Regex(pattern, RegexOptions.Compiled); int bestNumber = findBestNumber(existingNames, regex); @@ -48,7 +48,7 @@ namespace osu.Game.Utils string name = Path.GetFileNameWithoutExtension(desiredFilename); string extension = Path.GetExtension(desiredFilename); - string pattern = $@"^(?i){Regex.Escape(name)}(?-i)( \((?[1-9][0-9]*)\))?(?i){Regex.Escape(extension)}(?-i)$"; + string pattern = $@"^{getBaselineNameDetectingPattern(name)}(?i){Regex.Escape(extension)}(?-i)$"; var regex = new Regex(pattern, RegexOptions.Compiled); int bestNumber = findBestNumber(existingFilenames, regex); @@ -58,6 +58,22 @@ namespace osu.Game.Utils : $"{name} ({bestNumber.ToString()}){extension}"; } + /// + /// Generates a basic regex pattern that will match all possible conflicting filenames when picking the best available name, given the . + /// The generated pattern can be composed into more complicated regexes for particular uses, such as picking filenames, which need additional file extension handling. + /// + /// + /// The regex shall detect: + /// + /// all strings that are equal to , + /// all strings of the format desiredName (number), where number is a number written using Arabic numerals. + /// + /// All comparisons are made in a case-insensitive manner. + /// If a number is detected in the matches, it will be output to the copyNumber named group. + /// + private static string getBaselineNameDetectingPattern(string desiredName) + => $@"(?i){Regex.Escape(desiredName)}(?-i)( \((?[1-9][0-9]*)\))?"; + private static int findBestNumber(IEnumerable existingNames, Regex regex) { var takenNumbers = new HashSet(); From 36ab6bc64e6559a88b7d3f3ee1944903f40219b7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 3 Dec 2022 23:03:43 +0900 Subject: [PATCH 0916/2991] Update framework Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 75828147a5..0bf415e764 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 6e75450594..a176d73854 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index bb20b0474d..e192467247 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From 0db6c2ada147b5749228d414ff8521e83b69bf96 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 3 Dec 2022 22:38:11 +0300 Subject: [PATCH 0917/2991] Add enum with font types --- osu.Game/Skinning/DefaultFont.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 osu.Game/Skinning/DefaultFont.cs diff --git a/osu.Game/Skinning/DefaultFont.cs b/osu.Game/Skinning/DefaultFont.cs new file mode 100644 index 0000000000..69b6aaaff4 --- /dev/null +++ b/osu.Game/Skinning/DefaultFont.cs @@ -0,0 +1,18 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Skinning.Components; + +namespace osu.Game.Skinning +{ + /// + /// The type of built-in font to use for . + /// + public enum DefaultFont + { + Venera, + Torus, + TorusAlt, + Inter + } +} From b41f30c8689757c3b5850000dccefcb85c475cba Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 3 Dec 2022 22:44:54 +0300 Subject: [PATCH 0918/2991] Allow changing font of text elements --- .../Components/BeatmapAttributeText.cs | 10 ++--- .../Components/DefaultTextSkinComponent.cs | 42 +++++++++++++++++++ osu.Game/Skinning/Components/TextElement.cs | 11 ++--- 3 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 osu.Game/Skinning/Components/DefaultTextSkinComponent.cs diff --git a/osu.Game/Skinning/Components/BeatmapAttributeText.cs b/osu.Game/Skinning/Components/BeatmapAttributeText.cs index 0a5f0d22cb..71d8f1a40f 100644 --- a/osu.Game/Skinning/Components/BeatmapAttributeText.cs +++ b/osu.Game/Skinning/Components/BeatmapAttributeText.cs @@ -11,12 +11,11 @@ using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Extensions; -using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Localisation; using osu.Game.Resources.Localisation.Web; @@ -24,10 +23,8 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Skinning.Components { [UsedImplicitly] - public partial class BeatmapAttributeText : Container, ISkinnableDrawable + public partial class BeatmapAttributeText : DefaultTextSkinComponent { - public bool UsesFixedAnchor { get; set; } - [SettingSource("Attribute", "The attribute to be displayed.")] public Bindable Attribute { get; } = new Bindable(BeatmapAttribute.StarRating); @@ -67,7 +64,6 @@ namespace osu.Game.Skinning.Components { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Font = OsuFont.Default.With(size: 40) } }; } @@ -122,6 +118,8 @@ namespace osu.Game.Skinning.Components text.Text = LocalisableString.Format(numberedTemplate, args); } + + protected override void SetFont(FontUsage font) => text.Font = font.With(size: 40); } public enum BeatmapAttribute diff --git a/osu.Game/Skinning/Components/DefaultTextSkinComponent.cs b/osu.Game/Skinning/Components/DefaultTextSkinComponent.cs new file mode 100644 index 0000000000..aff400c798 --- /dev/null +++ b/osu.Game/Skinning/Components/DefaultTextSkinComponent.cs @@ -0,0 +1,42 @@ +// 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.Bindables; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Configuration; +using osu.Game.Graphics; + +namespace osu.Game.Skinning.Components +{ + /// + /// Skin element that contains text and have ability to control its font. + /// + public abstract partial class DefaultTextSkinComponent : Container, ISkinnableDrawable + { + public bool UsesFixedAnchor { get; set; } + + [SettingSource("Font", "Font to use.")] + public Bindable Font { get; } = new Bindable(DefaultFont.Torus); + + protected abstract void SetFont(FontUsage font); + + protected override void LoadComplete() + { + base.LoadComplete(); + Font.BindValueChanged(e => + { + FontUsage f = e.NewValue switch + { + DefaultFont.Venera => OsuFont.Numeric, + DefaultFont.Torus => OsuFont.Torus, + DefaultFont.TorusAlt => OsuFont.TorusAlternate, + DefaultFont.Inter => OsuFont.Inter, + _ => OsuFont.Default + }; + + SetFont(f); + }, true); + } + } +} diff --git a/osu.Game/Skinning/Components/TextElement.cs b/osu.Game/Skinning/Components/TextElement.cs index 74a0acb979..fb779fdb83 100644 --- a/osu.Game/Skinning/Components/TextElement.cs +++ b/osu.Game/Skinning/Components/TextElement.cs @@ -4,7 +4,7 @@ using JetBrains.Annotations; using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -12,17 +12,16 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Skinning.Components { [UsedImplicitly] - public partial class TextElement : Container, ISkinnableDrawable + public partial class TextElement : DefaultTextSkinComponent { - public bool UsesFixedAnchor { get; set; } - [SettingSource("Text", "The text to be displayed.")] public Bindable Text { get; } = new Bindable("Circles!"); + private readonly OsuSpriteText text; + public TextElement() { AutoSizeAxes = Axes.Both; - OsuSpriteText text; InternalChildren = new Drawable[] { text = new OsuSpriteText @@ -34,5 +33,7 @@ namespace osu.Game.Skinning.Components }; text.Current.BindTo(Text); } + + protected override void SetFont(FontUsage font) => text.Font = font.With(size: 40); } } From 8174f6be64a7877c0e0788028303236ef01e1ec6 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 3 Dec 2022 23:32:17 +0300 Subject: [PATCH 0919/2991] Get rid of dublicated enum --- .../Components/DefaultTextSkinComponent.cs | 12 ++---------- osu.Game/Skinning/DefaultFont.cs | 18 ------------------ 2 files changed, 2 insertions(+), 28 deletions(-) delete mode 100644 osu.Game/Skinning/DefaultFont.cs diff --git a/osu.Game/Skinning/Components/DefaultTextSkinComponent.cs b/osu.Game/Skinning/Components/DefaultTextSkinComponent.cs index aff400c798..1fd29effbd 100644 --- a/osu.Game/Skinning/Components/DefaultTextSkinComponent.cs +++ b/osu.Game/Skinning/Components/DefaultTextSkinComponent.cs @@ -17,7 +17,7 @@ namespace osu.Game.Skinning.Components public bool UsesFixedAnchor { get; set; } [SettingSource("Font", "Font to use.")] - public Bindable Font { get; } = new Bindable(DefaultFont.Torus); + public Bindable Font { get; } = new Bindable(Typeface.Torus); protected abstract void SetFont(FontUsage font); @@ -26,15 +26,7 @@ namespace osu.Game.Skinning.Components base.LoadComplete(); Font.BindValueChanged(e => { - FontUsage f = e.NewValue switch - { - DefaultFont.Venera => OsuFont.Numeric, - DefaultFont.Torus => OsuFont.Torus, - DefaultFont.TorusAlt => OsuFont.TorusAlternate, - DefaultFont.Inter => OsuFont.Inter, - _ => OsuFont.Default - }; - + FontUsage f = OsuFont.GetFont(e.NewValue); SetFont(f); }, true); } diff --git a/osu.Game/Skinning/DefaultFont.cs b/osu.Game/Skinning/DefaultFont.cs deleted file mode 100644 index 69b6aaaff4..0000000000 --- a/osu.Game/Skinning/DefaultFont.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Game.Skinning.Components; - -namespace osu.Game.Skinning -{ - /// - /// The type of built-in font to use for . - /// - public enum DefaultFont - { - Venera, - Torus, - TorusAlt, - Inter - } -} From b240d15731d7a4205825c78122f298d28cb096c7 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 3 Dec 2022 23:38:50 +0300 Subject: [PATCH 0920/2991] Fix numeric font --- osu.Game/Skinning/Components/DefaultTextSkinComponent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/Components/DefaultTextSkinComponent.cs b/osu.Game/Skinning/Components/DefaultTextSkinComponent.cs index 1fd29effbd..abe16918c5 100644 --- a/osu.Game/Skinning/Components/DefaultTextSkinComponent.cs +++ b/osu.Game/Skinning/Components/DefaultTextSkinComponent.cs @@ -26,7 +26,7 @@ namespace osu.Game.Skinning.Components base.LoadComplete(); Font.BindValueChanged(e => { - FontUsage f = OsuFont.GetFont(e.NewValue); + FontUsage f = OsuFont.GetFont(e.NewValue, weight: e.NewValue == Typeface.Venera ? FontWeight.Bold : FontWeight.Regular); SetFont(f); }, true); } From 7d7b824f568ac35602b0e39e38223412c4252ded Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 3 Dec 2022 23:42:16 +0300 Subject: [PATCH 0921/2991] Add description for torus alt --- osu.Game/Graphics/OsuFont.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Graphics/OsuFont.cs b/osu.Game/Graphics/OsuFont.cs index 038ea0f5d7..7aa98ece95 100644 --- a/osu.Game/Graphics/OsuFont.cs +++ b/osu.Game/Graphics/OsuFont.cs @@ -3,6 +3,7 @@ #nullable disable +using System.ComponentModel; using osu.Framework.Graphics.Sprites; namespace osu.Game.Graphics @@ -115,6 +116,8 @@ namespace osu.Game.Graphics { Venera, Torus, + + [Description("Torus (alternate)")] TorusAlternate, Inter, } From 6c95b1d90dbf1e6aa0dfb2039aa2747bd786b3ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 3 Dec 2022 21:59:57 +0100 Subject: [PATCH 0922/2991] Bump `dorny/test-reporter` action to 1.6.0 The only reason I'm bothering to do this is that I mistakenly clicked on one of the execution logs of the "Annotate CI with test results" workflow and noticed a bunch of deprecation warnings: https://github.com/ppy/osu/actions/runs/3610166871 Judging from the release notes [[1]] and diffstat [[2]] of version 1.6.0 of the action affected, a bump should silence these. [1]: https://github.com/dorny/test-reporter/blob/main/CHANGELOG.md [2]: https://github.com/dorny/test-reporter/compare/v1.4.2...v1.6.0 --- .github/workflows/report-nunit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/report-nunit.yml b/.github/workflows/report-nunit.yml index bfc9620174..99e39f6f56 100644 --- a/.github/workflows/report-nunit.yml +++ b/.github/workflows/report-nunit.yml @@ -28,7 +28,7 @@ jobs: timeout-minutes: 5 steps: - name: Annotate CI run with test results - uses: dorny/test-reporter@v1.4.2 + uses: dorny/test-reporter@v1.6.0 with: artifact: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}} name: Test Results (${{matrix.os.prettyname}}, ${{matrix.threadingMode}}) From af000c6e9205161e48bc988ed80eb65430401ca4 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 4 Dec 2022 21:58:00 +0300 Subject: [PATCH 0923/2991] Fix `RangeSlider` potentially throwing exception on mobile platforms --- osu.Game/Graphics/UserInterface/RangeSlider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/RangeSlider.cs b/osu.Game/Graphics/UserInterface/RangeSlider.cs index 483119cd58..4e23b06c2b 100644 --- a/osu.Game/Graphics/UserInterface/RangeSlider.cs +++ b/osu.Game/Graphics/UserInterface/RangeSlider.cs @@ -197,7 +197,7 @@ namespace osu.Game.Graphics.UserInterface }, true); } - [BackgroundDependencyLoader] + [BackgroundDependencyLoader(true)] private void load(OverlayColourProvider? colourProvider) { if (colourProvider == null) return; From 486ea153fe752d6b1dc94aabc73073d76c668023 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 5 Dec 2022 19:00:04 +0900 Subject: [PATCH 0924/2991] Add failing test --- .../Rulesets/Scoring/ScoreProcessorTest.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs b/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs index e9e94aa897..826c610f56 100644 --- a/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs +++ b/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Difficulty; @@ -355,6 +356,28 @@ namespace osu.Game.Tests.Rulesets.Scoring } #pragma warning restore CS0618 + [Test] + public void TestAccuracyWhenNearPerfect() + { + const int count_judgements = 1000; + const int count_misses = 1; + + double actual = new TestScoreProcessor().ComputeAccuracy(new ScoreInfo + { + Statistics = new Dictionary + { + { HitResult.Great, count_judgements - count_misses }, + { HitResult.Miss, count_misses } + } + }); + + const double expected = (count_judgements - count_misses) / (double)count_judgements; + + Assert.That(actual, Is.Not.EqualTo(0.0)); + Assert.That(actual, Is.Not.EqualTo(1.0)); + Assert.That(actual, Is.EqualTo(expected).Within(Precision.FLOAT_EPSILON)); + } + private class TestRuleset : Ruleset { public override IEnumerable GetModsFor(ModType type) => throw new NotImplementedException(); From 9e64f8dab1ea4ec5aa847ab838d359a03e8a8755 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 5 Dec 2022 19:08:50 +0900 Subject: [PATCH 0925/2991] Fix loss of precision when computing accuracy --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 29c37c31d5..18c88dff2a 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -285,7 +285,7 @@ namespace osu.Game.Rulesets.Scoring // We only extract scoring values from the score's statistics. This is because accuracy is always relative to the point of pass or fail rather than relative to the whole beatmap. extractScoringValues(scoreInfo.Statistics, out var current, out var maximum); - return maximum.BaseScore > 0 ? current.BaseScore / maximum.BaseScore : 1; + return maximum.BaseScore > 0 ? (double)current.BaseScore / maximum.BaseScore : 1; } /// From b6a6db1160342731d21f0da0645f1d0303461214 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 5 Dec 2022 12:29:23 +0100 Subject: [PATCH 0926/2991] Add dynamic BPM counter to SkinEditor --- osu.Game/Screens/Play/HUD/BPMCounter.cs | 52 +++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 osu.Game/Screens/Play/HUD/BPMCounter.cs diff --git a/osu.Game/Screens/Play/HUD/BPMCounter.cs b/osu.Game/Screens/Play/HUD/BPMCounter.cs new file mode 100644 index 0000000000..fec36f915d --- /dev/null +++ b/osu.Game/Screens/Play/HUD/BPMCounter.cs @@ -0,0 +1,52 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Localisation; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Skinning; + +namespace osu.Game.Screens.Play.HUD +{ + public partial class BPMCounter : RollingCounter, ISkinnableDrawable + { + [Resolved] + private IBindable beatmap { get; set; } = null!; + + [Resolved] + protected IGameplayClock GameplayClock { get; private set; } = null!; + + [BackgroundDependencyLoader] + private void load(OsuColour colour) + { + Colour = colour.BlueLighter; + Current.Value = DisplayedCount = 0; + } + + protected override void Update() + { + base.Update(); + + //We dont want it going to 0 when we pause. so we block the updates + if (GameplayClock.IsPaused.Value) return; + + // We want to check Rate every update to cover windup/down + Current.Value = beatmap.Value.Beatmap.ControlPointInfo.TimingPointAt(GameplayClock.CurrentTime).BPM * GameplayClock.Rate; + } + + protected override OsuSpriteText CreateSpriteText() + => base.CreateSpriteText().With(s => s.Font = s.Font.With(size: 20f, fixedWidth: true)); + + protected override LocalisableString FormatCount(double count) + { + return $@"{count:0} BPM"; + } + + public bool UsesFixedAnchor { get; set; } + } +} From a457a2fbbf5edd1c297cb367467b5b85974fea61 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 5 Dec 2022 14:45:29 +0300 Subject: [PATCH 0927/2991] Fix disposal of playing preview track not unmuting game track --- osu.Game/Audio/PreviewTrack.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Audio/PreviewTrack.cs b/osu.Game/Audio/PreviewTrack.cs index ea226ab650..2c63c16274 100644 --- a/osu.Game/Audio/PreviewTrack.cs +++ b/osu.Game/Audio/PreviewTrack.cs @@ -109,6 +109,8 @@ namespace osu.Game.Audio protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); + + Stop(); Track?.Dispose(); } } From f69c08496931804c47c50a8197996383087547df Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 5 Dec 2022 17:08:00 +0100 Subject: [PATCH 0928/2991] Add roll duration --- osu.Game/Screens/Play/HUD/BPMCounter.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/BPMCounter.cs b/osu.Game/Screens/Play/HUD/BPMCounter.cs index fec36f915d..83569c13d9 100644 --- a/osu.Game/Screens/Play/HUD/BPMCounter.cs +++ b/osu.Game/Screens/Play/HUD/BPMCounter.cs @@ -15,6 +15,8 @@ namespace osu.Game.Screens.Play.HUD { public partial class BPMCounter : RollingCounter, ISkinnableDrawable { + protected override double RollingDuration => 750; + [Resolved] private IBindable beatmap { get; set; } = null!; From 9eef74b8d89ed7f8125af41be3e7dba840cd5f73 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 5 Dec 2022 19:34:03 +0100 Subject: [PATCH 0929/2991] Add new counter to skin deserialisation test --- .../Archives/modified-default-20221205.osk | Bin 0 -> 1644 bytes osu.Game.Tests/Skins/SkinDeserialisationTest.cs | 4 +++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/Resources/Archives/modified-default-20221205.osk diff --git a/osu.Game.Tests/Resources/Archives/modified-default-20221205.osk b/osu.Game.Tests/Resources/Archives/modified-default-20221205.osk new file mode 100644 index 0000000000000000000000000000000000000000..ae421fc323baa8b1931a18e06e4d368adeb41352 GIT binary patch literal 1644 zcmWIWW@Zs#U|`^2csRQ?bn^awlY>BB5Hm=GfuT4%GfyuwFY{@?VHcC5fa_;F*O{7Y z&iNc}njtw;a_2;eDPg^4W#OLwrp@WM6Z*G=2M8(~#$S7L_;<~}-+%wD)QXUmi0Tde ztx$bqr9`)5zifh`Z$@If;XKC9841;FZ%;9-coJ>9WOCZ?2Hmpo6->DuIx{3z-PR~< zJJQzDCcHgvL&32fg{QNV%jBh^_%wc>xXaPzskx;w^U1TLe6!L&sJdT_oAZ0Mf8yVc z-1uywCWCZVC!GrLPwnazR7$l+PLO^PalbLN1&*>wnVcw2$w_kd8LP z(%_)WLf*w*CA~a7Jv=%*x=Dp6B&8&z9!@bfGUyGx#2EQ5X3DIHN%1V3>`nBo_4nKG zE4`Z;9y4i1_@tQ;lV;9;K6Cms{?di>tS@Y>I(TztW#!DumsN@e*PC2QL=w2B?8st7 zbvdKo73JrQ3=E+H3=CpGm-{AW=6Qs=IOpdUVBAW9GiaCw#S|&IoJEk%(o1>I~fDSL??x26q>phM{Ew-74tr?be;Fp11*l$ zHaz>9H#)7BbnEw*cv4r8nXqg@N!v*SjZ@K@Kg3t)eU)7?Q){VA`|mfc+YbG_S;zYO zYsK4x=1NivIgia~TN_n5^$3UkwtBP6`dgCEezE!*7gMD6(DT5y-JGJON^`aLU0wFh zL;C4#LFqvEb5ajaHT_kQODL7top#A-w&)z;tmM~6axc_qKRM+f`{Y;J6_ww?@4VOX zemN>zZXjsG^0C=S;8XB9@52>W#lKFzo>K1A*1DfT?QWUgo4xN}-2Gtt!}hh1{4eIk zSC<)7B_Fu8{lsh)f1P^Ihvj30V_@ZZ~@>AVQ{RPwiIsWwjzx0d$y!^Uf zSs%m`uHAYw<557y!a1_5R(J|Mc^@@r&*DRB-_N{TbH7owU~Smlviw#)Ux8juRoR9} znTHlj_3sEY3HfODK7RaaW$65B13s_&vp-*rKaf!U@8Br|ujPfa6D-w%ew)p(B{Bl2rwO;Voi)Z4fNuyD!{zNq}X*^(IVBiNPjo|#e z^x)K-)Z`Lynm8I9n|;VYr1pDwO6@zRTVGB$@@w6eJ2vA?p8g}}wdH0r)RuZW3jY5c zlxwclY-ld2$p2l%@_CWpyEW|>&gHbMsfcbUZPr<-RWtud!}4r37GZ6hX_bns9BV&t z2+dVL8t{6Ot`@Ih&X(R=>Sk4~L57-aEb`NOkBMFn3vsjsGqZ`LW`W`=;U=f$H{l&EfbuG28E+4RM_}%t6^3{@uE57zW zF!8mRvq?zii}S0X?T2qIh-)v=xa2eK*_QhZ{;JU%qYiUQKXGl`l`I`mcc<2SN7FXO z3%4v*zLJZ&RCw&irj}W$X75dt>`yNG_HUYVURSrfgW=a2p&eV2uWfyv_)2L01!Loa zTaVi=T#1){KgqseU+AS{J8s>L2+M3MVbe%WJ>?i1Df=~E{fqu(p;`JeErI0`ix{k* zt*=gh=Ca{Ed!9tay^|Yc9)4(g{7Et@?t_cG&;4Gt{^~6npYlJwI(r|Og&CPd7;u-e zz{rAtMi2!nbJ2C77g|s~3=ECWp}OEj7`j&UQUjrNAuz#UFGJAHKu=x>Gxh*03$(-* T;LXYgQosU)pMZ1 From 4ab7ef9af9ca0eae3b6b47c26de162d59dde16e5 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Mon, 5 Dec 2022 15:12:50 -0500 Subject: [PATCH 0930/2991] Show distance snap for first juice stream object. Fixes #18469 --- osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index bbdffbf39c..fbe897b484 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -188,7 +188,8 @@ namespace osu.Game.Rulesets.Catch.Edit if (EditorBeatmap.PlacementObject.Value is JuiceStream) { // Juice stream path is not subject to snapping. - return null; + if (((JuiceStream)EditorBeatmap.PlacementObject.Value).Distance != 0) + return null; } double timeAtCursor = ((CatchPlayfield)Playfield).TimeAtScreenSpacePosition(inputManager.CurrentState.Mouse.Position); From b66409bd37e519d40584fcb1d06a3690595f39ce Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 5 Dec 2022 23:38:45 +0300 Subject: [PATCH 0931/2991] Perform rewind with right click only if cursor didn't leave the button --- osu.Game/Screens/Select/FooterButtonRandom.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/FooterButtonRandom.cs b/osu.Game/Screens/Select/FooterButtonRandom.cs index 8d7463067e..f413126e87 100644 --- a/osu.Game/Screens/Select/FooterButtonRandom.cs +++ b/osu.Game/Screens/Select/FooterButtonRandom.cs @@ -119,7 +119,7 @@ namespace osu.Game.Screens.Select protected override void OnMouseUp(MouseUpEvent e) { - if (e.Button == MouseButton.Right) + if (e.Button == MouseButton.Right && IsHovered) { rewindSearch = true; TriggerClick(); From fc630165fd612baa3043ff35d50651c5c8ed5d09 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Tue, 6 Dec 2022 15:08:21 +0100 Subject: [PATCH 0932/2991] Adjust formatting of BPM text --- osu.Game/Screens/Play/HUD/BPMCounter.cs | 46 ++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/BPMCounter.cs b/osu.Game/Screens/Play/HUD/BPMCounter.cs index 83569c13d9..8d3cab40b0 100644 --- a/osu.Game/Screens/Play/HUD/BPMCounter.cs +++ b/osu.Game/Screens/Play/HUD/BPMCounter.cs @@ -4,12 +4,15 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Skinning; +using osuTK; namespace osu.Game.Screens.Play.HUD { @@ -46,7 +49,48 @@ namespace osu.Game.Screens.Play.HUD protected override LocalisableString FormatCount(double count) { - return $@"{count:0} BPM"; + return $@"{count:0}"; + } + + protected override IHasText CreateText() => new TextComponent(); + + private partial class TextComponent : CompositeDrawable, IHasText + { + public LocalisableString Text + { + get => text.Text; + set => text.Text = value; + } + + private readonly OsuSpriteText text; + + public TextComponent() + { + AutoSizeAxes = Axes.Both; + + InternalChild = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Spacing = new Vector2(2), + Children = new Drawable[] + { + text = new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Font = OsuFont.Numeric.With(size: 16, fixedWidth: true) + }, + new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Font = OsuFont.Numeric.With(size: 8, fixedWidth: true), + Text = @"BPM", + Padding = new MarginPadding { Bottom = 1.5f }, // align baseline better + } + } + }; + } } public bool UsesFixedAnchor { get; set; } From 0bfc46963b7ddd37ee2096b8bb1623f507d24988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 6 Dec 2022 22:46:39 +0100 Subject: [PATCH 0933/2991] Add failing test case --- .../TestSceneModDifficultyAdjustSettings.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModDifficultyAdjustSettings.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModDifficultyAdjustSettings.cs index 0d02a72d87..f45f5b9f59 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModDifficultyAdjustSettings.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModDifficultyAdjustSettings.cs @@ -126,6 +126,21 @@ namespace osu.Game.Tests.Visual.UserInterface checkBindableAtValue("Circle Size", 9); } + [Test] + public void TestExtendedLimitsRetainedAfterBoundCopyCreation() + { + setExtendedLimits(true); + setSliderValue("Circle Size", 11); + + checkSliderAtValue("Circle Size", 11); + checkBindableAtValue("Circle Size", 11); + + AddStep("create bound copy", () => _ = modDifficultyAdjust.CircleSize.GetBoundCopy()); + + checkSliderAtValue("Circle Size", 11); + checkBindableAtValue("Circle Size", 11); + } + [Test] public void TestResetToDefault() { From 81a42dc05d53d714b128b1704730d45fac85d454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 6 Dec 2022 22:50:14 +0100 Subject: [PATCH 0934/2991] Fix extended values in difficulty adjust being truncated to 10 on beatmap change --- osu.Game/Rulesets/Mods/DifficultyBindable.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/DifficultyBindable.cs b/osu.Game/Rulesets/Mods/DifficultyBindable.cs index cca72cf3ac..c21ce756c9 100644 --- a/osu.Game/Rulesets/Mods/DifficultyBindable.cs +++ b/osu.Game/Rulesets/Mods/DifficultyBindable.cs @@ -118,11 +118,18 @@ namespace osu.Game.Rulesets.Mods if (!(them is DifficultyBindable otherDifficultyBindable)) throw new InvalidOperationException($"Cannot bind to a non-{nameof(DifficultyBindable)}."); + // ensure that MaxValue and ExtendedMaxValue are copied across first before continuing. + // not doing so may cause the value of CurrentNumber to be truncated to 10. + otherDifficultyBindable.CopyTo(this); + + // set up mutual binding for ExtendedLimits to correctly set the upper bound of CurrentNumber. ExtendedLimits.BindTarget = otherDifficultyBindable.ExtendedLimits; - // the actual values need to be copied after the max value constraints. + // set up mutual binding for CurrentNumber. this must happen after all of the above. CurrentNumber.BindTarget = otherDifficultyBindable.CurrentNumber; + // finish up the binding by setting up weak references via the base call. + // unfortunately this will call `.CopyTo()` again, but fixing that is problematic and messy. base.BindTo(them); } From 30952199b8b4da83878f59fbeec88103e641a9fa Mon Sep 17 00:00:00 2001 From: Pasi4K5 Date: Wed, 7 Dec 2022 00:40:18 +0100 Subject: [PATCH 0935/2991] Allow random mod to flip sliders --- osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs | 5 ++++ .../Utils/OsuHitObjectGenerationUtils.cs | 23 ++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs index 1621bb50b1..fc92696e9a 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs @@ -65,6 +65,11 @@ namespace osu.Game.Rulesets.Osu.Mods flowDirection = !flowDirection; } + if (positionInfos[i].HitObject is Slider slider && random.NextDouble() < 0.5) + { + OsuHitObjectGenerationUtils.FlipSlider(slider); + } + if (i == 0) { positionInfos[i].DistanceFromPrevious = (float)(random.NextDouble() * OsuPlayfield.BASE_SIZE.Y / 2); diff --git a/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs b/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs index 3a8b3f67d0..b081978803 100644 --- a/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs +++ b/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs @@ -160,14 +160,31 @@ namespace osu.Game.Rulesets.Osu.Utils public static void RotateSlider(Slider slider, float rotation) { void rotateNestedObject(OsuHitObject nested) => nested.Position = rotateVector(nested.Position - slider.Position, rotation) + slider.Position; + void rotateControlPoint(PathControlPoint point) => point.Position = rotateVector(point.Position, rotation); + modifySlider(slider, rotateNestedObject, rotateControlPoint); + } + + /// + /// Flips the slider about its start position. + /// + public static void FlipSlider(Slider slider) + { + void flipNestedObject(OsuHitObject nested) => nested.Position = new Vector2(slider.Position.X - (nested.X - slider.Position.X), nested.Y); + static void flipControlPoint(PathControlPoint point) => point.Position = new Vector2(-point.Position.X, point.Position.Y); + + modifySlider(slider, flipNestedObject, flipControlPoint); + } + + private static void modifySlider(Slider slider, Action modifyNestedObject, Action modifyControlPoint) + { // No need to update the head and tail circles, since slider handles that when the new slider path is set - slider.NestedHitObjects.OfType().ForEach(rotateNestedObject); - slider.NestedHitObjects.OfType().ForEach(rotateNestedObject); + slider.NestedHitObjects.OfType().ForEach(modifyNestedObject); + slider.NestedHitObjects.OfType().ForEach(modifyNestedObject); var controlPoints = slider.Path.ControlPoints.Select(p => new PathControlPoint(p.Position, p.Type)).ToArray(); foreach (var point in controlPoints) - point.Position = rotateVector(point.Position, rotation); + modifyControlPoint(point); slider.Path = new SliderPath(controlPoints, slider.Path.ExpectedDistance.Value); } From 91e9c275078d7ec098cacdf14fb5cb766899a65d Mon Sep 17 00:00:00 2001 From: Pasi4K5 Date: Wed, 7 Dec 2022 00:48:25 +0100 Subject: [PATCH 0936/2991] Rename `FlipSlider()` to `FlipSliderHorizontally` --- osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs | 2 +- osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs index fc92696e9a..58f5b2fa8d 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs @@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Mods if (positionInfos[i].HitObject is Slider slider && random.NextDouble() < 0.5) { - OsuHitObjectGenerationUtils.FlipSlider(slider); + OsuHitObjectGenerationUtils.FlipSliderHorizontally(slider); } if (i == 0) diff --git a/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs b/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs index b081978803..42c6946414 100644 --- a/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs +++ b/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs @@ -166,9 +166,9 @@ namespace osu.Game.Rulesets.Osu.Utils } /// - /// Flips the slider about its start position. + /// Flips the slider about its start position horizontally. /// - public static void FlipSlider(Slider slider) + public static void FlipSliderHorizontally(Slider slider) { void flipNestedObject(OsuHitObject nested) => nested.Position = new Vector2(slider.Position.X - (nested.X - slider.Position.X), nested.Y); static void flipControlPoint(PathControlPoint point) => point.Position = new Vector2(-point.Position.X, point.Position.Y); From 8f3023ffd9c64c91258e3d7642d57f8431c12cd4 Mon Sep 17 00:00:00 2001 From: Pasi4K5 Date: Wed, 7 Dec 2022 01:05:15 +0100 Subject: [PATCH 0937/2991] Update `ReflectHorizontally()` and `ReflectVertically()` to use `FlipSliderHorizontally()` and `modifySlider()`. --- .../Utils/OsuHitObjectGenerationUtils.cs | 27 +++++-------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs b/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs index 42c6946414..f565456911 100644 --- a/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs +++ b/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs @@ -116,18 +116,10 @@ namespace osu.Game.Rulesets.Osu.Utils { osuObject.Position = new Vector2(OsuPlayfield.BASE_SIZE.X - osuObject.X, osuObject.Position.Y); - if (!(osuObject is Slider slider)) + if (osuObject is not Slider slider) return; - // No need to update the head and tail circles, since slider handles that when the new slider path is set - slider.NestedHitObjects.OfType().ForEach(h => h.Position = new Vector2(OsuPlayfield.BASE_SIZE.X - h.Position.X, h.Position.Y)); - slider.NestedHitObjects.OfType().ForEach(h => h.Position = new Vector2(OsuPlayfield.BASE_SIZE.X - h.Position.X, h.Position.Y)); - - var controlPoints = slider.Path.ControlPoints.Select(p => new PathControlPoint(p.Position, p.Type)).ToArray(); - foreach (var point in controlPoints) - point.Position = new Vector2(-point.Position.X, point.Position.Y); - - slider.Path = new SliderPath(controlPoints, slider.Path.ExpectedDistance.Value); + FlipSliderHorizontally(slider); } /// @@ -138,18 +130,13 @@ namespace osu.Game.Rulesets.Osu.Utils { osuObject.Position = new Vector2(osuObject.Position.X, OsuPlayfield.BASE_SIZE.Y - osuObject.Y); - if (!(osuObject is Slider slider)) + if (osuObject is not Slider slider) return; - // No need to update the head and tail circles, since slider handles that when the new slider path is set - slider.NestedHitObjects.OfType().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y)); - slider.NestedHitObjects.OfType().ForEach(h => h.Position = new Vector2(h.Position.X, OsuPlayfield.BASE_SIZE.Y - h.Position.Y)); + void flipNestedObject(OsuHitObject nested) => nested.Position = new Vector2(nested.X, slider.Y - (nested.Y - slider.Y)); + static void flipControlPoint(PathControlPoint point) => point.Position = new Vector2(point.Position.X, -point.Position.Y); - var controlPoints = slider.Path.ControlPoints.Select(p => new PathControlPoint(p.Position, p.Type)).ToArray(); - foreach (var point in controlPoints) - point.Position = new Vector2(point.Position.X, -point.Position.Y); - - slider.Path = new SliderPath(controlPoints, slider.Path.ExpectedDistance.Value); + modifySlider(slider, flipNestedObject, flipControlPoint); } /// @@ -170,7 +157,7 @@ namespace osu.Game.Rulesets.Osu.Utils /// public static void FlipSliderHorizontally(Slider slider) { - void flipNestedObject(OsuHitObject nested) => nested.Position = new Vector2(slider.Position.X - (nested.X - slider.Position.X), nested.Y); + void flipNestedObject(OsuHitObject nested) => nested.Position = new Vector2(slider.X - (nested.X - slider.X), nested.Y); static void flipControlPoint(PathControlPoint point) => point.Position = new Vector2(-point.Position.X, point.Position.Y); modifySlider(slider, flipNestedObject, flipControlPoint); From df181acffe1869cba648a75d9dc13b1f453cb98f Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Tue, 6 Dec 2022 20:10:51 +0900 Subject: [PATCH 0938/2991] Append lazer score data to .osr files --- .../Legacy/LegacyReplaySoloScoreInfo.cs | 38 +++++++++++ osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs | 64 ++++++++++++------- osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs | 12 +++- 3 files changed, 89 insertions(+), 25 deletions(-) create mode 100644 osu.Game/Scoring/Legacy/LegacyReplaySoloScoreInfo.cs diff --git a/osu.Game/Scoring/Legacy/LegacyReplaySoloScoreInfo.cs b/osu.Game/Scoring/Legacy/LegacyReplaySoloScoreInfo.cs new file mode 100644 index 0000000000..f2e8cf141b --- /dev/null +++ b/osu.Game/Scoring/Legacy/LegacyReplaySoloScoreInfo.cs @@ -0,0 +1,38 @@ +// 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 Newtonsoft.Json; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Scoring.Legacy +{ + /// + /// A minified version of retrofit onto the end of legacy replay files (.osr), + /// containing the minimum data required to support storage of non-legacy replays. + /// + [Serializable] + [JsonObject(MemberSerialization.OptIn)] + public class LegacyReplaySoloScoreInfo + { + [JsonProperty("mods")] + public APIMod[] Mods { get; set; } = Array.Empty(); + + [JsonProperty("statistics")] + public Dictionary Statistics { get; set; } = new Dictionary(); + + [JsonProperty("maximum_statistics")] + public Dictionary MaximumStatistics { get; set; } = new Dictionary(); + + public static LegacyReplaySoloScoreInfo FromScore(ScoreInfo score) => new LegacyReplaySoloScoreInfo + { + Mods = score.APIMods, + Statistics = score.Statistics.Where(kvp => kvp.Value != 0).ToDictionary(kvp => kvp.Key, kvp => kvp.Value), + MaximumStatistics = score.MaximumStatistics.Where(kvp => kvp.Value != 0).ToDictionary(kvp => kvp.Key, kvp => kvp.Value), + }; + } +} diff --git a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs index f64e730c06..2f7727ac49 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs @@ -6,6 +6,7 @@ using System; using System.IO; using System.Linq; +using Newtonsoft.Json; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Legacy; @@ -91,31 +92,23 @@ namespace osu.Game.Scoring.Legacy else if (version >= 20121008) scoreInfo.OnlineID = sr.ReadInt32(); + byte[] compressedScoreInfo = null; + + if (version >= 30000001) + compressedScoreInfo = sr.ReadByteArray(); + if (compressedReplay?.Length > 0) + readCompressedData(compressedReplay, reader => readLegacyReplay(score.Replay, reader)); + + if (compressedScoreInfo?.Length > 0) { - using (var replayInStream = new MemoryStream(compressedReplay)) + readCompressedData(compressedScoreInfo, reader => { - byte[] properties = new byte[5]; - if (replayInStream.Read(properties, 0, 5) != 5) - throw new IOException("input .lzma is too short"); - - long outSize = 0; - - for (int i = 0; i < 8; i++) - { - int v = replayInStream.ReadByte(); - if (v < 0) - throw new IOException("Can't Read 1"); - - outSize |= (long)(byte)v << (8 * i); - } - - long compressedSize = replayInStream.Length - replayInStream.Position; - - using (var lzma = new LzmaStream(properties, replayInStream, compressedSize, outSize)) - using (var reader = new StreamReader(lzma)) - readLegacyReplay(score.Replay, reader); - } + LegacyReplaySoloScoreInfo readScore = JsonConvert.DeserializeObject(reader.ReadToEnd()); + score.ScoreInfo.Statistics = readScore.Statistics; + score.ScoreInfo.MaximumStatistics = readScore.MaximumStatistics; + score.ScoreInfo.Mods = readScore.Mods.Select(m => m.ToMod(currentRuleset)).ToArray(); + }); } } @@ -128,6 +121,33 @@ namespace osu.Game.Scoring.Legacy return score; } + private void readCompressedData(byte[] data, Action readFunc) + { + using (var replayInStream = new MemoryStream(data)) + { + byte[] properties = new byte[5]; + if (replayInStream.Read(properties, 0, 5) != 5) + throw new IOException("input .lzma is too short"); + + long outSize = 0; + + for (int i = 0; i < 8; i++) + { + int v = replayInStream.ReadByte(); + if (v < 0) + throw new IOException("Can't Read 1"); + + outSize |= (long)(byte)v << (8 * i); + } + + long compressedSize = replayInStream.Length - replayInStream.Position; + + using (var lzma = new LzmaStream(properties, replayInStream, compressedSize, outSize)) + using (var reader = new StreamReader(lzma)) + readFunc(reader); + } + } + /// /// Populates the accuracy of a given from its contained statistics. /// diff --git a/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs index 750bb50be3..024b691de2 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs @@ -11,6 +11,7 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; using osu.Game.Extensions; using osu.Game.IO.Legacy; +using osu.Game.IO.Serialization; using osu.Game.Replays.Legacy; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Replays.Types; @@ -29,7 +30,7 @@ namespace osu.Game.Scoring.Legacy /// /// The first stable-compatible YYYYMMDD format version given to lazer usage of replays. /// - public const int FIRST_LAZER_VERSION = 30000000; + public const int FIRST_LAZER_VERSION = 30000001; private readonly Score score; private readonly IBeatmap? beatmap; @@ -77,6 +78,7 @@ namespace osu.Game.Scoring.Legacy sw.WriteByteArray(createReplayData()); sw.Write((long)0); writeModSpecificData(score.ScoreInfo, sw); + sw.WriteByteArray(createScoreInfoData()); } } @@ -84,9 +86,13 @@ namespace osu.Game.Scoring.Legacy { } - private byte[] createReplayData() + private byte[] createReplayData() => compress(replayStringContent); + + private byte[] createScoreInfoData() => compress(LegacyReplaySoloScoreInfo.FromScore(score.ScoreInfo).Serialize()); + + private byte[] compress(string data) { - byte[] content = new ASCIIEncoding().GetBytes(replayStringContent); + byte[] content = new ASCIIEncoding().GetBytes(data); using (var outStream = new MemoryStream()) { From 8709b1f2eaa2ef158149b1aaa08bfafe6109d7fc Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 7 Dec 2022 14:23:52 +0900 Subject: [PATCH 0939/2991] Immediately send ack request when joining new channels --- osu.Game/Online/Chat/ChannelManager.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index eaef940d5f..a4661dcbd7 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -529,6 +529,10 @@ namespace osu.Game.Online.Chat { Logger.Log($"Joined public channel {channel}"); joinChannel(channel, fetchInitialMessages); + + // Required after joining public channels to mark the user as online in them. + // Todo: Temporary workaround for https://github.com/ppy/osu-web/issues/9602 + SendAck(); }; req.Failure += e => { From eea7984ba936b5896b9afb26479150dafb1358cb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Dec 2022 14:53:56 +0900 Subject: [PATCH 0940/2991] Remove triangle effect from latency certifier buttons --- osu.Game/Screens/Utility/ButtonWithKeyBind.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Utility/ButtonWithKeyBind.cs b/osu.Game/Screens/Utility/ButtonWithKeyBind.cs index 29e9cd2515..7c78836b12 100644 --- a/osu.Game/Screens/Utility/ButtonWithKeyBind.cs +++ b/osu.Game/Screens/Utility/ButtonWithKeyBind.cs @@ -47,6 +47,8 @@ namespace osu.Game.Screens.Utility Height = 100; SpriteText.Colour = overlayColourProvider.Background6; SpriteText.Font = OsuFont.TorusAlternate.With(size: 34); + + Triangles?.Hide(); } } } From 49df05dd07a162955788a4cfde863272d18c1420 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 7 Dec 2022 15:07:39 +0900 Subject: [PATCH 0941/2991] Add test --- .../Formats/LegacyScoreDecoderTest.cs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs index cd6e5e7919..93cda34ef7 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyScoreDecoderTest.cs @@ -16,7 +16,9 @@ using osu.Game.Rulesets; using osu.Game.Rulesets.Catch; using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Mania.Mods; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Osu.Replays; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.Replays; @@ -179,6 +181,40 @@ namespace osu.Game.Tests.Beatmaps.Formats }); } + [Test] + public void TestSoloScoreData() + { + var ruleset = new OsuRuleset().RulesetInfo; + + var scoreInfo = TestResources.CreateTestScoreInfo(ruleset); + scoreInfo.Mods = new Mod[] + { + new OsuModDoubleTime { SpeedChange = { Value = 1.1 } } + }; + + var beatmap = new TestBeatmap(ruleset); + var score = new Score + { + ScoreInfo = scoreInfo, + Replay = new Replay + { + Frames = new List + { + new OsuReplayFrame(2000, OsuPlayfield.BASE_SIZE / 2, OsuAction.LeftButton) + } + } + }; + + var decodedAfterEncode = encodeThenDecode(LegacyBeatmapDecoder.LATEST_VERSION, score, beatmap); + + Assert.Multiple(() => + { + Assert.That(decodedAfterEncode.ScoreInfo.Statistics, Is.EqualTo(scoreInfo.Statistics)); + Assert.That(decodedAfterEncode.ScoreInfo.MaximumStatistics, Is.EqualTo(scoreInfo.MaximumStatistics)); + Assert.That(decodedAfterEncode.ScoreInfo.Mods, Is.EqualTo(scoreInfo.Mods)); + }); + } + private static Score encodeThenDecode(int beatmapVersion, Score score, TestBeatmap beatmap) { var encodeStream = new MemoryStream(); From e8766570c518cf35421db0a5a8ade5bb3caca0f0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Dec 2022 16:06:53 +0900 Subject: [PATCH 0942/2991] Update resources --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 0bf415e764..5494460de2 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -51,7 +51,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index a176d73854..725d1d6209 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index e192467247..29777c6584 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -61,7 +61,7 @@ - + From c5e461e734f47364333432af118d398b78f6f4c9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Dec 2022 16:28:51 +0900 Subject: [PATCH 0943/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 5494460de2..61c968ebc9 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 725d1d6209..fbac6f38b0 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 29777c6584..4683437173 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From 0497e433b1de18dd7c176fd6ab63e24d74581e1c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Dec 2022 16:30:15 +0900 Subject: [PATCH 0944/2991] Change `SectionsContainer` to use flowing children for section update logic --- osu.Game/Graphics/Containers/SectionsContainer.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/Containers/SectionsContainer.cs b/osu.Game/Graphics/Containers/SectionsContainer.cs index 123589c552..8dd6eac7bb 100644 --- a/osu.Game/Graphics/Containers/SectionsContainer.cs +++ b/osu.Game/Graphics/Containers/SectionsContainer.cs @@ -240,7 +240,9 @@ namespace osu.Game.Graphics.Containers headerBackgroundContainer.Height = expandableHeaderSize + fixedHeaderSize; headerBackgroundContainer.Y = ExpandableHeader?.Y ?? 0; - float smallestSectionHeight = Children.Count > 0 ? Children.Min(d => d.Height) : 0; + var flowChildren = scrollContentContainer.FlowingChildren.OfType(); + + float smallestSectionHeight = flowChildren.Any() ? flowChildren.Min(d => d.Height) : 0; // scroll offset is our fixed header height if we have it plus 10% of content height // plus 5% to fix floating point errors and to not have a section instantly unselect when scrolling upwards @@ -249,7 +251,7 @@ namespace osu.Game.Graphics.Containers float scrollCentre = fixedHeaderSize + scrollContainer.DisplayableContent * scroll_y_centre + selectionLenienceAboveSection; - var presentChildren = Children.Where(c => c.IsPresent); + var presentChildren = flowChildren.Where(c => c.IsPresent); if (lastClickedSection != null) SelectedSection.Value = lastClickedSection; From 56e94e49a36473178712f3e865e06ea68cabb5e0 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 6 Dec 2022 23:36:11 -0800 Subject: [PATCH 0945/2991] Display nominated ranked beatmaps in user profile --- osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs | 3 ++- osu.Game/Online/API/Requests/Responses/APIUser.cs | 3 +++ .../Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs | 3 +++ osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs | 3 ++- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs b/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs index d723786f23..e4134980b1 100644 --- a/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs @@ -32,6 +32,7 @@ namespace osu.Game.Online.API.Requests Loved, Pending, Guest, - Graveyard + Graveyard, + Nominated, } } diff --git a/osu.Game/Online/API/Requests/Responses/APIUser.cs b/osu.Game/Online/API/Requests/Responses/APIUser.cs index d3ddcffaf5..2b6193f661 100644 --- a/osu.Game/Online/API/Requests/Responses/APIUser.cs +++ b/osu.Game/Online/API/Requests/Responses/APIUser.cs @@ -164,6 +164,9 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"guest_beatmapset_count")] public int GuestBeatmapsetCount; + [JsonProperty(@"nominated_beatmapset_count")] + public int NominatedBeatmapsetCount; + [JsonProperty(@"scores_best_count")] public int ScoresBestCount; diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index 8c1eea6520..56d9fb9ec6 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -58,6 +58,9 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps case BeatmapSetType.Guest: return user.GuestBeatmapsetCount; + case BeatmapSetType.Nominated: + return user.NominatedBeatmapsetCount; + default: return 0; } diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs index 9f2e79b371..cf80ebd66f 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs @@ -25,7 +25,8 @@ namespace osu.Game.Overlays.Profile.Sections new PaginatedBeatmapContainer(BeatmapSetType.Loved, User, UsersStrings.ShowExtraBeatmapsLovedTitle), new PaginatedBeatmapContainer(BeatmapSetType.Guest, User, UsersStrings.ShowExtraBeatmapsGuestTitle), new PaginatedBeatmapContainer(BeatmapSetType.Pending, User, UsersStrings.ShowExtraBeatmapsPendingTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, User, UsersStrings.ShowExtraBeatmapsGraveyardTitle) + new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, User, UsersStrings.ShowExtraBeatmapsGraveyardTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Nominated, User, UsersStrings.ShowExtraBeatmapsNominatedTitle), }; } } From 62b0436bcf81d7274dd0c3a92c3301dc45699bc5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Dec 2022 16:31:24 +0900 Subject: [PATCH 0946/2991] Reverse depth of profile sections to allow for overflowing expanded beatmap cards Closes #21554. --- osu.Game/Overlays/UserProfileOverlay.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index b1a9b2096e..386f95cf0a 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -205,7 +205,9 @@ namespace osu.Game.Overlays protected override UserTrackingScrollContainer CreateScrollContainer() => new OverlayScrollContainer(); - protected override FlowContainer CreateScrollContentContainer() => new FillFlowContainer + // Reverse child ID is required so expanding beatmap panels can appear above sections below them. + // This can also be done by setting Depth when adding new sections above if using ReverseChildID turns out to have any issues. + protected override FlowContainer CreateScrollContentContainer() => new ReverseChildIDFillFlowContainer { Direction = FillDirection.Vertical, AutoSizeAxes = Axes.Y, From cd46ca31f9af73541e05f515018847a588b52775 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 7 Dec 2022 09:51:22 +0100 Subject: [PATCH 0947/2991] Add segmend end completions to SliderPath --- osu.Game/Rulesets/Objects/SliderPath.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/osu.Game/Rulesets/Objects/SliderPath.cs b/osu.Game/Rulesets/Objects/SliderPath.cs index ddc121eb5b..46c41f0b5a 100644 --- a/osu.Game/Rulesets/Objects/SliderPath.cs +++ b/osu.Game/Rulesets/Objects/SliderPath.cs @@ -41,6 +41,7 @@ namespace osu.Game.Rulesets.Objects private readonly List calculatedPath = new List(); private readonly List cumulativeLength = new List(); + private readonly List segmentEnds = new List(); private readonly Cached pathCache = new Cached(); private double calculatedLength; @@ -191,6 +192,16 @@ namespace osu.Game.Rulesets.Objects return pointsInCurrentSegment; } + /// + /// Returns the progress values at which segments of the path end. + /// + public IEnumerable GetSegmentEnds() + { + ensureValid(); + + return segmentEnds.Select(i => cumulativeLength[i] / calculatedLength); + } + private void invalidate() { pathCache.Invalidate(); @@ -211,6 +222,7 @@ namespace osu.Game.Rulesets.Objects private void calculatePath() { calculatedPath.Clear(); + segmentEnds.Clear(); if (ControlPoints.Count == 0) return; @@ -236,6 +248,9 @@ namespace osu.Game.Rulesets.Objects calculatedPath.Add(t); } + // Remember the index of the segment end + segmentEnds.Add(calculatedPath.Count - 1); + // Start the new segment at the current vertex start = i; } From 98a312ca9661c8d6a61141a4be57265a93b79a2a Mon Sep 17 00:00:00 2001 From: OliBomby Date: Thu, 3 Nov 2022 15:16:31 +0100 Subject: [PATCH 0948/2991] Fix segmentEnds incorrect on shortened paths --- osu.Game/Rulesets/Objects/SliderPath.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Rulesets/Objects/SliderPath.cs b/osu.Game/Rulesets/Objects/SliderPath.cs index 46c41f0b5a..2340cbd6c3 100644 --- a/osu.Game/Rulesets/Objects/SliderPath.cs +++ b/osu.Game/Rulesets/Objects/SliderPath.cs @@ -316,6 +316,10 @@ namespace osu.Game.Rulesets.Objects { cumulativeLength.RemoveAt(cumulativeLength.Count - 1); calculatedPath.RemoveAt(pathEndIndex--); + + // Shorten the last segment to the expected distance + if (segmentEnds.Count > 0) + segmentEnds[^1]--; } } From 819fd5f950f82a196ed8d4ce1b1b617a05e2f4e2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Dec 2022 17:52:57 +0900 Subject: [PATCH 0949/2991] Fix incorrect resolution of `GameHost` in `LegacyImportManager` --- osu.Game/Database/LegacyImportManager.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Database/LegacyImportManager.cs b/osu.Game/Database/LegacyImportManager.cs index 901b953bf2..b5338fbe1f 100644 --- a/osu.Game/Database/LegacyImportManager.cs +++ b/osu.Game/Database/LegacyImportManager.cs @@ -42,8 +42,8 @@ namespace osu.Game.Database [Resolved] private RealmAccess realmAccess { get; set; } = null!; - [Resolved(canBeNull: true)] // canBeNull required while we remain on mono for mobile platforms. - private DesktopGameHost? desktopGameHost { get; set; } + [Resolved] + private GameHost gameHost { get; set; } = null!; [Resolved] private INotificationOverlay? notifications { get; set; } @@ -52,7 +52,7 @@ namespace osu.Game.Database public bool SupportsImportFromStable => RuntimeInfo.IsDesktop; - public void UpdateStorage(string stablePath) => cachedStorage = new StableStorage(stablePath, desktopGameHost); + public void UpdateStorage(string stablePath) => cachedStorage = new StableStorage(stablePath, gameHost as DesktopGameHost); public virtual async Task GetImportCount(StableContent content, CancellationToken cancellationToken) { From 9f4bb3e0cacc3248bf4c76396ad6cb97fca82b46 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 7 Dec 2022 09:51:22 +0100 Subject: [PATCH 0950/2991] Add segmend end completions to SliderPath Fix segmentEnds incorrect on shortened paths Revert "Add segmend end completions to SliderPath" This reverts commit cd46ca31f9af73541e05f515018847a588b52775. Revert "Fix segmentEnds incorrect on shortened paths" This reverts commit 98a312ca9661c8d6a61141a4be57265a93b79a2a. From 10b59007107594402c946ba071164ff8975a717a Mon Sep 17 00:00:00 2001 From: OliBomby Date: Thu, 3 Nov 2022 12:25:23 +0100 Subject: [PATCH 0951/2991] made PathControlPointVisualiser generic --- .../TestScenePathControlPointVisualiser.cs | 4 +- .../TestSceneSliderControlPointPiece.cs | 14 ++-- .../TestSceneSliderSelectionBlueprint.cs | 2 +- .../Editor/TestSceneSliderSnapping.cs | 8 +- .../Editor/TestSceneSliderSplitting.cs | 8 +- .../PathControlPointConnectionPiece.cs | 28 ++++--- .../Components/PathControlPointPiece.cs | 45 +++++----- .../Components/PathControlPointVisualiser.cs | 82 +++++++++---------- .../Sliders/SliderPlacementBlueprint.cs | 4 +- .../Sliders/SliderSelectionBlueprint.cs | 4 +- .../Editing/TestSceneBlueprintOrdering.cs | 2 +- .../Editing/TestSceneComposerSelection.cs | 2 +- 12 files changed, 103 insertions(+), 100 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestScenePathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestScenePathControlPointVisualiser.cs index d1a04e28e5..37561fda85 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestScenePathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestScenePathControlPointVisualiser.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor public partial class TestScenePathControlPointVisualiser : OsuManualInputManagerTestScene { private Slider slider; - private PathControlPointVisualiser visualiser; + private PathControlPointVisualiser visualiser; [SetUp] public void Setup() => Schedule(() => @@ -148,7 +148,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor assertControlPointPathType(3, null); } - private void createVisualiser(bool allowSelection) => AddStep("create visualiser", () => Child = visualiser = new PathControlPointVisualiser(slider, allowSelection) + private void createVisualiser(bool allowSelection) => AddStep("create visualiser", () => Child = visualiser = new PathControlPointVisualiser(slider, allowSelection) { Anchor = Anchor.Centre, Origin = Anchor.Centre diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderControlPointPiece.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderControlPointPiece.cs index 112aab884b..db9eea4127 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderControlPointPiece.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderControlPointPiece.cs @@ -159,11 +159,11 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor } private void assertSelectionCount(int count) => - AddAssert($"{count} control point pieces selected", () => this.ChildrenOfType().Count(piece => piece.IsSelected.Value) == count); + AddAssert($"{count} control point pieces selected", () => this.ChildrenOfType>().Count(piece => piece.IsSelected.Value) == count); private void assertSelected(int index) => AddAssert($"{(index + 1).ToOrdinalWords()} control point piece selected", - () => this.ChildrenOfType().Single(piece => piece.ControlPoint == slider.Path.ControlPoints[index]).IsSelected.Value); + () => this.ChildrenOfType>().Single(piece => piece.ControlPoint == slider.Path.ControlPoints[index]).IsSelected.Value); private void moveMouseToRelativePosition(Vector2 relativePosition) => AddStep($"move mouse to {relativePosition}", () => @@ -202,12 +202,12 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor moveMouseToControlPoint(2); AddStep("hold left mouse", () => InputManager.PressButton(MouseButton.Left)); - AddAssert("three control point pieces selected", () => this.ChildrenOfType().Count(piece => piece.IsSelected.Value) == 3); + AddAssert("three control point pieces selected", () => this.ChildrenOfType>().Count(piece => piece.IsSelected.Value) == 3); addMovementStep(new Vector2(450, 50)); AddStep("release left mouse", () => InputManager.ReleaseButton(MouseButton.Left)); - AddAssert("three control point pieces selected", () => this.ChildrenOfType().Count(piece => piece.IsSelected.Value) == 3); + AddAssert("three control point pieces selected", () => this.ChildrenOfType>().Count(piece => piece.IsSelected.Value) == 3); assertControlPointPosition(2, new Vector2(450, 50)); assertControlPointType(2, PathType.PerfectCurve); @@ -236,12 +236,12 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor moveMouseToControlPoint(3); AddStep("hold left mouse", () => InputManager.PressButton(MouseButton.Left)); - AddAssert("three control point pieces selected", () => this.ChildrenOfType().Count(piece => piece.IsSelected.Value) == 3); + AddAssert("three control point pieces selected", () => this.ChildrenOfType>().Count(piece => piece.IsSelected.Value) == 3); addMovementStep(new Vector2(550, 50)); AddStep("release left mouse", () => InputManager.ReleaseButton(MouseButton.Left)); - AddAssert("three control point pieces selected", () => this.ChildrenOfType().Count(piece => piece.IsSelected.Value) == 3); + AddAssert("three control point pieces selected", () => this.ChildrenOfType>().Count(piece => piece.IsSelected.Value) == 3); // note: if the head is part of the selection being moved, the entire slider is moved. // the unselected nodes will therefore change position relative to the slider head. @@ -354,7 +354,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor public new SliderBodyPiece BodyPiece => base.BodyPiece; public new TestSliderCircleOverlay HeadOverlay => (TestSliderCircleOverlay)base.HeadOverlay; public new TestSliderCircleOverlay TailOverlay => (TestSliderCircleOverlay)base.TailOverlay; - public new PathControlPointVisualiser ControlPointVisualiser => base.ControlPointVisualiser; + public new PathControlPointVisualiser ControlPointVisualiser => base.ControlPointVisualiser; public TestSliderBlueprint(Slider slider) : base(slider) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSelectionBlueprint.cs index ad740b2977..8ed77d45d7 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSelectionBlueprint.cs @@ -199,7 +199,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor public new SliderBodyPiece BodyPiece => base.BodyPiece; public new TestSliderCircleOverlay HeadOverlay => (TestSliderCircleOverlay)base.HeadOverlay; public new TestSliderCircleOverlay TailOverlay => (TestSliderCircleOverlay)base.TailOverlay; - public new PathControlPointVisualiser ControlPointVisualiser => base.ControlPointVisualiser; + public new PathControlPointVisualiser ControlPointVisualiser => base.ControlPointVisualiser; public TestSliderBlueprint(Slider slider) : base(slider) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs index e9d50d5118..f262a4334a 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs @@ -72,14 +72,14 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor [Test] public void TestMovingUnsnappedSliderNodesSnaps() { - PathControlPointPiece sliderEnd = null; + PathControlPointPiece sliderEnd = null; assertSliderSnapped(false); AddStep("select slider", () => EditorBeatmap.SelectedHitObjects.Add(slider)); AddStep("select slider end", () => { - sliderEnd = this.ChildrenOfType().Single(piece => piece.ControlPoint == slider.Path.ControlPoints.Last()); + sliderEnd = this.ChildrenOfType>().Single(piece => piece.ControlPoint == slider.Path.ControlPoints.Last()); InputManager.MoveMouseTo(sliderEnd.ScreenSpaceDrawQuad.Centre); }); AddStep("move slider end", () => @@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("select slider", () => EditorBeatmap.SelectedHitObjects.Add(slider)); AddStep("move mouse to new point location", () => { - var firstPiece = this.ChildrenOfType().Single(piece => piece.ControlPoint == slider.Path.ControlPoints[0]); + var firstPiece = this.ChildrenOfType>().Single(piece => piece.ControlPoint == slider.Path.ControlPoints[0]); var pos = slider.Path.PositionAt(0.25d) + slider.Position; InputManager.MoveMouseTo(firstPiece.Parent.ToScreenSpace(pos)); }); @@ -120,7 +120,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("select slider", () => EditorBeatmap.SelectedHitObjects.Add(slider)); AddStep("move mouse to second control point", () => { - var secondPiece = this.ChildrenOfType().Single(piece => piece.ControlPoint == slider.Path.ControlPoints[1]); + var secondPiece = this.ChildrenOfType>().Single(piece => piece.ControlPoint == slider.Path.ControlPoints[1]); InputManager.MoveMouseTo(secondPiece); }); AddStep("quick delete", () => diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSplitting.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSplitting.cs index b2ac462c8f..6cb77c7b92 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSplitting.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSplitting.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor => Editor.ChildrenOfType().First(); private Slider? slider; - private PathControlPointVisualiser? visualiser; + private PathControlPointVisualiser? visualiser; private const double split_gap = 100; @@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("select added slider", () => { EditorBeatmap.SelectedHitObjects.Add(slider); - visualiser = blueprintContainer.SelectionBlueprints.First(o => o.Item == slider).ChildrenOfType().First(); + visualiser = blueprintContainer.SelectionBlueprints.First(o => o.Item == slider).ChildrenOfType>().First(); }); moveMouseToControlPoint(2); @@ -122,7 +122,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("select added slider", () => { EditorBeatmap.SelectedHitObjects.Add(slider); - visualiser = blueprintContainer.SelectionBlueprints.First(o => o.Item == slider).ChildrenOfType().First(); + visualiser = blueprintContainer.SelectionBlueprints.First(o => o.Item == slider).ChildrenOfType>().First(); }); moveMouseToControlPoint(2); @@ -190,7 +190,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("select added slider", () => { EditorBeatmap.SelectedHitObjects.Add(slider); - visualiser = blueprintContainer.SelectionBlueprints.First(o => o.Item == slider).ChildrenOfType().First(); + visualiser = blueprintContainer.SelectionBlueprints.First(o => o.Item == slider).ChildrenOfType>().First(); }); moveMouseToControlPoint(2); diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointConnectionPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointConnectionPiece.cs index 28e0d650c4..67685d21a7 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointConnectionPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointConnectionPiece.cs @@ -8,34 +8,36 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Lines; using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; using osuTK; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { /// - /// A visualisation of the line between two s. + /// A visualisation of the line between two s. /// - public partial class PathControlPointConnectionPiece : CompositeDrawable + /// The type of which this visualises. + public partial class PathControlPointConnectionPiece : CompositeDrawable where T : OsuHitObject, IHasPath { public readonly PathControlPoint ControlPoint; private readonly Path path; - private readonly Slider slider; + private readonly T hitObject; public int ControlPointIndex { get; set; } - private IBindable sliderPosition; + private IBindable hitObjectPosition; private IBindable pathVersion; - public PathControlPointConnectionPiece(Slider slider, int controlPointIndex) + public PathControlPointConnectionPiece(T hitObject, int controlPointIndex) { - this.slider = slider; + this.hitObject = hitObject; ControlPointIndex = controlPointIndex; Origin = Anchor.Centre; AutoSizeAxes = Axes.Both; - ControlPoint = slider.Path.ControlPoints[controlPointIndex]; + ControlPoint = hitObject.Path.ControlPoints[controlPointIndex]; InternalChild = path = new SmoothPath { @@ -48,10 +50,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { base.LoadComplete(); - sliderPosition = slider.PositionBindable.GetBoundCopy(); - sliderPosition.BindValueChanged(_ => updateConnectingPath()); + hitObjectPosition = hitObject.PositionBindable.GetBoundCopy(); + hitObjectPosition.BindValueChanged(_ => updateConnectingPath()); - pathVersion = slider.Path.Version.GetBoundCopy(); + pathVersion = hitObject.Path.Version.GetBoundCopy(); pathVersion.BindValueChanged(_ => updateConnectingPath()); updateConnectingPath(); @@ -62,16 +64,16 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components /// private void updateConnectingPath() { - Position = slider.StackedPosition + ControlPoint.Position; + Position = hitObject.StackedPosition + ControlPoint.Position; path.ClearVertices(); int nextIndex = ControlPointIndex + 1; - if (nextIndex == 0 || nextIndex >= slider.Path.ControlPoints.Count) + if (nextIndex == 0 || nextIndex >= hitObject.Path.ControlPoints.Count) return; path.AddVertex(Vector2.Zero); - path.AddVertex(slider.Path.ControlPoints[nextIndex].Position - ControlPoint.Position); + path.AddVertex(hitObject.Path.ControlPoints[nextIndex].Position - ControlPoint.Position); path.OriginPosition = path.PositionInBoundingBox(Vector2.Zero); } diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs index d83f35d13f..a4d5c08b8a 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs @@ -29,11 +29,12 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { /// - /// A visualisation of a single in a . + /// A visualisation of a single in an osu hit object with a path. /// - public partial class PathControlPointPiece : BlueprintPiece, IHasTooltip + /// The type of which this visualises. + public partial class PathControlPointPiece : BlueprintPiece, IHasTooltip where T : OsuHitObject, IHasPath { - public Action RequestSelection; + public Action, MouseButtonEvent> RequestSelection; public Action DragStarted; public Action DragInProgress; @@ -44,34 +45,34 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components public readonly BindableBool IsSelected = new BindableBool(); public readonly PathControlPoint ControlPoint; - private readonly Slider slider; + private readonly T hitObject; private readonly Container marker; private readonly Drawable markerRing; [Resolved] private OsuColour colours { get; set; } - private IBindable sliderPosition; - private IBindable sliderScale; + private IBindable hitObjectPosition; + private IBindable hitObjectScale; [UsedImplicitly] - private readonly IBindable sliderVersion; + private readonly IBindable hitObjectVersion; - public PathControlPointPiece(Slider slider, PathControlPoint controlPoint) + public PathControlPointPiece(T hitObject, PathControlPoint controlPoint) { - this.slider = slider; + this.hitObject = hitObject; ControlPoint = controlPoint; - // we don't want to run the path type update on construction as it may inadvertently change the slider. - cachePoints(slider); + // we don't want to run the path type update on construction as it may inadvertently change the hit object. + cachePoints(hitObject); - sliderVersion = slider.Path.Version.GetBoundCopy(); + hitObjectVersion = hitObject.Path.Version.GetBoundCopy(); // schedule ensure that updates are only applied after all operations from a single frame are applied. - // this avoids inadvertently changing the slider path type for batch operations. - sliderVersion.BindValueChanged(_ => Scheduler.AddOnce(() => + // this avoids inadvertently changing the hit object path type for batch operations. + hitObjectVersion.BindValueChanged(_ => Scheduler.AddOnce(() => { - cachePoints(slider); + cachePoints(hitObject); updatePathType(); })); @@ -120,11 +121,11 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { base.LoadComplete(); - sliderPosition = slider.PositionBindable.GetBoundCopy(); - sliderPosition.BindValueChanged(_ => updateMarkerDisplay()); + hitObjectPosition = hitObject.PositionBindable.GetBoundCopy(); + hitObjectPosition.BindValueChanged(_ => updateMarkerDisplay()); - sliderScale = slider.ScaleBindable.GetBoundCopy(); - sliderScale.BindValueChanged(_ => updateMarkerDisplay()); + hitObjectScale = hitObject.ScaleBindable.GetBoundCopy(); + hitObjectScale.BindValueChanged(_ => updateMarkerDisplay()); IsSelected.BindValueChanged(_ => updateMarkerDisplay()); @@ -212,7 +213,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components protected override void OnDragEnd(DragEndEvent e) => DragEnded?.Invoke(); - private void cachePoints(Slider slider) => PointsInSegment = slider.Path.PointsInSegment(ControlPoint); + private void cachePoints(T hitObject) => PointsInSegment = hitObject.Path.PointsInSegment(ControlPoint); /// /// Handles correction of invalid path types. @@ -239,7 +240,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components /// private void updateMarkerDisplay() { - Position = slider.StackedPosition + ControlPoint.Position; + Position = hitObject.StackedPosition + ControlPoint.Position; markerRing.Alpha = IsSelected.Value ? 1 : 0; @@ -249,7 +250,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components colour = colour.Lighten(1); marker.Colour = colour; - marker.Scale = new Vector2(slider.Scale); + marker.Scale = new Vector2(hitObject.Scale); } private Color4 getColourFromNodeType() diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index 3a175888d9..65b212e976 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -29,15 +29,15 @@ using osuTK.Input; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { - public partial class PathControlPointVisualiser : CompositeDrawable, IKeyBindingHandler, IHasContextMenu + public partial class PathControlPointVisualiser : CompositeDrawable, IKeyBindingHandler, IHasContextMenu where T : OsuHitObject, IHasPath { public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; // allow context menu to appear outside of the playfield. - internal readonly Container Pieces; - internal readonly Container Connections; + internal readonly Container> Pieces; + internal readonly Container> Connections; private readonly IBindableList controlPoints = new BindableList(); - private readonly Slider slider; + private readonly T hitObject; private readonly bool allowSelection; private InputManager inputManager; @@ -48,17 +48,17 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components [Resolved(CanBeNull = true)] private IDistanceSnapProvider snapProvider { get; set; } - public PathControlPointVisualiser(Slider slider, bool allowSelection) + public PathControlPointVisualiser(T hitObject, bool allowSelection) { - this.slider = slider; + this.hitObject = hitObject; this.allowSelection = allowSelection; RelativeSizeAxes = Axes.Both; InternalChildren = new Drawable[] { - Connections = new Container { RelativeSizeAxes = Axes.Both }, - Pieces = new Container { RelativeSizeAxes = Axes.Both } + Connections = new Container> { RelativeSizeAxes = Axes.Both }, + Pieces = new Container> { RelativeSizeAxes = Axes.Both } }; } @@ -69,12 +69,12 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components inputManager = GetContainingInputManager(); controlPoints.CollectionChanged += onControlPointsChanged; - controlPoints.BindTo(slider.Path.ControlPoints); + controlPoints.BindTo(hitObject.Path.ControlPoints); } /// - /// Selects the corresponding to the given , - /// and deselects all other s. + /// Selects the corresponding to the given , + /// and deselects all other s. /// public void SetSelectionTo(PathControlPoint pathControlPoint) { @@ -124,8 +124,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components return true; } - private bool isSplittable(PathControlPointPiece p) => - // A slider can only be split on control points which connect two different slider segments. + private bool isSplittable(PathControlPointPiece p) => + // A hit object can only be split on control points which connect two different path segments. p.ControlPoint.Type.HasValue && p != Pieces.FirstOrDefault() && p != Pieces.LastOrDefault(); private void onControlPointsChanged(object sender, NotifyCollectionChangedEventArgs e) @@ -148,7 +148,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { var point = (PathControlPoint)e.NewItems[i]; - Pieces.Add(new PathControlPointPiece(slider, point).With(d => + Pieces.Add(new PathControlPointPiece(hitObject, point).With(d => { if (allowSelection) d.RequestSelection = selectionRequested; @@ -158,7 +158,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components d.DragEnded = dragEnded; })); - Connections.Add(new PathControlPointConnectionPiece(slider, e.NewStartingIndex + i)); + Connections.Add(new PathControlPointConnectionPiece(hitObject, e.NewStartingIndex + i)); } break; @@ -215,7 +215,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { } - private void selectionRequested(PathControlPointPiece piece, MouseButtonEvent e) + private void selectionRequested(PathControlPointPiece piece, MouseButtonEvent e) { if (e.Button == MouseButton.Left && inputManager.CurrentState.Keyboard.ControlPressed) piece.IsSelected.Toggle(); @@ -230,7 +230,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components /// /// The control point piece that we want to change the path type of. /// The path type we want to assign to the given control point piece. - private void updatePathType(PathControlPointPiece piece, PathType? type) + private void updatePathType(PathControlPointPiece piece, PathType? type) { int indexInSegment = piece.PointsInSegment.IndexOf(piece.ControlPoint); @@ -264,9 +264,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components private void dragStarted(PathControlPoint controlPoint) { - dragStartPositions = slider.Path.ControlPoints.Select(point => point.Position).ToArray(); - dragPathTypes = slider.Path.ControlPoints.Select(point => point.Type).ToArray(); - draggedControlPointIndex = slider.Path.ControlPoints.IndexOf(controlPoint); + dragStartPositions = hitObject.Path.ControlPoints.Select(point => point.Position).ToArray(); + dragPathTypes = hitObject.Path.ControlPoints.Select(point => point.Type).ToArray(); + draggedControlPointIndex = hitObject.Path.ControlPoints.IndexOf(controlPoint); selectedControlPoints = new HashSet(Pieces.Where(piece => piece.IsSelected.Value).Select(piece => piece.ControlPoint)); Debug.Assert(draggedControlPointIndex >= 0); @@ -276,25 +276,25 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components private void dragInProgress(DragEvent e) { - Vector2[] oldControlPoints = slider.Path.ControlPoints.Select(cp => cp.Position).ToArray(); - var oldPosition = slider.Position; - double oldStartTime = slider.StartTime; + Vector2[] oldControlPoints = hitObject.Path.ControlPoints.Select(cp => cp.Position).ToArray(); + var oldPosition = hitObject.Position; + double oldStartTime = hitObject.StartTime; - if (selectedControlPoints.Contains(slider.Path.ControlPoints[0])) + if (selectedControlPoints.Contains(hitObject.Path.ControlPoints[0])) { - // Special handling for selections containing head control point - the position of the slider changes which means the snapped position and time have to be taken into account + // Special handling for selections containing head control point - the position of the hit object changes which means the snapped position and time have to be taken into account Vector2 newHeadPosition = Parent.ToScreenSpace(e.MousePosition + (dragStartPositions[0] - dragStartPositions[draggedControlPointIndex])); var result = snapProvider?.FindSnappedPositionAndTime(newHeadPosition); - Vector2 movementDelta = Parent.ToLocalSpace(result?.ScreenSpacePosition ?? newHeadPosition) - slider.Position; + Vector2 movementDelta = Parent.ToLocalSpace(result?.ScreenSpacePosition ?? newHeadPosition) - hitObject.Position; - slider.Position += movementDelta; - slider.StartTime = result?.Time ?? slider.StartTime; + hitObject.Position += movementDelta; + hitObject.StartTime = result?.Time ?? hitObject.StartTime; - for (int i = 1; i < slider.Path.ControlPoints.Count; i++) + for (int i = 1; i < hitObject.Path.ControlPoints.Count; i++) { - var controlPoint = slider.Path.ControlPoints[i]; - // Since control points are relative to the position of the slider, all points that are _not_ selected + var controlPoint = hitObject.Path.ControlPoints[i]; + // Since control points are relative to the position of the hit object, all points that are _not_ selected // need to be offset _back_ by the delta corresponding to the movement of the head point. // All other selected control points (if any) will move together with the head point // (and so they will not move at all, relative to each other). @@ -306,7 +306,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { var result = snapProvider?.FindSnappedPositionAndTime(Parent.ToScreenSpace(e.MousePosition)); - Vector2 movementDelta = Parent.ToLocalSpace(result?.ScreenSpacePosition ?? Parent.ToScreenSpace(e.MousePosition)) - dragStartPositions[draggedControlPointIndex] - slider.Position; + Vector2 movementDelta = Parent.ToLocalSpace(result?.ScreenSpacePosition ?? Parent.ToScreenSpace(e.MousePosition)) - dragStartPositions[draggedControlPointIndex] - hitObject.Position; for (int i = 0; i < controlPoints.Count; ++i) { @@ -317,23 +317,23 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components } // Snap the path to the current beat divisor before checking length validity. - slider.SnapTo(snapProvider); + hitObject.SnapTo(snapProvider); - if (!slider.Path.HasValidLength) + if (!hitObject.Path.HasValidLength) { - for (int i = 0; i < slider.Path.ControlPoints.Count; i++) - slider.Path.ControlPoints[i].Position = oldControlPoints[i]; + for (int i = 0; i < hitObject.Path.ControlPoints.Count; i++) + hitObject.Path.ControlPoints[i].Position = oldControlPoints[i]; - slider.Position = oldPosition; - slider.StartTime = oldStartTime; + hitObject.Position = oldPosition; + hitObject.StartTime = oldStartTime; // Snap the path length again to undo the invalid length. - slider.SnapTo(snapProvider); + hitObject.SnapTo(snapProvider); return; } // Maintain the path types in case they got defaulted to bezier at some point during the drag. - for (int i = 0; i < slider.Path.ControlPoints.Count; i++) - slider.Path.ControlPoints[i].Type = dragPathTypes[i]; + for (int i = 0; i < hitObject.Path.ControlPoints.Count; i++) + hitObject.Path.ControlPoints[i].Type = dragPathTypes[i]; } private void dragEnded() => changeHandler?.EndChange(); diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs index f91d35e2e1..77393efeb3 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs @@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders private SliderBodyPiece bodyPiece; private HitCirclePiece headCirclePiece; private HitCirclePiece tailCirclePiece; - private PathControlPointVisualiser controlPointVisualiser; + private PathControlPointVisualiser controlPointVisualiser; private InputManager inputManager; @@ -59,7 +59,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders bodyPiece = new SliderBodyPiece(), headCirclePiece = new HitCirclePiece(), tailCirclePiece = new HitCirclePiece(), - controlPointVisualiser = new PathControlPointVisualiser(HitObject, false) + controlPointVisualiser = new PathControlPointVisualiser(HitObject, false) }; setState(SliderPlacementState.Initial); diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index a51c223785..b37041674e 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders protected SliderCircleOverlay TailOverlay { get; private set; } [CanBeNull] - protected PathControlPointVisualiser ControlPointVisualiser { get; private set; } + protected PathControlPointVisualiser ControlPointVisualiser { get; private set; } [Resolved(CanBeNull = true)] private IDistanceSnapProvider snapProvider { get; set; } @@ -147,7 +147,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders { if (ControlPointVisualiser == null) { - AddInternal(ControlPointVisualiser = new PathControlPointVisualiser(HitObject, true) + AddInternal(ControlPointVisualiser = new PathControlPointVisualiser(HitObject, true) { RemoveControlPointsRequested = removeControlPoints, SplitControlPointsRequested = splitControlPoints diff --git a/osu.Game.Tests/Visual/Editing/TestSceneBlueprintOrdering.cs b/osu.Game.Tests/Visual/Editing/TestSceneBlueprintOrdering.cs index 7728adecae..8b598a6a24 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneBlueprintOrdering.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneBlueprintOrdering.cs @@ -66,7 +66,7 @@ namespace osu.Game.Tests.Visual.Editing AddStep("move mouse to common point", () => { - var pos = blueprintContainer.ChildrenOfType().ElementAt(1).ScreenSpaceDrawQuad.Centre; + var pos = blueprintContainer.ChildrenOfType>().ElementAt(1).ScreenSpaceDrawQuad.Centre; InputManager.MoveMouseTo(pos); }); AddStep("right click", () => InputManager.Click(MouseButton.Right)); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs b/osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs index ffb8a67c68..b14025c9d8 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneComposerSelection.cs @@ -286,7 +286,7 @@ namespace osu.Game.Tests.Visual.Editing AddStep("move mouse to controlpoint", () => { - var pos = blueprintContainer.ChildrenOfType().ElementAt(1).ScreenSpaceDrawQuad.Centre; + var pos = blueprintContainer.ChildrenOfType>().ElementAt(1).ScreenSpaceDrawQuad.Centre; InputManager.MoveMouseTo(pos); }); AddStep("hold shift", () => InputManager.PressKey(Key.ShiftLeft)); From d458c3a012264fa8095db2d24345ce31dfbf3fe1 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 7 Dec 2022 10:11:57 +0100 Subject: [PATCH 0952/2991] Fix variable which didnt get renamed --- .../Blueprints/Sliders/Components/PathControlPointVisualiser.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index 65b212e976..10ee7a9a05 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -248,7 +248,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components break; } - slider.Path.ExpectedDistance.Value = null; + hitObject.Path.ExpectedDistance.Value = null; piece.ControlPoint.Type = type; } From 0aeee8d6ab6ef72a33b09444cfff5546683df091 Mon Sep 17 00:00:00 2001 From: Loreos7 <86934170+Loreos7@users.noreply.github.com> Date: Wed, 7 Dec 2022 17:47:37 +0300 Subject: [PATCH 0953/2991] fix typo in today's tip --- osu.Game/Screens/Menu/Disclaimer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index e30be72704..539d58d2d7 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -239,7 +239,7 @@ namespace osu.Game.Screens.Menu "New features are coming online every update. Make sure to stay up-to-date!", "If you find the UI too large or small, try adjusting UI scale in settings!", "Try adjusting the \"Screen Scaling\" mode to change your gameplay or UI area, even in fullscreen!", - "What used to be \"osu!direct\" is available to all users just like on the website. You can access it anywhere using Ctrl-D!", + "What used to be \"osu!direct\" is available to all users just like on the website. You can access it anywhere using Ctrl-B!", "Seeking in replays is available by dragging on the difficulty bar at the bottom of the screen!", "Multithreading support means that even with low \"FPS\" your input and judgements will be accurate!", "Try scrolling down in the mod select panel to find a bunch of new fun mods!", From 1776485b93eeb2ff0b7e5ccf1657aa5704dac997 Mon Sep 17 00:00:00 2001 From: apollo-dw <83023433+apollo-dw@users.noreply.github.com> Date: Wed, 7 Dec 2022 20:20:11 +0000 Subject: [PATCH 0954/2991] Reflect nested objects vertically in the playfield correctly --- osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs b/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs index f565456911..5b327fc3b0 100644 --- a/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs +++ b/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs @@ -133,7 +133,7 @@ namespace osu.Game.Rulesets.Osu.Utils if (osuObject is not Slider slider) return; - void flipNestedObject(OsuHitObject nested) => nested.Position = new Vector2(nested.X, slider.Y - (nested.Y - slider.Y)); + void flipNestedObject(OsuHitObject nested) => nested.Position = new Vector2(nested.Position.X, OsuPlayfield.BASE_SIZE.Y - nested.Position.Y); static void flipControlPoint(PathControlPoint point) => point.Position = new Vector2(point.Position.X, -point.Position.Y); modifySlider(slider, flipNestedObject, flipControlPoint); From 684b16cef5dc7338ef3333106e3433de8085153f Mon Sep 17 00:00:00 2001 From: apollo-dw <83023433+apollo-dw@users.noreply.github.com> Date: Wed, 7 Dec 2022 21:09:53 +0000 Subject: [PATCH 0955/2991] Disambiguate object flipping and reflection methods --- osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModMirror.cs | 8 ++--- osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs | 2 +- .../Utils/OsuHitObjectGenerationUtils.cs | 32 +++++++++++-------- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs index 5430929143..19d4a1bf83 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Mods { var osuObject = (OsuHitObject)hitObject; - OsuHitObjectGenerationUtils.ReflectVertically(osuObject); + OsuHitObjectGenerationUtils.ReflectVerticallyAlongPlayfield(osuObject); } } } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModMirror.cs b/osu.Game.Rulesets.Osu/Mods/OsuModMirror.cs index 0a54d58718..6d01808fb5 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModMirror.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModMirror.cs @@ -27,16 +27,16 @@ namespace osu.Game.Rulesets.Osu.Mods switch (Reflection.Value) { case MirrorType.Horizontal: - OsuHitObjectGenerationUtils.ReflectHorizontally(osuObject); + OsuHitObjectGenerationUtils.ReflectHorizontallyAlongPlayfield(osuObject); break; case MirrorType.Vertical: - OsuHitObjectGenerationUtils.ReflectVertically(osuObject); + OsuHitObjectGenerationUtils.ReflectVerticallyAlongPlayfield(osuObject); break; case MirrorType.Both: - OsuHitObjectGenerationUtils.ReflectHorizontally(osuObject); - OsuHitObjectGenerationUtils.ReflectVertically(osuObject); + OsuHitObjectGenerationUtils.ReflectHorizontallyAlongPlayfield(osuObject); + OsuHitObjectGenerationUtils.ReflectVerticallyAlongPlayfield(osuObject); break; } } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs index 58f5b2fa8d..307d731fd4 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs @@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Mods if (positionInfos[i].HitObject is Slider slider && random.NextDouble() < 0.5) { - OsuHitObjectGenerationUtils.FlipSliderHorizontally(slider); + OsuHitObjectGenerationUtils.FlipSliderInPlaceHorizontally(slider); } if (i == 0) diff --git a/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs b/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs index 5b327fc3b0..15bc03261f 100644 --- a/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs +++ b/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs @@ -112,21 +112,24 @@ namespace osu.Game.Rulesets.Osu.Utils /// Reflects the position of the in the playfield horizontally. /// /// The object to reflect. - public static void ReflectHorizontally(OsuHitObject osuObject) + public static void ReflectHorizontallyAlongPlayfield(OsuHitObject osuObject) { osuObject.Position = new Vector2(OsuPlayfield.BASE_SIZE.X - osuObject.X, osuObject.Position.Y); if (osuObject is not Slider slider) return; - FlipSliderHorizontally(slider); + void flipNestedObject(OsuHitObject nested) => nested.Position = new Vector2(OsuPlayfield.BASE_SIZE.X - nested.Position.X, nested.Position.Y); + static void flipControlPoint(PathControlPoint point) => point.Position = new Vector2(-point.Position.X, point.Position.Y); + + modifySlider(slider, flipNestedObject, flipControlPoint); } /// /// Reflects the position of the in the playfield vertically. /// /// The object to reflect. - public static void ReflectVertically(OsuHitObject osuObject) + public static void ReflectVerticallyAlongPlayfield(OsuHitObject osuObject) { osuObject.Position = new Vector2(osuObject.Position.X, OsuPlayfield.BASE_SIZE.Y - osuObject.Y); @@ -139,6 +142,18 @@ namespace osu.Game.Rulesets.Osu.Utils modifySlider(slider, flipNestedObject, flipControlPoint); } + /// + /// Flips the position of the around its start position horizontally. + /// + /// The slider to be flipped. + public static void FlipSliderInPlaceHorizontally(Slider slider) + { + void flipNestedObject(OsuHitObject nested) => nested.Position = new Vector2(slider.X - (nested.X - slider.X), nested.Y); + static void flipControlPoint(PathControlPoint point) => point.Position = new Vector2(-point.Position.X, point.Position.Y); + + modifySlider(slider, flipNestedObject, flipControlPoint); + } + /// /// Rotate a slider about its start position by the specified angle. /// @@ -152,17 +167,6 @@ namespace osu.Game.Rulesets.Osu.Utils modifySlider(slider, rotateNestedObject, rotateControlPoint); } - /// - /// Flips the slider about its start position horizontally. - /// - public static void FlipSliderHorizontally(Slider slider) - { - void flipNestedObject(OsuHitObject nested) => nested.Position = new Vector2(slider.X - (nested.X - slider.X), nested.Y); - static void flipControlPoint(PathControlPoint point) => point.Position = new Vector2(-point.Position.X, point.Position.Y); - - modifySlider(slider, flipNestedObject, flipControlPoint); - } - private static void modifySlider(Slider slider, Action modifyNestedObject, Action modifyControlPoint) { // No need to update the head and tail circles, since slider handles that when the new slider path is set From 7676838cc04d162c37d87749d275b582cbed8e50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 7 Dec 2022 23:27:02 +0100 Subject: [PATCH 0956/2991] Apply "reflect" vernacular in nested methods --- .../Utils/OsuHitObjectGenerationUtils.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs b/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs index 15bc03261f..aa4cd0af14 100644 --- a/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs +++ b/osu.Game.Rulesets.Osu/Utils/OsuHitObjectGenerationUtils.cs @@ -119,10 +119,10 @@ namespace osu.Game.Rulesets.Osu.Utils if (osuObject is not Slider slider) return; - void flipNestedObject(OsuHitObject nested) => nested.Position = new Vector2(OsuPlayfield.BASE_SIZE.X - nested.Position.X, nested.Position.Y); - static void flipControlPoint(PathControlPoint point) => point.Position = new Vector2(-point.Position.X, point.Position.Y); + void reflectNestedObject(OsuHitObject nested) => nested.Position = new Vector2(OsuPlayfield.BASE_SIZE.X - nested.Position.X, nested.Position.Y); + static void reflectControlPoint(PathControlPoint point) => point.Position = new Vector2(-point.Position.X, point.Position.Y); - modifySlider(slider, flipNestedObject, flipControlPoint); + modifySlider(slider, reflectNestedObject, reflectControlPoint); } /// @@ -136,10 +136,10 @@ namespace osu.Game.Rulesets.Osu.Utils if (osuObject is not Slider slider) return; - void flipNestedObject(OsuHitObject nested) => nested.Position = new Vector2(nested.Position.X, OsuPlayfield.BASE_SIZE.Y - nested.Position.Y); - static void flipControlPoint(PathControlPoint point) => point.Position = new Vector2(point.Position.X, -point.Position.Y); + void reflectNestedObject(OsuHitObject nested) => nested.Position = new Vector2(nested.Position.X, OsuPlayfield.BASE_SIZE.Y - nested.Position.Y); + static void reflectControlPoint(PathControlPoint point) => point.Position = new Vector2(point.Position.X, -point.Position.Y); - modifySlider(slider, flipNestedObject, flipControlPoint); + modifySlider(slider, reflectNestedObject, reflectControlPoint); } /// From 5807d4c43dcc2dfd7f8b9b61e277b2dc35c862da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 7 Dec 2022 23:50:01 +0100 Subject: [PATCH 0957/2991] Add test coverage for slider transformations --- .../OsuHitObjectGenerationUtilsTest.cs | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 osu.Game.Rulesets.Osu.Tests/OsuHitObjectGenerationUtilsTest.cs diff --git a/osu.Game.Rulesets.Osu.Tests/OsuHitObjectGenerationUtilsTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuHitObjectGenerationUtilsTest.cs new file mode 100644 index 0000000000..daa914cac2 --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/OsuHitObjectGenerationUtilsTest.cs @@ -0,0 +1,91 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.UI; +using osu.Game.Rulesets.Osu.Utils; +using osuTK; + +namespace osu.Game.Rulesets.Osu.Tests +{ + [TestFixture] + public class OsuHitObjectGenerationUtilsTest + { + private static Slider createTestSlider() + { + var slider = new Slider + { + Position = new Vector2(128, 128), + Path = new SliderPath + { + ControlPoints = + { + new PathControlPoint(new Vector2(), PathType.Linear), + new PathControlPoint(new Vector2(-64, -128), PathType.Linear), // absolute position: (64, 0) + new PathControlPoint(new Vector2(-128, 0), PathType.Linear) // absolute position: (0, 128) + } + }, + RepeatCount = 1 + }; + slider.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + return slider; + } + + [Test] + public void TestReflectSliderHorizontallyAlongPlayfield() + { + var slider = createTestSlider(); + + OsuHitObjectGenerationUtils.ReflectHorizontallyAlongPlayfield(slider); + + Assert.That(slider.Position, Is.EqualTo(new Vector2(OsuPlayfield.BASE_SIZE.X - 128, 128))); + Assert.That(slider.NestedHitObjects.OfType().Single().Position, Is.EqualTo(new Vector2(OsuPlayfield.BASE_SIZE.X - 0, 128))); + Assert.That(slider.Path.ControlPoints.Select(point => point.Position), Is.EquivalentTo(new[] + { + new Vector2(), + new Vector2(64, -128), + new Vector2(128, 0) + })); + } + + [Test] + public void TestReflectSliderVerticallyAlongPlayfield() + { + var slider = createTestSlider(); + + OsuHitObjectGenerationUtils.ReflectVerticallyAlongPlayfield(slider); + + Assert.That(slider.Position, Is.EqualTo(new Vector2(128, OsuPlayfield.BASE_SIZE.Y - 128))); + Assert.That(slider.NestedHitObjects.OfType().Single().Position, Is.EqualTo(new Vector2(0, OsuPlayfield.BASE_SIZE.Y - 128))); + Assert.That(slider.Path.ControlPoints.Select(point => point.Position), Is.EquivalentTo(new[] + { + new Vector2(), + new Vector2(-64, 128), + new Vector2(-128, 0) + })); + } + + [Test] + public void TestFlipSliderInPlaceHorizontally() + { + var slider = createTestSlider(); + + OsuHitObjectGenerationUtils.FlipSliderInPlaceHorizontally(slider); + + Assert.That(slider.Position, Is.EqualTo(new Vector2(128, 128))); + Assert.That(slider.NestedHitObjects.OfType().Single().Position, Is.EqualTo(new Vector2(256, 128))); + Assert.That(slider.Path.ControlPoints.Select(point => point.Position), Is.EquivalentTo(new[] + { + new Vector2(), + new Vector2(64, -128), + new Vector2(128, 0) + })); + } + } +} From e00c075482a0be3f9ac52284328e95c56ac7d377 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Thu, 8 Dec 2022 11:30:18 +0900 Subject: [PATCH 0958/2991] Fix incorrectly modified first lazer version --- osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs index 024b691de2..63094c5548 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs @@ -25,12 +25,12 @@ namespace osu.Game.Scoring.Legacy /// Database version in stable-compatible YYYYMMDD format. /// Should be incremented if any changes are made to the format/usage. /// - public const int LATEST_VERSION = FIRST_LAZER_VERSION; + public const int LATEST_VERSION = 30000001; /// /// The first stable-compatible YYYYMMDD format version given to lazer usage of replays. /// - public const int FIRST_LAZER_VERSION = 30000001; + public const int FIRST_LAZER_VERSION = 30000000; private readonly Score score; private readonly IBeatmap? beatmap; From f21e903a94609400f2af8d24587c17dac6e1969d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Dec 2022 14:06:38 +0900 Subject: [PATCH 0959/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 61c968ebc9..a4900132b1 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index fbac6f38b0..3cb569bdd4 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 4683437173..184e3303c8 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From cdf76077b290db2eb583161f71782607c1d8d6af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Dec 2022 05:38:06 +0000 Subject: [PATCH 0960/2991] Bump Newtonsoft.Json from 13.0.1 to 13.0.2 in /osu.Game Bumps [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json) from 13.0.1 to 13.0.2. - [Release notes](https://github.com/JamesNK/Newtonsoft.Json/releases) - [Commits](https://github.com/JamesNK/Newtonsoft.Json/compare/13.0.1...13.0.2) --- updated-dependencies: - dependency-name: Newtonsoft.Json dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 3cb569bdd4..8639ce6361 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -29,7 +29,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 34ad1e1d61223d289a59879d34d44f6504178c74 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Thu, 8 Dec 2022 22:50:29 +0100 Subject: [PATCH 0961/2991] Fix Android linker removing `System.Globalisation.*Calendar` --- osu.Android.props | 3 +++ osu.Android/Linker.xml | 7 +++++++ 2 files changed, 10 insertions(+) create mode 100644 osu.Android/Linker.xml diff --git a/osu.Android.props b/osu.Android.props index a4900132b1..147d236d98 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -58,4 +58,7 @@ + + + diff --git a/osu.Android/Linker.xml b/osu.Android/Linker.xml new file mode 100644 index 0000000000..c7d31fe087 --- /dev/null +++ b/osu.Android/Linker.xml @@ -0,0 +1,7 @@ + + + + + + + From 27a96b8e6d92c93b5fa4a9323898d1c05be60569 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Thu, 8 Dec 2022 22:52:10 +0100 Subject: [PATCH 0962/2991] Add linker exception to iOS out of an abundance of caution --- osu.iOS/Linker.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.iOS/Linker.xml b/osu.iOS/Linker.xml index 04591c55d0..b55be3be39 100644 --- a/osu.iOS/Linker.xml +++ b/osu.iOS/Linker.xml @@ -24,4 +24,8 @@ + + + + From 3570fa8d930abc35d6ec5990161dba9f0e733055 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 9 Dec 2022 17:12:20 +0900 Subject: [PATCH 0963/2991] Fix hub clients not reconnecting after connection error --- osu.Game/Online/PersistentEndpointClientConnector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/PersistentEndpointClientConnector.cs b/osu.Game/Online/PersistentEndpointClientConnector.cs index be76644745..55e9190f99 100644 --- a/osu.Game/Online/PersistentEndpointClientConnector.cs +++ b/osu.Game/Online/PersistentEndpointClientConnector.cs @@ -150,7 +150,7 @@ namespace osu.Game.Online await disconnect(true); if (ex != null) - await handleErrorAndDelay(ex, cancellationToken).ConfigureAwait(false); + await handleErrorAndDelay(ex, CancellationToken.None).ConfigureAwait(false); else Logger.Log($"{ClientName} disconnected", LoggingTarget.Network); From 4a65f5c8647ec402904c9736c865f980e7c5c1ae Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 9 Dec 2022 16:05:36 +0900 Subject: [PATCH 0964/2991] Add score token to spectator state --- osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs | 2 +- .../Visual/Gameplay/TestSceneSpectatorPlayback.cs | 2 +- osu.Game/Online/Spectator/SpectatorClient.cs | 3 ++- osu.Game/Online/Spectator/SpectatorState.cs | 7 +++++-- osu.Game/Screens/Play/SubmittingPlayer.cs | 2 +- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs index 8f1eb98c79..4f319a7c34 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs @@ -261,7 +261,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestFinalFramesPurgedBeforeEndingPlay() { - AddStep("begin playing", () => spectatorClient.BeginPlaying(TestGameplayState.Create(new OsuRuleset()), new Score())); + AddStep("begin playing", () => spectatorClient.BeginPlaying(TestGameplayState.Create(new OsuRuleset()), new Score(), 0)); AddStep("send frames and finish play", () => { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs index 1ad1da0994..a949c0d79d 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs @@ -147,7 +147,7 @@ namespace osu.Game.Tests.Visual.Gameplay } }; - spectatorClient.BeginPlaying(TestGameplayState.Create(new OsuRuleset()), recordingScore); + spectatorClient.BeginPlaying(TestGameplayState.Create(new OsuRuleset()), recordingScore, 0); spectatorClient.OnNewFrames += onNewFrames; }); } diff --git a/osu.Game/Online/Spectator/SpectatorClient.cs b/osu.Game/Online/Spectator/SpectatorClient.cs index b0ee0bc37b..c532cb266d 100644 --- a/osu.Game/Online/Spectator/SpectatorClient.cs +++ b/osu.Game/Online/Spectator/SpectatorClient.cs @@ -159,7 +159,7 @@ namespace osu.Game.Online.Spectator return Task.CompletedTask; } - public void BeginPlaying(GameplayState state, Score score) + public void BeginPlaying(GameplayState state, Score score, long? token) { // This schedule is only here to match the one below in `EndPlaying`. Schedule(() => @@ -175,6 +175,7 @@ namespace osu.Game.Online.Spectator currentState.Mods = score.ScoreInfo.Mods.Select(m => new APIMod(m)).ToArray(); currentState.State = SpectatedUserState.Playing; currentState.MaximumScoringValues = state.ScoreProcessor.MaximumScoringValues; + currentState.ScoreToken = token; currentBeatmap = state.Beatmap; currentScore = score; diff --git a/osu.Game/Online/Spectator/SpectatorState.cs b/osu.Game/Online/Spectator/SpectatorState.cs index 766b274e63..34dbefd2a5 100644 --- a/osu.Game/Online/Spectator/SpectatorState.cs +++ b/osu.Game/Online/Spectator/SpectatorState.cs @@ -33,14 +33,17 @@ namespace osu.Game.Online.Spectator [Key(4)] public ScoringValues MaximumScoringValues { get; set; } + [Key(5)] + public long? ScoreToken { get; set; } + public bool Equals(SpectatorState other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; - return BeatmapID == other.BeatmapID && Mods.SequenceEqual(other.Mods) && RulesetID == other.RulesetID && State == other.State; + return BeatmapID == other.BeatmapID && Mods.SequenceEqual(other.Mods) && RulesetID == other.RulesetID && State == other.State && ScoreToken == other.ScoreToken; } - public override string ToString() => $"Beatmap:{BeatmapID} Mods:{string.Join(',', Mods)} Ruleset:{RulesetID} State:{State}"; + public override string ToString() => $"Beatmap:{BeatmapID} Mods:{string.Join(',', Mods)} Ruleset:{RulesetID} State:{State} Token:{ScoreToken}"; } } diff --git a/osu.Game/Screens/Play/SubmittingPlayer.cs b/osu.Game/Screens/Play/SubmittingPlayer.cs index 14453c8cbe..81c4e9ab2a 100644 --- a/osu.Game/Screens/Play/SubmittingPlayer.cs +++ b/osu.Game/Screens/Play/SubmittingPlayer.cs @@ -148,7 +148,7 @@ namespace osu.Game.Screens.Play realmBeatmap.LastPlayed = DateTimeOffset.Now; }); - spectatorClient.BeginPlaying(GameplayState, Score); + spectatorClient.BeginPlaying(GameplayState, Score, token); } public override bool OnExiting(ScreenExitEvent e) From e9998f1690003675f8b8642b98f34e72c18584c2 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 9 Dec 2022 20:15:07 +0900 Subject: [PATCH 0965/2991] Store maximum statistics to spectator state --- .../Multiplayer/MultiplayerGameplayLeaderboardTestScene.cs | 6 ++---- osu.Game/Online/Spectator/SpectatorClient.cs | 2 +- osu.Game/Online/Spectator/SpectatorScoreProcessor.cs | 4 ++-- osu.Game/Online/Spectator/SpectatorState.cs | 4 ++-- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 7 ++----- 5 files changed, 9 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/MultiplayerGameplayLeaderboardTestScene.cs b/osu.Game.Tests/Visual/Multiplayer/MultiplayerGameplayLeaderboardTestScene.cs index fa7d2c04f4..649c662e41 100644 --- a/osu.Game.Tests/Visual/Multiplayer/MultiplayerGameplayLeaderboardTestScene.cs +++ b/osu.Game.Tests/Visual/Multiplayer/MultiplayerGameplayLeaderboardTestScene.cs @@ -117,11 +117,9 @@ namespace osu.Game.Tests.Visual.Multiplayer BeatmapID = 0, RulesetID = 0, Mods = user.Mods, - MaximumScoringValues = new ScoringValues + MaximumStatistics = new Dictionary { - BaseScore = 10000, - MaxCombo = 1000, - CountBasicHitObjects = 1000 + { HitResult.Perfect, 100 } } }; } diff --git a/osu.Game/Online/Spectator/SpectatorClient.cs b/osu.Game/Online/Spectator/SpectatorClient.cs index b0ee0bc37b..0a499a202c 100644 --- a/osu.Game/Online/Spectator/SpectatorClient.cs +++ b/osu.Game/Online/Spectator/SpectatorClient.cs @@ -174,7 +174,7 @@ namespace osu.Game.Online.Spectator currentState.RulesetID = score.ScoreInfo.RulesetID; currentState.Mods = score.ScoreInfo.Mods.Select(m => new APIMod(m)).ToArray(); currentState.State = SpectatedUserState.Playing; - currentState.MaximumScoringValues = state.ScoreProcessor.MaximumScoringValues; + currentState.MaximumStatistics = state.ScoreProcessor.MaximumStatistics; currentBeatmap = state.Beatmap; currentScore = score; diff --git a/osu.Game/Online/Spectator/SpectatorScoreProcessor.cs b/osu.Game/Online/Spectator/SpectatorScoreProcessor.cs index c97871c3aa..75b6a6e83b 100644 --- a/osu.Game/Online/Spectator/SpectatorScoreProcessor.cs +++ b/osu.Game/Online/Spectator/SpectatorScoreProcessor.cs @@ -152,12 +152,12 @@ namespace osu.Game.Online.Spectator scoreInfo.MaxCombo = frame.Header.MaxCombo; scoreInfo.Statistics = frame.Header.Statistics; + scoreInfo.MaximumStatistics = spectatorState.MaximumStatistics; Accuracy.Value = frame.Header.Accuracy; Combo.Value = frame.Header.Combo; - scoreProcessor.ExtractScoringValues(frame.Header, out var currentScoringValues, out _); - TotalScore.Value = scoreProcessor.ComputeScore(Mode.Value, currentScoringValues, spectatorState.MaximumScoringValues); + TotalScore.Value = scoreProcessor.ComputeScore(Mode.Value, scoreInfo); } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Online/Spectator/SpectatorState.cs b/osu.Game/Online/Spectator/SpectatorState.cs index 766b274e63..91df05bf96 100644 --- a/osu.Game/Online/Spectator/SpectatorState.cs +++ b/osu.Game/Online/Spectator/SpectatorState.cs @@ -9,7 +9,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using MessagePack; using osu.Game.Online.API; -using osu.Game.Scoring; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Online.Spectator { @@ -31,7 +31,7 @@ namespace osu.Game.Online.Spectator public SpectatedUserState State { get; set; } [Key(4)] - public ScoringValues MaximumScoringValues { get; set; } + public Dictionary MaximumStatistics { get; set; } = new Dictionary(); public bool Equals(SpectatorState other) { diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 18c88dff2a..b2b31c5394 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -90,17 +90,14 @@ namespace osu.Game.Rulesets.Scoring private readonly double accuracyPortion; private readonly double comboPortion; - /// - /// Scoring values for a perfect play. - /// - public ScoringValues MaximumScoringValues + public Dictionary MaximumStatistics { get { if (!beatmapApplied) throw new InvalidOperationException($"Cannot access maximum scoring values before calling {nameof(ApplyBeatmap)}."); - return maximumScoringValues; + return maximumResultCounts.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); } } From 19afce67767b95e67aaf06ea1df8c5b291797ddd Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Fri, 9 Dec 2022 23:41:07 +0900 Subject: [PATCH 0966/2991] Fix overwriting existing files https://github.com/ppy/osu/pull/21468 --- osu.Game/Database/LegacyModelExporter.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 3523d18f29..5c4b7a4578 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -11,6 +12,7 @@ using osu.Framework.Platform; using osu.Game.Extensions; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; +using osu.Game.Utils; using Realms; using SharpCompress.Archives.Zip; @@ -64,7 +66,11 @@ namespace osu.Game.Database { if (item is TModel model) { - filename = $"{model.GetDisplayString().GetValidFilename()}{FileExtension}"; + string itemFilename = item.GetDisplayString().GetValidFilename(); + + IEnumerable existingExports = ExportStorage.GetFiles("", $"{itemFilename}*{FileExtension}"); + + string filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); using (var stream = ExportStorage.CreateFileSafely(filename)) { From 405985ec5b09769ca5d9031eadc2c8ad801b399d Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Fri, 9 Dec 2022 23:57:03 +0900 Subject: [PATCH 0967/2991] remove Component exportStorage to private notification should post when export instead of class being constructed --- osu.Game/Database/LegacyModelExporter.cs | 25 ++++++++++++------------ 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 5c4b7a4578..ae092d15e8 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; -using osu.Framework.Graphics; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Extensions; @@ -21,7 +20,7 @@ namespace osu.Game.Database /// /// A class which handles exporting legacy user data of a single type from osu-stable. /// - public abstract class LegacyModelExporter : Component + public abstract class LegacyModelExporter where TModel : RealmObject, IHasNamedFiles, IHasGuidPrimaryKey { /// @@ -30,22 +29,23 @@ namespace osu.Game.Database protected abstract string FileExtension { get; } protected Storage UserFileStorage; - protected Storage ExportStorage; + private readonly Storage exportStorage; protected RealmAccess RealmAccess; private readonly ProgressNotification notification; - private string filename = ""; - private bool canCancel = true; + private readonly INotificationOverlay? notifications; + protected LegacyModelExporter(Storage storage, RealmAccess realm, INotificationOverlay? notifications = null) { - ExportStorage = storage.GetStorageForDirectory(@"exports"); + exportStorage = storage.GetStorageForDirectory(@"exports"); UserFileStorage = storage.GetStorageForDirectory(@"files"); RealmAccess = realm; + this.notifications = notifications; notification = new ProgressNotification { State = ProgressNotificationState.Active, @@ -53,8 +53,6 @@ namespace osu.Game.Database CompletionText = "Export completed" }; notification.CancelRequested += () => canCancel; - - notifications?.Post(notification); } /// @@ -66,13 +64,15 @@ namespace osu.Game.Database { if (item is TModel model) { + notifications?.Post(notification); + string itemFilename = item.GetDisplayString().GetValidFilename(); - - IEnumerable existingExports = ExportStorage.GetFiles("", $"{itemFilename}*{FileExtension}"); - + IEnumerable existingExports = exportStorage.GetFiles("", $"{itemFilename}*{FileExtension}"); string filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); - using (var stream = ExportStorage.CreateFileSafely(filename)) + notification.CompletionClickAction += () => exportStorage.PresentFileExternally(filename); + + using (var stream = exportStorage.CreateFileSafely(filename)) { await ExportToStreamAsync(model, stream); } @@ -138,7 +138,6 @@ namespace osu.Game.Database } notification.CompletionText = "Export Complete, Click to open the folder"; - notification.CompletionClickAction += () => ExportStorage.PresentFileExternally(filename); notification.State = ProgressNotificationState.Completed; } } From 951302fe61374cb8b4cc1dedf830c6d8fe748ae6 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sat, 10 Dec 2022 00:43:03 +0900 Subject: [PATCH 0968/2991] ExportAsync use TModel --- osu.Game/Database/LegacyModelExporter.cs | 27 +++++++++++------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index ae092d15e8..ad61338c8b 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -58,24 +58,21 @@ namespace osu.Game.Database /// /// Export the model to default folder. /// - /// The model should export. + /// The model should export. /// - public async Task ExportAsync(RealmObject item) + public async Task ExportAsync(TModel model) { - if (item is TModel model) + notifications?.Post(notification); + + string itemFilename = model.GetDisplayString().GetValidFilename(); + IEnumerable existingExports = exportStorage.GetFiles("", $"{itemFilename}*{FileExtension}"); + string filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); + + notification.CompletionClickAction += () => exportStorage.PresentFileExternally(filename); + + using (var stream = exportStorage.CreateFileSafely(filename)) { - notifications?.Post(notification); - - string itemFilename = item.GetDisplayString().GetValidFilename(); - IEnumerable existingExports = exportStorage.GetFiles("", $"{itemFilename}*{FileExtension}"); - string filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); - - notification.CompletionClickAction += () => exportStorage.PresentFileExternally(filename); - - using (var stream = exportStorage.CreateFileSafely(filename)) - { - await ExportToStreamAsync(model, stream); - } + await ExportToStreamAsync(model, stream); } } From 0372e38f577e7ef82a5ca5e6a0907125823df671 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 11 Dec 2022 13:00:12 +0900 Subject: [PATCH 0969/2991] Add nullability assertion to appease CI --- osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs index 2f7727ac49..15ed992c3e 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs @@ -4,6 +4,7 @@ #nullable disable using System; +using System.Diagnostics; using System.IO; using System.Linq; using Newtonsoft.Json; @@ -105,6 +106,9 @@ namespace osu.Game.Scoring.Legacy readCompressedData(compressedScoreInfo, reader => { LegacyReplaySoloScoreInfo readScore = JsonConvert.DeserializeObject(reader.ReadToEnd()); + + Debug.Assert(readScore != null); + score.ScoreInfo.Statistics = readScore.Statistics; score.ScoreInfo.MaximumStatistics = readScore.MaximumStatistics; score.ScoreInfo.Mods = readScore.Mods.Select(m => m.ToMod(currentRuleset)).ToArray(); From fa30f3348ff11e68c42b9b63082b5409ee479746 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 11 Dec 2022 16:53:11 +0900 Subject: [PATCH 0970/2991] `onComplete` should private --- osu.Game/Database/LegacyModelExporter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index ad61338c8b..4ea56c0056 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -92,7 +92,7 @@ namespace osu.Game.Database TModel refetchModel = r.Find(id); ExportToStream(refetchModel, stream); }); - }).ContinueWith(OnComplete); + }).ContinueWith(onComplete); } protected virtual void ExportToStream(TModel model, Stream outputStream) => createZipArchive(model, outputStream); @@ -119,7 +119,7 @@ namespace osu.Game.Database } } - protected void OnComplete(Task t) + private void onComplete(Task t) { if (t.IsFaulted) { From 2d5763340944ab99fcffb81f3c2915a441befa6e Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 11 Dec 2022 16:54:20 +0900 Subject: [PATCH 0971/2991] rename method name and add xmldoc --- osu.Game/Database/LegacyModelExporter.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 4ea56c0056..cf41ffc780 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -95,9 +95,14 @@ namespace osu.Game.Database }).ContinueWith(onComplete); } - protected virtual void ExportToStream(TModel model, Stream outputStream) => createZipArchive(model, outputStream); + protected virtual void ExportToStream(TModel model, Stream outputStream) => exportZipArchive(model, outputStream); - private void createZipArchive(TModel model, Stream outputStream) + /// + /// Exports an item to Stream as a legacy (.zip based) package. + /// + /// The item to export. + /// The output stream to export to. + private void exportZipArchive(TModel model, Stream outputStream) { using (var archive = ZipArchive.Create()) { From a87bcccc42b2e69d619087b46b324499bfdd058a Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 11 Dec 2022 16:55:44 +0900 Subject: [PATCH 0972/2991] xmldoc --- osu.Game/Database/LegacyModelExporter.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index cf41ffc780..18e840fedd 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -95,6 +95,12 @@ namespace osu.Game.Database }).ContinueWith(onComplete); } + /// + /// Exports an item to Stream. + /// Override if custom export method is required. + /// + /// The item to export. + /// The output stream to export to. protected virtual void ExportToStream(TModel model, Stream outputStream) => exportZipArchive(model, outputStream); /// From e02b8cb199ebdc13f18aaae292febbfb9c75ec89 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 11 Dec 2022 18:30:24 +0900 Subject: [PATCH 0973/2991] Group export methods into their respective managers --- osu.Game/Beatmaps/BeatmapManager.cs | 9 ++ osu.Game/Database/LegacyBeatmapExporter.cs | 5 +- osu.Game/Database/LegacyModelExporter.cs | 82 +++++++++---------- osu.Game/Database/LegacyScoreExporter.cs | 8 +- osu.Game/Database/LegacySkinExporter.cs | 5 +- .../Online/Leaderboards/LeaderboardScore.cs | 18 ++-- .../Overlays/Settings/Sections/SkinSection.cs | 12 +-- osu.Game/Scoring/ScoreManager.cs | 8 ++ osu.Game/Screens/Edit/Editor.cs | 11 +-- osu.Game/Skinning/SkinManager.cs | 9 ++ 10 files changed, 80 insertions(+), 87 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 965cc43815..34780082da 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -42,6 +42,8 @@ namespace osu.Game.Beatmaps private readonly WorkingBeatmapCache workingBeatmapCache; + private readonly LegacyBeatmapExporter beatmapExporter; + public Action<(BeatmapSetInfo beatmapSet, bool isBatch)>? ProcessBeatmap { private get; set; } public BeatmapManager(Storage storage, RealmAccess realm, IAPIProvider? api, AudioManager audioManager, IResourceStore gameResources, GameHost? host = null, @@ -66,6 +68,11 @@ namespace osu.Game.Beatmaps beatmapImporter.PostNotification = obj => PostNotification?.Invoke(obj); workingBeatmapCache = CreateWorkingBeatmapCache(audioManager, gameResources, userResources, defaultBeatmap, host); + + beatmapExporter = new LegacyBeatmapExporter(storage, realm) + { + PostNotification = obj => PostNotification?.Invoke(obj) + }; } protected virtual WorkingBeatmapCache CreateWorkingBeatmapCache(AudioManager audioManager, IResourceStore resources, IResourceStore storage, WorkingBeatmap? defaultBeatmap, @@ -446,6 +453,8 @@ namespace osu.Game.Beatmaps public Task?> ImportAsUpdate(ProgressNotification notification, ImportTask importTask, BeatmapSetInfo original) => beatmapImporter.ImportAsUpdate(notification, importTask, original); + public void Export(BeatmapSetInfo beatmap) => Task.Run(() => beatmapExporter.ExportAsync(beatmap)); + private void updateHashAndMarkDirty(BeatmapSetInfo setInfo) { setInfo.Hash = beatmapImporter.ComputeHash(setInfo); diff --git a/osu.Game/Database/LegacyBeatmapExporter.cs b/osu.Game/Database/LegacyBeatmapExporter.cs index 22bccbcda6..6349ebde2c 100644 --- a/osu.Game/Database/LegacyBeatmapExporter.cs +++ b/osu.Game/Database/LegacyBeatmapExporter.cs @@ -3,14 +3,13 @@ using osu.Framework.Platform; using osu.Game.Beatmaps; -using osu.Game.Overlays; namespace osu.Game.Database { public class LegacyBeatmapExporter : LegacyModelExporter { - public LegacyBeatmapExporter(Storage storage, RealmAccess realm, INotificationOverlay? notifications = null) - : base(storage, realm, notifications) + public LegacyBeatmapExporter(Storage storage, RealmAccess realm) + : base(storage, realm) { } diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 18e840fedd..5150651b15 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -9,7 +9,6 @@ using System.Threading.Tasks; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Extensions; -using osu.Game.Overlays; using osu.Game.Overlays.Notifications; using osu.Game.Utils; using Realms; @@ -33,26 +32,16 @@ namespace osu.Game.Database protected RealmAccess RealmAccess; - private readonly ProgressNotification notification; - private bool canCancel = true; - private readonly INotificationOverlay? notifications; + private string filename = string.Empty; + public Action? PostNotification { get; set; } - protected LegacyModelExporter(Storage storage, RealmAccess realm, INotificationOverlay? notifications = null) + protected LegacyModelExporter(Storage storage, RealmAccess realm) { exportStorage = storage.GetStorageForDirectory(@"exports"); UserFileStorage = storage.GetStorageForDirectory(@"files"); RealmAccess = realm; - - this.notifications = notifications; - notification = new ProgressNotification - { - State = ProgressNotificationState.Active, - Text = "Exporting...", - CompletionText = "Export completed" - }; - notification.CancelRequested += () => canCancel; } /// @@ -62,13 +51,9 @@ namespace osu.Game.Database /// public async Task ExportAsync(TModel model) { - notifications?.Post(notification); - string itemFilename = model.GetDisplayString().GetValidFilename(); IEnumerable existingExports = exportStorage.GetFiles("", $"{itemFilename}*{FileExtension}"); - string filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); - - notification.CompletionClickAction += () => exportStorage.PresentFileExternally(filename); + filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); using (var stream = exportStorage.CreateFileSafely(filename)) { @@ -77,22 +62,50 @@ namespace osu.Game.Database } /// - /// Export te model corresponding to model to given stream. + /// Export model to stream. /// /// The medel which have . /// The stream to export. /// public async Task ExportToStreamAsync(TModel model, Stream stream) { + ProgressNotification notification = new ProgressNotification + { + State = ProgressNotificationState.Active, + Text = "Exporting...", + CompletionText = "Export completed" + }; + notification.CompletionClickAction += () => exportStorage.PresentFileExternally(filename); + notification.CancelRequested += () => canCancel; + PostNotification?.Invoke(notification); + canCancel = true; + Guid id = model.ID; await Task.Run(() => { RealmAccess.Run(r => { TModel refetchModel = r.Find(id); - ExportToStream(refetchModel, stream); + ExportToStream(refetchModel, stream, notification); }); - }).ContinueWith(onComplete); + }).ContinueWith(t => + { + if (t.IsFaulted) + { + notification.State = ProgressNotificationState.Cancelled; + Logger.Error(t.Exception, "An error occurred while exporting"); + + return; + } + + if (notification.CancellationToken.IsCancellationRequested) + { + return; + } + + notification.CompletionText = "Export Complete, Click to open the folder"; + notification.State = ProgressNotificationState.Completed; + }); } /// @@ -101,14 +114,16 @@ namespace osu.Game.Database /// /// The item to export. /// The output stream to export to. - protected virtual void ExportToStream(TModel model, Stream outputStream) => exportZipArchive(model, outputStream); + /// The notification will displayed to the user + protected virtual void ExportToStream(TModel model, Stream outputStream, ProgressNotification notification) => exportZipArchive(model, outputStream, notification); /// /// Exports an item to Stream as a legacy (.zip based) package. /// /// The item to export. /// The output stream to export to. - private void exportZipArchive(TModel model, Stream outputStream) + /// The notification will displayed to the user + private void exportZipArchive(TModel model, Stream outputStream, ProgressNotification notification) { using (var archive = ZipArchive.Create()) { @@ -129,24 +144,5 @@ namespace osu.Game.Database archive.SaveTo(outputStream); } } - - private void onComplete(Task t) - { - if (t.IsFaulted) - { - notification.State = ProgressNotificationState.Cancelled; - Logger.Error(t.Exception, "An error occurred while exporting"); - - return; - } - - if (notification.CancellationToken.IsCancellationRequested) - { - return; - } - - notification.CompletionText = "Export Complete, Click to open the folder"; - notification.State = ProgressNotificationState.Completed; - } } } diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index eb46bc6db2..1a30d823e1 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -5,21 +5,21 @@ using System.IO; using System.Linq; using osu.Framework.Platform; using osu.Game.Extensions; -using osu.Game.Overlays; +using osu.Game.Overlays.Notifications; using osu.Game.Scoring; namespace osu.Game.Database { public class LegacyScoreExporter : LegacyModelExporter { - public LegacyScoreExporter(Storage storage, RealmAccess realm, INotificationOverlay? notifications = null) - : base(storage, realm, notifications) + public LegacyScoreExporter(Storage storage, RealmAccess realm) + : base(storage, realm) { } protected override string FileExtension => ".osr"; - protected override void ExportToStream(ScoreInfo model, Stream stream) + protected override void ExportToStream(ScoreInfo model, Stream stream, ProgressNotification notification) { var file = model.Files.SingleOrDefault(); if (file == null) diff --git a/osu.Game/Database/LegacySkinExporter.cs b/osu.Game/Database/LegacySkinExporter.cs index 6e65963f29..52d0e56cbf 100644 --- a/osu.Game/Database/LegacySkinExporter.cs +++ b/osu.Game/Database/LegacySkinExporter.cs @@ -2,15 +2,14 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Platform; -using osu.Game.Overlays; using osu.Game.Skinning; namespace osu.Game.Database { public class LegacySkinExporter : LegacyModelExporter { - public LegacySkinExporter(Storage storage, RealmAccess realm, INotificationOverlay? notifications = null) - : base(storage, realm, notifications) + public LegacySkinExporter(Storage storage, RealmAccess realm) + : base(storage, realm) { } diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index f0457de2dc..e5edf90d1a 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -18,7 +17,6 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Framework.Localisation; -using osu.Game.Database; using osu.Game.Extensions; using osu.Game.Graphics; using osu.Game.Graphics.Containers; @@ -34,7 +32,6 @@ using osuTK.Graphics; using osu.Game.Online.API; using osu.Game.Resources.Localisation.Web; using osu.Game.Utils; -using osu.Framework.Platform; namespace osu.Game.Online.Leaderboards { @@ -73,18 +70,11 @@ namespace osu.Game.Online.Leaderboards [Resolved(canBeNull: true)] private SongSelect songSelect { get; set; } - [Resolved] - private Storage storage { get; set; } - - [Resolved] - private RealmAccess realm { get; set; } - - [Resolved(canBeNull: true)] - private INotificationOverlay notifications { get; set; } - public ITooltip GetCustomTooltip() => new LeaderboardScoreTooltip(); public virtual ScoreInfo TooltipContent => Score; + private ScoreManager scoreManager = null!; + public LeaderboardScore(ScoreInfo score, int? rank, bool isOnlineScope = true) { Score = score; @@ -103,6 +93,8 @@ namespace osu.Game.Online.Leaderboards statisticsLabels = GetStatistics(Score).Select(s => new ScoreComponentLabel(s)).ToList(); + this.scoreManager = scoreManager; + ClickableAvatar innerAvatar; Children = new Drawable[] @@ -434,7 +426,7 @@ namespace osu.Game.Online.Leaderboards if (Score.Files.Count > 0) { - items.Add(new OsuMenuItem("Export", MenuItemType.Standard, () => Task.Run(() => new LegacyScoreExporter(storage, realm, notifications).ExportAsync(Score)))); + items.Add(new OsuMenuItem("Export", MenuItemType.Standard, () => scoreManager.Export(Score))); items.Add(new OsuMenuItem(CommonStrings.ButtonsDelete, MenuItemType.Destructive, () => dialogOverlay?.Push(new LocalScoreDeleteDialog(Score)))); } diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 9400e803c8..6d338df2fe 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -13,7 +13,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Framework.Logging; -using osu.Framework.Platform; using osu.Game.Database; using osu.Game.Graphics.UserInterface; using osu.Game.Localisation; @@ -138,15 +137,6 @@ namespace osu.Game.Overlays.Settings.Sections [Resolved] private SkinManager skins { get; set; } - [Resolved] - private Storage storage { get; set; } - - [Resolved] - private RealmAccess realm { get; set; } - - [Resolved(canBeNull: true)] - private INotificationOverlay notifications { get; set; } - private Bindable currentSkin; [BackgroundDependencyLoader] @@ -168,7 +158,7 @@ namespace osu.Game.Overlays.Settings.Sections { try { - currentSkin.Value.SkinInfo.PerformRead(s => new LegacySkinExporter(storage, realm, notifications).ExportAsync(s)); + skins.ExporCurrenttSkin(); } catch (Exception e) { diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index b2944ad219..525ff58778 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -27,6 +27,7 @@ namespace osu.Game.Scoring { private readonly OsuConfigManager configManager; private readonly ScoreImporter scoreImporter; + private readonly LegacyScoreExporter scoreExporter; public ScoreManager(RulesetStore rulesets, Func beatmaps, Storage storage, RealmAccess realm, IAPIProvider api, OsuConfigManager configManager = null) @@ -38,6 +39,11 @@ namespace osu.Game.Scoring { PostNotification = obj => PostNotification?.Invoke(obj) }; + + scoreExporter = new LegacyScoreExporter(storage, realm) + { + PostNotification = obj => PostNotification?.Invoke(obj) + }; } public Score GetScore(ScoreInfo score) => scoreImporter.GetScore(score); @@ -177,6 +183,8 @@ namespace osu.Game.Scoring public Task>> Import(ProgressNotification notification, params ImportTask[] tasks) => scoreImporter.Import(notification, tasks); + public void Export(ScoreInfo score) => Task.Run(() => scoreExporter.ExportAsync(score)); + public Task> ImportAsUpdate(ProgressNotification notification, ImportTask task, ScoreInfo original) => scoreImporter.ImportAsUpdate(notification, task, original); public Live Import(ScoreInfo item, ArchiveReader archive = null, bool batchImport = false, CancellationToken cancellationToken = default) => diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 342ee2e219..69bcda69c1 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using JetBrains.Annotations; using osu.Framework; using osu.Framework.Allocation; @@ -21,7 +20,6 @@ using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Framework.Logging; -using osu.Framework.Platform; using osu.Framework.Screens; using osu.Framework.Testing; using osu.Framework.Threading; @@ -30,7 +28,6 @@ using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Configuration; -using osu.Game.Database; using osu.Game.Graphics.Cursor; using osu.Game.Graphics.UserInterface; using osu.Game.Input.Bindings; @@ -89,12 +86,6 @@ namespace osu.Game.Screens.Edit [Resolved] private RulesetStore rulesets { get; set; } - [Resolved] - private Storage storage { get; set; } - - [Resolved] - private RealmAccess realm { get; set; } - [Resolved(canBeNull: true)] private IDialogOverlay dialogOverlay { get; set; } @@ -958,7 +949,7 @@ namespace osu.Game.Screens.Edit private void exportBeatmap() { Save(); - Task.Run(() => new LegacyBeatmapExporter(storage, realm, notifications).ExportAsync(Beatmap.Value.BeatmapSetInfo)); + beatmapManager.Export(Beatmap.Value.BeatmapSetInfo); } /// diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index 4a5277f3bf..65a602b764 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -58,6 +58,8 @@ namespace osu.Game.Skinning private readonly SkinImporter skinImporter; + private readonly LegacySkinExporter skinExporter; + private readonly IResourceStore userFiles; private Skin argonSkin { get; } @@ -109,6 +111,11 @@ namespace osu.Game.Skinning SourceChanged?.Invoke(); }; + + skinExporter = new LegacySkinExporter(storage, realm) + { + PostNotification = obj => PostNotification?.Invoke(obj) + }; } public void SelectRandomSkin() @@ -280,6 +287,8 @@ namespace osu.Game.Skinning public Task> Import(ImportTask task, bool batchImport = false, CancellationToken cancellationToken = default) => skinImporter.Import(task, batchImport, cancellationToken); + public void ExporCurrenttSkin() => CurrentSkinInfo.Value.PerformRead(s => skinExporter.ExportAsync(s)); + #endregion public void Delete([CanBeNull] Expression> filter = null, bool silent = false) From 85039209f80347462f9d25d0026dfdaa966015b1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Dec 2022 01:56:32 +0900 Subject: [PATCH 0974/2991] Fix parsing of ruleset configuration values being incorrect on some locales Closes #21611. --- osu.Game/Rulesets/Configuration/RulesetConfigManager.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs b/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs index 4ff4f66665..0eea1ff215 100644 --- a/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs +++ b/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs @@ -5,9 +5,11 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using osu.Framework.Bindables; using osu.Framework.Configuration; +using osu.Framework.Extensions; using osu.Game.Configuration; using osu.Game.Database; @@ -67,7 +69,7 @@ namespace osu.Game.Rulesets.Configuration { var setting = r.All().First(s => s.RulesetName == rulesetName && s.Variant == variant && s.Key == c.ToString()); - setting.Value = ConfigStore[c].ToString(); + setting.Value = ConfigStore[c].ToString(CultureInfo.InvariantCulture); } }); @@ -89,7 +91,7 @@ namespace osu.Game.Rulesets.Configuration setting = new RealmRulesetSetting { Key = lookup.ToString(), - Value = bindable.Value.ToString(), + Value = bindable.ToString(CultureInfo.InvariantCulture), RulesetName = rulesetName, Variant = variant, }; From ffbe68bd26f8e4dbe154037ad47c15e972699676 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 11 Dec 2022 22:08:48 +0100 Subject: [PATCH 0975/2991] Add judgementTally to HUD overlay --- .../HUD/JudgementCounter/JudgementTally.cs | 56 +++++++++++++++++++ osu.Game/Screens/Play/HUDOverlay.cs | 5 ++ 2 files changed, 61 insertions(+) create mode 100644 osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs new file mode 100644 index 0000000000..2bc89aeea1 --- /dev/null +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs @@ -0,0 +1,56 @@ + + + +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.UI; + +namespace osu.Game.Screens.Play.HUD.JudgementCounter +{ + public partial class JudgementTally : CompositeDrawable + { + [Resolved] + private ScoreProcessor scoreProcessor { get; set; } = null!; + + public List Results = new List(); + + [BackgroundDependencyLoader] + private void load(DrawableRuleset ruleset) + { + foreach (var result in ruleset.Ruleset.GetHitResults()) + { + Results.Add(new JudgementCounterInfo + { + ResultInfo = (result.result, result.displayName), + ResultCount = new BindableInt(), + }); + } + } + + protected override void LoadComplete() + { + base.LoadComplete(); + scoreProcessor.NewJudgement += judgement => + { + foreach (JudgementCounterInfo result in Results.Where(result => result.ResultInfo.Type == judgement.Type)) + { + result.ResultCount.Value++; + } + }; + scoreProcessor.JudgementReverted += judgement => + { + foreach (JudgementCounterInfo result in Results.Where(result => result.ResultInfo.Type == judgement.Type)) + { + result.ResultCount.Value--; + } + }; + } + } +} diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 4c2483a0e6..816b8b2543 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -24,6 +24,7 @@ using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.HUD.ClicksPerSecond; using osu.Game.Skinning; using osuTK; +using JudgementTally = osu.Game.Screens.Play.HUD.JudgementCounter.JudgementTally; namespace osu.Game.Screens.Play { @@ -58,6 +59,9 @@ namespace osu.Game.Screens.Play [Cached] private readonly ClicksPerSecondCalculator clicksPerSecondCalculator; + [Cached] + private readonly JudgementTally tally; + public Bindable ShowHealthBar = new Bindable(true); private readonly DrawableRuleset drawableRuleset; @@ -146,6 +150,7 @@ namespace osu.Game.Screens.Play Spacing = new Vector2(5) }, clicksPerSecondCalculator = new ClicksPerSecondCalculator(), + tally = new JudgementTally() }; hideTargets = new List { mainComponents, KeyCounter, topRightElements }; From f798951f0974b49592d10b1f7959d6e0e0a8ce46 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 11 Dec 2022 22:09:14 +0100 Subject: [PATCH 0976/2991] Create Judgement Info struct --- .../HUD/JudgementCounter/JudgementCounterInfo.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs new file mode 100644 index 0000000000..45f89c30d2 --- /dev/null +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs @@ -0,0 +1,16 @@ +// 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.Bindables; +using osu.Framework.Localisation; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Screens.Play.HUD.JudgementCounter +{ + public struct JudgementCounterInfo + { + public (HitResult Type, LocalisableString Displayname) ResultInfo { get; set; } + + public BindableInt ResultCount { get; set; } + } +} From 4c17b27273b638e2f271782be2cb50b8abf59f2b Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 11 Dec 2022 23:47:17 +0100 Subject: [PATCH 0977/2991] Add Display, Counter, Tests --- .../Gameplay/TestSceneJudgementCounter.cs | 136 ++++++++++++++++++ .../HUD/JudgementCounter/JudgementCounter.cs | 118 +++++++++++++++ .../JudgementCounterDisplay.cs | 133 +++++++++++++++++ .../HUD/JudgementCounter/JudgementTally.cs | 8 +- 4 files changed, 391 insertions(+), 4 deletions(-) create mode 100644 osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs create mode 100644 osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs create mode 100644 osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs new file mode 100644 index 0000000000..27f2362047 --- /dev/null +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -0,0 +1,136 @@ +// 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.Diagnostics; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Mania; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Osu.Judgements; +using osu.Game.Rulesets.Scoring; +using osu.Game.Screens.Play.HUD.JudgementCounter; + +namespace osu.Game.Tests.Visual.Gameplay +{ + public partial class TestSceneJudgementCounter : OsuTestScene + { + private ScoreProcessor scoreProcessor = null!; + private JudgementTally judgementTally = null!; + private TestJudgementCounterDisplay counter = null!; + + private readonly Bindable lastJudgementResult = new Bindable(); + + private int iteration; + + [SetUpSteps] + public void SetupSteps() => AddStep("Create components", () => + { + var ruleset = CreateRuleset(); + + Debug.Assert(ruleset != null); + + scoreProcessor = new ScoreProcessor(ruleset); + Child = new DependencyProvidingContainer + { + RelativeSizeAxes = Axes.Both, + CachedDependencies = new (Type, object)[] { (typeof(ScoreProcessor), scoreProcessor), (typeof(Ruleset), ruleset) }, + Children = new Drawable[] + { + judgementTally = new JudgementTally(), + new DependencyProvidingContainer + { + RelativeSizeAxes = Axes.Both, + CachedDependencies = new (Type, object)[] { (typeof(JudgementTally), judgementTally) }, + Child = counter = new TestJudgementCounterDisplay + { + Margin = new MarginPadding { Top = 100 }, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre + } + } + }, + }; + }); + + protected override Ruleset CreateRuleset() => new ManiaRuleset(); + + private void applyOneJudgement(HitResult result) + { + lastJudgementResult.Value = new OsuJudgementResult(new HitObject + { + StartTime = iteration * 10000 + }, new OsuJudgement()) + { + Type = result, + }; + scoreProcessor.ApplyResult(lastJudgementResult.Value); + + iteration++; + } + + [Test] + public void TestAddJudgementsToCounters() + { + AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Great), 2); + AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Miss), 2); + AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Meh), 2); + AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.LargeTickHit), 2); + AddStep("Show all judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.All); + AddAssert("Check value added whilst hidden", () => hiddenCount() == 2); + } + + [Test] + public void TestAddWhilstHidden() + { + AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.LargeTickHit), 2); + AddAssert("Check value added whilst hidden", () => hiddenCount() == 2); + AddStep("Show all judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.All); + } + + [Test] + public void TestChangeFlowDirection() + { + AddStep("Set direction vertical", () => counter.Direction.Value = FillDirection.Vertical); + AddStep("Set direction horizontal", () => counter.Direction.Value = FillDirection.Vertical); + } + + [Test] + public void TestHideJudgementNames() + { + AddStep("Hide judgement names", () => counter.ShowName.Value = false); + } + + [Test] + public void TestHideMaxValue() + { + AddStep("Hide max judgement", () => counter.ShowMax.Value = false); + AddStep("Show max judgement", () => counter.ShowMax.Value = true); + } + + [Test] + public void TestCycleDisplayModes() + { + AddStep("Show all judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.All); + AddStep("Show normal judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.Normal); + AddStep("Show basic judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.Simple); + } + + private int hiddenCount() + { + var num = counter.JudgementContainer.Children.OfType().First(child => child.Result.ResultInfo.Type == HitResult.LargeTickHit); + return num.Result.ResultCount.Value; + } + + private partial class TestJudgementCounterDisplay : JudgementCounterDisplay + { + public new FillFlowContainer JudgementContainer => base.JudgementContainer; + } + } +} diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs new file mode 100644 index 0000000000..d9709eb88a --- /dev/null +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -0,0 +1,118 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Screens.Play.HUD.JudgementCounter +{ + public partial class JudgementCounter : OverlayContainer + { + public BindableBool ShowName = new BindableBool(); + public Bindable Direction = new Bindable(); + + public readonly JudgementCounterInfo Result; + + public JudgementCounter(JudgementCounterInfo result) + { + Result = result; + } + + private OsuSpriteText resultName = null!; + private FillFlowContainer flowContainer = null!; + private JudgementRollingCounter counter = null!; + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + AutoSizeAxes = Axes.Both; + InternalChild = flowContainer = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + counter = new JudgementRollingCounter + { + Current = Result.ResultCount + }, + resultName = new OsuSpriteText + { + Font = OsuFont.Numeric.With(size: 8), + Text = Result.ResultInfo.Displayname + } + } + }; + + var result = Result.ResultInfo.Type; + + if (result.IsBasic()) + { + Colour = colours.ForHitResult(Result.ResultInfo.Type); + return; + } + + if (!result.IsBonus()) + { + Colour = colours.PurpleLight; + return; + } + + Colour = colours.PurpleLighter; + } + + protected override void LoadComplete() + { + ShowName.BindValueChanged(value => + { + if (value.NewValue) + { + resultName.Show(); + return; + } + + resultName.Hide(); + }, true); + + Direction.BindValueChanged(direction => + { + flowContainer.Direction = direction.NewValue; + + if (direction.NewValue == FillDirection.Vertical) + { + changeAnchor(Anchor.TopLeft); + return; + } + + changeAnchor(Anchor.BottomLeft); + + void changeAnchor(Anchor anchor) => counter.Anchor = resultName.Anchor = counter.Origin = resultName.Origin = anchor; + }, true); + + base.LoadComplete(); + } + + protected override void PopIn() + { + this.FadeInFromZero(500, Easing.OutQuint); + } + + protected override void PopOut() + { + this.FadeOut(100); + } + + private sealed partial class JudgementRollingCounter : RollingCounter + { + protected override OsuSpriteText CreateSpriteText() + => base.CreateSpriteText().With(s => s.Font = s.Font.With(fixedWidth: true, size: 16)); + + protected override double RollingDuration => 750; + } + } +} diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs new file mode 100644 index 0000000000..b392ce8e04 --- /dev/null +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -0,0 +1,133 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Configuration; +using osu.Game.Rulesets.Scoring; +using osu.Game.Skinning; +using osuTK; + +namespace osu.Game.Screens.Play.HUD.JudgementCounter +{ + public partial class JudgementCounterDisplay : CompositeDrawable, ISkinnableDrawable + { + public bool UsesFixedAnchor { get; set; } + + [SettingSource("Counter direction")] + public Bindable Direction { get; set; } = new Bindable(); + + [SettingSource("Show judgement names")] + public BindableBool ShowName { get; set; } = new BindableBool(true); + + [SettingSource("Show max judgement")] + public BindableBool ShowMax { get; set; } = new BindableBool(true); + + [SettingSource("Display mode")] + public Bindable Mode { get; set; } = new Bindable(); + + [Resolved] + private JudgementTally tally { get; set; } = null!; + + protected FillFlowContainer JudgementContainer = null!; + + [BackgroundDependencyLoader] + private void load() + { + InternalChild = JudgementContainer = new FillFlowContainer + { + Direction = Direction.Value, + Spacing = new Vector2(10), + AutoSizeAxes = Axes.Both + }; + + foreach (var result in tally.Results) + { + JudgementContainer.Add(createCounter(result)); + } + } + + protected override void Update() + { + Size = JudgementContainer.Size; + base.Update(); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + Direction.BindValueChanged(direction => JudgementContainer.Direction = direction.NewValue); + Mode.BindValueChanged(_ => updateCounter(), true); + + ShowMax.BindValueChanged(value => + { + var firstChild = JudgementContainer.Children.FirstOrDefault(); + + if (value.NewValue) + { + firstChild?.Show(); + return; + } + + firstChild?.Hide(); + }, true); + } + + private void updateCounter() + { + var counters = JudgementContainer.Children.OfType().ToList(); + + switch (Mode.Value) + { + case DisplayMode.Simple: + foreach (var counter in counters.Where(counter => counter.Result.ResultInfo.Type.IsBasic())) + counter.Show(); + + foreach (var counter in counters.Where(counter => !counter.Result.ResultInfo.Type.IsBasic())) + counter.Hide(); + + break; + + case DisplayMode.Normal: + foreach (var counter in counters.Where(counter => !counter.Result.ResultInfo.Type.IsBonus())) + counter.Show(); + + foreach (var counter in counters.Where(counter => counter.Result.ResultInfo.Type.IsBonus())) + counter.Hide(); + + break; + + case DisplayMode.All: + foreach (JudgementCounter counter in counters.Where(counter => !counter.IsPresent)) + counter.Show(); + + break; + + default: + throw new ArgumentOutOfRangeException(); + } + } + + public enum DisplayMode + { + Simple, + Normal, + All + } + + private JudgementCounter createCounter(JudgementCounterInfo info) + { + JudgementCounter counter = new JudgementCounter(info) + { + ShowName = { BindTarget = ShowName }, + Direction = { BindTarget = Direction } + }; + return counter; + } + } +} diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs index 2bc89aeea1..9cbeea7a2a 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs @@ -9,8 +9,8 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.UI; namespace osu.Game.Screens.Play.HUD.JudgementCounter { @@ -22,14 +22,14 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter public List Results = new List(); [BackgroundDependencyLoader] - private void load(DrawableRuleset ruleset) + private void load(IBindable working) { - foreach (var result in ruleset.Ruleset.GetHitResults()) + foreach (var result in working.Value.BeatmapInfo.Ruleset.CreateInstance().GetHitResults()) { Results.Add(new JudgementCounterInfo { ResultInfo = (result.result, result.displayName), - ResultCount = new BindableInt(), + ResultCount = new BindableInt() }); } } From 161894da3ba0c26ff1fe7a4473351999c19ba77b Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 11 Dec 2022 23:58:10 +0100 Subject: [PATCH 0978/2991] Add more test checks and fix deserialisation test --- .../Archives/modified-default-20221211.osk | Bin 0 -> 1650 bytes osu.Game.Tests/Skins/SkinDeserialisationTest.cs | 4 +++- .../Visual/Gameplay/TestSceneJudgementCounter.cs | 5 ++++- .../HUD/JudgementCounter/JudgementCounter.cs | 10 +++++----- 4 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 osu.Game.Tests/Resources/Archives/modified-default-20221211.osk diff --git a/osu.Game.Tests/Resources/Archives/modified-default-20221211.osk b/osu.Game.Tests/Resources/Archives/modified-default-20221211.osk new file mode 100644 index 0000000000000000000000000000000000000000..07190db267cfcbf0abf44a5eb95b4e43bb0955d2 GIT binary patch literal 1650 zcmWIWW@Zs#U|`^2__41$)V#A{#{nQOh#4fpz)+l>nWvYTm-)2cFptSlz_ogQ(hG;C zH@8F=E%uturR8F1usI>|yvx0fVRLj{`=)5Kh%9yb!m&$#@A~!s>-O!N%@*d~<`;ZP z@f71Xtz$_B3H%Yh#!+{Yz0w_&)Nagm{B6aw>S`{J3j_M*Aq3^;H=}T|8F6)dAv(Ab<5aqY1+2Z>O|HRMo z=|^O*rEI>?cH!LLn%^>Fr~Wd|K|=s@#Vyw=@NZF-`xgcUZ^iK^V0J5 zvWoNbO8Yi)9WoGc{a$y}IG8)v!$>ro{pF)YewP#{EU~$@&tcLdg@3!*&fa)i^sco! zPLyHyi>sTI4dk~oU(sB!EOX<=#;UJuvQd{0EIx8BV)=H}QZEhFs+;}Rb47yQmU*3; zxb^2Bku`pHPySnM)8007O90!Ns(J=g zhwp#q^9Xfu&d)8#&r8iKDF*xC?R4Ml#|8pz?|+J_rMsWl zm~))lvSjXE-romjEqlB4%K|N7_mGKQD$Zv&{jYs`jPJ6-FWs`BcD?Mo z>hJ};;YEEHA3v|2DIJqF!&_tRvP0iLeF`i1#=MHVl)XsLTk+Vxd)4cBw&!h&K3He# zS6$HCz>?8rs8+W+%#T;OMgDgE?3d3^T}rEZTcy8FLbM=h!`nO`R$1@#Nx4(kSx<8N zxwi6P_UTOJ7%7AJpUi9clg&dUGWIrYjS*W`c1P;$wwN`hSKQX+yY+7V|8!rHmvj7` zLiXT}c7?hCHmAB{5i2!U|5{{M>HAWy?eL*^CegCp51!pC{W9-^?UU+Ts&-!(7pF|j z4$Uxlru&KS@nn&HcBOq!zI9*o`p;CpM&irNSISRyFYy;l|L6E~!T*?Flb5U8SDOAP zz97A{JjCdP==5tmp;wL=7M1Jv-49HhY?)Sm%r$}4=Va;jyU`1slUx=}XpwEm6nUVb zc%H|jBgu!ObJ62hD?{h+GUW5RfAHr^y#xbW`wc-olOm_69JfB)IpfIX@-4>uroUz? zQ^DtQ)=Hi-THF6kzeb!+_4#F^7J1$uPry5p|;f1 zQSkropj>mUWReY~TlDD8rhZwUB}upTn8nIe8{If2()ak$1dF(o?Juq^sB5Wxb@_m8!|%4ok*}6K zT=BL4fr+ohoJ~S9Uz}eBZ9jZ#L0o%@#wDL=&$irW@K=rA7M6(ANZGIP>R}+Y)!F-u0p5&E zA`H08T3}>BKqH8PmAvS>(915U9tMWSXHZ@6k_=rddg+1CIv diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index 27f2362047..885b182a6f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -102,9 +102,12 @@ namespace osu.Game.Tests.Visual.Gameplay } [Test] - public void TestHideJudgementNames() + public void TestToggleJudgementNames() { AddStep("Hide judgement names", () => counter.ShowName.Value = false); + AddAssert("Assert hidden", () => counter.JudgementContainer.Children.OfType().First().ResultName.Alpha == 0); + AddStep("Hide judgement names", () => counter.ShowName.Value = true); + AddAssert("Assert shown", () => counter.JudgementContainer.Children.OfType().First().ResultName.Alpha == 1); } [Test] diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs index d9709eb88a..d7bb8939e1 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -24,7 +24,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter Result = result; } - private OsuSpriteText resultName = null!; + public OsuSpriteText ResultName = null!; private FillFlowContainer flowContainer = null!; private JudgementRollingCounter counter = null!; @@ -41,7 +41,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { Current = Result.ResultCount }, - resultName = new OsuSpriteText + ResultName = new OsuSpriteText { Font = OsuFont.Numeric.With(size: 8), Text = Result.ResultInfo.Displayname @@ -72,11 +72,11 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { if (value.NewValue) { - resultName.Show(); + ResultName.Show(); return; } - resultName.Hide(); + ResultName.Hide(); }, true); Direction.BindValueChanged(direction => @@ -91,7 +91,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter changeAnchor(Anchor.BottomLeft); - void changeAnchor(Anchor anchor) => counter.Anchor = resultName.Anchor = counter.Origin = resultName.Origin = anchor; + void changeAnchor(Anchor anchor) => counter.Anchor = ResultName.Anchor = counter.Origin = ResultName.Origin = anchor; }, true); base.LoadComplete(); From a107fca5d0a774178d8bd3b0fd1ff2725dfeb61b Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 12 Dec 2022 00:33:28 +0100 Subject: [PATCH 0979/2991] Hide "Full" option from counter flow directions --- .../Gameplay/TestSceneJudgementCounter.cs | 4 +- .../JudgementCounterDisplay.cs | 39 ++++++++++++++++--- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index 885b182a6f..1cded54b3e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -97,8 +97,8 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestChangeFlowDirection() { - AddStep("Set direction vertical", () => counter.Direction.Value = FillDirection.Vertical); - AddStep("Set direction horizontal", () => counter.Direction.Value = FillDirection.Vertical); + AddStep("Set direction vertical", () => counter.FlowDirection.Value = JudgementCounterDisplay.Flow.Vertical); + AddStep("Set direction horizontal", () => counter.FlowDirection.Value = JudgementCounterDisplay.Flow.Horizonal); } [Test] diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index b392ce8e04..3ac9e7fc55 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter public bool UsesFixedAnchor { get; set; } [SettingSource("Counter direction")] - public Bindable Direction { get; set; } = new Bindable(); + public Bindable FlowDirection { get; set; } = new Bindable(); [SettingSource("Show judgement names")] public BindableBool ShowName { get; set; } = new BindableBool(true); @@ -40,7 +40,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { InternalChild = JudgementContainer = new FillFlowContainer { - Direction = Direction.Value, + Direction = getFlow(FlowDirection.Value), Spacing = new Vector2(10), AutoSizeAxes = Axes.Both }; @@ -61,9 +61,17 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { base.LoadComplete(); - Direction.BindValueChanged(direction => JudgementContainer.Direction = direction.NewValue); - Mode.BindValueChanged(_ => updateCounter(), true); + FlowDirection.BindValueChanged(direction => + { + JudgementContainer.Direction = getFlow(direction.NewValue); + //Can't pass directly due to Enum conversion + foreach (var counter in JudgementContainer.Children.OfType()) + { + counter.Direction.Value = getFlow(direction.NewValue); + } + }); + Mode.BindValueChanged(_ => updateCounter(), true); ShowMax.BindValueChanged(value => { var firstChild = JudgementContainer.Children.FirstOrDefault(); @@ -113,6 +121,28 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter } } + private FillDirection getFlow(Flow flow) + { + switch (flow) + { + case Flow.Horizonal: + return FillDirection.Horizontal; + + case Flow.Vertical: + return FillDirection.Vertical; + + default: + throw new ArgumentOutOfRangeException(nameof(flow), flow, @"Unsupported direction"); + } + } + + //Used to hide default full option in FillDirection + public enum Flow + { + Horizonal, + Vertical + } + public enum DisplayMode { Simple, @@ -125,7 +155,6 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter JudgementCounter counter = new JudgementCounter(info) { ShowName = { BindTarget = ShowName }, - Direction = { BindTarget = Direction } }; return counter; } From f0c780f1f648860c83584aabf28063f7386b856a Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 12 Dec 2022 00:48:35 +0100 Subject: [PATCH 0980/2991] Fix tally header --- osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs index 9cbeea7a2a..e11b09d5a7 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs @@ -1,6 +1,3 @@ - - - // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. From 133256879685caf181defefe128ddd9e752e51cd Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 12 Dec 2022 03:10:13 +0300 Subject: [PATCH 0981/2991] Fix SettingsButton receiving input at padded area --- .../UserInterface/TestSceneSettingsButton.cs | 41 +++++++++++++++++++ osu.Game/Overlays/Settings/SettingsButton.cs | 4 ++ 2 files changed, 45 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneSettingsButton.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsButton.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsButton.cs new file mode 100644 index 0000000000..4353e7ffef --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsButton.cs @@ -0,0 +1,41 @@ +// 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.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Game.Overlays.Settings; +using NUnit.Framework; +using osuTK; +using osu.Game.Overlays; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public partial class TestSceneSettingsButton : OsuManualInputManagerTestScene + { + private readonly SettingsButton settingsButton; + + public TestSceneSettingsButton() + { + Add(new Container + { + AutoSizeAxes = Axes.Y, + Width = 500, + Child = settingsButton = new SettingsButton + { + Enabled = { Value = true }, + Text = "Test settings button" + } + }); + } + + [Test] + public void TestInputAtPaddedArea() + { + AddStep("Move cursor to button", () => InputManager.MoveMouseTo(settingsButton)); + AddAssert("Button is hovered", () => settingsButton.IsHovered); + AddStep("Move cursor to padded area", () => InputManager.MoveMouseTo(settingsButton.ScreenSpaceDrawQuad.TopLeft + new Vector2(SettingsPanel.CONTENT_MARGINS / 2f, 10))); + AddAssert("Cursor within a button", () => settingsButton.ScreenSpaceDrawQuad.Contains(InputManager.CurrentState.Mouse.Position)); + AddAssert("Button is not hovered", () => !settingsButton.IsHovered); + } + } +} diff --git a/osu.Game/Overlays/Settings/SettingsButton.cs b/osu.Game/Overlays/Settings/SettingsButton.cs index 5091ddc2d0..68cb95a2d8 100644 --- a/osu.Game/Overlays/Settings/SettingsButton.cs +++ b/osu.Game/Overlays/Settings/SettingsButton.cs @@ -9,11 +9,15 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterfaceV2; +using osuTK; namespace osu.Game.Overlays.Settings { public partial class SettingsButton : RoundedButton, IHasTooltip, IConditionalFilterable { + // We don't want to receive input at the padded area + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Content.ReceivePositionalInputAt(screenSpacePos); + public SettingsButton() { RelativeSizeAxes = Axes.X; From 5e8d75bbbfdf02e10eba7a7b95cd07920a9baaa6 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 12 Dec 2022 11:39:03 +0900 Subject: [PATCH 0982/2991] Remove unused overload --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 25 --------------------- 1 file changed, 25 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index b2b31c5394..cdef3e5afb 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -487,31 +487,6 @@ namespace osu.Game.Rulesets.Scoring extractScoringValues(scoreInfo.MaximumStatistics, out _, out maximum); } - /// - /// Applies a best-effort extraction of hit statistics into . - /// - /// - /// This method is useful in a variety of situations, with a few drawbacks that need to be considered: - /// - /// The maximum will always be 0. - /// The current and maximum will always be the same value. - /// - /// Consumers are expected to more accurately fill in the above values through external means. - /// - /// Ensure to fill in the maximum for use in - /// . - /// - /// - /// The replay frame header to extract scoring values from. - /// The "current" scoring values, representing the hit statistics as they appear. - /// The "maximum" scoring values, representing the hit statistics as if the maximum hit result was attained each time. - [Pure] - internal void ExtractScoringValues(FrameHeader header, out ScoringValues current, out ScoringValues maximum) - { - extractScoringValues(header.Statistics, out current, out maximum); - current.MaxCombo = header.MaxCombo; - } - /// /// Applies a best-effort extraction of hit statistics into . /// From 6e41efede88ba6bdabd2e54a645f7303c256e898 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 12 Dec 2022 11:40:15 +0900 Subject: [PATCH 0983/2991] Simplify dictionary construction --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index cdef3e5afb..7e94ea2b36 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -95,9 +95,9 @@ namespace osu.Game.Rulesets.Scoring get { if (!beatmapApplied) - throw new InvalidOperationException($"Cannot access maximum scoring values before calling {nameof(ApplyBeatmap)}."); + throw new InvalidOperationException($"Cannot access maximum statistics before calling {nameof(ApplyBeatmap)}."); - return maximumResultCounts.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + return new Dictionary(maximumResultCounts); } } From 7a54bcac57b193a9b2c1f268fe4751a9da691703 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 12 Dec 2022 11:41:07 +0900 Subject: [PATCH 0984/2991] Remove unused using --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 7e94ea2b36..5e05c7e2a6 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -10,7 +10,6 @@ using osu.Framework.Bindables; using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Extensions; -using osu.Game.Online.Spectator; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; From e76c56b03b1039b75010528a20cd9284b0833949 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 11 Dec 2022 20:10:06 -0800 Subject: [PATCH 0985/2991] Fix changelog single build dates disappearing before being off screen --- osu.Game/Overlays/Changelog/ChangelogBuild.cs | 10 ++++-- .../Changelog/ChangelogSingleBuild.cs | 32 ++++++++++--------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogBuild.cs b/osu.Game/Overlays/Changelog/ChangelogBuild.cs index fd7a3f8791..96d5203d14 100644 --- a/osu.Game/Overlays/Changelog/ChangelogBuild.cs +++ b/osu.Game/Overlays/Changelog/ChangelogBuild.cs @@ -68,11 +68,15 @@ namespace osu.Game.Overlays.Changelog Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, + Direction = FillDirection.Vertical, Margin = new MarginPadding { Top = 20 }, - Children = new Drawable[] + Child = new FillFlowContainer { - new OsuHoverContainer + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Child = new OsuHoverContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs index ddee6ff8bb..902aa72178 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs @@ -104,27 +104,29 @@ namespace osu.Game.Overlays.Changelog { var fill = base.CreateHeader(); - foreach (var existing in fill.Children.OfType()) + var nestedFill = fill.Children.OfType().First(); + + var buildDisplay = nestedFill.Children.OfType().First(); + + buildDisplay.Scale = new Vector2(1.25f); + buildDisplay.Action = null; + + fill.Add(date = new OsuSpriteText { - existing.Scale = new Vector2(1.25f); - existing.Action = null; + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = Build.CreatedAt.Date.ToString("dd MMMM yyyy"), + Font = OsuFont.GetFont(weight: FontWeight.Regular, size: 14), + Margin = new MarginPadding { Top = 5 }, + Scale = new Vector2(1.25f), + }); - existing.Add(date = new OsuSpriteText - { - Text = Build.CreatedAt.Date.ToString("dd MMMM yyyy"), - Font = OsuFont.GetFont(weight: FontWeight.Regular, size: 14), - Anchor = Anchor.BottomCentre, - Origin = Anchor.TopCentre, - Margin = new MarginPadding { Top = 5 }, - }); - } - - fill.Insert(-1, new NavigationIconButton(Build.Versions?.Previous) + nestedFill.Insert(-1, new NavigationIconButton(Build.Versions?.Previous) { Icon = FontAwesome.Solid.ChevronLeft, SelectBuild = b => SelectBuild(b) }); - fill.Insert(1, new NavigationIconButton(Build.Versions?.Next) + nestedFill.Insert(1, new NavigationIconButton(Build.Versions?.Next) { Icon = FontAwesome.Solid.ChevronRight, SelectBuild = b => SelectBuild(b) From 731184eb39b7ad0f6d11c4aeaf32eaef52a11316 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Dec 2022 13:43:01 +0900 Subject: [PATCH 0986/2991] Revert "Merge pull request #21614 from EVAST9919/button-fix" This reverts commit 4bd196684fe26b146986b04f8af5c75735774817, reversing changes made to a1d22ef77a0dd71aff97b17fd656ac68d347d4d7. --- .../UserInterface/TestSceneSettingsButton.cs | 41 ------------------- osu.Game/Overlays/Settings/SettingsButton.cs | 4 -- 2 files changed, 45 deletions(-) delete mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneSettingsButton.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsButton.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsButton.cs deleted file mode 100644 index 4353e7ffef..0000000000 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsButton.cs +++ /dev/null @@ -1,41 +0,0 @@ -// 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.Graphics.Containers; -using osu.Framework.Graphics; -using osu.Game.Overlays.Settings; -using NUnit.Framework; -using osuTK; -using osu.Game.Overlays; - -namespace osu.Game.Tests.Visual.UserInterface -{ - public partial class TestSceneSettingsButton : OsuManualInputManagerTestScene - { - private readonly SettingsButton settingsButton; - - public TestSceneSettingsButton() - { - Add(new Container - { - AutoSizeAxes = Axes.Y, - Width = 500, - Child = settingsButton = new SettingsButton - { - Enabled = { Value = true }, - Text = "Test settings button" - } - }); - } - - [Test] - public void TestInputAtPaddedArea() - { - AddStep("Move cursor to button", () => InputManager.MoveMouseTo(settingsButton)); - AddAssert("Button is hovered", () => settingsButton.IsHovered); - AddStep("Move cursor to padded area", () => InputManager.MoveMouseTo(settingsButton.ScreenSpaceDrawQuad.TopLeft + new Vector2(SettingsPanel.CONTENT_MARGINS / 2f, 10))); - AddAssert("Cursor within a button", () => settingsButton.ScreenSpaceDrawQuad.Contains(InputManager.CurrentState.Mouse.Position)); - AddAssert("Button is not hovered", () => !settingsButton.IsHovered); - } - } -} diff --git a/osu.Game/Overlays/Settings/SettingsButton.cs b/osu.Game/Overlays/Settings/SettingsButton.cs index 68cb95a2d8..5091ddc2d0 100644 --- a/osu.Game/Overlays/Settings/SettingsButton.cs +++ b/osu.Game/Overlays/Settings/SettingsButton.cs @@ -9,15 +9,11 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterfaceV2; -using osuTK; namespace osu.Game.Overlays.Settings { public partial class SettingsButton : RoundedButton, IHasTooltip, IConditionalFilterable { - // We don't want to receive input at the padded area - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Content.ReceivePositionalInputAt(screenSpacePos); - public SettingsButton() { RelativeSizeAxes = Axes.X; From f27603dd6de7521a8fb0bd98334325de5dffe6ad Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Oct 2022 17:46:01 +0900 Subject: [PATCH 0987/2991] Use hard links instead of file copy when available --- osu.Game/Database/RealmFileStore.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/osu.Game/Database/RealmFileStore.cs b/osu.Game/Database/RealmFileStore.cs index 036b15ea17..56ea8f23bc 100644 --- a/osu.Game/Database/RealmFileStore.cs +++ b/osu.Game/Database/RealmFileStore.cs @@ -4,6 +4,8 @@ using System; using System.IO; using System.Linq; +using System.Runtime.InteropServices; +using osu.Framework; using osu.Framework.Extensions; using osu.Framework.IO.Stores; using osu.Framework.Logging; @@ -60,6 +62,13 @@ namespace osu.Game.Database private void copyToStore(RealmFile file, Stream data) { + if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows && data is FileStream fs) + { + // attempt to do a fast hard link rather than copy. + if (CreateHardLink(Storage.GetFullPath(file.GetStoragePath()), fs.Name, IntPtr.Zero)) + return; + } + data.Seek(0, SeekOrigin.Begin); using (var output = Storage.CreateFileSafely(file.GetStoragePath())) @@ -68,6 +77,13 @@ namespace osu.Game.Database data.Seek(0, SeekOrigin.Begin); } + [DllImport("Kernel32.dll", CharSet = CharSet.Unicode)] + private static extern bool CreateHardLink( + string lpFileName, + string lpExistingFileName, + IntPtr lpSecurityAttributes + ); + private bool checkFileExistsAndMatchesHash(RealmFile file) { string path = file.GetStoragePath(); From 3b1920c060b9352654b3f2d429548bffcbbbc4a0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Oct 2022 18:18:29 +0900 Subject: [PATCH 0988/2991] Add code to check whether a file is a hard link --- osu.Game/Database/RealmFileStore.cs | 48 +++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/osu.Game/Database/RealmFileStore.cs b/osu.Game/Database/RealmFileStore.cs index 56ea8f23bc..4aa65dd50a 100644 --- a/osu.Game/Database/RealmFileStore.cs +++ b/osu.Game/Database/RealmFileStore.cs @@ -5,6 +5,8 @@ using System; using System.IO; using System.Linq; using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; +using Microsoft.Win32.SafeHandles; using osu.Framework; using osu.Framework.Extensions; using osu.Framework.IO.Stores; @@ -77,6 +79,20 @@ namespace osu.Game.Database data.Seek(0, SeekOrigin.Begin); } + public static int GetFileLinkCount(string filePath) + { + int result = 0; + SafeFileHandle handle = CreateFile(filePath, FileAccess.Read, FileShare.Read, IntPtr.Zero, FileMode.Open, FileAttributes.Archive, IntPtr.Zero); + + ByHandleFileInformation fileInfo; + + if (GetFileInformationByHandle(handle, out fileInfo)) + result = (int)fileInfo.NumberOfLinks; + CloseHandle(handle); + + return result; + } + [DllImport("Kernel32.dll", CharSet = CharSet.Unicode)] private static extern bool CreateHardLink( string lpFileName, @@ -84,6 +100,38 @@ namespace osu.Game.Database IntPtr lpSecurityAttributes ); + [StructLayout(LayoutKind.Sequential)] + private struct ByHandleFileInformation + { + public readonly uint FileAttributes; + public readonly FILETIME CreationTime; + public readonly FILETIME LastAccessTime; + public readonly FILETIME LastWriteTime; + public readonly uint VolumeSerialNumber; + public readonly uint FileSizeHigh; + public readonly uint FileSizeLow; + public readonly uint NumberOfLinks; + public readonly uint FileIndexHigh; + public readonly uint FileIndexLow; + } + + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] + private static extern SafeFileHandle CreateFile( + string lpFileName, + [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess, + [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode, + IntPtr lpSecurityAttributes, + [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition, + [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes, + IntPtr hTemplateFile); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool GetFileInformationByHandle(SafeFileHandle handle, out ByHandleFileInformation lpFileInformation); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool CloseHandle(SafeHandle hObject); + private bool checkFileExistsAndMatchesHash(RealmFile file) { string path = file.GetStoragePath(); From 902dff15e38be4259e79d022bec5b39c3a466861 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Oct 2022 18:20:49 +0900 Subject: [PATCH 0989/2991] Add todo regarding validity check --- osu.Game/Beatmaps/WorkingBeatmapCache.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Beatmaps/WorkingBeatmapCache.cs b/osu.Game/Beatmaps/WorkingBeatmapCache.cs index adb5f8c433..e6f96330e7 100644 --- a/osu.Game/Beatmaps/WorkingBeatmapCache.cs +++ b/osu.Game/Beatmaps/WorkingBeatmapCache.cs @@ -141,6 +141,9 @@ namespace osu.Game.Beatmaps try { string fileStorePath = BeatmapSetInfo.GetPathForFile(BeatmapInfo.Path); + + // TODO: check validity of file + var stream = GetStream(fileStorePath); if (stream == null) From d8de99bbe452d000896d4ac75e036e854038dda9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Oct 2022 18:39:52 +0900 Subject: [PATCH 0990/2991] Check for hard link support in first run overlay --- osu.Game/Database/LegacyImportManager.cs | 21 +++++++++++++++++++ osu.Game/Database/RealmFileStore.cs | 2 +- .../FirstRunSetup/ScreenImportFromStable.cs | 4 ++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/osu.Game/Database/LegacyImportManager.cs b/osu.Game/Database/LegacyImportManager.cs index b5338fbe1f..80c8e9c19e 100644 --- a/osu.Game/Database/LegacyImportManager.cs +++ b/osu.Game/Database/LegacyImportManager.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; using osu.Framework; @@ -54,6 +55,26 @@ namespace osu.Game.Database public void UpdateStorage(string stablePath) => cachedStorage = new StableStorage(stablePath, gameHost as DesktopGameHost); + public bool CheckHardLinkAvailability() + { + if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows) + return false; + + var stableStorage = GetCurrentStableStorage(); + + if (stableStorage == null || gameHost is not DesktopGameHost desktopGameHost) + return false; + + const string test_filename = "_hard_link_test"; + + desktopGameHost.Storage.Delete(test_filename); + + string testExistingPath = stableStorage.GetFullPath(stableStorage.GetFiles(string.Empty).First()); + string testDestinationPath = desktopGameHost.Storage.GetFullPath(test_filename); + + return RealmFileStore.CreateHardLink(testDestinationPath, testExistingPath, IntPtr.Zero); + } + public virtual async Task GetImportCount(StableContent content, CancellationToken cancellationToken) { var stableStorage = GetCurrentStableStorage(); diff --git a/osu.Game/Database/RealmFileStore.cs b/osu.Game/Database/RealmFileStore.cs index 4aa65dd50a..99033e2c88 100644 --- a/osu.Game/Database/RealmFileStore.cs +++ b/osu.Game/Database/RealmFileStore.cs @@ -94,7 +94,7 @@ namespace osu.Game.Database } [DllImport("Kernel32.dll", CharSet = CharSet.Unicode)] - private static extern bool CreateHardLink( + public static extern bool CreateHardLink( string lpFileName, string lpExistingFileName, IntPtr lpSecurityAttributes diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index 29cf3824fd..8227106ac2 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -14,6 +14,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; +using osu.Framework.Logging; using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Graphics.Containers; @@ -105,6 +106,9 @@ namespace osu.Game.Overlays.FirstRunSetup toggleInteraction(true); stableLocatorTextBox.Current.Value = storage.GetFullPath(string.Empty); importButton.Enabled.Value = true; + + bool available = legacyImportManager.CheckHardLinkAvailability(); + Logger.Log($"Hard link support is {available}"); } private void runImport() From 726943cb14150f8673b6ef0b71a2805bd6e43e9a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Dec 2022 17:01:28 +0900 Subject: [PATCH 0991/2991] Add information attempting to explain hard links to the end user --- ...RunOverlayImportFromStableScreenStrings.cs | 4 ++-- .../FirstRunSetup/ScreenImportFromStable.cs | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/osu.Game/Localisation/FirstRunOverlayImportFromStableScreenStrings.cs b/osu.Game/Localisation/FirstRunOverlayImportFromStableScreenStrings.cs index deac7d8628..f0620245c3 100644 --- a/osu.Game/Localisation/FirstRunOverlayImportFromStableScreenStrings.cs +++ b/osu.Game/Localisation/FirstRunOverlayImportFromStableScreenStrings.cs @@ -15,10 +15,10 @@ namespace osu.Game.Localisation public static LocalisableString Header => new TranslatableString(getKey(@"header"), @"Import"); /// - /// "If you have an installation of a previous osu! version, you can choose to migrate your existing content. Note that this will create a copy, and not affect your existing installation." + /// "If you have an installation of a previous osu! version, you can choose to migrate your existing content. Note that this will not affect your existing installation's files in any way." /// public static LocalisableString Description => new TranslatableString(getKey(@"description"), - @"If you have an installation of a previous osu! version, you can choose to migrate your existing content. Note that this will create a copy, and not affect your existing installation."); + @"If you have an installation of a previous osu! version, you can choose to migrate your existing content. Note that this will not affect your existing installation's files in any way."); /// /// "previous osu! install" diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index 8227106ac2..d1221d4174 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -7,6 +7,7 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions; @@ -40,6 +41,8 @@ namespace osu.Game.Overlays.FirstRunSetup private StableLocatorLabelledTextBox stableLocatorTextBox = null!; + private OsuTextFlowContainer copyInformation = null!; + private IEnumerable contentCheckboxes => Content.Children.OfType(); [BackgroundDependencyLoader(permitNulls: true)] @@ -63,6 +66,12 @@ namespace osu.Game.Overlays.FirstRunSetup new ImportCheckbox(CommonStrings.Scores, StableContent.Scores), new ImportCheckbox(CommonStrings.Skins, StableContent.Skins), new ImportCheckbox(CommonStrings.Collections, StableContent.Collections), + copyInformation = new OsuTextFlowContainer(cp => cp.Font = OsuFont.Default.With(size: CONTENT_FONT_SIZE)) + { + Colour = OverlayColourProvider.Content1, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y + }, importButton = new ProgressRoundedButton { Size = button_size, @@ -109,6 +118,18 @@ namespace osu.Game.Overlays.FirstRunSetup bool available = legacyImportManager.CheckHardLinkAvailability(); Logger.Log($"Hard link support is {available}"); + + if (available) + { + copyInformation.Text = "Data migration will use \"hard links\". No extra disk space will be used, and you can delete either data folder at any point without affecting the other installation."; + } + else if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows) + copyInformation.Text = "Hard links are not supported on this operating system, so a copy of all files will be made during import."; + else + { + copyInformation.Text = + "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install and the file system is NTFS."; + } } private void runImport() From e2d8909e7355d5773d69cb1245a3536d61973a09 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 11 Dec 2022 20:17:04 +0900 Subject: [PATCH 0992/2991] Add link to change folder location if it isn't on the same drive as import path --- .../FirstRunSetup/ScreenImportFromStable.cs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index d1221d4174..4af80c6fbb 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -16,12 +16,14 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Framework.Logging; +using osu.Framework.Screens; using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Localisation; using osu.Game.Overlays.Settings; +using osu.Game.Overlays.Settings.Sections.Maintenance; using osu.Game.Screens.Edit.Setup; using osuTK; @@ -41,7 +43,7 @@ namespace osu.Game.Overlays.FirstRunSetup private StableLocatorLabelledTextBox stableLocatorTextBox = null!; - private OsuTextFlowContainer copyInformation = null!; + private LinkFlowContainer copyInformation = null!; private IEnumerable contentCheckboxes => Content.Children.OfType(); @@ -50,7 +52,7 @@ namespace osu.Game.Overlays.FirstRunSetup { Content.Children = new Drawable[] { - new OsuTextFlowContainer(cp => cp.Font = OsuFont.Default.With(size: CONTENT_FONT_SIZE)) + new LinkFlowContainer(cp => cp.Font = OsuFont.Default.With(size: CONTENT_FONT_SIZE)) { Colour = OverlayColourProvider.Content1, Text = FirstRunOverlayImportFromStableScreenStrings.Description, @@ -66,7 +68,7 @@ namespace osu.Game.Overlays.FirstRunSetup new ImportCheckbox(CommonStrings.Scores, StableContent.Scores), new ImportCheckbox(CommonStrings.Skins, StableContent.Skins), new ImportCheckbox(CommonStrings.Collections, StableContent.Collections), - copyInformation = new OsuTextFlowContainer(cp => cp.Font = OsuFont.Default.With(size: CONTENT_FONT_SIZE)) + copyInformation = new LinkFlowContainer(cp => cp.Font = OsuFont.Default.With(size: CONTENT_FONT_SIZE)) { Colour = OverlayColourProvider.Content1, RelativeSizeAxes = Axes.X, @@ -93,6 +95,9 @@ namespace osu.Game.Overlays.FirstRunSetup stableLocatorTextBox.Current.BindValueChanged(_ => updateStablePath(), true); } + [Resolved(canBeNull: true)] + private OsuGame? game { get; set; } + private void updateStablePath() { var storage = legacyImportManager.GetCurrentStableStorage(); @@ -124,11 +129,15 @@ namespace osu.Game.Overlays.FirstRunSetup copyInformation.Text = "Data migration will use \"hard links\". No extra disk space will be used, and you can delete either data folder at any point without affecting the other installation."; } else if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows) - copyInformation.Text = "Hard links are not supported on this operating system, so a copy of all files will be made during import."; + copyInformation.Text = "Lightweight linking of files are not supported on your operating system yet, so a copy of all files will be made during import."; else { copyInformation.Text = - "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install and the file system is NTFS."; + "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install (and the file system is NTFS). "; + copyInformation.AddLink(GeneralSettingsStrings.ChangeFolderLocation, () => + { + game?.PerformFromScreen(menu => menu.Push(new MigrationSelectScreen())); + }); } } From caa0b7c290acdc70a61440d6ff209b77236c1325 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 12 Dec 2022 13:59:27 +0900 Subject: [PATCH 0993/2991] Move score token to BeginPlaying --- osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs | 2 +- .../Visual/Gameplay/TestSceneSpectatorPlayback.cs | 2 +- osu.Game/Online/Spectator/ISpectatorServer.cs | 3 ++- osu.Game/Online/Spectator/OnlineSpectatorClient.cs | 6 +++--- osu.Game/Online/Spectator/SpectatorClient.cs | 11 ++++++----- osu.Game/Online/Spectator/SpectatorState.cs | 7 ++----- osu.Game/Screens/Play/SubmittingPlayer.cs | 2 +- .../Tests/Visual/Spectator/TestSpectatorClient.cs | 2 +- 8 files changed, 17 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs index 4f319a7c34..ffd034e4d2 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectator.cs @@ -261,7 +261,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestFinalFramesPurgedBeforeEndingPlay() { - AddStep("begin playing", () => spectatorClient.BeginPlaying(TestGameplayState.Create(new OsuRuleset()), new Score(), 0)); + AddStep("begin playing", () => spectatorClient.BeginPlaying(0, TestGameplayState.Create(new OsuRuleset()), new Score())); AddStep("send frames and finish play", () => { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs index a949c0d79d..794860b9ec 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs @@ -147,7 +147,7 @@ namespace osu.Game.Tests.Visual.Gameplay } }; - spectatorClient.BeginPlaying(TestGameplayState.Create(new OsuRuleset()), recordingScore, 0); + spectatorClient.BeginPlaying(0, TestGameplayState.Create(new OsuRuleset()), recordingScore); spectatorClient.OnNewFrames += onNewFrames; }); } diff --git a/osu.Game/Online/Spectator/ISpectatorServer.cs b/osu.Game/Online/Spectator/ISpectatorServer.cs index 25785f60a4..fa9d04792a 100644 --- a/osu.Game/Online/Spectator/ISpectatorServer.cs +++ b/osu.Game/Online/Spectator/ISpectatorServer.cs @@ -15,8 +15,9 @@ namespace osu.Game.Online.Spectator /// /// Signal the start of a new play session. /// + /// The score submission token. /// The state of gameplay. - Task BeginPlaySession(SpectatorState state); + Task BeginPlaySession(long? scoreToken, SpectatorState state); /// /// Send a bundle of frame data for the current play session. diff --git a/osu.Game/Online/Spectator/OnlineSpectatorClient.cs b/osu.Game/Online/Spectator/OnlineSpectatorClient.cs index d69bd81b57..d5c1e56761 100644 --- a/osu.Game/Online/Spectator/OnlineSpectatorClient.cs +++ b/osu.Game/Online/Spectator/OnlineSpectatorClient.cs @@ -47,7 +47,7 @@ namespace osu.Game.Online.Spectator } } - protected override async Task BeginPlayingInternal(SpectatorState state) + protected override async Task BeginPlayingInternal(long? scoreToken, SpectatorState state) { if (!IsConnected.Value) return; @@ -56,7 +56,7 @@ namespace osu.Game.Online.Spectator try { - await connection.InvokeAsync(nameof(ISpectatorServer.BeginPlaySession), state); + await connection.InvokeAsync(nameof(ISpectatorServer.BeginPlaySession), scoreToken, state); } catch (Exception exception) { @@ -65,7 +65,7 @@ namespace osu.Game.Online.Spectator Debug.Assert(connector != null); await connector.Reconnect(); - await BeginPlayingInternal(state); + await BeginPlayingInternal(scoreToken, state); } // Exceptions can occur if, for instance, the locally played beatmap doesn't have a server-side counterpart. diff --git a/osu.Game/Online/Spectator/SpectatorClient.cs b/osu.Game/Online/Spectator/SpectatorClient.cs index c532cb266d..71b1896922 100644 --- a/osu.Game/Online/Spectator/SpectatorClient.cs +++ b/osu.Game/Online/Spectator/SpectatorClient.cs @@ -76,6 +76,7 @@ namespace osu.Game.Online.Spectator private IBeatmap? currentBeatmap; private Score? currentScore; + private long? currentScoreToken; private readonly Queue pendingFrameBundles = new Queue(); @@ -108,7 +109,7 @@ namespace osu.Game.Online.Spectator // re-send state in case it wasn't received if (IsPlaying) // TODO: this is likely sent out of order after a reconnect scenario. needs further consideration. - BeginPlayingInternal(currentState); + BeginPlayingInternal(currentScoreToken, currentState); } else { @@ -159,7 +160,7 @@ namespace osu.Game.Online.Spectator return Task.CompletedTask; } - public void BeginPlaying(GameplayState state, Score score, long? token) + public void BeginPlaying(long? scoreToken, GameplayState state, Score score) { // This schedule is only here to match the one below in `EndPlaying`. Schedule(() => @@ -175,12 +176,12 @@ namespace osu.Game.Online.Spectator currentState.Mods = score.ScoreInfo.Mods.Select(m => new APIMod(m)).ToArray(); currentState.State = SpectatedUserState.Playing; currentState.MaximumScoringValues = state.ScoreProcessor.MaximumScoringValues; - currentState.ScoreToken = token; currentBeatmap = state.Beatmap; currentScore = score; + currentScoreToken = scoreToken; - BeginPlayingInternal(currentState); + BeginPlayingInternal(currentScoreToken, currentState); }); } @@ -265,7 +266,7 @@ namespace osu.Game.Online.Spectator }); } - protected abstract Task BeginPlayingInternal(SpectatorState state); + protected abstract Task BeginPlayingInternal(long? scoreToken, SpectatorState state); protected abstract Task SendFramesInternal(FrameDataBundle bundle); diff --git a/osu.Game/Online/Spectator/SpectatorState.cs b/osu.Game/Online/Spectator/SpectatorState.cs index 34dbefd2a5..766b274e63 100644 --- a/osu.Game/Online/Spectator/SpectatorState.cs +++ b/osu.Game/Online/Spectator/SpectatorState.cs @@ -33,17 +33,14 @@ namespace osu.Game.Online.Spectator [Key(4)] public ScoringValues MaximumScoringValues { get; set; } - [Key(5)] - public long? ScoreToken { get; set; } - public bool Equals(SpectatorState other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; - return BeatmapID == other.BeatmapID && Mods.SequenceEqual(other.Mods) && RulesetID == other.RulesetID && State == other.State && ScoreToken == other.ScoreToken; + return BeatmapID == other.BeatmapID && Mods.SequenceEqual(other.Mods) && RulesetID == other.RulesetID && State == other.State; } - public override string ToString() => $"Beatmap:{BeatmapID} Mods:{string.Join(',', Mods)} Ruleset:{RulesetID} State:{State} Token:{ScoreToken}"; + public override string ToString() => $"Beatmap:{BeatmapID} Mods:{string.Join(',', Mods)} Ruleset:{RulesetID} State:{State}"; } } diff --git a/osu.Game/Screens/Play/SubmittingPlayer.cs b/osu.Game/Screens/Play/SubmittingPlayer.cs index 81c4e9ab2a..4c507f8c67 100644 --- a/osu.Game/Screens/Play/SubmittingPlayer.cs +++ b/osu.Game/Screens/Play/SubmittingPlayer.cs @@ -148,7 +148,7 @@ namespace osu.Game.Screens.Play realmBeatmap.LastPlayed = DateTimeOffset.Now; }); - spectatorClient.BeginPlaying(GameplayState, Score, token); + spectatorClient.BeginPlaying(token, GameplayState, Score); } public override bool OnExiting(ScreenExitEvent e) diff --git a/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs b/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs index a76f6c7052..1db35b3aaa 100644 --- a/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs +++ b/osu.Game/Tests/Visual/Spectator/TestSpectatorClient.cs @@ -126,7 +126,7 @@ namespace osu.Game.Tests.Visual.Spectator } } - protected override Task BeginPlayingInternal(SpectatorState state) + protected override Task BeginPlayingInternal(long? scoreToken, SpectatorState state) { // Track the local user's playing beatmap ID. Debug.Assert(state.BeatmapID != null); From 05b59498108925db6d2934c5ba96d29870728361 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Dec 2022 17:38:39 +0900 Subject: [PATCH 0994/2991] Use explicit casts --- osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs index 902aa72178..a729ef2cc8 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs @@ -4,7 +4,6 @@ #nullable disable using System; -using System.Linq; using System.Threading; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; @@ -104,9 +103,9 @@ namespace osu.Game.Overlays.Changelog { var fill = base.CreateHeader(); - var nestedFill = fill.Children.OfType().First(); + var nestedFill = (FillFlowContainer)fill.Child; - var buildDisplay = nestedFill.Children.OfType().First(); + var buildDisplay = (OsuHoverContainer)nestedFill.Child; buildDisplay.Scale = new Vector2(1.25f); buildDisplay.Action = null; From 58bf081096c0c7dbb1ee72cd4de8c7f022db7ca1 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 12 Dec 2022 10:52:55 +0100 Subject: [PATCH 0995/2991] Fix judgement counter not loading after first attempt in gameplay, Fix typo in Display --- .../Gameplay/TestSceneJudgementCounter.cs | 2 +- .../JudgementCounterDisplay.cs | 28 ++++++++----------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index 1cded54b3e..b3e6fefb68 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -98,7 +98,7 @@ namespace osu.Game.Tests.Visual.Gameplay public void TestChangeFlowDirection() { AddStep("Set direction vertical", () => counter.FlowDirection.Value = JudgementCounterDisplay.Flow.Vertical); - AddStep("Set direction horizontal", () => counter.FlowDirection.Value = JudgementCounterDisplay.Flow.Horizonal); + AddStep("Set direction horizontal", () => counter.FlowDirection.Value = JudgementCounterDisplay.Flow.Horizontal); } [Test] diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 3ac9e7fc55..b8e3c97bb5 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -33,32 +33,28 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter [Resolved] private JudgementTally tally { get; set; } = null!; - protected FillFlowContainer JudgementContainer = null!; + protected FillFlowContainer JudgementContainer; - [BackgroundDependencyLoader] - private void load() + public JudgementCounterDisplay() { + AutoSizeAxes = Axes.Both; InternalChild = JudgementContainer = new FillFlowContainer { Direction = getFlow(FlowDirection.Value), Spacing = new Vector2(10), AutoSizeAxes = Axes.Both }; - - foreach (var result in tally.Results) - { - JudgementContainer.Add(createCounter(result)); - } - } - - protected override void Update() - { - Size = JudgementContainer.Size; - base.Update(); } protected override void LoadComplete() { + //Adding this in "load" will cause it to not load in properly after the first beatmap attempt. Or after existing and reentering. + //this does not happen in tests, or in the skin editor component preview button. + foreach (var result in tally.Results) + { + JudgementContainer.Add(createCounter(result)); + } + base.LoadComplete(); FlowDirection.BindValueChanged(direction => @@ -125,7 +121,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { switch (flow) { - case Flow.Horizonal: + case Flow.Horizontal: return FillDirection.Horizontal; case Flow.Vertical: @@ -139,7 +135,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter //Used to hide default full option in FillDirection public enum Flow { - Horizonal, + Horizontal, Vertical } From 7b48c91fe255c838784939dc9295307ab9690a90 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 12 Dec 2022 18:56:43 +0900 Subject: [PATCH 0996/2991] Only show local results in multi-spectator results screen --- .../Spectate/MultiSpectatorPlayer.cs | 3 +++ .../Spectate/MultiSpectatorResultsScreen.cs | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorResultsScreen.cs diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs index 5a686ffa72..930bea4497 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs @@ -7,6 +7,7 @@ using osu.Framework.Audio; using osu.Game.Beatmaps; using osu.Game.Scoring; using osu.Game.Screens.Play; +using osu.Game.Screens.Ranking; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate { @@ -70,5 +71,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate clockAdjustmentsFromMods.BindAdjustments(gameplayClockContainer.AdjustmentsFromMods); return gameplayClockContainer; } + + protected override ResultsScreen CreateResults(ScoreInfo score) => new MultiSpectatorResultsScreen(score); } } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorResultsScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorResultsScreen.cs new file mode 100644 index 0000000000..fe3f02466d --- /dev/null +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorResultsScreen.cs @@ -0,0 +1,25 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable disable + +using System; +using System.Collections.Generic; +using osu.Game.Online.API; +using osu.Game.Scoring; +using osu.Game.Screens.Play; + +namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate +{ + public partial class MultiSpectatorResultsScreen : SpectatorResultsScreen + { + public MultiSpectatorResultsScreen(ScoreInfo score) + : base(score) + { + } + + protected override APIRequest FetchScores(Action> scoresCallback) => null; + + protected override APIRequest FetchNextPage(int direction, Action> scoresCallback) => null; + } +} From df94af44956e06f9c7cce10daef7794262f1b5ef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Dec 2022 19:22:09 +0900 Subject: [PATCH 0997/2991] Inline `ScoringValues` and make some more methods `private` inside `ScoreProcessor` --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 38 +++++++++++++++--- osu.Game/Scoring/ScoringValues.cs | 43 --------------------- 2 files changed, 32 insertions(+), 49 deletions(-) delete mode 100644 osu.Game/Scoring/ScoringValues.cs diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 5e05c7e2a6..b048566c8a 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -264,7 +264,7 @@ namespace osu.Game.Rulesets.Scoring private void updateScore() { Accuracy.Value = currentMaximumScoringValues.BaseScore > 0 ? (double)currentScoringValues.BaseScore / currentMaximumScoringValues.BaseScore : 1; - TotalScore.Value = ComputeScore(Mode.Value, currentScoringValues, maximumScoringValues); + TotalScore.Value = computeScore(Mode.Value, currentScoringValues, maximumScoringValues); } /// @@ -299,9 +299,9 @@ namespace osu.Game.Rulesets.Scoring if (!ruleset.RulesetInfo.Equals(scoreInfo.Ruleset)) throw new ArgumentException($"Unexpected score ruleset. Expected \"{ruleset.RulesetInfo.ShortName}\" but was \"{scoreInfo.Ruleset.ShortName}\"."); - ExtractScoringValues(scoreInfo, out var current, out var maximum); + extractScoringValues(scoreInfo, out var current, out var maximum); - return ComputeScore(mode, current, maximum); + return computeScore(mode, current, maximum); } /// @@ -312,7 +312,7 @@ namespace osu.Game.Rulesets.Scoring /// The maximum scoring values. /// The total score computed from the given scoring values. [Pure] - public long ComputeScore(ScoringMode mode, ScoringValues current, ScoringValues maximum) + private long computeScore(ScoringMode mode, ScoringValues current, ScoringValues maximum) { double accuracyRatio = maximum.BaseScore > 0 ? (double)current.BaseScore / maximum.BaseScore : 1; double comboRatio = maximum.MaxCombo > 0 ? (double)current.MaxCombo / maximum.MaxCombo : 1; @@ -470,14 +470,14 @@ namespace osu.Game.Rulesets.Scoring /// Consumers are expected to more accurately fill in the above values through external means. /// /// Ensure to fill in the maximum for use in - /// . + /// . /// /// /// The score to extract scoring values from. /// The "current" scoring values, representing the hit statistics as they appear. /// The "maximum" scoring values, representing the hit statistics as if the maximum hit result was attained each time. [Pure] - internal void ExtractScoringValues(ScoreInfo scoreInfo, out ScoringValues current, out ScoringValues maximum) + private void extractScoringValues(ScoreInfo scoreInfo, out ScoringValues current, out ScoringValues maximum) { extractScoringValues(scoreInfo.Statistics, out current, out maximum); current.MaxCombo = scoreInfo.MaxCombo; @@ -560,6 +560,32 @@ namespace osu.Game.Rulesets.Scoring base.Dispose(isDisposing); hitEvents.Clear(); } + + /// + /// Stores the required scoring data that fulfils the minimum requirements for a to calculate score. + /// + private struct ScoringValues + { + /// + /// The sum of all "basic" scoring values. See: and . + /// + public long BaseScore; + + /// + /// The sum of all "bonus" scoring values. See: and . + /// + public long BonusScore; + + /// + /// The highest achieved combo. + /// + public int MaxCombo; + + /// + /// The count of "basic" s. See: . + /// + public int CountBasicHitObjects; + } } public enum ScoringMode diff --git a/osu.Game/Scoring/ScoringValues.cs b/osu.Game/Scoring/ScoringValues.cs deleted file mode 100644 index 471067c9db..0000000000 --- a/osu.Game/Scoring/ScoringValues.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -#nullable disable - -using MessagePack; -using osu.Game.Rulesets.Judgements; -using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Scoring; - -namespace osu.Game.Scoring -{ - /// - /// Stores the required scoring data that fulfils the minimum requirements for a to calculate score. - /// - [MessagePackObject] - public struct ScoringValues - { - /// - /// The sum of all "basic" scoring values. See: and . - /// - [Key(0)] - public long BaseScore; - - /// - /// The sum of all "bonus" scoring values. See: and . - /// - [Key(1)] - public long BonusScore; - - /// - /// The highest achieved combo. - /// - [Key(2)] - public int MaxCombo; - - /// - /// The count of "basic" s. See: . - /// - [Key(3)] - public int CountBasicHitObjects; - } -} From 4d592184ca585119343806486573497d6c841aec Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 12 Dec 2022 11:53:07 +0100 Subject: [PATCH 0998/2991] temp cmt --- .../Visual/Gameplay/TestSceneJudgementCounter.cs | 7 +++++-- .../Play/HUD/JudgementCounter/JudgementCounter.cs | 5 +++-- .../Play/HUD/JudgementCounter/JudgementTally.cs | 11 ++++++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index b3e6fefb68..2e35e012f7 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -34,13 +34,16 @@ namespace osu.Game.Tests.Visual.Gameplay { var ruleset = CreateRuleset(); + var r = ruleset.CreateBeatmapConverter(Beatmap.Value.Beatmap); + + var n = r.Convert().BeatmapInfo.Ruleset.CreateInstance(); Debug.Assert(ruleset != null); - scoreProcessor = new ScoreProcessor(ruleset); + scoreProcessor = new ScoreProcessor(n); Child = new DependencyProvidingContainer { RelativeSizeAxes = Axes.Both, - CachedDependencies = new (Type, object)[] { (typeof(ScoreProcessor), scoreProcessor), (typeof(Ruleset), ruleset) }, + CachedDependencies = new (Type, object)[] { (typeof(ScoreProcessor), scoreProcessor), (typeof(Ruleset), n) }, Children = new Drawable[] { judgementTally = new JudgementTally(), diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs index d7bb8939e1..16cbfd6c7a 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -9,6 +9,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.UI; namespace osu.Game.Screens.Play.HUD.JudgementCounter { @@ -29,7 +30,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter private JudgementRollingCounter counter = null!; [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OsuColour colours, DrawableRuleset ruleset) { AutoSizeAxes = Axes.Both; InternalChild = flowContainer = new FillFlowContainer @@ -44,7 +45,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter ResultName = new OsuSpriteText { Font = OsuFont.Numeric.With(size: 8), - Text = Result.ResultInfo.Displayname + Text = ruleset.Ruleset.GetDisplayNameForHitResult(Result.ResultInfo.Type) } } }; diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs index e11b09d5a7..b03f71a579 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs @@ -7,6 +7,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Rulesets; using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.HUD.JudgementCounter @@ -21,7 +22,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter [BackgroundDependencyLoader] private void load(IBindable working) { - foreach (var result in working.Value.BeatmapInfo.Ruleset.CreateInstance().GetHitResults()) + foreach (var result in getRuleset(working).GetHitResults()) { Results.Add(new JudgementCounterInfo { @@ -31,6 +32,14 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter } } + private Ruleset getRuleset(IBindable working) + { + var ruleset = working.Value.BeatmapInfo.Ruleset.CreateInstance(); + var converter = ruleset.RulesetInfo.CreateInstance().CreateBeatmapConverter(working.Value.Beatmap); + + return converter.CanConvert() ? converter.Convert().BeatmapInfo.Ruleset.CreateInstance() : ruleset; + } + protected override void LoadComplete() { base.LoadComplete(); From 37a075632163e6acea5aa7125a8bceaadebbd0f8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 12 Dec 2022 14:38:24 +0300 Subject: [PATCH 0999/2991] Add tests --- .../UserInterface/TestSceneButtonsInput.cs | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneButtonsInput.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneButtonsInput.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneButtonsInput.cs new file mode 100644 index 0000000000..b8bcf583bf --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneButtonsInput.cs @@ -0,0 +1,92 @@ +// 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.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Game.Overlays.Settings; +using NUnit.Framework; +using osuTK; +using osu.Game.Overlays; +using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Graphics.UserInterface; +using osu.Framework.Allocation; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public partial class TestSceneButtonsInput : OsuManualInputManagerTestScene + { + private const int width = 500; + + [Cached] + private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); + + private readonly SettingsButton settingsButton; + private readonly RoundedButton roundedButton; + private readonly ShearedButton shearedButton; + + public TestSceneButtonsInput() + { + Add(new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + Width = 500, + Spacing = new Vector2(0, 5), + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + settingsButton = new SettingsButton + { + Enabled = { Value = true }, + Text = "Settings button" + }, + roundedButton = new RoundedButton + { + RelativeSizeAxes = Axes.X, + Enabled = { Value = true }, + Text = "Rounded button" + }, + shearedButton = new ShearedButton(width) + { + Text = "Sheared button", + LighterColour = Colour4.FromHex("#FFFFFF"), + DarkerColour = Colour4.FromHex("#FFCC22"), + TextColour = Colour4.Black, + Height = 40, + Enabled = { Value = true }, + Padding = new MarginPadding(0) + } + } + }); + } + + [Test] + public void TestSettingsButtonInput() + { + AddStep("Move cursor to button", () => InputManager.MoveMouseTo(settingsButton)); + AddAssert("Button is hovered", () => settingsButton.IsHovered); + AddStep("Move cursor to padded area", () => InputManager.MoveMouseTo(settingsButton.ScreenSpaceDrawQuad.TopLeft + new Vector2(SettingsPanel.CONTENT_MARGINS / 2f, 10))); + AddAssert("Cursor within a button", () => settingsButton.ScreenSpaceDrawQuad.Contains(InputManager.CurrentState.Mouse.Position)); + AddAssert("Button is not hovered", () => !settingsButton.IsHovered); + } + + [Test] + public void TestRoundedButtonInput() + { + AddStep("Move cursor to button", () => InputManager.MoveMouseTo(roundedButton)); + AddAssert("Button is hovered", () => roundedButton.IsHovered); + AddStep("Move cursor to corner", () => InputManager.MoveMouseTo(roundedButton.ScreenSpaceDrawQuad.TopLeft + Vector2.One)); + AddAssert("Cursor within a button", () => roundedButton.ScreenSpaceDrawQuad.Contains(InputManager.CurrentState.Mouse.Position)); + AddAssert("Button is not hovered", () => !roundedButton.IsHovered); + } + + [Test] + public void TestShearedButtonInput() + { + AddStep("Move cursor to button", () => InputManager.MoveMouseTo(shearedButton)); + AddAssert("Button is hovered", () => shearedButton.IsHovered); + AddStep("Move cursor to corner", () => InputManager.MoveMouseTo(shearedButton.ScreenSpaceDrawQuad.TopLeft + Vector2.One)); + AddAssert("Cursor within a button", () => shearedButton.ScreenSpaceDrawQuad.Contains(InputManager.CurrentState.Mouse.Position)); + AddAssert("Button is not hovered", () => !shearedButton.IsHovered); + } + } +} From 7e39f171fbd787339e59ed0ceee38f6e51be4654 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 12 Dec 2022 14:40:38 +0300 Subject: [PATCH 1000/2991] Fix OsuButton input receiving --- osu.Game/Graphics/UserInterface/OsuButton.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index fa61b06cff..70f76fb453 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -13,6 +11,7 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Game.Graphics.Sprites; +using osuTK; using osuTK.Graphics; namespace osu.Game.Graphics.UserInterface @@ -66,6 +65,8 @@ namespace osu.Game.Graphics.UserInterface protected override Container Content { get; } + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Content.ReceivePositionalInputAt(screenSpacePos); + protected Box Hover; protected Box Background; protected SpriteText SpriteText; @@ -115,7 +116,7 @@ namespace osu.Game.Graphics.UserInterface }); if (hoverSounds.HasValue) - AddInternal(new HoverClickSounds(hoverSounds.Value) { Enabled = { BindTarget = Enabled } }); + Add(new HoverClickSounds(hoverSounds.Value) { Enabled = { BindTarget = Enabled } }); } [BackgroundDependencyLoader] From d2b3533356d22d3ac0350e3c8f3eb08a561413de Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 12 Dec 2022 14:42:50 +0300 Subject: [PATCH 1001/2991] Fix OsuClickableContainer input receiving --- .../Graphics/Containers/OsuClickableContainer.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuClickableContainer.cs b/osu.Game/Graphics/Containers/OsuClickableContainer.cs index 4729ddf1a8..945ebbb02d 100644 --- a/osu.Game/Graphics/Containers/OsuClickableContainer.cs +++ b/osu.Game/Graphics/Containers/OsuClickableContainer.cs @@ -1,14 +1,13 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; +using osuTK; namespace osu.Game.Graphics.Containers { @@ -18,6 +17,8 @@ namespace osu.Game.Graphics.Containers private readonly Container content = new Container { RelativeSizeAxes = Axes.Both }; + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Content.ReceivePositionalInputAt(screenSpacePos); + protected override Container Content => content; protected virtual HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverClickSounds(sampleSet) { Enabled = { BindTarget = Enabled } }; @@ -38,11 +39,8 @@ namespace osu.Game.Graphics.Containers content.AutoSizeAxes = AutoSizeAxes; } - InternalChildren = new Drawable[] - { - content, - CreateHoverSounds(sampleSet) - }; + AddInternal(content); + Add(CreateHoverSounds(sampleSet)); } } } From b0d475cd8b2f641d5cece506ad05a46b4552ae71 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 12 Dec 2022 14:57:07 +0300 Subject: [PATCH 1002/2991] CI fix --- osu.Game/Graphics/UserInterface/OsuButton.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index 70f76fb453..9216b41170 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -23,12 +23,8 @@ namespace osu.Game.Graphics.UserInterface { public LocalisableString Text { - get => SpriteText?.Text ?? default; - set - { - if (SpriteText != null) - SpriteText.Text = value; - } + get => SpriteText.Text; + set => SpriteText.Text = value; } private Color4? backgroundColour; From 890dd9cd061d34eaf693ad81c219937324f7192f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 12 Dec 2022 15:10:03 +0300 Subject: [PATCH 1003/2991] Fix input doesn't take original drawable modifications into account --- .../UserInterface/TestSceneButtonsInput.cs | 37 +++++++++++++++++++ .../Containers/OsuClickableContainer.cs | 2 +- osu.Game/Graphics/UserInterface/OsuButton.cs | 2 +- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneButtonsInput.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneButtonsInput.cs index b8bcf583bf..985f613b63 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneButtonsInput.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneButtonsInput.cs @@ -10,6 +10,10 @@ using osu.Game.Overlays; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Graphics.UserInterface; using osu.Framework.Allocation; +using osu.Game.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osuTK.Graphics; +using osu.Game.Graphics.Sprites; namespace osu.Game.Tests.Visual.UserInterface { @@ -21,6 +25,7 @@ namespace osu.Game.Tests.Visual.UserInterface private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); private readonly SettingsButton settingsButton; + private readonly OsuClickableContainer clickableContainer; private readonly RoundedButton roundedButton; private readonly ShearedButton shearedButton; @@ -34,6 +39,28 @@ namespace osu.Game.Tests.Visual.UserInterface Direction = FillDirection.Vertical, Children = new Drawable[] { + clickableContainer = new OsuClickableContainer + { + RelativeSizeAxes = Axes.X, + Height = 40, + Enabled = { Value = true }, + Masking = true, + CornerRadius = 20, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Red + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Text = "Rounded clickable container" + } + } + }, settingsButton = new SettingsButton { Enabled = { Value = true }, @@ -88,5 +115,15 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("Cursor within a button", () => shearedButton.ScreenSpaceDrawQuad.Contains(InputManager.CurrentState.Mouse.Position)); AddAssert("Button is not hovered", () => !shearedButton.IsHovered); } + + [Test] + public void TestRoundedClickableContainerInput() + { + AddStep("Move cursor to button", () => InputManager.MoveMouseTo(clickableContainer)); + AddAssert("Button is hovered", () => clickableContainer.IsHovered); + AddStep("Move cursor to corner", () => InputManager.MoveMouseTo(clickableContainer.ScreenSpaceDrawQuad.TopLeft + Vector2.One)); + AddAssert("Cursor within a button", () => clickableContainer.ScreenSpaceDrawQuad.Contains(InputManager.CurrentState.Mouse.Position)); + AddAssert("Button is not hovered", () => !clickableContainer.IsHovered); + } } } diff --git a/osu.Game/Graphics/Containers/OsuClickableContainer.cs b/osu.Game/Graphics/Containers/OsuClickableContainer.cs index 945ebbb02d..ecae456e88 100644 --- a/osu.Game/Graphics/Containers/OsuClickableContainer.cs +++ b/osu.Game/Graphics/Containers/OsuClickableContainer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Graphics.Containers private readonly Container content = new Container { RelativeSizeAxes = Axes.Both }; - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Content.ReceivePositionalInputAt(screenSpacePos); + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => base.ReceivePositionalInputAt(screenSpacePos) && Content.ReceivePositionalInputAt(screenSpacePos); protected override Container Content => content; diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index 9216b41170..00cd3b13e5 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -61,7 +61,7 @@ namespace osu.Game.Graphics.UserInterface protected override Container Content { get; } - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Content.ReceivePositionalInputAt(screenSpacePos); + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => base.ReceivePositionalInputAt(screenSpacePos) && Content.ReceivePositionalInputAt(screenSpacePos); protected Box Hover; protected Box Background; From 8efe7528e3266d08575cf2985ecfd76647e9949e Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 12 Dec 2022 15:10:10 +0100 Subject: [PATCH 1004/2991] change ruleset source to avoid issues with converted beatmaps --- .../Gameplay/TestSceneJudgementCounter.cs | 9 +++------ .../HUD/JudgementCounter/JudgementCounter.cs | 10 +++++----- .../JudgementCounterDisplay.cs | 12 ++++++------ .../JudgementCounter/JudgementCounterInfo.cs | 3 +-- .../HUD/JudgementCounter/JudgementTally.cs | 19 +++++-------------- 5 files changed, 20 insertions(+), 33 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index 2e35e012f7..7a54f47c46 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -34,16 +34,13 @@ namespace osu.Game.Tests.Visual.Gameplay { var ruleset = CreateRuleset(); - var r = ruleset.CreateBeatmapConverter(Beatmap.Value.Beatmap); - - var n = r.Convert().BeatmapInfo.Ruleset.CreateInstance(); Debug.Assert(ruleset != null); - scoreProcessor = new ScoreProcessor(n); + scoreProcessor = new ScoreProcessor(ruleset); Child = new DependencyProvidingContainer { RelativeSizeAxes = Axes.Both, - CachedDependencies = new (Type, object)[] { (typeof(ScoreProcessor), scoreProcessor), (typeof(Ruleset), n) }, + CachedDependencies = new (Type, object)[] { (typeof(ScoreProcessor), scoreProcessor), (typeof(Ruleset), ruleset) }, Children = new Drawable[] { judgementTally = new JudgementTally(), @@ -130,7 +127,7 @@ namespace osu.Game.Tests.Visual.Gameplay private int hiddenCount() { - var num = counter.JudgementContainer.Children.OfType().First(child => child.Result.ResultInfo.Type == HitResult.LargeTickHit); + var num = counter.JudgementContainer.Children.OfType().First(child => child.Result.Type == HitResult.LargeTickHit); return num.Result.ResultCount.Value; } diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs index 16cbfd6c7a..a4ebd80e9f 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -8,8 +8,8 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets; using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.UI; namespace osu.Game.Screens.Play.HUD.JudgementCounter { @@ -30,7 +30,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter private JudgementRollingCounter counter = null!; [BackgroundDependencyLoader] - private void load(OsuColour colours, DrawableRuleset ruleset) + private void load(OsuColour colours, IBindable ruleset) { AutoSizeAxes = Axes.Both; InternalChild = flowContainer = new FillFlowContainer @@ -45,16 +45,16 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter ResultName = new OsuSpriteText { Font = OsuFont.Numeric.With(size: 8), - Text = ruleset.Ruleset.GetDisplayNameForHitResult(Result.ResultInfo.Type) + Text = ruleset.Value.CreateInstance().GetDisplayNameForHitResult(Result.Type) } } }; - var result = Result.ResultInfo.Type; + var result = Result.Type; if (result.IsBasic()) { - Colour = colours.ForHitResult(Result.ResultInfo.Type); + Colour = colours.ForHitResult(Result.Type); return; } diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index b8e3c97bb5..bcbf8198fb 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -48,7 +48,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter protected override void LoadComplete() { - //Adding this in "load" will cause it to not load in properly after the first beatmap attempt. Or after existing and reentering. + //Adding this in "load" will cause the component to not load in properly after the first beatmap attempt. Or after existing and reentering. //this does not happen in tests, or in the skin editor component preview button. foreach (var result in tally.Results) { @@ -66,7 +66,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { counter.Direction.Value = getFlow(direction.NewValue); } - }); + }, true); Mode.BindValueChanged(_ => updateCounter(), true); ShowMax.BindValueChanged(value => { @@ -89,19 +89,19 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter switch (Mode.Value) { case DisplayMode.Simple: - foreach (var counter in counters.Where(counter => counter.Result.ResultInfo.Type.IsBasic())) + foreach (var counter in counters.Where(counter => counter.Result.Type.IsBasic())) counter.Show(); - foreach (var counter in counters.Where(counter => !counter.Result.ResultInfo.Type.IsBasic())) + foreach (var counter in counters.Where(counter => !counter.Result.Type.IsBasic())) counter.Hide(); break; case DisplayMode.Normal: - foreach (var counter in counters.Where(counter => !counter.Result.ResultInfo.Type.IsBonus())) + foreach (var counter in counters.Where(counter => !counter.Result.Type.IsBonus())) counter.Show(); - foreach (var counter in counters.Where(counter => counter.Result.ResultInfo.Type.IsBonus())) + foreach (var counter in counters.Where(counter => counter.Result.Type.IsBonus())) counter.Hide(); break; diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs index 45f89c30d2..0237981db1 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs @@ -2,14 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Bindables; -using osu.Framework.Localisation; using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.HUD.JudgementCounter { public struct JudgementCounterInfo { - public (HitResult Type, LocalisableString Displayname) ResultInfo { get; set; } + public HitResult Type { get; set; } public BindableInt ResultCount { get; set; } } diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs index b03f71a579..a88b18ff6f 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs @@ -6,7 +6,6 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; -using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Scoring; @@ -20,39 +19,31 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter public List Results = new List(); [BackgroundDependencyLoader] - private void load(IBindable working) + private void load(IBindable ruleset) { - foreach (var result in getRuleset(working).GetHitResults()) + foreach (var result in ruleset.Value.CreateInstance().GetHitResults()) { Results.Add(new JudgementCounterInfo { - ResultInfo = (result.result, result.displayName), + Type = result.result, ResultCount = new BindableInt() }); } } - private Ruleset getRuleset(IBindable working) - { - var ruleset = working.Value.BeatmapInfo.Ruleset.CreateInstance(); - var converter = ruleset.RulesetInfo.CreateInstance().CreateBeatmapConverter(working.Value.Beatmap); - - return converter.CanConvert() ? converter.Convert().BeatmapInfo.Ruleset.CreateInstance() : ruleset; - } - protected override void LoadComplete() { base.LoadComplete(); scoreProcessor.NewJudgement += judgement => { - foreach (JudgementCounterInfo result in Results.Where(result => result.ResultInfo.Type == judgement.Type)) + foreach (JudgementCounterInfo result in Results.Where(result => result.Type == judgement.Type)) { result.ResultCount.Value++; } }; scoreProcessor.JudgementReverted += judgement => { - foreach (JudgementCounterInfo result in Results.Where(result => result.ResultInfo.Type == judgement.Type)) + foreach (JudgementCounterInfo result in Results.Where(result => result.Type == judgement.Type)) { result.ResultCount.Value--; } From 99d83315c11a946472f9dbeb001f55ad74970b2f Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 12 Dec 2022 15:10:45 +0100 Subject: [PATCH 1005/2991] change settings order --- .../Play/HUD/JudgementCounter/JudgementCounterDisplay.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index bcbf8198fb..4880314f29 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -18,6 +18,9 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { public bool UsesFixedAnchor { get; set; } + [SettingSource("Display mode")] + public Bindable Mode { get; set; } = new Bindable(); + [SettingSource("Counter direction")] public Bindable FlowDirection { get; set; } = new Bindable(); @@ -27,9 +30,6 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter [SettingSource("Show max judgement")] public BindableBool ShowMax { get; set; } = new BindableBool(true); - [SettingSource("Display mode")] - public Bindable Mode { get; set; } = new Bindable(); - [Resolved] private JudgementTally tally { get; set; } = null!; From edb46e422c20983ae9599a394244c01787282806 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 12 Dec 2022 15:15:30 +0100 Subject: [PATCH 1006/2991] Fix "using" name in HUD overlay --- osu.Game/Screens/Play/HUDOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 816b8b2543..89d02e5fb0 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -24,7 +24,7 @@ using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.HUD.ClicksPerSecond; using osu.Game.Skinning; using osuTK; -using JudgementTally = osu.Game.Screens.Play.HUD.JudgementCounter.JudgementTally; +using osu.Game.Screens.Play.HUD.JudgementCounter; namespace osu.Game.Screens.Play { From 15bd82add819fb7ee61a2b2c785b8153094493de Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 12 Dec 2022 18:24:49 +0300 Subject: [PATCH 1007/2991] Fix DrawableUsername being affected --- osu.Game/Overlays/Chat/DrawableUsername.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs index 7026d519a5..6bae498a6c 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -30,7 +30,7 @@ namespace osu.Game.Overlays.Chat public Color4 AccentColour { get; } public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => - Child.ReceivePositionalInputAt(screenSpacePos); + colouredDrawable.ReceivePositionalInputAt(screenSpacePos); public float FontSize { @@ -87,13 +87,13 @@ namespace osu.Game.Overlays.Chat { AccentColour = default_colours[user.Id % default_colours.Length]; - Child = colouredDrawable = drawableText; + Add(colouredDrawable = drawableText); } else { AccentColour = Color4Extensions.FromHex(user.Colour); - Child = new Container + Add(new Container { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, @@ -127,7 +127,7 @@ namespace osu.Game.Overlays.Chat } } } - }; + }); } } From 0dd4e0cf940a5650f013bc0845aee59303b9e238 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Mon, 12 Dec 2022 21:18:01 -0500 Subject: [PATCH 1008/2991] hide cursor in catch --- ...tchRelaxCursorContainer.cs => CatchCursorContainer.cs} | 4 ++-- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 8 +------- 2 files changed, 3 insertions(+), 9 deletions(-) rename osu.Game.Rulesets.Catch/UI/{CatchRelaxCursorContainer.cs => CatchCursorContainer.cs} (78%) diff --git a/osu.Game.Rulesets.Catch/UI/CatchRelaxCursorContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchCursorContainer.cs similarity index 78% rename from osu.Game.Rulesets.Catch/UI/CatchRelaxCursorContainer.cs rename to osu.Game.Rulesets.Catch/UI/CatchCursorContainer.cs index f30b8f0f36..4ae61ef8c7 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchRelaxCursorContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchCursorContainer.cs @@ -6,9 +6,9 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Catch.UI { - public partial class CatchRelaxCursorContainer : GameplayCursorContainer + public partial class CatchCursorContainer : GameplayCursorContainer { - // Just hide the cursor in relax. + // Just hide the cursor. // The main goal here is to show that we have a cursor so the game never shows the global one. protected override Drawable CreateCursor() => Empty(); } diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 184ff38cc6..2c7b52b1b5 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -52,13 +52,7 @@ namespace osu.Game.Rulesets.Catch.UI this.difficulty = difficulty; } - protected override GameplayCursorContainer CreateCursor() - { - if (Mods != null && Mods.Any(m => m is ModRelax)) - return new CatchRelaxCursorContainer(); - - return base.CreateCursor(); - } + protected override GameplayCursorContainer CreateCursor() => new CatchCursorContainer(); [BackgroundDependencyLoader] private void load() From ad7554cc7d60b3449433abd1df84e07b75d0a6cb Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Tue, 13 Dec 2022 16:15:14 +0900 Subject: [PATCH 1009/2991] Allow keeping stream open after encoding scores --- osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs index 63094c5548..5452e4b9eb 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs @@ -53,9 +53,9 @@ namespace osu.Game.Scoring.Legacy throw new ArgumentException(@"Only scores in the osu, taiko, catch, or mania rulesets can be encoded to the legacy score format.", nameof(score)); } - public void Encode(Stream stream) + public void Encode(Stream stream, bool leaveOpen = false) { - using (SerializationWriter sw = new SerializationWriter(stream)) + using (SerializationWriter sw = new SerializationWriter(stream, leaveOpen)) { sw.Write((byte)(score.ScoreInfo.Ruleset.OnlineID)); sw.Write(LATEST_VERSION); From 775952380fe2927ed901b5248220598bd6fb3be2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Dec 2022 18:57:17 +0900 Subject: [PATCH 1010/2991] Remove unused using statements --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 2c7b52b1b5..6167ee53f6 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -3,14 +3,12 @@ #nullable disable -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawables; using osu.Game.Rulesets.Judgements; -using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI.Scrolling; From cf2719d4c0661bf2f0b34e668069ec8f5bf660ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Dec 2022 23:56:11 +0900 Subject: [PATCH 1011/2991] Convert `batchImport` parameter to parameters class to allow further import configuration --- .../Database/BeatmapImporterTests.cs | 2 +- ...eneOnlinePlayBeatmapAvailabilityTracker.cs | 4 +-- osu.Game.Tests/Skins/IO/ImportSkinTest.cs | 3 +- osu.Game/Beatmaps/BeatmapImporter.cs | 6 ++-- osu.Game/Beatmaps/BeatmapManager.cs | 26 +++++++++++++++-- .../Database/RealmArchiveModelImporter.cs | 29 ++++++++++--------- osu.Game/Scoring/ScoreImporter.cs | 4 +-- osu.Game/Scoring/ScoreManager.cs | 4 +-- osu.Game/Skinning/SkinManager.cs | 10 +++++-- 9 files changed, 57 insertions(+), 31 deletions(-) diff --git a/osu.Game.Tests/Database/BeatmapImporterTests.cs b/osu.Game.Tests/Database/BeatmapImporterTests.cs index 56964aa8b2..cbaa7bf972 100644 --- a/osu.Game.Tests/Database/BeatmapImporterTests.cs +++ b/osu.Game.Tests/Database/BeatmapImporterTests.cs @@ -1052,7 +1052,7 @@ namespace osu.Game.Tests.Database { string? temp = path ?? TestResources.GetTestBeatmapForImport(virtualTrack); - var importedSet = await importer.Import(new ImportTask(temp), batchImport); + var importedSet = await importer.Import(new ImportTask(temp), new ImportParameters { Batch = batchImport }); Assert.NotNull(importedSet); Debug.Assert(importedSet != null); diff --git a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs index e1d8e08c5e..585fd516bd 100644 --- a/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs +++ b/osu.Game.Tests/Online/TestSceneOnlinePlayBeatmapAvailabilityTracker.cs @@ -226,12 +226,12 @@ namespace osu.Game.Tests.Online this.testBeatmapManager = testBeatmapManager; } - public override Live ImportModel(BeatmapSetInfo item, ArchiveReader archive = null, bool batchImport = false, CancellationToken cancellationToken = default) + public override Live ImportModel(BeatmapSetInfo item, ArchiveReader archive = null, ImportParameters parameters = default, CancellationToken cancellationToken = default) { if (!testBeatmapManager.AllowImport.Wait(TimeSpan.FromSeconds(10), cancellationToken)) throw new TimeoutException("Timeout waiting for import to be allowed."); - return (testBeatmapManager.CurrentImport = base.ImportModel(item, archive, batchImport, cancellationToken)); + return (testBeatmapManager.CurrentImport = base.ImportModel(item, archive, parameters, cancellationToken)); } } } diff --git a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs index 5c20f46787..f90c983627 100644 --- a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs +++ b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs @@ -12,6 +12,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Extensions; using osu.Framework.Platform; +using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Extensions; using osu.Game.IO; @@ -360,7 +361,7 @@ namespace osu.Game.Tests.Skins.IO private async Task> loadSkinIntoOsu(OsuGameBase osu, ImportTask import, bool batchImport = false) { var skinManager = osu.Dependencies.Get(); - return await skinManager.Import(import, batchImport); + return await skinManager.Import(import, new ImportParameters { Batch = batchImport }); } } } diff --git a/osu.Game/Beatmaps/BeatmapImporter.cs b/osu.Game/Beatmaps/BeatmapImporter.cs index bcb1d7f961..303e85b83a 100644 --- a/osu.Game/Beatmaps/BeatmapImporter.cs +++ b/osu.Game/Beatmaps/BeatmapImporter.cs @@ -203,10 +203,10 @@ namespace osu.Game.Beatmaps } } - protected override void PostImport(BeatmapSetInfo model, Realm realm, bool batchImport) + protected override void PostImport(BeatmapSetInfo model, Realm realm, ImportParameters parameters) { - base.PostImport(model, realm, batchImport); - ProcessBeatmap?.Invoke((model, batchImport)); + base.PostImport(model, realm, parameters); + ProcessBeatmap?.Invoke((model, parameters.Batch)); } private void validateOnlineIds(BeatmapSetInfo beatmapSet, Realm realm) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 965cc43815..e288239d74 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -460,11 +460,11 @@ namespace osu.Game.Beatmaps public Task>> Import(ProgressNotification notification, params ImportTask[] tasks) => beatmapImporter.Import(notification, tasks); - public Task?> Import(ImportTask task, bool batchImport = false, CancellationToken cancellationToken = default) => - beatmapImporter.Import(task, batchImport, cancellationToken); + public Task?> Import(ImportTask task, ImportParameters parameters = default, CancellationToken cancellationToken = default) => + beatmapImporter.Import(task, parameters, cancellationToken); public Live? Import(BeatmapSetInfo item, ArchiveReader? archive = null, CancellationToken cancellationToken = default) => - beatmapImporter.ImportModel(item, archive, false, cancellationToken); + beatmapImporter.ImportModel(item, archive, default, cancellationToken); public IEnumerable HandledExtensions => beatmapImporter.HandledExtensions; @@ -526,4 +526,24 @@ namespace osu.Game.Beatmaps public override string HumanisedModelName => "beatmap"; } + + public struct ImportParameters + { + /// + /// Whether this import is part of a larger batch. + /// + /// + /// May skip intensive pre-import checks in favour of faster processing. + /// + /// More specifically, imports will be skipped before they begin, given an existing model matches on hash and filenames. Should generally only be used for large batch imports, as it may defy user expectations when updating an existing model. + /// + /// Will also change scheduling behaviour to run at a lower priority. + /// + public bool Batch { get; set; } + + /// + /// Whether this import should use hard links rather than file copy operations if available. + /// + public bool PreferHardLinks { get; set; } + } } diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index 0286815569..41e491bce6 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -13,6 +13,7 @@ using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Framework.Threading; +using osu.Game.Beatmaps; using osu.Game.Extensions; using osu.Game.IO.Archives; using osu.Game.Models; @@ -115,7 +116,7 @@ namespace osu.Game.Database try { - var model = await Import(task, isBatchImport, notification.CancellationToken).ConfigureAwait(false); + var model = await Import(task, new ImportParameters { Batch = isBatchImport }, notification.CancellationToken).ConfigureAwait(false); lock (imported) { @@ -176,16 +177,16 @@ namespace osu.Game.Database /// Note that this bypasses the UI flow and should only be used for special cases or testing. /// /// The containing data about the to import. - /// Whether this import is part of a larger batch. + /// Parameters to further configure the import process. /// An optional cancellation token. /// The imported model, if successful. - public async Task?> Import(ImportTask task, bool batchImport = false, CancellationToken cancellationToken = default) + public async Task?> Import(ImportTask task, ImportParameters parameters = default, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); Live? import; using (ArchiveReader reader = task.GetReader()) - import = await importFromArchive(reader, batchImport, cancellationToken).ConfigureAwait(false); + import = await importFromArchive(reader, parameters, cancellationToken).ConfigureAwait(false); // We may or may not want to delete the file depending on where it is stored. // e.g. reconstructing/repairing database with items from default storage. @@ -211,9 +212,9 @@ namespace osu.Game.Database /// This method also handled queueing the import task on a relevant import thread pool. /// /// The archive to be imported. - /// Whether this import is part of a larger batch. + /// Parameters to further configure the import process. /// An optional cancellation token. - private async Task?> importFromArchive(ArchiveReader archive, bool batchImport = false, CancellationToken cancellationToken = default) + private async Task?> importFromArchive(ArchiveReader archive, ImportParameters parameters = default, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); @@ -236,10 +237,10 @@ namespace osu.Game.Database return null; } - var scheduledImport = Task.Factory.StartNew(() => ImportModel(model, archive, batchImport, cancellationToken), + var scheduledImport = Task.Factory.StartNew(() => ImportModel(model, archive, parameters, cancellationToken), cancellationToken, TaskCreationOptions.HideScheduler, - batchImport ? import_scheduler_batch : import_scheduler); + parameters.Batch ? import_scheduler_batch : import_scheduler); return await scheduledImport.ConfigureAwait(false); } @@ -249,15 +250,15 @@ namespace osu.Game.Database /// /// The model to be imported. /// An optional archive to use for model population. - /// If true, imports will be skipped before they begin, given an existing model matches on hash and filenames. Should generally only be used for large batch imports, as it may defy user expectations when updating an existing model. + /// Parameters to further configure the import process. /// An optional cancellation token. - public virtual Live? ImportModel(TModel item, ArchiveReader? archive = null, bool batchImport = false, CancellationToken cancellationToken = default) => Realm.Run(realm => + public virtual Live? ImportModel(TModel item, ArchiveReader? archive = null, ImportParameters parameters = default, CancellationToken cancellationToken = default) => Realm.Run(realm => { cancellationToken.ThrowIfCancellationRequested(); TModel? existing; - if (batchImport && archive != null) + if (parameters.Batch && archive != null) { // this is a fast bail condition to improve large import performance. item.Hash = computeHashFast(archive); @@ -358,7 +359,7 @@ namespace osu.Game.Database // import to store realm.Add(item); - PostImport(item, realm, batchImport); + PostImport(item, realm, parameters); transaction.Commit(); } @@ -493,8 +494,8 @@ namespace osu.Game.Database /// /// The model prepared for import. /// The current realm context. - /// Whether the import was part of a batch. - protected virtual void PostImport(TModel model, Realm realm, bool batchImport) + /// Parameters to further configure the import process. + protected virtual void PostImport(TModel model, Realm realm, ImportParameters parameters) { } diff --git a/osu.Game/Scoring/ScoreImporter.cs b/osu.Game/Scoring/ScoreImporter.cs index 5c8e21014c..4656f02897 100644 --- a/osu.Game/Scoring/ScoreImporter.cs +++ b/osu.Game/Scoring/ScoreImporter.cs @@ -145,9 +145,9 @@ namespace osu.Game.Scoring #pragma warning restore CS0618 } - protected override void PostImport(ScoreInfo model, Realm realm, bool batchImport) + protected override void PostImport(ScoreInfo model, Realm realm, ImportParameters parameters) { - base.PostImport(model, realm, batchImport); + base.PostImport(model, realm, parameters); var userRequest = new GetUserRequest(model.RealmUser.Username); diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index b2944ad219..a57db0eccf 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -179,8 +179,8 @@ namespace osu.Game.Scoring public Task> ImportAsUpdate(ProgressNotification notification, ImportTask task, ScoreInfo original) => scoreImporter.ImportAsUpdate(notification, task, original); - public Live Import(ScoreInfo item, ArchiveReader archive = null, bool batchImport = false, CancellationToken cancellationToken = default) => - scoreImporter.ImportModel(item, archive, batchImport, cancellationToken); + public Live Import(ScoreInfo item, ArchiveReader archive = null, ImportParameters parameters = default, CancellationToken cancellationToken = default) => + scoreImporter.ImportModel(item, archive, parameters, cancellationToken); /// /// Populates the for a given . diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index 4a5277f3bf..40c43563b2 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -22,6 +22,7 @@ using osu.Framework.Testing; using osu.Framework.Threading; using osu.Framework.Utils; using osu.Game.Audio; +using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.IO; using osu.Game.Overlays.Notifications; @@ -274,11 +275,14 @@ namespace osu.Game.Skinning public IEnumerable HandledExtensions => skinImporter.HandledExtensions; - public Task>> Import(ProgressNotification notification, params ImportTask[] tasks) => skinImporter.Import(notification, tasks); + public Task>> Import(ProgressNotification notification, params ImportTask[] tasks) => + skinImporter.Import(notification, tasks); - public Task> ImportAsUpdate(ProgressNotification notification, ImportTask task, SkinInfo original) => skinImporter.ImportAsUpdate(notification, task, original); + public Task> ImportAsUpdate(ProgressNotification notification, ImportTask task, SkinInfo original) => + skinImporter.ImportAsUpdate(notification, task, original); - public Task> Import(ImportTask task, bool batchImport = false, CancellationToken cancellationToken = default) => skinImporter.Import(task, batchImport, cancellationToken); + public Task> Import(ImportTask task, ImportParameters parameters = default, CancellationToken cancellationToken = default) => + skinImporter.Import(task, parameters, cancellationToken); #endregion From 1d4230993dfceca084d0195318a336622d386a94 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Dec 2022 00:56:27 +0900 Subject: [PATCH 1012/2991] Hook up parameter with `RealmFileStore` to complete the chain --- .../Database/RealmArchiveModelImporter.cs | 2 +- osu.Game/Database/RealmFileStore.cs | 110 +++++++++--------- 2 files changed, 59 insertions(+), 53 deletions(-) diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index 41e491bce6..1f9debc46f 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -304,7 +304,7 @@ namespace osu.Game.Database foreach (var filenames in getShortenedFilenames(archive)) { using (Stream s = archive.GetStream(filenames.original)) - files.Add(new RealmNamedFileUsage(Files.Add(s, realm, false), filenames.shortened)); + files.Add(new RealmNamedFileUsage(Files.Add(s, realm, false, parameters.PreferHardLinks), filenames.shortened)); } } diff --git a/osu.Game/Database/RealmFileStore.cs b/osu.Game/Database/RealmFileStore.cs index 99033e2c88..87d347fbfa 100644 --- a/osu.Game/Database/RealmFileStore.cs +++ b/osu.Game/Database/RealmFileStore.cs @@ -45,7 +45,8 @@ namespace osu.Game.Database /// The file data stream. /// The realm instance to add to. Should already be in a transaction. /// Whether the should immediately be added to the underlying realm. If false is provided here, the instance must be manually added. - public RealmFile Add(Stream data, Realm realm, bool addToRealm = true) + /// Whether this import should use hard links rather than file copy operations if available. + public RealmFile Add(Stream data, Realm realm, bool addToRealm = true, bool preferHardLinks = false) { string hash = data.ComputeSHA2Hash(); @@ -54,7 +55,7 @@ namespace osu.Game.Database var file = existing ?? new RealmFile { Hash = hash }; if (!checkFileExistsAndMatchesHash(file)) - copyToStore(file, data); + copyToStore(file, data, preferHardLinks); if (addToRealm && !file.IsManaged) realm.Add(file); @@ -62,9 +63,9 @@ namespace osu.Game.Database return file; } - private void copyToStore(RealmFile file, Stream data) + private void copyToStore(RealmFile file, Stream data, bool preferHardLinks) { - if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows && data is FileStream fs) + if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows && data is FileStream fs && preferHardLinks) { // attempt to do a fast hard link rather than copy. if (CreateHardLink(Storage.GetFullPath(file.GetStoragePath()), fs.Name, IntPtr.Zero)) @@ -79,6 +80,58 @@ namespace osu.Game.Database data.Seek(0, SeekOrigin.Begin); } + private bool checkFileExistsAndMatchesHash(RealmFile file) + { + string path = file.GetStoragePath(); + + // we may be re-adding a file to fix missing store entries. + if (!Storage.Exists(path)) + return false; + + // even if the file already exists, check the existing checksum for safety. + using (var stream = Storage.GetStream(path)) + return stream.ComputeSHA2Hash() == file.Hash; + } + + public void Cleanup() + { + Logger.Log(@"Beginning realm file store cleanup"); + + int totalFiles = 0; + int removedFiles = 0; + + // can potentially be run asynchronously, although we will need to consider operation order for disk deletion vs realm removal. + realm.Write(r => + { + // TODO: consider using a realm native query to avoid iterating all files (https://github.com/realm/realm-dotnet/issues/2659#issuecomment-927823707) + var files = r.All().ToList(); + + foreach (var file in files) + { + totalFiles++; + + if (file.BacklinksCount > 0) + continue; + + try + { + removedFiles++; + Storage.Delete(file.GetStoragePath()); + r.Remove(file); + } + catch (Exception e) + { + Logger.Error(e, $@"Could not delete databased file {file.Hash}"); + } + } + }); + + Logger.Log($@"Finished realm file store cleanup ({removedFiles} of {totalFiles} deleted)"); + } + + #region Windows hard link support + + // For future use (to detect if a file is a hard link with other references existing on disk). public static int GetFileLinkCount(string filePath) { int result = 0; @@ -132,53 +185,6 @@ namespace osu.Game.Database [return: MarshalAs(UnmanagedType.Bool)] private static extern bool CloseHandle(SafeHandle hObject); - private bool checkFileExistsAndMatchesHash(RealmFile file) - { - string path = file.GetStoragePath(); - - // we may be re-adding a file to fix missing store entries. - if (!Storage.Exists(path)) - return false; - - // even if the file already exists, check the existing checksum for safety. - using (var stream = Storage.GetStream(path)) - return stream.ComputeSHA2Hash() == file.Hash; - } - - public void Cleanup() - { - Logger.Log(@"Beginning realm file store cleanup"); - - int totalFiles = 0; - int removedFiles = 0; - - // can potentially be run asynchronously, although we will need to consider operation order for disk deletion vs realm removal. - realm.Write(r => - { - // TODO: consider using a realm native query to avoid iterating all files (https://github.com/realm/realm-dotnet/issues/2659#issuecomment-927823707) - var files = r.All().ToList(); - - foreach (var file in files) - { - totalFiles++; - - if (file.BacklinksCount > 0) - continue; - - try - { - removedFiles++; - Storage.Delete(file.GetStoragePath()); - r.Remove(file); - } - catch (Exception e) - { - Logger.Error(e, $@"Could not delete databased file {file.Hash}"); - } - } - }); - - Logger.Log($@"Finished realm file store cleanup ({removedFiles} of {totalFiles} deleted)"); - } + #endregion } } From bbf931c746341c1e80239670dbcc7e3ce4ccdf01 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Dec 2022 19:53:12 +0900 Subject: [PATCH 1013/2991] Move hard link helper functions to their own class --- osu.Game/Database/LegacyImportManager.cs | 2 +- osu.Game/Database/RealmFileStore.cs | 64 +--------------------- osu.Game/IO/HardLinkHelper.cs | 68 ++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 63 deletions(-) create mode 100644 osu.Game/IO/HardLinkHelper.cs diff --git a/osu.Game/Database/LegacyImportManager.cs b/osu.Game/Database/LegacyImportManager.cs index 80c8e9c19e..ec8eac611c 100644 --- a/osu.Game/Database/LegacyImportManager.cs +++ b/osu.Game/Database/LegacyImportManager.cs @@ -72,7 +72,7 @@ namespace osu.Game.Database string testExistingPath = stableStorage.GetFullPath(stableStorage.GetFiles(string.Empty).First()); string testDestinationPath = desktopGameHost.Storage.GetFullPath(test_filename); - return RealmFileStore.CreateHardLink(testDestinationPath, testExistingPath, IntPtr.Zero); + return HardLinkHelper.CreateHardLink(testDestinationPath, testExistingPath, IntPtr.Zero); } public virtual async Task GetImportCount(StableContent content, CancellationToken cancellationToken) diff --git a/osu.Game/Database/RealmFileStore.cs b/osu.Game/Database/RealmFileStore.cs index 87d347fbfa..71ea6cba58 100644 --- a/osu.Game/Database/RealmFileStore.cs +++ b/osu.Game/Database/RealmFileStore.cs @@ -4,9 +4,6 @@ using System; using System.IO; using System.Linq; -using System.Runtime.InteropServices; -using System.Runtime.InteropServices.ComTypes; -using Microsoft.Win32.SafeHandles; using osu.Framework; using osu.Framework.Extensions; using osu.Framework.IO.Stores; @@ -14,6 +11,7 @@ using osu.Framework.Logging; using osu.Framework.Platform; using osu.Framework.Testing; using osu.Game.Extensions; +using osu.Game.IO; using osu.Game.Models; using Realms; @@ -68,7 +66,7 @@ namespace osu.Game.Database if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows && data is FileStream fs && preferHardLinks) { // attempt to do a fast hard link rather than copy. - if (CreateHardLink(Storage.GetFullPath(file.GetStoragePath()), fs.Name, IntPtr.Zero)) + if (HardLinkHelper.CreateHardLink(Storage.GetFullPath(file.GetStoragePath()), fs.Name, IntPtr.Zero)) return; } @@ -128,63 +126,5 @@ namespace osu.Game.Database Logger.Log($@"Finished realm file store cleanup ({removedFiles} of {totalFiles} deleted)"); } - - #region Windows hard link support - - // For future use (to detect if a file is a hard link with other references existing on disk). - public static int GetFileLinkCount(string filePath) - { - int result = 0; - SafeFileHandle handle = CreateFile(filePath, FileAccess.Read, FileShare.Read, IntPtr.Zero, FileMode.Open, FileAttributes.Archive, IntPtr.Zero); - - ByHandleFileInformation fileInfo; - - if (GetFileInformationByHandle(handle, out fileInfo)) - result = (int)fileInfo.NumberOfLinks; - CloseHandle(handle); - - return result; - } - - [DllImport("Kernel32.dll", CharSet = CharSet.Unicode)] - public static extern bool CreateHardLink( - string lpFileName, - string lpExistingFileName, - IntPtr lpSecurityAttributes - ); - - [StructLayout(LayoutKind.Sequential)] - private struct ByHandleFileInformation - { - public readonly uint FileAttributes; - public readonly FILETIME CreationTime; - public readonly FILETIME LastAccessTime; - public readonly FILETIME LastWriteTime; - public readonly uint VolumeSerialNumber; - public readonly uint FileSizeHigh; - public readonly uint FileSizeLow; - public readonly uint NumberOfLinks; - public readonly uint FileIndexHigh; - public readonly uint FileIndexLow; - } - - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] - private static extern SafeFileHandle CreateFile( - string lpFileName, - [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess, - [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode, - IntPtr lpSecurityAttributes, - [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition, - [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes, - IntPtr hTemplateFile); - - [DllImport("kernel32.dll", SetLastError = true)] - private static extern bool GetFileInformationByHandle(SafeFileHandle handle, out ByHandleFileInformation lpFileInformation); - - [DllImport("kernel32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool CloseHandle(SafeHandle hObject); - - #endregion } } diff --git a/osu.Game/IO/HardLinkHelper.cs b/osu.Game/IO/HardLinkHelper.cs new file mode 100644 index 0000000000..4b6f871719 --- /dev/null +++ b/osu.Game/IO/HardLinkHelper.cs @@ -0,0 +1,68 @@ +// 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.IO; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; +using Microsoft.Win32.SafeHandles; + +namespace osu.Game.IO +{ + internal static class HardLinkHelper + { + // For future use (to detect if a file is a hard link with other references existing on disk). + public static int GetFileLinkCount(string filePath) + { + int result = 0; + SafeFileHandle handle = CreateFile(filePath, FileAccess.Read, FileShare.Read, IntPtr.Zero, FileMode.Open, FileAttributes.Archive, IntPtr.Zero); + + ByHandleFileInformation fileInfo; + + if (GetFileInformationByHandle(handle, out fileInfo)) + result = (int)fileInfo.NumberOfLinks; + CloseHandle(handle); + + return result; + } + + [DllImport("Kernel32.dll", CharSet = CharSet.Unicode)] + public static extern bool CreateHardLink( + string lpFileName, + string lpExistingFileName, + IntPtr lpSecurityAttributes + ); + + [StructLayout(LayoutKind.Sequential)] + private struct ByHandleFileInformation + { + public readonly uint FileAttributes; + public readonly FILETIME CreationTime; + public readonly FILETIME LastAccessTime; + public readonly FILETIME LastWriteTime; + public readonly uint VolumeSerialNumber; + public readonly uint FileSizeHigh; + public readonly uint FileSizeLow; + public readonly uint NumberOfLinks; + public readonly uint FileIndexHigh; + public readonly uint FileIndexLow; + } + + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] + private static extern SafeFileHandle CreateFile( + string lpFileName, + [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess, + [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode, + IntPtr lpSecurityAttributes, + [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition, + [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes, + IntPtr hTemplateFile); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool GetFileInformationByHandle(SafeFileHandle handle, out ByHandleFileInformation lpFileInformation); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool CloseHandle(SafeHandle hObject); + } +} From 6bb612ce697a8d7bd09bb4dee2ff1572f542ef91 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Dec 2022 20:02:57 +0900 Subject: [PATCH 1014/2991] Move hard link availability check to helper class --- osu.Game/Database/LegacyImportManager.cs | 14 +---- osu.Game/IO/HardLinkHelper.cs | 80 ++++++++++++++++++------ 2 files changed, 63 insertions(+), 31 deletions(-) diff --git a/osu.Game/Database/LegacyImportManager.cs b/osu.Game/Database/LegacyImportManager.cs index ec8eac611c..3f1ddb1eda 100644 --- a/osu.Game/Database/LegacyImportManager.cs +++ b/osu.Game/Database/LegacyImportManager.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading; using System.Threading.Tasks; using osu.Framework; @@ -57,22 +56,15 @@ namespace osu.Game.Database public bool CheckHardLinkAvailability() { - if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows) - return false; - var stableStorage = GetCurrentStableStorage(); if (stableStorage == null || gameHost is not DesktopGameHost desktopGameHost) return false; - const string test_filename = "_hard_link_test"; + string testExistingPath = stableStorage.GetFullPath(string.Empty); + string testDestinationPath = desktopGameHost.Storage.GetFullPath(string.Empty); - desktopGameHost.Storage.Delete(test_filename); - - string testExistingPath = stableStorage.GetFullPath(stableStorage.GetFiles(string.Empty).First()); - string testDestinationPath = desktopGameHost.Storage.GetFullPath(test_filename); - - return HardLinkHelper.CreateHardLink(testDestinationPath, testExistingPath, IntPtr.Zero); + return HardLinkHelper.CheckAvailability(testDestinationPath, testExistingPath); } public virtual async Task GetImportCount(StableContent content, CancellationToken cancellationToken) diff --git a/osu.Game/IO/HardLinkHelper.cs b/osu.Game/IO/HardLinkHelper.cs index 4b6f871719..7e1f92c0ad 100644 --- a/osu.Game/IO/HardLinkHelper.cs +++ b/osu.Game/IO/HardLinkHelper.cs @@ -6,11 +6,55 @@ using System.IO; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using Microsoft.Win32.SafeHandles; +using osu.Framework; namespace osu.Game.IO { internal static class HardLinkHelper { + public static bool CheckAvailability(string testDestinationPath, string testSourcePath) + { + // We can support other operating systems quite easily in the future. + // Let's handle the most common one for now, though. + if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows) + return false; + + const string test_filename = "_hard_link_test"; + + testDestinationPath = Path.Combine(testDestinationPath, test_filename); + testSourcePath = Path.Combine(testSourcePath, test_filename); + + cleanupFiles(); + + try + { + File.WriteAllText(testSourcePath, string.Empty); + + // Test availability by creating an arbitrary hard link between the source and destination paths. + return CreateHardLink(testDestinationPath, testSourcePath, IntPtr.Zero); + } + catch + { + return false; + } + finally + { + cleanupFiles(); + } + + void cleanupFiles() + { + try + { + File.Delete(testDestinationPath); + File.Delete(testSourcePath); + } + catch + { + } + } + } + // For future use (to detect if a file is a hard link with other references existing on disk). public static int GetFileLinkCount(string filePath) { @@ -27,26 +71,7 @@ namespace osu.Game.IO } [DllImport("Kernel32.dll", CharSet = CharSet.Unicode)] - public static extern bool CreateHardLink( - string lpFileName, - string lpExistingFileName, - IntPtr lpSecurityAttributes - ); - - [StructLayout(LayoutKind.Sequential)] - private struct ByHandleFileInformation - { - public readonly uint FileAttributes; - public readonly FILETIME CreationTime; - public readonly FILETIME LastAccessTime; - public readonly FILETIME LastWriteTime; - public readonly uint VolumeSerialNumber; - public readonly uint FileSizeHigh; - public readonly uint FileSizeLow; - public readonly uint NumberOfLinks; - public readonly uint FileIndexHigh; - public readonly uint FileIndexLow; - } + public static extern bool CreateHardLink(string lpFileName, string lpExistingFileName, IntPtr lpSecurityAttributes); [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] private static extern SafeFileHandle CreateFile( @@ -64,5 +89,20 @@ namespace osu.Game.IO [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool CloseHandle(SafeHandle hObject); + + [StructLayout(LayoutKind.Sequential)] + private struct ByHandleFileInformation + { + public readonly uint FileAttributes; + public readonly FILETIME CreationTime; + public readonly FILETIME LastAccessTime; + public readonly FILETIME LastWriteTime; + public readonly uint VolumeSerialNumber; + public readonly uint FileSizeHigh; + public readonly uint FileSizeLow; + public readonly uint NumberOfLinks; + public readonly uint FileIndexHigh; + public readonly uint FileIndexLow; + } } } From cb16d62700f3c107588c96fef4537501a9de4cc7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Dec 2022 21:03:25 +0900 Subject: [PATCH 1015/2991] Hook up `ImportParameter` flow with `IModelImporter` caller methods --- osu.Game.Tests/Database/BeatmapImporterTests.cs | 2 +- osu.Game/Beatmaps/BeatmapImporter.cs | 2 +- osu.Game/Beatmaps/BeatmapManager.cs | 4 ++-- osu.Game/Database/ICanAcceptFiles.cs | 4 +++- osu.Game/Database/IModelImporter.cs | 4 +++- osu.Game/Database/LegacyModelImporter.cs | 8 +++++++- osu.Game/Database/ModelDownloader.cs | 2 +- osu.Game/Database/RealmArchiveModelImporter.cs | 10 +++++----- osu.Game/OsuGame.cs | 4 ++-- osu.Game/OsuGameBase_Importing.cs | 5 +++-- .../Overlays/FirstRunSetup/ScreenImportFromStable.cs | 3 ++- osu.Game/Scoring/ScoreManager.cs | 4 ++-- osu.Game/Screens/Edit/Setup/LabelledFileChooser.cs | 3 ++- osu.Game/Skinning/Editor/SkinEditor.cs | 3 ++- osu.Game/Skinning/SkinManager.cs | 6 +++--- 15 files changed, 39 insertions(+), 25 deletions(-) diff --git a/osu.Game.Tests/Database/BeatmapImporterTests.cs b/osu.Game.Tests/Database/BeatmapImporterTests.cs index cbaa7bf972..446eb72b04 100644 --- a/osu.Game.Tests/Database/BeatmapImporterTests.cs +++ b/osu.Game.Tests/Database/BeatmapImporterTests.cs @@ -564,7 +564,7 @@ namespace osu.Game.Tests.Database var imported = await importer.Import( progressNotification, - new ImportTask(zipStream, string.Empty) + new[] { new ImportTask(zipStream, string.Empty) } ); realm.Run(r => r.Refresh()); diff --git a/osu.Game/Beatmaps/BeatmapImporter.cs b/osu.Game/Beatmaps/BeatmapImporter.cs index 303e85b83a..8a6315fc65 100644 --- a/osu.Game/Beatmaps/BeatmapImporter.cs +++ b/osu.Game/Beatmaps/BeatmapImporter.cs @@ -44,7 +44,7 @@ namespace osu.Game.Beatmaps public override async Task?> ImportAsUpdate(ProgressNotification notification, ImportTask importTask, BeatmapSetInfo original) { - var imported = await Import(notification, importTask); + var imported = await Import(notification, new[] { importTask }); if (!imported.Any()) return null; diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index e288239d74..f0fd8bd2e0 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -456,9 +456,9 @@ namespace osu.Game.Beatmaps public Task Import(params string[] paths) => beatmapImporter.Import(paths); - public Task Import(params ImportTask[] tasks) => beatmapImporter.Import(tasks); + public Task Import(ImportTask[] tasks, ImportParameters parameters = default) => beatmapImporter.Import(tasks, parameters); - public Task>> Import(ProgressNotification notification, params ImportTask[] tasks) => beatmapImporter.Import(notification, tasks); + public Task>> Import(ProgressNotification notification, ImportTask[] tasks, ImportParameters parameters = default) => beatmapImporter.Import(notification, tasks, parameters); public Task?> Import(ImportTask task, ImportParameters parameters = default, CancellationToken cancellationToken = default) => beatmapImporter.Import(task, parameters, cancellationToken); diff --git a/osu.Game/Database/ICanAcceptFiles.cs b/osu.Game/Database/ICanAcceptFiles.cs index 3ce343249b..4fdedd4688 100644 --- a/osu.Game/Database/ICanAcceptFiles.cs +++ b/osu.Game/Database/ICanAcceptFiles.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Threading.Tasks; +using osu.Game.Beatmaps; namespace osu.Game.Database { @@ -31,7 +32,8 @@ namespace osu.Game.Database /// This will post notifications tracking progress. /// /// The import tasks from which the files should be imported. - Task Import(params ImportTask[] tasks); + /// Parameters to further configure the import process. + Task Import(ImportTask[] tasks, ImportParameters parameters = default); /// /// An array of accepted file extensions (in the standard format of ".abc"). diff --git a/osu.Game/Database/IModelImporter.cs b/osu.Game/Database/IModelImporter.cs index 4085f122d0..5896715a8f 100644 --- a/osu.Game/Database/IModelImporter.cs +++ b/osu.Game/Database/IModelImporter.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using osu.Game.Beatmaps; using osu.Game.Overlays.Notifications; namespace osu.Game.Database @@ -20,8 +21,9 @@ namespace osu.Game.Database /// /// The notification to update. /// The import tasks. + /// Parameters to further configure the import process. /// The imported models. - Task>> Import(ProgressNotification notification, params ImportTask[] tasks); + Task>> Import(ProgressNotification notification, ImportTask[] tasks, ImportParameters parameters = default); /// /// Process a single import as an update for an existing model. diff --git a/osu.Game/Database/LegacyModelImporter.cs b/osu.Game/Database/LegacyModelImporter.cs index df354a856e..176c660e61 100644 --- a/osu.Game/Database/LegacyModelImporter.cs +++ b/osu.Game/Database/LegacyModelImporter.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Threading.Tasks; using osu.Framework.Logging; using osu.Framework.Platform; +using osu.Game.Beatmaps; using osu.Game.IO; namespace osu.Game.Database @@ -57,7 +58,12 @@ namespace osu.Game.Database return Task.CompletedTask; } - return Task.Run(async () => await Importer.Import(GetStableImportPaths(storage).ToArray()).ConfigureAwait(false)); + return Task.Run(async () => + { + var tasks = GetStableImportPaths(storage).Select(p => new ImportTask(p)).ToArray(); + + await Importer.Import(tasks, new ImportParameters { Batch = true, PreferHardLinks = true }).ConfigureAwait(false); + }); } /// diff --git a/osu.Game/Database/ModelDownloader.cs b/osu.Game/Database/ModelDownloader.cs index 3e2d034937..2f082306d0 100644 --- a/osu.Game/Database/ModelDownloader.cs +++ b/osu.Game/Database/ModelDownloader.cs @@ -73,7 +73,7 @@ namespace osu.Game.Database if (originalModel != null) importSuccessful = (await importer.ImportAsUpdate(notification, new ImportTask(filename), originalModel)) != null; else - importSuccessful = (await importer.Import(notification, new ImportTask(filename))).Any(); + importSuccessful = (await importer.Import(notification, new[] { new ImportTask(filename) })).Any(); // for now a failed import will be marked as a failed download for simplicity. if (!importSuccessful) diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index 1f9debc46f..bf51e8d49e 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -82,16 +82,16 @@ namespace osu.Game.Database public Task Import(params string[] paths) => Import(paths.Select(p => new ImportTask(p)).ToArray()); - public Task Import(params ImportTask[] tasks) + public Task Import(ImportTask[] tasks, ImportParameters parameters = default) { var notification = new ProgressNotification { State = ProgressNotificationState.Active }; PostNotification?.Invoke(notification); - return Import(notification, tasks); + return Import(notification, tasks, parameters); } - public async Task>> Import(ProgressNotification notification, params ImportTask[] tasks) + public async Task>> Import(ProgressNotification notification, ImportTask[] tasks, ImportParameters parameters = default) { if (tasks.Length == 0) { @@ -107,7 +107,7 @@ namespace osu.Game.Database var imported = new List>(); - bool isBatchImport = tasks.Length >= minimum_items_considered_batch_import; + parameters.Batch |= tasks.Length >= minimum_items_considered_batch_import; await Task.WhenAll(tasks.Select(async task => { @@ -116,7 +116,7 @@ namespace osu.Game.Database try { - var model = await Import(task, new ImportParameters { Batch = isBatchImport }, notification.CancellationToken).ConfigureAwait(false); + var model = await Import(task, parameters, notification.CancellationToken).ConfigureAwait(false); lock (imported) { diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 5565fa7ef3..8fb6806c27 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -616,14 +616,14 @@ namespace osu.Game }, validScreens: validScreens); } - public override Task Import(params ImportTask[] imports) + public override Task Import(ImportTask[] imports, ImportParameters parameters = default) { // encapsulate task as we don't want to begin the import process until in a ready state. // ReSharper disable once AsyncVoidLambda // TODO: This is bad because `new Task` doesn't have a Func override. // Only used for android imports and a bit of a mess. Probably needs rethinking overall. - var importTask = new Task(async () => await base.Import(imports).ConfigureAwait(false)); + var importTask = new Task(async () => await base.Import(imports, parameters).ConfigureAwait(false)); waitForReady(() => this, _ => importTask.Start()); diff --git a/osu.Game/OsuGameBase_Importing.cs b/osu.Game/OsuGameBase_Importing.cs index e34e48f21d..565b0f37ae 100644 --- a/osu.Game/OsuGameBase_Importing.cs +++ b/osu.Game/OsuGameBase_Importing.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; +using osu.Game.Beatmaps; using osu.Game.Database; namespace osu.Game @@ -44,13 +45,13 @@ namespace osu.Game } } - public virtual async Task Import(params ImportTask[] tasks) + public virtual async Task Import(ImportTask[] tasks, ImportParameters parameters = default) { var tasksPerExtension = tasks.GroupBy(t => Path.GetExtension(t.Path).ToLowerInvariant()); await Task.WhenAll(tasksPerExtension.Select(taskGroup => { var importer = fileImporters.FirstOrDefault(i => i.HandledExtensions.Contains(taskGroup.Key)); - return importer?.Import(taskGroup.ToArray()) ?? Task.CompletedTask; + return importer?.Import(taskGroup.ToArray(), parameters) ?? Task.CompletedTask; })).ConfigureAwait(false); } diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index 4af80c6fbb..bf8092fbfa 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -17,6 +17,7 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Framework.Logging; using osu.Framework.Screens; +using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Graphics.Containers; @@ -269,7 +270,7 @@ namespace osu.Game.Overlays.FirstRunSetup return Task.CompletedTask; } - Task ICanAcceptFiles.Import(params ImportTask[] tasks) => throw new NotImplementedException(); + Task ICanAcceptFiles.Import(ImportTask[] tasks, ImportParameters parameters) => throw new NotImplementedException(); protected override void Dispose(bool isDisposing) { diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index a57db0eccf..5ec96a951b 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -169,13 +169,13 @@ namespace osu.Game.Scoring public Task Import(params string[] paths) => scoreImporter.Import(paths); - public Task Import(params ImportTask[] tasks) => scoreImporter.Import(tasks); + public Task Import(ImportTask[] imports, ImportParameters parameters = default) => scoreImporter.Import(imports, parameters); public override bool IsAvailableLocally(ScoreInfo model) => Realm.Run(realm => realm.All().Any(s => s.OnlineID == model.OnlineID)); public IEnumerable HandledExtensions => scoreImporter.HandledExtensions; - public Task>> Import(ProgressNotification notification, params ImportTask[] tasks) => scoreImporter.Import(notification, tasks); + public Task>> Import(ProgressNotification notification, ImportTask[] tasks, ImportParameters parameters = default) => scoreImporter.Import(notification, tasks); public Task> ImportAsUpdate(ProgressNotification notification, ImportTask task, ScoreInfo original) => scoreImporter.ImportAsUpdate(notification, task, original); diff --git a/osu.Game/Screens/Edit/Setup/LabelledFileChooser.cs b/osu.Game/Screens/Edit/Setup/LabelledFileChooser.cs index 57d28824b1..b7ca84776b 100644 --- a/osu.Game/Screens/Edit/Setup/LabelledFileChooser.cs +++ b/osu.Game/Screens/Edit/Setup/LabelledFileChooser.cs @@ -16,6 +16,7 @@ using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Framework.Platform; +using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Graphics.UserInterfaceV2; using osuTK; @@ -91,7 +92,7 @@ namespace osu.Game.Screens.Edit.Setup return Task.CompletedTask; } - Task ICanAcceptFiles.Import(params ImportTask[] tasks) => throw new NotImplementedException(); + Task ICanAcceptFiles.Import(ImportTask[] tasks, ImportParameters parameters) => throw new NotImplementedException(); protected override void Dispose(bool isDisposing) { diff --git a/osu.Game/Skinning/Editor/SkinEditor.cs b/osu.Game/Skinning/Editor/SkinEditor.cs index 1dd9c93845..5531e08d3c 100644 --- a/osu.Game/Skinning/Editor/SkinEditor.cs +++ b/osu.Game/Skinning/Editor/SkinEditor.cs @@ -18,6 +18,7 @@ using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Framework.Testing; +using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Graphics.Containers; @@ -411,7 +412,7 @@ namespace osu.Game.Skinning.Editor return Task.CompletedTask; } - public Task Import(params ImportTask[] tasks) => throw new NotImplementedException(); + Task ICanAcceptFiles.Import(ImportTask[] tasks, ImportParameters parameters) => throw new NotImplementedException(); public IEnumerable HandledExtensions => new[] { ".jpg", ".jpeg", ".png" }; diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index 40c43563b2..467a88c864 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -271,12 +271,12 @@ namespace osu.Game.Skinning public Task Import(params string[] paths) => skinImporter.Import(paths); - public Task Import(params ImportTask[] tasks) => skinImporter.Import(tasks); + public Task Import(ImportTask[] imports, ImportParameters parameters = default) => skinImporter.Import(imports, parameters); public IEnumerable HandledExtensions => skinImporter.HandledExtensions; - public Task>> Import(ProgressNotification notification, params ImportTask[] tasks) => - skinImporter.Import(notification, tasks); + public Task>> Import(ProgressNotification notification, ImportTask[] tasks, ImportParameters parameters = default) => + skinImporter.Import(notification, tasks, parameters); public Task> ImportAsUpdate(ProgressNotification notification, ImportTask task, SkinInfo original) => skinImporter.ImportAsUpdate(notification, task, original); From b8904fe7474e17bf48a7dbbbd60ae338dd77529c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Dec 2022 21:41:26 +0900 Subject: [PATCH 1016/2991] Move `ImportParameters` to better home --- osu.Game.Tests/Skins/IO/ImportSkinTest.cs | 1 - osu.Game/Beatmaps/BeatmapManager.cs | 20 --------------- osu.Game/Database/ICanAcceptFiles.cs | 1 - osu.Game/Database/IModelImporter.cs | 1 - osu.Game/Database/ImportParameters.cs | 25 +++++++++++++++++++ osu.Game/Database/LegacyModelImporter.cs | 1 - .../Database/RealmArchiveModelImporter.cs | 1 - osu.Game/OsuGameBase_Importing.cs | 1 - .../FirstRunSetup/ScreenImportFromStable.cs | 1 - .../Screens/Edit/Setup/LabelledFileChooser.cs | 1 - osu.Game/Skinning/Editor/SkinEditor.cs | 1 - osu.Game/Skinning/SkinManager.cs | 1 - 12 files changed, 25 insertions(+), 30 deletions(-) create mode 100644 osu.Game/Database/ImportParameters.cs diff --git a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs index f90c983627..0bd40e9962 100644 --- a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs +++ b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs @@ -12,7 +12,6 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Extensions; using osu.Framework.Platform; -using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Extensions; using osu.Game.IO; diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index f0fd8bd2e0..f0533f27be 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -526,24 +526,4 @@ namespace osu.Game.Beatmaps public override string HumanisedModelName => "beatmap"; } - - public struct ImportParameters - { - /// - /// Whether this import is part of a larger batch. - /// - /// - /// May skip intensive pre-import checks in favour of faster processing. - /// - /// More specifically, imports will be skipped before they begin, given an existing model matches on hash and filenames. Should generally only be used for large batch imports, as it may defy user expectations when updating an existing model. - /// - /// Will also change scheduling behaviour to run at a lower priority. - /// - public bool Batch { get; set; } - - /// - /// Whether this import should use hard links rather than file copy operations if available. - /// - public bool PreferHardLinks { get; set; } - } } diff --git a/osu.Game/Database/ICanAcceptFiles.cs b/osu.Game/Database/ICanAcceptFiles.cs index 4fdedd4688..da970a29d4 100644 --- a/osu.Game/Database/ICanAcceptFiles.cs +++ b/osu.Game/Database/ICanAcceptFiles.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Threading.Tasks; -using osu.Game.Beatmaps; namespace osu.Game.Database { diff --git a/osu.Game/Database/IModelImporter.cs b/osu.Game/Database/IModelImporter.cs index 5896715a8f..dcbbad0d35 100644 --- a/osu.Game/Database/IModelImporter.cs +++ b/osu.Game/Database/IModelImporter.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using osu.Game.Beatmaps; using osu.Game.Overlays.Notifications; namespace osu.Game.Database diff --git a/osu.Game/Database/ImportParameters.cs b/osu.Game/Database/ImportParameters.cs new file mode 100644 index 0000000000..83ca0ac694 --- /dev/null +++ b/osu.Game/Database/ImportParameters.cs @@ -0,0 +1,25 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Database +{ + public struct ImportParameters + { + /// + /// Whether this import is part of a larger batch. + /// + /// + /// May skip intensive pre-import checks in favour of faster processing. + /// + /// More specifically, imports will be skipped before they begin, given an existing model matches on hash and filenames. Should generally only be used for large batch imports, as it may defy user expectations when updating an existing model. + /// + /// Will also change scheduling behaviour to run at a lower priority. + /// + public bool Batch { get; set; } + + /// + /// Whether this import should use hard links rather than file copy operations if available. + /// + public bool PreferHardLinks { get; set; } + } +} diff --git a/osu.Game/Database/LegacyModelImporter.cs b/osu.Game/Database/LegacyModelImporter.cs index 176c660e61..29386a1103 100644 --- a/osu.Game/Database/LegacyModelImporter.cs +++ b/osu.Game/Database/LegacyModelImporter.cs @@ -8,7 +8,6 @@ using System.Linq; using System.Threading.Tasks; using osu.Framework.Logging; using osu.Framework.Platform; -using osu.Game.Beatmaps; using osu.Game.IO; namespace osu.Game.Database diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index bf51e8d49e..4e8b27e0b4 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -13,7 +13,6 @@ using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Framework.Threading; -using osu.Game.Beatmaps; using osu.Game.Extensions; using osu.Game.IO.Archives; using osu.Game.Models; diff --git a/osu.Game/OsuGameBase_Importing.cs b/osu.Game/OsuGameBase_Importing.cs index 565b0f37ae..cf65460bab 100644 --- a/osu.Game/OsuGameBase_Importing.cs +++ b/osu.Game/OsuGameBase_Importing.cs @@ -7,7 +7,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; -using osu.Game.Beatmaps; using osu.Game.Database; namespace osu.Game diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index bf8092fbfa..8ce92dab12 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -17,7 +17,6 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Framework.Logging; using osu.Framework.Screens; -using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Graphics.Containers; diff --git a/osu.Game/Screens/Edit/Setup/LabelledFileChooser.cs b/osu.Game/Screens/Edit/Setup/LabelledFileChooser.cs index b7ca84776b..d14357e875 100644 --- a/osu.Game/Screens/Edit/Setup/LabelledFileChooser.cs +++ b/osu.Game/Screens/Edit/Setup/LabelledFileChooser.cs @@ -16,7 +16,6 @@ using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Framework.Platform; -using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Graphics.UserInterfaceV2; using osuTK; diff --git a/osu.Game/Skinning/Editor/SkinEditor.cs b/osu.Game/Skinning/Editor/SkinEditor.cs index 5531e08d3c..0ed4e5afd2 100644 --- a/osu.Game/Skinning/Editor/SkinEditor.cs +++ b/osu.Game/Skinning/Editor/SkinEditor.cs @@ -18,7 +18,6 @@ using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Framework.Testing; -using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Graphics.Containers; diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index 467a88c864..2ad62dbb61 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -22,7 +22,6 @@ using osu.Framework.Testing; using osu.Framework.Threading; using osu.Framework.Utils; using osu.Game.Audio; -using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.IO; using osu.Game.Overlays.Notifications; From edc78205d5312e9278f2a22ef156fd34af492595 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Dec 2022 22:06:03 +0900 Subject: [PATCH 1017/2991] Add comments about why both positional input checks are required in `OsuClickableContainer` --- osu.Game/Graphics/Containers/OsuClickableContainer.cs | 6 +++++- osu.Game/Graphics/UserInterface/OsuButton.cs | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuClickableContainer.cs b/osu.Game/Graphics/Containers/OsuClickableContainer.cs index ecae456e88..6ec393df4b 100644 --- a/osu.Game/Graphics/Containers/OsuClickableContainer.cs +++ b/osu.Game/Graphics/Containers/OsuClickableContainer.cs @@ -17,7 +17,11 @@ namespace osu.Game.Graphics.Containers private readonly Container content = new Container { RelativeSizeAxes = Axes.Both }; - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => base.ReceivePositionalInputAt(screenSpacePos) && Content.ReceivePositionalInputAt(screenSpacePos); + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => + // base call is checked for cases when `OsuClickableContainer` has masking applied to it directly (ie. externally in object initialisation). + base.ReceivePositionalInputAt(screenSpacePos) + // Implementations often apply masking / edge rounding at a content level, so it's imperative to check that as well. + && Content.ReceivePositionalInputAt(screenSpacePos); protected override Container Content => content; diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index 00cd3b13e5..3fccf51cc2 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -61,7 +61,11 @@ namespace osu.Game.Graphics.UserInterface protected override Container Content { get; } - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => base.ReceivePositionalInputAt(screenSpacePos) && Content.ReceivePositionalInputAt(screenSpacePos); + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => + // base call is checked for cases when `OsuClickableContainer` has masking applied to it directly (ie. externally in object initialisation). + base.ReceivePositionalInputAt(screenSpacePos) + // Implementations often apply masking / edge rounding at a content level, so it's imperative to check that as well. + && Content.ReceivePositionalInputAt(screenSpacePos); protected Box Hover; protected Box Background; From efe057176e26b82ec320cce03115a7e121fb3d0d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Dec 2022 22:13:48 +0900 Subject: [PATCH 1018/2991] Make `OsuButton` `abstract` --- .../UserInterface/TestSceneOsuButton.cs | 47 ------------------- osu.Game/Graphics/UserInterface/OsuButton.cs | 4 +- 2 files changed, 2 insertions(+), 49 deletions(-) delete mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneOsuButton.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuButton.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOsuButton.cs deleted file mode 100644 index 41e5d47093..0000000000 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOsuButton.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -#nullable disable - -using NUnit.Framework; -using osu.Framework.Graphics; -using osu.Game.Graphics.UserInterface; -using osuTK; - -namespace osu.Game.Tests.Visual.UserInterface -{ - public partial class TestSceneOsuButton : OsuTestScene - { - [Test] - public void TestToggleEnabled() - { - OsuButton button = null; - - AddStep("add button", () => Child = button = new OsuButton - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(200), - Text = "Button" - }); - - AddToggleStep("toggle enabled", toggle => - { - for (int i = 0; i < 6; i++) - button.Action = toggle ? () => { } : null; - }); - } - - [Test] - public void TestInitiallyDisabled() - { - AddStep("add button", () => Child = new OsuButton - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(200), - Text = "Button" - }); - } - } -} diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index 3fccf51cc2..805dfcaa95 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -19,7 +19,7 @@ namespace osu.Game.Graphics.UserInterface /// /// A button with added default sound effects. /// - public partial class OsuButton : Button + public abstract partial class OsuButton : Button { public LocalisableString Text { @@ -73,7 +73,7 @@ namespace osu.Game.Graphics.UserInterface private readonly Box flashLayer; - public OsuButton(HoverSampleSet? hoverSounds = HoverSampleSet.Button) + protected OsuButton(HoverSampleSet? hoverSounds = HoverSampleSet.Button) { Height = 40; From bf56f5f8c08583927a35cc02da3881dba40a196a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Dec 2022 18:27:14 +0900 Subject: [PATCH 1019/2991] Show error message on attempting to open a URL with an unsupported protocol --- osu.Game.Tests/Chat/MessageFormatterTests.cs | 10 ++++++++++ osu.Game/OsuGame.cs | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/osu.Game.Tests/Chat/MessageFormatterTests.cs b/osu.Game.Tests/Chat/MessageFormatterTests.cs index ebfa9bd8b7..3c35dc311f 100644 --- a/osu.Game.Tests/Chat/MessageFormatterTests.cs +++ b/osu.Game.Tests/Chat/MessageFormatterTests.cs @@ -26,6 +26,16 @@ namespace osu.Game.Tests.Chat MessageFormatter.WebsiteRootUrl = originalWebsiteRootUrl; } + [Test] + public void TestUnsupportedProtocolLink() + { + Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a gopher://really-old-protocol we don't support." }); + + Assert.AreEqual(result.Content, result.DisplayContent); + Assert.AreEqual(1, result.Links.Count); + Assert.AreEqual("gopher://really-old-protocol", result.Links[0].Url); + } + [Test] public void TestBareLink() { diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 5565fa7ef3..bd33ab6545 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -16,6 +16,7 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Bindables; using osu.Framework.Configuration; +using osu.Framework.Extensions; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.TypeExtensions; using osu.Framework.Graphics; @@ -406,6 +407,16 @@ namespace osu.Game if (url.StartsWith('/')) url = $"{API.APIEndpointUrl}{url}"; + if (!url.CheckIsValidUrl()) + { + Notifications.Post(new SimpleErrorNotification + { + Text = $"The URL {url} has an unsupported or dangerous protocol and will not be opened.", + }); + + return; + } + externalLinkOpener.OpenUrlExternally(url, bypassExternalUrlWarning); }); From 3d65984a893533166df3a93e3396625d79b84abd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Dec 2022 22:34:01 +0900 Subject: [PATCH 1020/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 147d236d98..c2c74e2c0e 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8639ce6361..31cd851c03 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 184e3303c8..b2aa3caa14 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -62,7 +62,7 @@ - + @@ -82,7 +82,7 @@ - + From f4316a9827d89fcf62120419f46b290c9a2a4e6c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 14 Dec 2022 11:30:01 +0900 Subject: [PATCH 1021/2991] Fix incorrect grammar in hard link explanation text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index 8ce92dab12..04aa976ff1 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -129,7 +129,7 @@ namespace osu.Game.Overlays.FirstRunSetup copyInformation.Text = "Data migration will use \"hard links\". No extra disk space will be used, and you can delete either data folder at any point without affecting the other installation."; } else if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows) - copyInformation.Text = "Lightweight linking of files are not supported on your operating system yet, so a copy of all files will be made during import."; + copyInformation.Text = "Lightweight linking of files is not supported on your operating system yet, so a copy of all files will be made during import."; else { copyInformation.Text = From a3c3112f897a0d9c327c4aaf6fa96c00bff3abe4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 14 Dec 2022 11:34:06 +0900 Subject: [PATCH 1022/2991] Add `SetLastError` hint to `CreateHardLink` pinvoke method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/IO/HardLinkHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/IO/HardLinkHelper.cs b/osu.Game/IO/HardLinkHelper.cs index 7e1f92c0ad..1393bf26fd 100644 --- a/osu.Game/IO/HardLinkHelper.cs +++ b/osu.Game/IO/HardLinkHelper.cs @@ -70,7 +70,7 @@ namespace osu.Game.IO return result; } - [DllImport("Kernel32.dll", CharSet = CharSet.Unicode)] + [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool CreateHardLink(string lpFileName, string lpExistingFileName, IntPtr lpSecurityAttributes); [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] From fb85eaee950ed490e9238fa261766eeef58802a1 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 14 Dec 2022 18:30:31 +0900 Subject: [PATCH 1023/2991] Add description for lazer score version 30000001 --- osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs index 5452e4b9eb..a78ae24da2 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreEncoder.cs @@ -25,6 +25,11 @@ namespace osu.Game.Scoring.Legacy /// Database version in stable-compatible YYYYMMDD format. /// Should be incremented if any changes are made to the format/usage. /// + /// + /// + /// 30000001: Appends to the end of scores. + /// + /// public const int LATEST_VERSION = 30000001; /// From ee945c9b58a8463598685a53fb4ba38cacf71efe Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Wed, 14 Dec 2022 10:34:21 -0500 Subject: [PATCH 1024/2991] disable mouse input to touchscreen controls --- .../UI/CatchTouchInputMapper.cs | 24 ------------------- osu.Game.Rulesets.Mania/UI/Column.cs | 12 ---------- .../UI/DrumTouchInputArea.cs | 18 -------------- 3 files changed, 54 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchTouchInputMapper.cs b/osu.Game.Rulesets.Catch/UI/CatchTouchInputMapper.cs index d23913136d..55a90d62e5 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchTouchInputMapper.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchTouchInputMapper.cs @@ -106,41 +106,17 @@ namespace osu.Game.Rulesets.Catch.UI return false; } - protected override bool OnMouseDown(MouseDownEvent e) - { - return updateAction(e.Button, getTouchCatchActionFromInput(e.ScreenSpaceMousePosition)); - } - protected override bool OnTouchDown(TouchDownEvent e) { return updateAction(e.Touch.Source, getTouchCatchActionFromInput(e.ScreenSpaceTouch.Position)); } - protected override bool OnMouseMove(MouseMoveEvent e) - { - Show(); - - TouchCatchAction? action = getTouchCatchActionFromInput(e.ScreenSpaceMousePosition); - - // multiple mouse buttons may be pressed and handling the same action. - foreach (MouseButton button in e.PressedButtons) - updateAction(button, action); - - return false; - } - protected override void OnTouchMove(TouchMoveEvent e) { updateAction(e.Touch.Source, getTouchCatchActionFromInput(e.ScreenSpaceTouch.Position)); base.OnTouchMove(e); } - protected override void OnMouseUp(MouseUpEvent e) - { - updateAction(e.Button, null); - base.OnMouseUp(e); - } - protected override void OnTouchUp(TouchUpEvent e) { updateAction(e.Touch.Source, null); diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 6a31fb3fda..f355c43ad0 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -206,18 +206,6 @@ namespace osu.Game.Rulesets.Mania.UI keyBindingContainer = maniaInputManager?.KeyBindingContainer; } - protected override bool OnMouseDown(MouseDownEvent e) - { - keyBindingContainer?.TriggerPressed(column.Action.Value); - return base.OnMouseDown(e); - } - - protected override void OnMouseUp(MouseUpEvent e) - { - keyBindingContainer?.TriggerReleased(column.Action.Value); - base.OnMouseUp(e); - } - protected override bool OnTouchDown(TouchDownEvent e) { keyBindingContainer?.TriggerPressed(column.Action.Value); diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index ab8c0a484e..0232c10d65 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -107,24 +107,6 @@ namespace osu.Game.Rulesets.Taiko.UI return false; } - protected override bool OnMouseDown(MouseDownEvent e) - { - if (!validMouse(e)) - return false; - - handleDown(e.Button, e.ScreenSpaceMousePosition); - return true; - } - - protected override void OnMouseUp(MouseUpEvent e) - { - if (!validMouse(e)) - return; - - handleUp(e.Button); - base.OnMouseUp(e); - } - protected override bool OnTouchDown(TouchDownEvent e) { handleDown(e.Touch.Source, e.ScreenSpaceTouchDownPosition); From f5cc2f6ed5e3597d032c638bbf498f7a5d818f77 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Wed, 14 Dec 2022 11:19:16 -0500 Subject: [PATCH 1025/2991] remove unnecessary using --- osu.Game.Rulesets.Catch/UI/CatchTouchInputMapper.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchTouchInputMapper.cs b/osu.Game.Rulesets.Catch/UI/CatchTouchInputMapper.cs index 55a90d62e5..10e43cf74a 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchTouchInputMapper.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchTouchInputMapper.cs @@ -11,7 +11,6 @@ using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Game.Graphics; using osuTK; -using osuTK.Input; namespace osu.Game.Rulesets.Catch.UI { From 6bf1477939980b597d07784744dfa65cb85e0c65 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Dec 2022 14:17:28 +0900 Subject: [PATCH 1026/2991] Fix some hard links not being created due to missing directory structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Database/RealmFileStore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Database/RealmFileStore.cs b/osu.Game/Database/RealmFileStore.cs index 71ea6cba58..04b503b808 100644 --- a/osu.Game/Database/RealmFileStore.cs +++ b/osu.Game/Database/RealmFileStore.cs @@ -66,7 +66,7 @@ namespace osu.Game.Database if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows && data is FileStream fs && preferHardLinks) { // attempt to do a fast hard link rather than copy. - if (HardLinkHelper.CreateHardLink(Storage.GetFullPath(file.GetStoragePath()), fs.Name, IntPtr.Zero)) + if (HardLinkHelper.CreateHardLink(Storage.GetFullPath(file.GetStoragePath(), true), fs.Name, IntPtr.Zero)) return; } From a7f3e139461d1c63a4aa4fb98a01b859e3ab6cb9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Dec 2022 16:56:09 +0900 Subject: [PATCH 1027/2991] Fix `MultipleSelectionFilter` not correctly handling initial selection --- .../BeatmapSearchMultipleSelectionFilterRow.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs index 79a794a9ad..5d1ccbd58b 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; +using System.Collections.Specialized; using System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; @@ -18,6 +19,7 @@ using osuTK; namespace osu.Game.Overlays.BeatmapListing { public partial class BeatmapSearchMultipleSelectionFilterRow : BeatmapSearchFilterRow> + where T : Enum { public new readonly BindableList Current = new BindableList(); @@ -31,7 +33,7 @@ namespace osu.Game.Overlays.BeatmapListing [BackgroundDependencyLoader] private void load() { - Current.BindTo(filter.Current); + filter.Current.BindTo(Current); } protected sealed override Drawable CreateFilter() => filter = CreateMultipleSelectionFilter(); @@ -64,6 +66,14 @@ namespace osu.Game.Overlays.BeatmapListing foreach (var item in Children) item.Active.BindValueChanged(active => toggleItem(item.Value, active.NewValue)); + + Current.BindCollectionChanged(currentChanged, true); + } + + private void currentChanged(object sender, NotifyCollectionChangedEventArgs e) + { + foreach (var c in Children) + c.Active.Value = Current.Contains(c.Value); } /// @@ -79,7 +89,10 @@ namespace osu.Game.Overlays.BeatmapListing private void toggleItem(T value, bool active) { if (active) - Current.Add(value); + { + if (!Current.Contains(value)) + Current.Add(value); + } else Current.Remove(value); } From 78bc94d3cb179c390c2753c1b1a5073085ab274d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Dec 2022 16:57:39 +0900 Subject: [PATCH 1028/2991] Set featured artists filter to enabled by default --- osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs index f28ec9c295..23de1cf76d 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs @@ -146,6 +146,7 @@ namespace osu.Game.Overlays.BeatmapListing } }); + generalFilter.Current.Add(SearchGeneral.FeaturedArtists); categoryFilter.Current.Value = SearchCategory.Leaderboard; } From 0763b86236bad6fe3b1839f0103746ca2c47a8e3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Dec 2022 17:32:27 +0900 Subject: [PATCH 1029/2991] Add more padding around text in dialog popups --- osu.Game/Overlays/Dialog/PopupDialog.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/Dialog/PopupDialog.cs b/osu.Game/Overlays/Dialog/PopupDialog.cs index 80e0ffe427..f5a7e9e43d 100644 --- a/osu.Game/Overlays/Dialog/PopupDialog.cs +++ b/osu.Game/Overlays/Dialog/PopupDialog.cs @@ -198,6 +198,7 @@ namespace osu.Game.Overlays.Dialog TextAnchor = Anchor.TopCentre, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, + Padding = new MarginPadding(5), }, }, }, From d2b98b803d398c5ecf4284dbbcdd5b13edad3192 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Dec 2022 17:35:39 +0900 Subject: [PATCH 1030/2991] Turn on featured artist filter by default and add disclaimer when toggling for the first time --- osu.Game/Configuration/SessionStatics.cs | 4 +- .../Localisation/BeatmapOverlayStrings.cs | 34 ++++++++++ .../BeatmapSearchGeneralFilterRow.cs | 63 +++++++++++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Localisation/BeatmapOverlayStrings.cs diff --git a/osu.Game/Configuration/SessionStatics.cs b/osu.Game/Configuration/SessionStatics.cs index 12a30a0c84..276563e163 100644 --- a/osu.Game/Configuration/SessionStatics.cs +++ b/osu.Game/Configuration/SessionStatics.cs @@ -19,6 +19,7 @@ namespace osu.Game.Configuration SetDefault(Static.LoginOverlayDisplayed, false); SetDefault(Static.MutedAudioNotificationShownOnce, false); SetDefault(Static.LowBatteryNotificationShownOnce, false); + SetDefault(Static.FeaturedArtistDisclaimerShownOnce, false); SetDefault(Static.LastHoverSoundPlaybackTime, (double?)null); SetDefault(Static.SeasonalBackgrounds, null); } @@ -42,6 +43,7 @@ namespace osu.Game.Configuration LoginOverlayDisplayed, MutedAudioNotificationShownOnce, LowBatteryNotificationShownOnce, + FeaturedArtistDisclaimerShownOnce, /// /// Info about seasonal backgrounds available fetched from API - see . @@ -53,6 +55,6 @@ namespace osu.Game.Configuration /// The last playback time in milliseconds of a hover sample (from ). /// Used to debounce hover sounds game-wide to avoid volume saturation, especially in scrolling views with many UI controls like . /// - LastHoverSoundPlaybackTime + LastHoverSoundPlaybackTime, } } diff --git a/osu.Game/Localisation/BeatmapOverlayStrings.cs b/osu.Game/Localisation/BeatmapOverlayStrings.cs new file mode 100644 index 0000000000..efa9fcf155 --- /dev/null +++ b/osu.Game/Localisation/BeatmapOverlayStrings.cs @@ -0,0 +1,34 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class BeatmapOverlayStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.BeatmapOverlayStrings"; + + /// + /// "User content disclaimer" + /// + public static LocalisableString UserContentDisclaimer => new TranslatableString(getKey(@"user_content_disclaimer"), @"User content disclaimer"); + + /// + /// "By turning off the "featured artist" filter, all user uploaded content will be displayed. + /// + /// This includes content which may not be correctly licensed for use and as such may not be safe for streaming, sharing, or consumption." + /// + public static LocalisableString ByTurningOffTheFeatured => new TranslatableString(getKey(@"by_turning_off_the_featured"), + @"By turning off the ""featured artist"" filter, all user uploaded content will be displayed. + +This includes content which may not be correctly licensed for use and as such may not be safe for streaming, sharing, or consumption."); + + /// + /// "I understand" + /// + public static LocalisableString Understood => new TranslatableString(getKey(@"understood"), @"I understand"); + + private static string getKey(string key) => $@"{prefix}:{key}"; + } +} diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchGeneralFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchGeneralFilterRow.cs index 10ec66e396..41a78473e5 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchGeneralFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchGeneralFilterRow.cs @@ -3,10 +3,18 @@ #nullable disable +using System; using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Events; +using osu.Game.Configuration; using osu.Game.Graphics; +using osu.Game.Localisation; +using osu.Game.Overlays.Dialog; using osu.Game.Resources.Localisation.Web; using osuTK.Graphics; +using CommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings; namespace osu.Game.Overlays.BeatmapListing { @@ -32,6 +40,8 @@ namespace osu.Game.Overlays.BeatmapListing private partial class FeaturedArtistsTabItem : MultipleSelectionFilterTabItem { + private Bindable disclaimerShown; + public FeaturedArtistsTabItem() : base(SearchGeneral.FeaturedArtists) { @@ -40,7 +50,60 @@ namespace osu.Game.Overlays.BeatmapListing [Resolved] private OsuColour colours { get; set; } + [Resolved] + private SessionStatics sessionStatics { get; set; } + + [Resolved(canBeNull: true)] + private IDialogOverlay dialogOverlay { get; set; } + protected override Color4 GetStateColour() => colours.Orange1; + + protected override void LoadComplete() + { + base.LoadComplete(); + + disclaimerShown = sessionStatics.GetBindable(Static.FeaturedArtistDisclaimerShownOnce); + } + + protected override bool OnClick(ClickEvent e) + { + if (!disclaimerShown.Value && dialogOverlay != null) + { + dialogOverlay.Push(new FeaturedArtistConfirmDialog(() => + { + disclaimerShown.Value = true; + base.OnClick(e); + })); + + return true; + } + + return base.OnClick(e); + } + } + } + + internal partial class FeaturedArtistConfirmDialog : PopupDialog + { + public FeaturedArtistConfirmDialog(Action confirm) + { + HeaderText = BeatmapOverlayStrings.UserContentDisclaimer; + BodyText = BeatmapOverlayStrings.ByTurningOffTheFeatured; + + Icon = FontAwesome.Solid.ExclamationTriangle; + + Buttons = new PopupDialogButton[] + { + new PopupDialogDangerousButton + { + Text = BeatmapOverlayStrings.Understood, + Action = confirm + }, + new PopupDialogCancelButton + { + Text = CommonStrings.ButtonsCancel, + }, + }; } } } From 57048f0ebaaf11ef14253c78005bfcd84a5f603d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Dec 2022 18:42:58 +0900 Subject: [PATCH 1031/2991] Add test coverage of featured artist filter confirmation process --- .../Navigation/TestSceneScreenNavigation.cs | 23 +++++++++++++++++++ .../Online/TestSceneBeatmapListingOverlay.cs | 9 ++++++++ 2 files changed, 32 insertions(+) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index d8fda5b21f..ddb01b90ce 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -19,6 +19,7 @@ using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Leaderboards; using osu.Game.Overlays; +using osu.Game.Overlays.BeatmapListing; using osu.Game.Overlays.Mods; using osu.Game.Overlays.Toolbar; using osu.Game.Rulesets.Mods; @@ -515,6 +516,28 @@ namespace osu.Game.Tests.Visual.Navigation AddWaitStep("wait two frames", 2); } + [Test] + public void TestFeaturedArtistDisclaimerDialog() + { + BeatmapListingOverlay getBeatmapListingOverlay() => Game.ChildrenOfType().FirstOrDefault(); + + AddStep("Wait for notifications to load", () => Game.SearchBeatmapSet(string.Empty)); + AddUntilStep("wait for dialog overlay", () => Game.ChildrenOfType().SingleOrDefault() != null); + + AddUntilStep("Wait for beatmap overlay to load", () => getBeatmapListingOverlay()?.State.Value == Visibility.Visible); + AddAssert("featured artist filter is on", () => getBeatmapListingOverlay().ChildrenOfType().First().Current.Contains(SearchGeneral.FeaturedArtists)); + AddStep("toggle featured artist filter", + () => getBeatmapListingOverlay().ChildrenOfType>().First(i => i.Value == SearchGeneral.FeaturedArtists).TriggerClick()); + + AddAssert("disclaimer dialog is shown", () => Game.ChildrenOfType().Single().CurrentDialog != null); + AddAssert("featured artist filter is still on", () => getBeatmapListingOverlay().ChildrenOfType().First().Current.Contains(SearchGeneral.FeaturedArtists)); + + AddStep("confirm", () => InputManager.Key(Key.Enter)); + AddAssert("dialog dismissed", () => Game.ChildrenOfType().Single().CurrentDialog == null); + + AddUntilStep("featured artist filter is off", () => !getBeatmapListingOverlay().ChildrenOfType().First().Current.Contains(SearchGeneral.FeaturedArtists)); + } + [Test] public void TestMainOverlaysClosesNotificationOverlay() { diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs index c64343b47b..5e49cb633e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs @@ -80,6 +80,15 @@ namespace osu.Game.Tests.Visual.Online AddStep("reset size", () => localConfig.SetValue(OsuSetting.BeatmapListingCardSize, BeatmapCardSize.Normal)); } + [Test] + public void TestFeaturedArtistFilter() + { + AddAssert("is visible", () => overlay.State.Value == Visibility.Visible); + AddAssert("featured artist filter is on", () => overlay.ChildrenOfType().First().Current.Contains(SearchGeneral.FeaturedArtists)); + AddStep("toggle featured artist filter", () => overlay.ChildrenOfType>().First(i => i.Value == SearchGeneral.FeaturedArtists).TriggerClick()); + AddAssert("featured artist filter is off", () => !overlay.ChildrenOfType().First().Current.Contains(SearchGeneral.FeaturedArtists)); + } + [Test] public void TestHideViaBack() { From 3d6d3b40257c17184311f1442b850747d1b3b287 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 15 Dec 2022 20:59:11 +0900 Subject: [PATCH 1032/2991] fix weird async logic --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- osu.Game/Scoring/ScoreManager.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 34780082da..56b87eaf11 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -453,7 +453,7 @@ namespace osu.Game.Beatmaps public Task?> ImportAsUpdate(ProgressNotification notification, ImportTask importTask, BeatmapSetInfo original) => beatmapImporter.ImportAsUpdate(notification, importTask, original); - public void Export(BeatmapSetInfo beatmap) => Task.Run(() => beatmapExporter.ExportAsync(beatmap)); + public Task Export(BeatmapSetInfo beatmap) => beatmapExporter.ExportAsync(beatmap); private void updateHashAndMarkDirty(BeatmapSetInfo setInfo) { diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index 525ff58778..f52172a200 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -183,7 +183,7 @@ namespace osu.Game.Scoring public Task>> Import(ProgressNotification notification, params ImportTask[] tasks) => scoreImporter.Import(notification, tasks); - public void Export(ScoreInfo score) => Task.Run(() => scoreExporter.ExportAsync(score)); + public Task Export(ScoreInfo score) => scoreExporter.ExportAsync(score); public Task> ImportAsUpdate(ProgressNotification notification, ImportTask task, ScoreInfo original) => scoreImporter.ImportAsUpdate(notification, task, original); From c9cffc82484f32c70395509111149d5b0123b539 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 15 Dec 2022 21:01:38 +0900 Subject: [PATCH 1033/2991] use resolved attribute --- osu.Game/Online/Leaderboards/LeaderboardScore.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index e5edf90d1a..e4ea277756 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -73,7 +73,8 @@ namespace osu.Game.Online.Leaderboards public ITooltip GetCustomTooltip() => new LeaderboardScoreTooltip(); public virtual ScoreInfo TooltipContent => Score; - private ScoreManager scoreManager = null!; + [Resolved] + private ScoreManager scoreManager { get; set; } = null!; public LeaderboardScore(ScoreInfo score, int? rank, bool isOnlineScope = true) { @@ -87,14 +88,12 @@ namespace osu.Game.Online.Leaderboards } [BackgroundDependencyLoader] - private void load(IAPIProvider api, OsuColour colour, ScoreManager scoreManager) + private void load(IAPIProvider api, OsuColour colour) { var user = Score.User; statisticsLabels = GetStatistics(Score).Select(s => new ScoreComponentLabel(s)).ToList(); - this.scoreManager = scoreManager; - ClickableAvatar innerAvatar; Children = new Drawable[] From 6900d0120a70287ef531a4c0facd398508a76b06 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 15 Dec 2022 21:39:48 +0900 Subject: [PATCH 1034/2991] change abstract implement --- osu.Game/Database/LegacyBeatmapExporter.cs | 2 +- osu.Game/Database/LegacyModelExporter.cs | 21 ++++++++++++++++----- osu.Game/Database/LegacySkinExporter.cs | 2 +- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/osu.Game/Database/LegacyBeatmapExporter.cs b/osu.Game/Database/LegacyBeatmapExporter.cs index 6349ebde2c..107b91a234 100644 --- a/osu.Game/Database/LegacyBeatmapExporter.cs +++ b/osu.Game/Database/LegacyBeatmapExporter.cs @@ -6,7 +6,7 @@ using osu.Game.Beatmaps; namespace osu.Game.Database { - public class LegacyBeatmapExporter : LegacyModelExporter + public class LegacyBeatmapExporter : LegacyArchiveExporter { public LegacyBeatmapExporter(Storage storage, RealmAccess realm) : base(storage, realm) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 5150651b15..6b5f8e7e96 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -32,7 +32,7 @@ namespace osu.Game.Database protected RealmAccess RealmAccess; - private bool canCancel = true; + protected bool CanCancel = true; private string filename = string.Empty; public Action? PostNotification { get; set; } @@ -76,9 +76,9 @@ namespace osu.Game.Database CompletionText = "Export completed" }; notification.CompletionClickAction += () => exportStorage.PresentFileExternally(filename); - notification.CancelRequested += () => canCancel; + notification.CancelRequested += () => CanCancel; PostNotification?.Invoke(notification); - canCancel = true; + CanCancel = true; Guid id = model.ID; await Task.Run(() => @@ -115,7 +115,18 @@ namespace osu.Game.Database /// The item to export. /// The output stream to export to. /// The notification will displayed to the user - protected virtual void ExportToStream(TModel model, Stream outputStream, ProgressNotification notification) => exportZipArchive(model, outputStream, notification); + protected abstract void ExportToStream(TModel model, Stream outputStream, ProgressNotification notification); + } + + public abstract class LegacyArchiveExporter : LegacyModelExporter + where TModel : RealmObject, IHasNamedFiles, IHasGuidPrimaryKey + { + protected LegacyArchiveExporter(Storage storage, RealmAccess realm) + : base(storage, realm) + { + } + + protected override void ExportToStream(TModel model, Stream outputStream, ProgressNotification notification) => exportZipArchive(model, outputStream, notification); /// /// Exports an item to Stream as a legacy (.zip based) package. @@ -140,7 +151,7 @@ namespace osu.Game.Database } notification.Text = "Saving Zip Archive..."; - canCancel = false; + CanCancel = false; archive.SaveTo(outputStream); } } diff --git a/osu.Game/Database/LegacySkinExporter.cs b/osu.Game/Database/LegacySkinExporter.cs index 52d0e56cbf..d3e6a2f0f4 100644 --- a/osu.Game/Database/LegacySkinExporter.cs +++ b/osu.Game/Database/LegacySkinExporter.cs @@ -6,7 +6,7 @@ using osu.Game.Skinning; namespace osu.Game.Database { - public class LegacySkinExporter : LegacyModelExporter + public class LegacySkinExporter : LegacyArchiveExporter { public LegacySkinExporter(Storage storage, RealmAccess realm) : base(storage, realm) From 6ef5b2733f01a4ebd2ccd733a4e6c80c6158698f Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 15 Dec 2022 21:41:15 +0900 Subject: [PATCH 1035/2991] Export instead of ExportCurrentSkin --- osu.Game/Overlays/Settings/Sections/SkinSection.cs | 2 +- osu.Game/Skinning/SkinManager.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 6d338df2fe..1a64416b3e 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -158,7 +158,7 @@ namespace osu.Game.Overlays.Settings.Sections { try { - skins.ExporCurrenttSkin(); + skins.CurrentSkinInfo.Value.PerformRead(s => skins.ExportSkin(s)); } catch (Exception e) { diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index 65a602b764..d4e7d252ac 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -287,7 +287,7 @@ namespace osu.Game.Skinning public Task> Import(ImportTask task, bool batchImport = false, CancellationToken cancellationToken = default) => skinImporter.Import(task, batchImport, cancellationToken); - public void ExporCurrenttSkin() => CurrentSkinInfo.Value.PerformRead(s => skinExporter.ExportAsync(s)); + public Task ExportSkin(SkinInfo skin) => skinExporter.ExportAsync(skin); #endregion From 91adf2e80f62f7ffd296474c3836d7e8ef7f5510 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Dec 2022 22:44:47 +0900 Subject: [PATCH 1036/2991] Apply the wala-hyphen Co-authored-by: Walavouchey <36758269+Walavouchey@users.noreply.github.com> --- osu.Game/Localisation/BeatmapOverlayStrings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Localisation/BeatmapOverlayStrings.cs b/osu.Game/Localisation/BeatmapOverlayStrings.cs index efa9fcf155..b2625dc0e6 100644 --- a/osu.Game/Localisation/BeatmapOverlayStrings.cs +++ b/osu.Game/Localisation/BeatmapOverlayStrings.cs @@ -15,12 +15,12 @@ namespace osu.Game.Localisation public static LocalisableString UserContentDisclaimer => new TranslatableString(getKey(@"user_content_disclaimer"), @"User content disclaimer"); /// - /// "By turning off the "featured artist" filter, all user uploaded content will be displayed. + /// "By turning off the "Featured Artist" filter, all user-uploaded content will be displayed. /// /// This includes content which may not be correctly licensed for use and as such may not be safe for streaming, sharing, or consumption." /// public static LocalisableString ByTurningOffTheFeatured => new TranslatableString(getKey(@"by_turning_off_the_featured"), - @"By turning off the ""featured artist"" filter, all user uploaded content will be displayed. + @"By turning off the ""Featured Artist"" filter, all user-uploaded content will be displayed. This includes content which may not be correctly licensed for use and as such may not be safe for streaming, sharing, or consumption."); From ec251664a7c4a2bbb6b022a046cf35960bd2497b Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 15 Dec 2022 22:45:36 +0900 Subject: [PATCH 1037/2991] use ThrowIfCancellationRequested instead of CancelRequested --- osu.Game/Database/LegacyModelExporter.cs | 70 ++++++++++++++---------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 6b5f8e7e96..0ebcfaa07e 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -32,8 +32,6 @@ namespace osu.Game.Database protected RealmAccess RealmAccess; - protected bool CanCancel = true; - private string filename = string.Empty; public Action? PostNotification { get; set; } @@ -54,10 +52,16 @@ namespace osu.Game.Database string itemFilename = model.GetDisplayString().GetValidFilename(); IEnumerable existingExports = exportStorage.GetFiles("", $"{itemFilename}*{FileExtension}"); filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); + bool success; using (var stream = exportStorage.CreateFileSafely(filename)) { - await ExportToStreamAsync(model, stream); + success = await ExportToStreamAsync(model, stream); + } + + if (!success) + { + exportStorage.Delete(filename); } } @@ -66,8 +70,8 @@ namespace osu.Game.Database /// /// The medel which have . /// The stream to export. - /// - public async Task ExportToStreamAsync(TModel model, Stream stream) + /// Whether the export was successful + public async Task ExportToStreamAsync(TModel model, Stream stream) { ProgressNotification notification = new ProgressNotification { @@ -76,35 +80,33 @@ namespace osu.Game.Database CompletionText = "Export completed" }; notification.CompletionClickAction += () => exportStorage.PresentFileExternally(filename); - notification.CancelRequested += () => CanCancel; PostNotification?.Invoke(notification); - CanCancel = true; Guid id = model.ID; - await Task.Run(() => + return await Task.Run(() => { RealmAccess.Run(r => { TModel refetchModel = r.Find(id); ExportToStream(refetchModel, stream, notification); }); - }).ContinueWith(t => + }, notification.CancellationToken).ContinueWith(t => { + if (t.IsCanceled) + { + return false; + } + if (t.IsFaulted) { notification.State = ProgressNotificationState.Cancelled; Logger.Error(t.Exception, "An error occurred while exporting"); - - return; - } - - if (notification.CancellationToken.IsCancellationRequested) - { - return; + return false; } notification.CompletionText = "Export Complete, Click to open the folder"; notification.State = ProgressNotificationState.Completed; + return true; }); } @@ -121,6 +123,8 @@ namespace osu.Game.Database public abstract class LegacyArchiveExporter : LegacyModelExporter where TModel : RealmObject, IHasNamedFiles, IHasGuidPrimaryKey { + private bool canCancel = true; + protected LegacyArchiveExporter(Storage storage, RealmAccess realm) : base(storage, realm) { @@ -136,23 +140,33 @@ namespace osu.Game.Database /// The notification will displayed to the user private void exportZipArchive(TModel model, Stream outputStream, ProgressNotification notification) { - using (var archive = ZipArchive.Create()) + try { - float i = 0; + notification.CancelRequested += () => canCancel; - foreach (var file in model.Files) + using (var archive = ZipArchive.Create()) { - if (notification.CancellationToken.IsCancellationRequested) return; + float i = 0; - archive.AddEntry(file.Filename, UserFileStorage.GetStream(file.File.GetStoragePath())); - i++; - notification.Progress = i / model.Files.Count(); - notification.Text = $"Exporting... ({i}/{model.Files.Count()})"; + foreach (var file in model.Files) + { + notification.CancellationToken.ThrowIfCancellationRequested(); + + archive.AddEntry(file.Filename, UserFileStorage.GetStream(file.File.GetStoragePath())); + i++; + notification.Progress = i / model.Files.Count(); + notification.Text = $"Exporting... ({i}/{model.Files.Count()})"; + } + + notification.Text = "Saving Zip Archive..."; + canCancel = false; + archive.SaveTo(outputStream); } - - notification.Text = "Saving Zip Archive..."; - CanCancel = false; - archive.SaveTo(outputStream); + } + catch (OperationCanceledException) + { + Logger.Log("Export operat canceled"); + throw; } } } From 9813bc95444466b723608aab2b4ae72e0111f7df Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 15 Dec 2022 22:46:31 +0900 Subject: [PATCH 1038/2991] Reword disclaimer and fix translation keys --- osu.Game/Localisation/BeatmapOverlayStrings.cs | 11 +++++------ .../BeatmapListing/BeatmapSearchGeneralFilterRow.cs | 6 +++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/osu.Game/Localisation/BeatmapOverlayStrings.cs b/osu.Game/Localisation/BeatmapOverlayStrings.cs index b2625dc0e6..fc818f7596 100644 --- a/osu.Game/Localisation/BeatmapOverlayStrings.cs +++ b/osu.Game/Localisation/BeatmapOverlayStrings.cs @@ -12,22 +12,21 @@ namespace osu.Game.Localisation /// /// "User content disclaimer" /// - public static LocalisableString UserContentDisclaimer => new TranslatableString(getKey(@"user_content_disclaimer"), @"User content disclaimer"); + public static LocalisableString UserContentDisclaimerHeader => new TranslatableString(getKey(@"user_content_disclaimer"), @"User content disclaimer"); /// /// "By turning off the "Featured Artist" filter, all user-uploaded content will be displayed. /// - /// This includes content which may not be correctly licensed for use and as such may not be safe for streaming, sharing, or consumption." + /// This includes content that may not be correctly licensed for osu! usage. Browse at your own risk." /// - public static LocalisableString ByTurningOffTheFeatured => new TranslatableString(getKey(@"by_turning_off_the_featured"), - @"By turning off the ""Featured Artist"" filter, all user-uploaded content will be displayed. + public static LocalisableString UserContentDisclaimerDescription => new TranslatableString(getKey(@"by_turning_off_the_featured"), @"By turning off the ""Featured Artist"" filter, all user-uploaded content will be displayed. -This includes content which may not be correctly licensed for use and as such may not be safe for streaming, sharing, or consumption."); +This includes content that may not be correctly licensed for osu! usage. Browse at your own risk."); /// /// "I understand" /// - public static LocalisableString Understood => new TranslatableString(getKey(@"understood"), @"I understand"); + public static LocalisableString UserContentConfirmButtonText => new TranslatableString(getKey(@"understood"), @"I understand"); private static string getKey(string key) => $@"{prefix}:{key}"; } diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchGeneralFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchGeneralFilterRow.cs index 41a78473e5..a4a914db55 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchGeneralFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchGeneralFilterRow.cs @@ -87,8 +87,8 @@ namespace osu.Game.Overlays.BeatmapListing { public FeaturedArtistConfirmDialog(Action confirm) { - HeaderText = BeatmapOverlayStrings.UserContentDisclaimer; - BodyText = BeatmapOverlayStrings.ByTurningOffTheFeatured; + HeaderText = BeatmapOverlayStrings.UserContentDisclaimerHeader; + BodyText = BeatmapOverlayStrings.UserContentDisclaimerDescription; Icon = FontAwesome.Solid.ExclamationTriangle; @@ -96,7 +96,7 @@ namespace osu.Game.Overlays.BeatmapListing { new PopupDialogDangerousButton { - Text = BeatmapOverlayStrings.Understood, + Text = BeatmapOverlayStrings.UserContentConfirmButtonText, Action = confirm }, new PopupDialogCancelButton From f5226bd50b02068e42116940e12c1f47bbf158ce Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 15 Dec 2022 23:12:25 +0900 Subject: [PATCH 1039/2991] use ZipWriter Export directly to stream instead of creating a archive so we can cancel this anytime --- osu.Game/Database/LegacyModelExporter.cs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 0ebcfaa07e..9e0c1e0c6d 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -12,7 +12,9 @@ using osu.Game.Extensions; using osu.Game.Overlays.Notifications; using osu.Game.Utils; using Realms; -using SharpCompress.Archives.Zip; +using SharpCompress.Common; +using SharpCompress.Writers; +using SharpCompress.Writers.Zip; namespace osu.Game.Database { @@ -123,8 +125,6 @@ namespace osu.Game.Database public abstract class LegacyArchiveExporter : LegacyModelExporter where TModel : RealmObject, IHasNamedFiles, IHasGuidPrimaryKey { - private bool canCancel = true; - protected LegacyArchiveExporter(Storage storage, RealmAccess realm) : base(storage, realm) { @@ -142,9 +142,7 @@ namespace osu.Game.Database { try { - notification.CancelRequested += () => canCancel; - - using (var archive = ZipArchive.Create()) + using (var writer = new ZipWriter(outputStream, new ZipWriterOptions(CompressionType.Deflate))) { float i = 0; @@ -152,15 +150,11 @@ namespace osu.Game.Database { notification.CancellationToken.ThrowIfCancellationRequested(); - archive.AddEntry(file.Filename, UserFileStorage.GetStream(file.File.GetStoragePath())); + writer.Write(file.Filename, UserFileStorage.GetStream(file.File.GetStoragePath())); i++; notification.Progress = i / model.Files.Count(); notification.Text = $"Exporting... ({i}/{model.Files.Count()})"; } - - notification.Text = "Saving Zip Archive..."; - canCancel = false; - archive.SaveTo(outputStream); } } catch (OperationCanceledException) From dadadaff65057cd16210ae9ba05634e308b5ec53 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 15 Dec 2022 23:20:29 +0900 Subject: [PATCH 1040/2991] remove try catch --- osu.Game/Database/LegacyModelExporter.cs | 26 ++++++++---------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 9e0c1e0c6d..824460cdc9 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -140,28 +140,20 @@ namespace osu.Game.Database /// The notification will displayed to the user private void exportZipArchive(TModel model, Stream outputStream, ProgressNotification notification) { - try + using (var writer = new ZipWriter(outputStream, new ZipWriterOptions(CompressionType.Deflate))) { - using (var writer = new ZipWriter(outputStream, new ZipWriterOptions(CompressionType.Deflate))) + float i = 0; + + foreach (var file in model.Files) { - float i = 0; + notification.CancellationToken.ThrowIfCancellationRequested(); - foreach (var file in model.Files) - { - notification.CancellationToken.ThrowIfCancellationRequested(); - - writer.Write(file.Filename, UserFileStorage.GetStream(file.File.GetStoragePath())); - i++; - notification.Progress = i / model.Files.Count(); - notification.Text = $"Exporting... ({i}/{model.Files.Count()})"; - } + writer.Write(file.Filename, UserFileStorage.GetStream(file.File.GetStoragePath())); + i++; + notification.Progress = i / model.Files.Count(); + notification.Text = $"Exporting... ({i}/{model.Files.Count()})"; } } - catch (OperationCanceledException) - { - Logger.Log("Export operat canceled"); - throw; - } } } } From 9a235b32133e45827f71533cd86e799ca66155bb Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Wed, 14 Dec 2022 23:00:34 +0100 Subject: [PATCH 1041/2991] remove rolling duration, fix issue with loading --- .../Play/HUD/JudgementCounter/JudgementCounter.cs | 2 -- .../HUD/JudgementCounter/JudgementCounterDisplay.cs | 13 ++++++------- .../Play/HUD/JudgementCounter/JudgementTally.cs | 6 ++---- osu.Game/Screens/Play/HUDOverlay.cs | 3 ++- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs index a4ebd80e9f..3f7dbefcd1 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -112,8 +112,6 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { protected override OsuSpriteText CreateSpriteText() => base.CreateSpriteText().With(s => s.Font = s.Font.With(fixedWidth: true, size: 16)); - - protected override double RollingDuration => 750; } } } diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 4880314f29..36466fa8a9 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -33,9 +33,10 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter [Resolved] private JudgementTally tally { get; set; } = null!; - protected FillFlowContainer JudgementContainer; + protected FillFlowContainer JudgementContainer = null!; - public JudgementCounterDisplay() + [BackgroundDependencyLoader] + private void load() { AutoSizeAxes = Axes.Both; InternalChild = JudgementContainer = new FillFlowContainer @@ -44,17 +45,15 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter Spacing = new Vector2(10), AutoSizeAxes = Axes.Both }; - } - protected override void LoadComplete() - { - //Adding this in "load" will cause the component to not load in properly after the first beatmap attempt. Or after existing and reentering. - //this does not happen in tests, or in the skin editor component preview button. foreach (var result in tally.Results) { JudgementContainer.Add(createCounter(result)); } + } + protected override void LoadComplete() + { base.LoadComplete(); FlowDirection.BindValueChanged(direction => diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs index a88b18ff6f..e6bc336b0b 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs @@ -34,19 +34,17 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter protected override void LoadComplete() { base.LoadComplete(); + scoreProcessor.NewJudgement += judgement => { foreach (JudgementCounterInfo result in Results.Where(result => result.Type == judgement.Type)) - { result.ResultCount.Value++; - } }; + scoreProcessor.JudgementReverted += judgement => { foreach (JudgementCounterInfo result in Results.Where(result => result.Type == judgement.Type)) - { result.ResultCount.Value--; - } }; } } diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 89d02e5fb0..728da22123 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -107,6 +107,8 @@ namespace osu.Game.Screens.Play Children = new Drawable[] { CreateFailingLayer(), + //Needs to be initialized before skinnable drawables. + tally = new JudgementTally(), mainComponents = new MainComponentsContainer { AlwaysPresent = true, @@ -150,7 +152,6 @@ namespace osu.Game.Screens.Play Spacing = new Vector2(5) }, clicksPerSecondCalculator = new ClicksPerSecondCalculator(), - tally = new JudgementTally() }; hideTargets = new List { mainComponents, KeyCounter, topRightElements }; From cd8420bc66c56aa7e686a579ebd9a18634861b45 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 15 Dec 2022 23:34:40 +0900 Subject: [PATCH 1042/2991] Handle the case where the file cannot be found --- osu.Game/Database/LegacyModelExporter.cs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 824460cdc9..531a6f48da 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -143,12 +143,33 @@ namespace osu.Game.Database using (var writer = new ZipWriter(outputStream, new ZipWriterOptions(CompressionType.Deflate))) { float i = 0; + bool fileMissing = false; foreach (var file in model.Files) { notification.CancellationToken.ThrowIfCancellationRequested(); - writer.Write(file.Filename, UserFileStorage.GetStream(file.File.GetStoragePath())); + using (var stream = UserFileStorage.GetStream(file.File.GetStoragePath())) + { + // Sometimes we cannot find the file(probably deleted by the user), so we handle this and post a error. + if (stream == null) + { + // Only pop up once to prevent spam. + if (!fileMissing) + { + PostNotification?.Invoke(new SimpleErrorNotification + { + Text = "Some of your files are missing, they will not be included in the archive" + }); + fileMissing = true; + } + } + else + { + writer.Write(file.Filename, stream); + } + } + i++; notification.Progress = i / model.Files.Count(); notification.Text = $"Exporting... ({i}/{model.Files.Count()})"; From 5912dfd443effad317f5085aba57f4b380868d6e Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 15 Dec 2022 23:42:49 +0900 Subject: [PATCH 1043/2991] using declaration reshaper --- osu.Game/Database/LegacyModelExporter.cs | 49 ++++++++++++------------ 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 531a6f48da..d896e4bce6 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -140,40 +140,39 @@ namespace osu.Game.Database /// The notification will displayed to the user private void exportZipArchive(TModel model, Stream outputStream, ProgressNotification notification) { - using (var writer = new ZipWriter(outputStream, new ZipWriterOptions(CompressionType.Deflate))) + using var writer = new ZipWriter(outputStream, new ZipWriterOptions(CompressionType.Deflate)); + + float i = 0; + bool fileMissing = false; + + foreach (var file in model.Files) { - float i = 0; - bool fileMissing = false; + notification.CancellationToken.ThrowIfCancellationRequested(); - foreach (var file in model.Files) + using (var stream = UserFileStorage.GetStream(file.File.GetStoragePath())) { - notification.CancellationToken.ThrowIfCancellationRequested(); - - using (var stream = UserFileStorage.GetStream(file.File.GetStoragePath())) + // Sometimes we cannot find the file(probably deleted by the user), so we handle this and post a error. + if (stream == null) { - // Sometimes we cannot find the file(probably deleted by the user), so we handle this and post a error. - if (stream == null) + // Only pop up once to prevent spam. + if (!fileMissing) { - // Only pop up once to prevent spam. - if (!fileMissing) + PostNotification?.Invoke(new SimpleErrorNotification { - PostNotification?.Invoke(new SimpleErrorNotification - { - Text = "Some of your files are missing, they will not be included in the archive" - }); - fileMissing = true; - } - } - else - { - writer.Write(file.Filename, stream); + Text = "Some of your files are missing, they will not be included in the archive" + }); + fileMissing = true; } } - - i++; - notification.Progress = i / model.Files.Count(); - notification.Text = $"Exporting... ({i}/{model.Files.Count()})"; + else + { + writer.Write(file.Filename, stream); + } } + + i++; + notification.Progress = i / model.Files.Count(); + notification.Text = $"Exporting... ({i}/{model.Files.Count()})"; } } } From 0c177aa7dedb51352da4de6f5fd1d239a51a8331 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Thu, 15 Dec 2022 16:12:34 +0100 Subject: [PATCH 1044/2991] Improve tests, simplify "updateDisplay" method --- .../Gameplay/TestSceneJudgementCounter.cs | 38 ++++++++------ .../HUD/JudgementCounter/JudgementCounter.cs | 2 +- .../JudgementCounterDisplay.cs | 50 +++++++++---------- 3 files changed, 47 insertions(+), 43 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index 7a54f47c46..1d79d8e408 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual.Gameplay { private ScoreProcessor scoreProcessor = null!; private JudgementTally judgementTally = null!; - private TestJudgementCounterDisplay counter = null!; + private TestJudgementCounterDisplay counterDisplay = null!; private readonly Bindable lastJudgementResult = new Bindable(); @@ -48,7 +48,7 @@ namespace osu.Game.Tests.Visual.Gameplay { RelativeSizeAxes = Axes.Both, CachedDependencies = new (Type, object)[] { (typeof(JudgementTally), judgementTally) }, - Child = counter = new TestJudgementCounterDisplay + Child = counterDisplay = new TestJudgementCounterDisplay { Margin = new MarginPadding { Top = 100 }, Anchor = Anchor.TopCentre, @@ -82,7 +82,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Miss), 2); AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Meh), 2); AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.LargeTickHit), 2); - AddStep("Show all judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.All); + AddStep("Show all judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.All); AddAssert("Check value added whilst hidden", () => hiddenCount() == 2); } @@ -91,43 +91,49 @@ namespace osu.Game.Tests.Visual.Gameplay { AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.LargeTickHit), 2); AddAssert("Check value added whilst hidden", () => hiddenCount() == 2); - AddStep("Show all judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.All); + AddStep("Show all judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.All); } [Test] public void TestChangeFlowDirection() { - AddStep("Set direction vertical", () => counter.FlowDirection.Value = JudgementCounterDisplay.Flow.Vertical); - AddStep("Set direction horizontal", () => counter.FlowDirection.Value = JudgementCounterDisplay.Flow.Horizontal); + AddStep("Set direction vertical", () => counterDisplay.FlowDirection.Value = JudgementCounterDisplay.Flow.Vertical); + AddStep("Set direction horizontal", () => counterDisplay.FlowDirection.Value = JudgementCounterDisplay.Flow.Horizontal); } [Test] public void TestToggleJudgementNames() { - AddStep("Hide judgement names", () => counter.ShowName.Value = false); - AddAssert("Assert hidden", () => counter.JudgementContainer.Children.OfType().First().ResultName.Alpha == 0); - AddStep("Hide judgement names", () => counter.ShowName.Value = true); - AddAssert("Assert shown", () => counter.JudgementContainer.Children.OfType().First().ResultName.Alpha == 1); + AddStep("Hide judgement names", () => counterDisplay.ShowName.Value = false); + AddAssert("Assert hidden", () => counterDisplay.JudgementContainer.Children.OfType().First().ResultName.Alpha == 0); + AddStep("Hide judgement names", () => counterDisplay.ShowName.Value = true); + AddAssert("Assert shown", () => counterDisplay.JudgementContainer.Children.OfType().First().ResultName.Alpha == 1); } [Test] public void TestHideMaxValue() { - AddStep("Hide max judgement", () => counter.ShowMax.Value = false); - AddStep("Show max judgement", () => counter.ShowMax.Value = true); + AddStep("Hide max judgement", () => counterDisplay.ShowMax.Value = false); + AddWaitStep("wait some", 2); + AddAssert("Check max hidden", () => counterDisplay.JudgementContainer.ChildrenOfType().First().Alpha == 0); + AddStep("Show max judgement", () => counterDisplay.ShowMax.Value = true); } [Test] public void TestCycleDisplayModes() { - AddStep("Show all judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.All); - AddStep("Show normal judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.Normal); - AddStep("Show basic judgements", () => counter.Mode.Value = JudgementCounterDisplay.DisplayMode.Simple); + AddStep("Show basic judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.Simple); + AddWaitStep("wait some", 2); + AddAssert("Check only basic", () => counterDisplay.JudgementContainer.ChildrenOfType().Last().Alpha == 0); + AddStep("Show normal judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.Normal); + AddStep("Show all judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.All); + AddWaitStep("wait some", 2); + AddAssert("Check all visible", () => counterDisplay.JudgementContainer.ChildrenOfType().Last().Alpha == 1); } private int hiddenCount() { - var num = counter.JudgementContainer.Children.OfType().First(child => child.Result.Type == HitResult.LargeTickHit); + var num = counterDisplay.JudgementContainer.Children.OfType().First(child => child.Result.Type == HitResult.LargeTickHit); return num.Result.ResultCount.Value; } diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs index 3f7dbefcd1..efb4c532f9 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -100,7 +100,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter protected override void PopIn() { - this.FadeInFromZero(500, Easing.OutQuint); + this.FadeIn(500, Easing.OutQuint); } protected override void PopOut() diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 36466fa8a9..1842ba1eae 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -66,7 +66,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter counter.Direction.Value = getFlow(direction.NewValue); } }, true); - Mode.BindValueChanged(_ => updateCounter(), true); + Mode.BindValueChanged(_ => updateMode(), true); ShowMax.BindValueChanged(value => { var firstChild = JudgementContainer.Children.FirstOrDefault(); @@ -81,38 +81,35 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter }, true); } - private void updateCounter() + private void updateMode() { - var counters = JudgementContainer.Children.OfType().ToList(); - - switch (Mode.Value) + foreach (var counter in JudgementContainer.Children.OfType().Where(counter => !counter.Result.Type.IsBasic())) { - case DisplayMode.Simple: - foreach (var counter in counters.Where(counter => counter.Result.Type.IsBasic())) - counter.Show(); - - foreach (var counter in counters.Where(counter => !counter.Result.Type.IsBasic())) + switch (Mode.Value) + { + case DisplayMode.Simple: counter.Hide(); - break; + break; - case DisplayMode.Normal: - foreach (var counter in counters.Where(counter => !counter.Result.Type.IsBonus())) + case DisplayMode.Normal: + if (counter.Result.Type.IsBonus()) + { + counter.Hide(); + break; + } + + counter.Show(); + break; + + case DisplayMode.All: counter.Show(); - foreach (var counter in counters.Where(counter => counter.Result.Type.IsBonus())) - counter.Hide(); + break; - break; - - case DisplayMode.All: - foreach (JudgementCounter counter in counters.Where(counter => !counter.IsPresent)) - counter.Show(); - - break; - - default: - throw new ArgumentOutOfRangeException(); + default: + throw new ArgumentOutOfRangeException(); + } } } @@ -149,7 +146,8 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { JudgementCounter counter = new JudgementCounter(info) { - ShowName = { BindTarget = ShowName }, + State = { Value = Visibility.Visible }, + ShowName = { BindTarget = ShowName } }; return counter; } From c1647440641abe58d4ef1abf834e8f936d0877a2 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Fri, 16 Dec 2022 01:03:30 +0900 Subject: [PATCH 1045/2991] Add ability to set preview time --- .../Summary/Parts/PreviewTimePart.cs | 31 +++++++++++++++++++ .../Timelines/Summary/SummaryTimeline.cs | 8 +++++ osu.Game/Screens/Edit/Editor.cs | 12 +++++++ osu.Game/Screens/Edit/EditorBeatmap.cs | 5 +++ 4 files changed, 56 insertions(+) create mode 100644 osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs new file mode 100644 index 0000000000..a09d93fd5a --- /dev/null +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs @@ -0,0 +1,31 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Game.Graphics; +using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations; + +namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts +{ + public partial class PreviewTimePart : TimelinePart + { + protected override void LoadBeatmap(EditorBeatmap beatmap) + { + base.LoadBeatmap(beatmap); + Add(new PreviewTimeVisualisation(beatmap.PreviewTime)); + } + + private partial class PreviewTimeVisualisation : PointVisualisation + { + public PreviewTimeVisualisation(BindableInt time) + : base(time.Value) + { + time.BindValueChanged(s => X = s.NewValue); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) => Colour = colours.Lime; + } + } +} diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs index 7f762b9d50..41377bcb18 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs @@ -41,6 +41,14 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary RelativeSizeAxes = Axes.Both, Height = 0.35f }, + new PreviewTimePart + { + Anchor = Anchor.Centre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.Both, + Y = -10, + Height = 0.35f + }, new Container { Name = "centre line", diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index f3f2b8ad6b..16fff76ac7 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -322,6 +322,13 @@ namespace osu.Game.Screens.Edit State = { BindTarget = editorHitMarkers }, } } + }, + new MenuItem("Timing") + { + Items = new MenuItem[] + { + new EditorMenuItem("Set Current Position as Preview Point", MenuItemType.Standard, SetCurrectTimeAsPreview) + } } } }, @@ -801,6 +808,11 @@ namespace osu.Game.Screens.Edit protected void Redo() => changeHandler?.RestoreState(1); + protected void SetCurrectTimeAsPreview() + { + editorBeatmap.PreviewTime.Value = (int)clock.CurrentTime; + } + private void resetTrack(bool seekToStart = false) { Beatmap.Value.Track.Stop(); diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index e204b44db3..0a0557a992 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -86,6 +86,8 @@ namespace osu.Game.Screens.Edit [Resolved] private EditorClock editorClock { get; set; } + public BindableInt PreviewTime; + private readonly IBeatmapProcessor beatmapProcessor; private readonly Dictionary> startTimeBindables = new Dictionary>(); @@ -107,6 +109,9 @@ namespace osu.Game.Screens.Edit foreach (var obj in HitObjects) trackStartTime(obj); + + PreviewTime = new BindableInt(playableBeatmap.Metadata.PreviewTime); + PreviewTime.BindValueChanged(s => this.beatmapInfo.Metadata.PreviewTime = s.NewValue); } /// From 984f0b5fa961e5ed54dbbac132f39273fa2e7e8f Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Fri, 16 Dec 2022 01:35:54 +0900 Subject: [PATCH 1046/2991] Add test for set preview point --- .../Visual/Editing/TestScenePreviewTime.cs | 23 +++++++++++++++++++ osu.Game/Tests/Visual/EditorTestScene.cs | 2 ++ 2 files changed, 25 insertions(+) create mode 100644 osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs diff --git a/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs b/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs new file mode 100644 index 0000000000..f95851f646 --- /dev/null +++ b/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.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 NUnit.Framework; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Osu; + +namespace osu.Game.Tests.Visual.Editing +{ + public partial class TestScenePreviewTime : EditorTestScene + { + protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); + + [Test] + public void TestSetPreviewTimingPoint() + { + AddStep("seek to 1000", () => EditorClock.Seek(1000)); + AddAssert("time is 1000", () => EditorClock.CurrentTime == 1000); + AddStep("set current time as preview point", () => Editor.SetCurrectTimeAsPreview()); + AddAssert("preview time is 1000", () => EditorBeatmap.PreviewTime.Value == 1000); + } + } +} diff --git a/osu.Game/Tests/Visual/EditorTestScene.cs b/osu.Game/Tests/Visual/EditorTestScene.cs index 833c12ba54..9944a561ca 100644 --- a/osu.Game/Tests/Visual/EditorTestScene.cs +++ b/osu.Game/Tests/Visual/EditorTestScene.cs @@ -102,6 +102,8 @@ namespace osu.Game.Tests.Visual public new void Redo() => base.Redo(); + public new void SetCurrectTimeAsPreview() => base.SetCurrectTimeAsPreview(); + public new bool Save() => base.Save(); public new void Cut() => base.Cut(); From 467e87902198e8ba3a83653dde6992e2382769f9 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 12 Dec 2022 01:25:56 +0300 Subject: [PATCH 1047/2991] Migrate osu! iOS to .NET 6 and target iOS 13.4 --- README.md | 2 +- .../Application.cs | 3 +- osu.Game.Rulesets.Catch.Tests.iOS/Info.plist | 2 +- .../osu.Game.Rulesets.Catch.Tests.iOS.csproj | 28 +--- .../Application.cs | 3 +- osu.Game.Rulesets.Mania.Tests.iOS/Info.plist | 2 +- .../osu.Game.Rulesets.Mania.Tests.iOS.csproj | 28 +--- .../Application.cs | 3 +- osu.Game.Rulesets.Osu.Tests.iOS/Info.plist | 2 +- .../osu.Game.Rulesets.Osu.Tests.iOS.csproj | 29 +---- .../Application.cs | 3 +- osu.Game.Rulesets.Taiko.Tests.iOS/Info.plist | 2 +- .../osu.Game.Rulesets.Taiko.Tests.iOS.csproj | 28 +--- osu.Game.Tests.iOS/Application.cs | 3 +- osu.Game.Tests.iOS/Info.plist | 2 +- osu.Game.Tests.iOS/osu.Game.Tests.iOS.csproj | 44 ++----- osu.iOS.props | 80 +++--------- osu.iOS/Application.cs | 3 +- osu.iOS/Info.plist | 2 +- osu.iOS/osu.iOS.csproj | 123 ++---------------- 20 files changed, 72 insertions(+), 320 deletions(-) diff --git a/README.md b/README.md index 75d61dad4d..0de82eba75 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ If you are looking to install or test osu! without setting up a development envi **Latest build:** -| [Windows 8.1+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | macOS 10.15+ ([Intel](https://github.com/ppy/osu/releases/latest/download/osu.app.Intel.zip), [Apple Silicon](https://github.com/ppy/osu/releases/latest/download/osu.app.Apple.Silicon.zip)) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS 10+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) | +| [Windows 8.1+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | macOS 10.15+ ([Intel](https://github.com/ppy/osu/releases/latest/download/osu.app.Intel.zip), [Apple Silicon](https://github.com/ppy/osu/releases/latest/download/osu.app.Apple.Silicon.zip)) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS 13.4+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) | | ------------- | ------------- | ------------- | ------------- | ------------- | - The iOS testflight link may fill up (Apple has a hard limit of 10,000 users). We reset it occasionally when this happens. Please do not ask about this. Check back regularly for link resets or follow [peppy](https://twitter.com/ppy) on twitter for announcements of link resets. diff --git a/osu.Game.Rulesets.Catch.Tests.iOS/Application.cs b/osu.Game.Rulesets.Catch.Tests.iOS/Application.cs index 71d943ece1..1fcb0aa427 100644 --- a/osu.Game.Rulesets.Catch.Tests.iOS/Application.cs +++ b/osu.Game.Rulesets.Catch.Tests.iOS/Application.cs @@ -3,7 +3,6 @@ #nullable disable -using osu.Framework.iOS; using UIKit; namespace osu.Game.Rulesets.Catch.Tests.iOS @@ -12,7 +11,7 @@ namespace osu.Game.Rulesets.Catch.Tests.iOS { public static void Main(string[] args) { - UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate)); + UIApplication.Main(args, null, typeof(AppDelegate)); } } } diff --git a/osu.Game.Rulesets.Catch.Tests.iOS/Info.plist b/osu.Game.Rulesets.Catch.Tests.iOS/Info.plist index 16a2b99997..5ace6c07f5 100644 --- a/osu.Game.Rulesets.Catch.Tests.iOS/Info.plist +++ b/osu.Game.Rulesets.Catch.Tests.iOS/Info.plist @@ -13,7 +13,7 @@ LSRequiresIPhoneOS MinimumOSVersion - 10.0 + 13.4 UIDeviceFamily 1 diff --git a/osu.Game.Rulesets.Catch.Tests.iOS/osu.Game.Rulesets.Catch.Tests.iOS.csproj b/osu.Game.Rulesets.Catch.Tests.iOS/osu.Game.Rulesets.Catch.Tests.iOS.csproj index be6044bbd0..acf12bb0ac 100644 --- a/osu.Game.Rulesets.Catch.Tests.iOS/osu.Game.Rulesets.Catch.Tests.iOS.csproj +++ b/osu.Game.Rulesets.Catch.Tests.iOS/osu.Game.Rulesets.Catch.Tests.iOS.csproj @@ -1,35 +1,19 @@ - - + - Debug - iPhoneSimulator - {4004C7B7-1A62-43F1-9DF2-52450FA67E70} Exe + net6.0-ios + 13.4 osu.Game.Rulesets.Catch.Tests osu.Game.Rulesets.Catch.Tests.iOS - - - - Linker.xml - - - %(RecursiveDir)%(Filename)%(Extension) - - {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D} - osu.Game - - - {58F6C80C-1253-4A0E-A465-B8C85EBEADF3} - osu.Game.Rulesets.Catch - + + - - \ No newline at end of file + diff --git a/osu.Game.Rulesets.Mania.Tests.iOS/Application.cs b/osu.Game.Rulesets.Mania.Tests.iOS/Application.cs index 2d1015387a..a508198f7f 100644 --- a/osu.Game.Rulesets.Mania.Tests.iOS/Application.cs +++ b/osu.Game.Rulesets.Mania.Tests.iOS/Application.cs @@ -3,7 +3,6 @@ #nullable disable -using osu.Framework.iOS; using UIKit; namespace osu.Game.Rulesets.Mania.Tests.iOS @@ -12,7 +11,7 @@ namespace osu.Game.Rulesets.Mania.Tests.iOS { public static void Main(string[] args) { - UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate)); + UIApplication.Main(args, null, typeof(AppDelegate)); } } } diff --git a/osu.Game.Rulesets.Mania.Tests.iOS/Info.plist b/osu.Game.Rulesets.Mania.Tests.iOS/Info.plist index 82d1c8ea24..ff5dde856e 100644 --- a/osu.Game.Rulesets.Mania.Tests.iOS/Info.plist +++ b/osu.Game.Rulesets.Mania.Tests.iOS/Info.plist @@ -13,7 +13,7 @@ LSRequiresIPhoneOS MinimumOSVersion - 10.0 + 13.4 UIDeviceFamily 1 diff --git a/osu.Game.Rulesets.Mania.Tests.iOS/osu.Game.Rulesets.Mania.Tests.iOS.csproj b/osu.Game.Rulesets.Mania.Tests.iOS/osu.Game.Rulesets.Mania.Tests.iOS.csproj index 88ad484bc1..51e07dd6c1 100644 --- a/osu.Game.Rulesets.Mania.Tests.iOS/osu.Game.Rulesets.Mania.Tests.iOS.csproj +++ b/osu.Game.Rulesets.Mania.Tests.iOS/osu.Game.Rulesets.Mania.Tests.iOS.csproj @@ -1,35 +1,19 @@ - - + - Debug - iPhoneSimulator - {39FD990E-B6CE-4B2A-999F-BC008CF2C64C} Exe + net6.0-ios + 13.4 osu.Game.Rulesets.Mania.Tests osu.Game.Rulesets.Mania.Tests.iOS - - - - Linker.xml - - - %(RecursiveDir)%(Filename)%(Extension) - - {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D} - osu.Game - - - {48F4582B-7687-4621-9CBE-5C24197CB536} - osu.Game.Rulesets.Mania - + + - - \ No newline at end of file + diff --git a/osu.Game.Rulesets.Osu.Tests.iOS/Application.cs b/osu.Game.Rulesets.Osu.Tests.iOS/Application.cs index ad23f3ee33..6ef29fa68e 100644 --- a/osu.Game.Rulesets.Osu.Tests.iOS/Application.cs +++ b/osu.Game.Rulesets.Osu.Tests.iOS/Application.cs @@ -3,7 +3,6 @@ #nullable disable -using osu.Framework.iOS; using UIKit; namespace osu.Game.Rulesets.Osu.Tests.iOS @@ -12,7 +11,7 @@ namespace osu.Game.Rulesets.Osu.Tests.iOS { public static void Main(string[] args) { - UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate)); + UIApplication.Main(args, null, typeof(AppDelegate)); } } } diff --git a/osu.Game.Rulesets.Osu.Tests.iOS/Info.plist b/osu.Game.Rulesets.Osu.Tests.iOS/Info.plist index a88b74695c..1e33f2ff16 100644 --- a/osu.Game.Rulesets.Osu.Tests.iOS/Info.plist +++ b/osu.Game.Rulesets.Osu.Tests.iOS/Info.plist @@ -13,7 +13,7 @@ LSRequiresIPhoneOS MinimumOSVersion - 10.0 + 13.4 UIDeviceFamily 1 diff --git a/osu.Game.Rulesets.Osu.Tests.iOS/osu.Game.Rulesets.Osu.Tests.iOS.csproj b/osu.Game.Rulesets.Osu.Tests.iOS/osu.Game.Rulesets.Osu.Tests.iOS.csproj index 545abcec6c..7d50deb8ba 100644 --- a/osu.Game.Rulesets.Osu.Tests.iOS/osu.Game.Rulesets.Osu.Tests.iOS.csproj +++ b/osu.Game.Rulesets.Osu.Tests.iOS/osu.Game.Rulesets.Osu.Tests.iOS.csproj @@ -1,35 +1,20 @@ - - + - Debug - iPhoneSimulator - {6653CA6F-DB06-4604-A3FD-762E25C2AF96} + Exe + net6.0-ios + 13.4 Exe osu.Game.Rulesets.Osu.Tests osu.Game.Rulesets.Osu.Tests.iOS - - - - Linker.xml - - - %(RecursiveDir)%(Filename)%(Extension) - - {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D} - osu.Game - - - {C92A607B-1FDD-4954-9F92-03FF547D9080} - osu.Game.Rulesets.Osu - + + - - \ No newline at end of file + diff --git a/osu.Game.Rulesets.Taiko.Tests.iOS/Application.cs b/osu.Game.Rulesets.Taiko.Tests.iOS/Application.cs index 1ebbd61a94..0e3a953728 100644 --- a/osu.Game.Rulesets.Taiko.Tests.iOS/Application.cs +++ b/osu.Game.Rulesets.Taiko.Tests.iOS/Application.cs @@ -3,7 +3,6 @@ #nullable disable -using osu.Framework.iOS; using UIKit; namespace osu.Game.Rulesets.Taiko.Tests.iOS @@ -12,7 +11,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.iOS { public static void Main(string[] args) { - UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate)); + UIApplication.Main(args, null, typeof(AppDelegate)); } } } diff --git a/osu.Game.Rulesets.Taiko.Tests.iOS/Info.plist b/osu.Game.Rulesets.Taiko.Tests.iOS/Info.plist index 9628475b3e..76cb3c0db0 100644 --- a/osu.Game.Rulesets.Taiko.Tests.iOS/Info.plist +++ b/osu.Game.Rulesets.Taiko.Tests.iOS/Info.plist @@ -13,7 +13,7 @@ LSRequiresIPhoneOS MinimumOSVersion - 10.0 + 13.4 UIDeviceFamily 1 diff --git a/osu.Game.Rulesets.Taiko.Tests.iOS/osu.Game.Rulesets.Taiko.Tests.iOS.csproj b/osu.Game.Rulesets.Taiko.Tests.iOS/osu.Game.Rulesets.Taiko.Tests.iOS.csproj index 8ee640cd99..e648a11299 100644 --- a/osu.Game.Rulesets.Taiko.Tests.iOS/osu.Game.Rulesets.Taiko.Tests.iOS.csproj +++ b/osu.Game.Rulesets.Taiko.Tests.iOS/osu.Game.Rulesets.Taiko.Tests.iOS.csproj @@ -1,35 +1,19 @@ - - + - Debug - iPhoneSimulator - {7E408809-66AC-49D1-AF4D-98834F9B979A} Exe + net6.0-ios + 13.4 osu.Game.Rulesets.Taiko.Tests osu.Game.Rulesets.Taiko.Tests.iOS - - - - Linker.xml - - - %(RecursiveDir)%(Filename)%(Extension) - - {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D} - osu.Game - - - {F167E17A-7DE6-4AF5-B920-A5112296C695} - osu.Game.Rulesets.Taiko - + + - - \ No newline at end of file + diff --git a/osu.Game.Tests.iOS/Application.cs b/osu.Game.Tests.iOS/Application.cs index cf36fea139..4678be4fb8 100644 --- a/osu.Game.Tests.iOS/Application.cs +++ b/osu.Game.Tests.iOS/Application.cs @@ -3,7 +3,6 @@ #nullable disable -using osu.Framework.iOS; using UIKit; namespace osu.Game.Tests.iOS @@ -12,7 +11,7 @@ namespace osu.Game.Tests.iOS { public static void Main(string[] args) { - UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate)); + UIApplication.Main(args, null, typeof(AppDelegate)); } } } diff --git a/osu.Game.Tests.iOS/Info.plist b/osu.Game.Tests.iOS/Info.plist index 31e2b3f257..ac661f6263 100644 --- a/osu.Game.Tests.iOS/Info.plist +++ b/osu.Game.Tests.iOS/Info.plist @@ -13,7 +13,7 @@ LSRequiresIPhoneOS MinimumOSVersion - 10.0 + 13.4 UIDeviceFamily 1 diff --git a/osu.Game.Tests.iOS/osu.Game.Tests.iOS.csproj b/osu.Game.Tests.iOS/osu.Game.Tests.iOS.csproj index 05b3cad6da..79771fcd50 100644 --- a/osu.Game.Tests.iOS/osu.Game.Tests.iOS.csproj +++ b/osu.Game.Tests.iOS/osu.Game.Tests.iOS.csproj @@ -1,54 +1,26 @@ - - + - Debug - iPhoneSimulator Exe - {65FF8E19-6934-469B-B690-23C6D6E56A17} + net6.0-ios + 13.4 osu.Game.Tests osu.Game.Tests.iOS - - - - Linker.xml - - - %(RecursiveDir)%(Filename)%(Extension) - - $(NoWarn);CA2007 - - - {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D} - osu.Game - - - {C92A607B-1FDD-4954-9F92-03FF547D9080} - osu.Game.Rulesets.Osu - - - {58F6C80C-1253-4A0E-A465-B8C85EBEADF3} - osu.Game.Rulesets.Catch - - - {48F4582B-7687-4621-9CBE-5C24197CB536} - osu.Game.Rulesets.Mania - - - {F167E17A-7DE6-4AF5-B920-A5112296C695} - osu.Game.Rulesets.Taiko - + + + + + - diff --git a/osu.iOS.props b/osu.iOS.props index 184e3303c8..d67248f8e0 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -1,72 +1,14 @@  - 8.0 - {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Resources - PackageReference - bin\$(Platform)\$(Configuration) - cjk,mideast,other,rare,west - false - NSUrlSessionHandler - iPhone Developer + true true - - - --nosymbolstrip=BASS_FX_BPM_BeatCallbackReset --nosymbolstrip=BASS_FX_BPM_BeatCallbackSet --nosymbolstrip=BASS_FX_BPM_BeatDecodeGet --nosymbolstrip=BASS_FX_BPM_BeatFree --nosymbolstrip=BASS_FX_BPM_BeatGetParameters --nosymbolstrip=BASS_FX_BPM_BeatSetParameters --nosymbolstrip=BASS_FX_BPM_CallbackReset --nosymbolstrip=BASS_FX_BPM_CallbackSet --nosymbolstrip=BASS_FX_BPM_DecodeGet --nosymbolstrip=BASS_FX_BPM_Free --nosymbolstrip=BASS_FX_BPM_Translate --nosymbolstrip=BASS_FX_GetVersion --nosymbolstrip=BASS_FX_ReverseCreate --nosymbolstrip=BASS_FX_ReverseGetSource --nosymbolstrip=BASS_FX_TempoCreate --nosymbolstrip=BASS_FX_TempoGetRateRatio --nosymbolstrip=BASS_FX_TempoGetSource --nosymbolstrip=BASS_Mixer_ChannelFlags --nosymbolstrip=BASS_Mixer_ChannelGetData --nosymbolstrip=BASS_Mixer_ChannelGetEnvelopePos --nosymbolstrip=BASS_Mixer_ChannelGetLevel --nosymbolstrip=BASS_Mixer_ChannelGetLevelEx --nosymbolstrip=BASS_Mixer_ChannelGetMatrix --nosymbolstrip=BASS_Mixer_ChannelGetMixer --nosymbolstrip=BASS_Mixer_ChannelGetPosition --nosymbolstrip=BASS_Mixer_ChannelGetPositionEx --nosymbolstrip=BASS_Mixer_ChannelIsActive --nosymbolstrip=BASS_Mixer_ChannelRemove --nosymbolstrip=BASS_Mixer_ChannelRemoveSync --nosymbolstrip=BASS_Mixer_ChannelSetEnvelope --nosymbolstrip=BASS_Mixer_ChannelSetEnvelopePos --nosymbolstrip=BASS_Mixer_ChannelSetMatrix --nosymbolstrip=BASS_Mixer_ChannelSetMatrixEx --nosymbolstrip=BASS_Mixer_ChannelSetPosition --nosymbolstrip=BASS_Mixer_ChannelSetSync --nosymbolstrip=BASS_Mixer_GetVersion --nosymbolstrip=BASS_Mixer_StreamAddChannel --nosymbolstrip=BASS_Mixer_StreamAddChannelEx --nosymbolstrip=BASS_Mixer_StreamCreate --nosymbolstrip=BASS_Mixer_StreamGetChannels --nosymbolstrip=BASS_Split_StreamCreate --nosymbolstrip=BASS_Split_StreamGetAvailable --nosymbolstrip=BASS_Split_StreamGetSource --nosymbolstrip=BASS_Split_StreamGetSplits --nosymbolstrip=BASS_Split_StreamReset --nosymbolstrip=BASS_Split_StreamResetEx - - --nolinkaway --nostrip $(GeneratedMtouchSymbolStripFlags) - - - true - full - false - DEBUG;ENABLE_TEST_CLOUD; - true - true - - - pdbonly - true + + ios-arm64 - x86_64 - None - - - true - SdkOnly - ARM64 - Entitlements.plist - - - true - 25823 - false - - - true - - - true - 28126 - - - - - - - - - - - - - - - - $(NoWarn);NU1605 + iossimulator-x64 @@ -77,6 +19,9 @@ none + + + @@ -86,7 +31,16 @@ - + + + + + + <_LinkerFrameworks Remove="Quartz"/> + + diff --git a/osu.iOS/Application.cs b/osu.iOS/Application.cs index c5b2d0b451..64eb5c63f5 100644 --- a/osu.iOS/Application.cs +++ b/osu.iOS/Application.cs @@ -3,7 +3,6 @@ #nullable disable -using osu.Framework.iOS; using UIKit; namespace osu.iOS @@ -12,7 +11,7 @@ namespace osu.iOS { public static void Main(string[] args) { - UIApplication.Main(args, typeof(GameUIApplication), typeof(AppDelegate)); + UIApplication.Main(args, null, typeof(AppDelegate)); } } } diff --git a/osu.iOS/Info.plist b/osu.iOS/Info.plist index 16cb68fa7d..c4b08ab78e 100644 --- a/osu.iOS/Info.plist +++ b/osu.iOS/Info.plist @@ -15,7 +15,7 @@ LSRequiresIPhoneOS MinimumOSVersion - 10.0 + 13.4 UIDeviceFamily 1 diff --git a/osu.iOS/osu.iOS.csproj b/osu.iOS/osu.iOS.csproj index b9da874f30..95ca3e2142 100644 --- a/osu.iOS/osu.iOS.csproj +++ b/osu.iOS/osu.iOS.csproj @@ -1,124 +1,19 @@ - - - - Debug - iPhoneSimulator + + + net6.0-ios + 13.4 Exe - {3F082D0B-A964-43D7-BDF7-C256D76A50D0} - osu.iOS - osu.iOS false - - - - - - - - - - - - - - - - - - - - - {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D} - osu.Game - - - {58F6C80C-1253-4A0E-A465-B8C85EBEADF3} - osu.Game.Rulesets.Catch - - - {48F4582B-7687-4621-9CBE-5C24197CB536} - osu.Game.Rulesets.Mania - - - {C92A607B-1FDD-4954-9F92-03FF547D9080} - osu.Game.Rulesets.Osu - - - {F167E17A-7DE6-4AF5-B920-A5112296C695} - osu.Game.Rulesets.Taiko - - - - - - - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - + + + + + - From c900965a82d5c0ab86d9c017015a17eef45e4773 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 12 Dec 2022 01:26:13 +0300 Subject: [PATCH 1048/2991] Replace `Xamarin.Essentials` with .NET MAUI Essentials --- osu.iOS/OsuGameIOS.cs | 2 +- osu.iOS/osu.iOS.csproj | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.iOS/OsuGameIOS.cs b/osu.iOS/OsuGameIOS.cs index b3194e497b..cb3b260033 100644 --- a/osu.iOS/OsuGameIOS.cs +++ b/osu.iOS/OsuGameIOS.cs @@ -5,6 +5,7 @@ using System; using Foundation; +using Microsoft.Maui.Devices; using osu.Framework.Graphics; using osu.Framework.Input.Handlers; using osu.Framework.iOS.Input; @@ -12,7 +13,6 @@ using osu.Game; using osu.Game.Overlays.Settings; using osu.Game.Updater; using osu.Game.Utils; -using Xamarin.Essentials; namespace osu.iOS { diff --git a/osu.iOS/osu.iOS.csproj b/osu.iOS/osu.iOS.csproj index 95ca3e2142..ce19cb7ee6 100644 --- a/osu.iOS/osu.iOS.csproj +++ b/osu.iOS/osu.iOS.csproj @@ -4,6 +4,7 @@ 13.4 Exe false + true @@ -13,7 +14,4 @@ - - - From e85975b5f1269c7c2a106be6e677fd4d029630e0 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 12 Dec 2022 01:28:01 +0300 Subject: [PATCH 1049/2991] Work around JIT compilation error in Realm --- osu.iOS.props | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.iOS.props b/osu.iOS.props index d67248f8e0..4a0fe55d4e 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -3,6 +3,8 @@ iPhone Developer true true + + true ios-arm64 From 660cc72f2a36f89c75567f3910bdaee52b8e955b Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 12 Dec 2022 01:30:49 +0300 Subject: [PATCH 1050/2991] Avoid configuring web proxies on iOS for now --- osu.Game/Online/HubClientConnector.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/osu.Game/Online/HubClientConnector.cs b/osu.Game/Online/HubClientConnector.cs index ca6d2932f7..ff63c0657c 100644 --- a/osu.Game/Online/HubClientConnector.cs +++ b/osu.Game/Online/HubClientConnector.cs @@ -59,11 +59,15 @@ namespace osu.Game.Online var builder = new HubConnectionBuilder() .WithUrl(endpoint, options => { - // Use HttpClient.DefaultProxy once on net6 everywhere. - // The credential setter can also be removed at this point. - options.Proxy = WebRequest.DefaultWebProxy; - if (options.Proxy != null) - options.Proxy.Credentials = CredentialCache.DefaultCredentials; + // Configuring proxies is not supported on iOS, see https://github.com/xamarin/xamarin-macios/issues/14632. + if (RuntimeInfo.OS != RuntimeInfo.Platform.iOS) + { + // Use HttpClient.DefaultProxy once on net6 everywhere. + // The credential setter can also be removed at this point. + options.Proxy = WebRequest.DefaultWebProxy; + if (options.Proxy != null) + options.Proxy.Credentials = CredentialCache.DefaultCredentials; + } options.Headers.Add("Authorization", $"Bearer {api.AccessToken}"); options.Headers.Add("OsuVersionHash", versionHash); From 5fbd4ad3b467414e925b29e118654e91637fe8c1 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 14 Dec 2022 17:01:05 +0300 Subject: [PATCH 1051/2991] Update usages of `SupportsJIT` in line with framework changes --- osu.Game/Online/HubClientConnector.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/HubClientConnector.cs b/osu.Game/Online/HubClientConnector.cs index ff63c0657c..8fd79bd703 100644 --- a/osu.Game/Online/HubClientConnector.cs +++ b/osu.Game/Online/HubClientConnector.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.SignalR.Client; @@ -73,7 +74,7 @@ namespace osu.Game.Online options.Headers.Add("OsuVersionHash", versionHash); }); - if (RuntimeInfo.SupportsJIT && preferMessagePack) + if (RuntimeFeature.IsDynamicCodeCompiled && preferMessagePack) { builder.AddMessagePackProtocol(options => { From b488421c7aa0fd7431043d09695f2f0a4978a808 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 15 Dec 2022 12:24:17 +0300 Subject: [PATCH 1052/2991] Remove `MtouchUseLlvm` key for now I haven't found a way to disable LLVM, and the issue may potentially be resolved (doesn't occur for me), so we might as well just remove the key for now. --- osu.iOS/osu.iOS.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.iOS/osu.iOS.csproj b/osu.iOS/osu.iOS.csproj index ce19cb7ee6..def538af1a 100644 --- a/osu.iOS/osu.iOS.csproj +++ b/osu.iOS/osu.iOS.csproj @@ -3,7 +3,6 @@ net6.0-ios 13.4 Exe - false true From d791bc56e7b64980b2969c8ea1ceefe4b4450da7 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 15 Dec 2022 14:43:41 +0300 Subject: [PATCH 1053/2991] Remove transitive dependencies --- osu.iOS.props | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/osu.iOS.props b/osu.iOS.props index 4a0fe55d4e..064ee5cceb 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -2,7 +2,6 @@ iPhone Developer true - true true @@ -24,19 +23,6 @@ - - - - - - - - - - - - - From 2c78fed5e4511c43c2d02e6a8fb268a28f80a967 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 15 Dec 2022 18:21:23 +0300 Subject: [PATCH 1054/2991] Update workflows in line with framework changes --- .github/workflows/ci.yml | 8 ++++---- appveyor.yml | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 56b3ebe87b..798e54e155 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -132,8 +132,8 @@ jobs: with: dotnet-version: "6.0.x" - # Contrary to seemingly any other msbuild, msbuild running on macOS/Mono - # cannot accept .sln(f) files as arguments. - # Build just the main game for now. + - name: Install .NET Workloads + run: dotnet workload install maui-ios + - name: Build - run: msbuild osu.iOS/osu.iOS.csproj /restore /p:Configuration=Debug + run: dotnet build -c Debug osu.iOS diff --git a/appveyor.yml b/appveyor.yml index 5be73f9875..19ef6ae63f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ clone_depth: 1 version: '{branch}-{build}' -image: Visual Studio 2019 +image: Visual Studio 2022 cache: - '%LOCALAPPDATA%\NuGet\v3-cache -> appveyor.yml' @@ -11,6 +11,7 @@ dotnet_csproj: before_build: - cmd: dotnet --info # Useful when version mismatch between CI and local + - cmd: dotnet workload install maui-ios # Change to `dotnet workload restore` once there's no old projects - cmd: nuget restore -verbosity quiet # Only nuget.exe knows both new (.NET Core) and old (Xamarin) projects build: From 67787da4cfbc25d4a077e5ebd3b400167039d2f9 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 16 Dec 2022 00:46:32 +0300 Subject: [PATCH 1055/2991] Suppress MT7091 --- osu.iOS.props | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.iOS.props b/osu.iOS.props index 064ee5cceb..9168c019ba 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -4,6 +4,10 @@ true true + + $(NoWarn);MT7091 ios-arm64 From 0f34d908c791692c4d10ff516f8274b0d56a4413 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Fri, 16 Dec 2022 00:05:47 +0100 Subject: [PATCH 1056/2991] Use `LocalisableString`s for date and time formats --- osu.Game/Graphics/DateTooltip.cs | 5 +++-- osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs | 5 ++--- osu.Game/Overlays/Changelog/ChangelogListing.cs | 3 ++- osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs | 3 ++- osu.Game/Overlays/Chat/ChatLine.cs | 5 ++--- .../Overlays/Dashboard/Home/News/FeaturedNewsItemPanel.cs | 5 +++-- osu.Game/Overlays/Dashboard/Home/News/NewsGroupItem.cs | 5 +++-- osu.Game/Overlays/News/Sidebar/MonthSection.cs | 3 ++- osu.Game/Overlays/Toolbar/DigitalClockDisplay.cs | 3 ++- .../Screens/Ranking/Expanded/ExpandedPanelMiddleContent.cs | 4 +++- 10 files changed, 24 insertions(+), 17 deletions(-) diff --git a/osu.Game/Graphics/DateTooltip.cs b/osu.Game/Graphics/DateTooltip.cs index d9bb2b610a..c62f53f1d4 100644 --- a/osu.Game/Graphics/DateTooltip.cs +++ b/osu.Game/Graphics/DateTooltip.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; +using osu.Framework.Localisation; using osu.Game.Graphics.Sprites; using osuTK; @@ -69,8 +70,8 @@ namespace osu.Game.Graphics { DateTimeOffset localDate = date.ToLocalTime(); - dateText.Text = $"{localDate:d MMMM yyyy} "; - timeText.Text = $"{localDate:HH:mm:ss \"UTC\"z}"; + dateText.Text = LocalisableString.Interpolate($"{localDate:d MMMM yyyy} "); + timeText.Text = LocalisableString.Interpolate($"{localDate:HH:mm:ss \"UTC\"z}"); } public void Move(Vector2 pos) => Position = pos; diff --git a/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs b/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs index 170f266307..0b2e401f57 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs @@ -136,9 +136,8 @@ namespace osu.Game.Online.Leaderboards { if (displayedScore != null) { - timestampLabel.Text = prefer24HourTime.Value - ? $"Played on {displayedScore.Date.ToLocalTime():d MMMM yyyy HH:mm}" - : $"Played on {displayedScore.Date.ToLocalTime():d MMMM yyyy h:mm tt}"; + timestampLabel.Text = LocalisableString.Format("Played on {0}", + displayedScore.Date.ToLocalTime().ToLocalisableString(prefer24HourTime.Value ? @"d MMMM yyyy HH:mm" : @"d MMMM yyyy h:mm tt")); } } diff --git a/osu.Game/Overlays/Changelog/ChangelogListing.cs b/osu.Game/Overlays/Changelog/ChangelogListing.cs index d30fd97652..d7c9ff67fe 100644 --- a/osu.Game/Overlays/Changelog/ChangelogListing.cs +++ b/osu.Game/Overlays/Changelog/ChangelogListing.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; +using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -51,7 +52,7 @@ namespace osu.Game.Overlays.Changelog Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Margin = new MarginPadding { Top = 20 }, - Text = build.CreatedAt.Date.ToString("dd MMMM yyyy"), + Text = build.CreatedAt.Date.ToLocalisableString("dd MMMM yyyy"), Font = OsuFont.GetFont(weight: FontWeight.Regular, size: 24), }); diff --git a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs index a729ef2cc8..13a19de22a 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSingleBuild.cs @@ -7,6 +7,7 @@ using System; using System.Threading; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -114,7 +115,7 @@ namespace osu.Game.Overlays.Changelog { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - Text = Build.CreatedAt.Date.ToString("dd MMMM yyyy"), + Text = Build.CreatedAt.Date.ToLocalisableString("dd MMMM yyyy"), Font = OsuFont.GetFont(weight: FontWeight.Regular, size: 14), Margin = new MarginPadding { Top = 5 }, Scale = new Vector2(1.25f), diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index 2b8718939e..70c3bf181c 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -175,9 +176,7 @@ namespace osu.Game.Overlays.Chat private void updateTimestamp() { - drawableTimestamp.Text = prefer24HourTime.Value - ? $@"{message.Timestamp.LocalDateTime:HH:mm:ss}" - : $@"{message.Timestamp.LocalDateTime:hh:mm:ss tt}"; + drawableTimestamp.Text = message.Timestamp.LocalDateTime.ToLocalisableString(prefer24HourTime.Value ? @"HH:mm:ss" : @"hh:mm:ss tt"); } } } diff --git a/osu.Game/Overlays/Dashboard/Home/News/FeaturedNewsItemPanel.cs b/osu.Game/Overlays/Dashboard/Home/News/FeaturedNewsItemPanel.cs index 3066d253eb..dabe65964a 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/FeaturedNewsItemPanel.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/FeaturedNewsItemPanel.cs @@ -5,6 +5,7 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; @@ -167,7 +168,7 @@ namespace osu.Game.Overlays.Dashboard.Home.News Origin = Anchor.TopRight, Font = OsuFont.GetFont(weight: FontWeight.Bold), // using Bold since there is no 800 weight alternative Colour = colourProvider.Light1, - Text = $"{date:dd}" + Text = date.ToLocalisableString(@"dd") }, new TextFlowContainer(f => { @@ -178,7 +179,7 @@ namespace osu.Game.Overlays.Dashboard.Home.News Anchor = Anchor.TopRight, Origin = Anchor.TopRight, AutoSizeAxes = Axes.Both, - Text = $"{date:MMM yyyy}" + Text = date.ToLocalisableString(@"MMM yyyy") } } }; diff --git a/osu.Game/Overlays/Dashboard/Home/News/NewsGroupItem.cs b/osu.Game/Overlays/Dashboard/Home/News/NewsGroupItem.cs index e277a5fa16..9b27d1a193 100644 --- a/osu.Game/Overlays/Dashboard/Home/News/NewsGroupItem.cs +++ b/osu.Game/Overlays/Dashboard/Home/News/NewsGroupItem.cs @@ -5,6 +5,7 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; @@ -98,12 +99,12 @@ namespace osu.Game.Overlays.Dashboard.Home.News Margin = new MarginPadding { Vertical = 5 } }; - textFlow.AddText($"{date:dd}", t => + textFlow.AddText(date.ToLocalisableString(@"dd"), t => { t.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold); }); - textFlow.AddText($"{date: MMM}", t => + textFlow.AddText(date.ToLocalisableString(@" MMM"), t => { t.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Regular); }); diff --git a/osu.Game/Overlays/News/Sidebar/MonthSection.cs b/osu.Game/Overlays/News/Sidebar/MonthSection.cs index d205fcb908..30d29048ba 100644 --- a/osu.Game/Overlays/News/Sidebar/MonthSection.cs +++ b/osu.Game/Overlays/News/Sidebar/MonthSection.cs @@ -19,6 +19,7 @@ using osu.Framework.Graphics.Sprites; using System.Diagnostics; using osu.Framework.Audio; using osu.Framework.Audio.Sample; +using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Platform; namespace osu.Game.Overlays.News.Sidebar @@ -99,7 +100,7 @@ namespace osu.Game.Overlays.News.Sidebar Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), - Text = date.ToString("MMM yyyy") + Text = date.ToLocalisableString(@"MMM yyyy") }, icon = new SpriteIcon { diff --git a/osu.Game/Overlays/Toolbar/DigitalClockDisplay.cs b/osu.Game/Overlays/Toolbar/DigitalClockDisplay.cs index bc803db739..ada2f6ff86 100644 --- a/osu.Game/Overlays/Toolbar/DigitalClockDisplay.cs +++ b/osu.Game/Overlays/Toolbar/DigitalClockDisplay.cs @@ -5,6 +5,7 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -69,7 +70,7 @@ namespace osu.Game.Overlays.Toolbar protected override void UpdateDisplay(DateTimeOffset now) { - realTime.Text = use24HourDisplay ? $"{now:HH:mm:ss}" : $"{now:h:mm:ss tt}"; + realTime.Text = now.ToLocalisableString(use24HourDisplay ? @"HH:mm:ss" : @"h:mm:ss tt"); gameTime.Text = $"running {new TimeSpan(TimeSpan.TicksPerSecond * (int)(Clock.CurrentTime / 1000)):c}"; } diff --git a/osu.Game/Screens/Ranking/Expanded/ExpandedPanelMiddleContent.cs b/osu.Game/Screens/Ranking/Expanded/ExpandedPanelMiddleContent.cs index 8fe0ae509b..f23b469f5c 100644 --- a/osu.Game/Screens/Ranking/Expanded/ExpandedPanelMiddleContent.cs +++ b/osu.Game/Screens/Ranking/Expanded/ExpandedPanelMiddleContent.cs @@ -9,6 +9,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions; +using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Localisation; @@ -309,7 +310,8 @@ namespace osu.Game.Screens.Ranking.Expanded private void updateDisplay() { - Text = prefer24HourTime.Value ? $"Played on {time.ToLocalTime():d MMMM yyyy HH:mm}" : $"Played on {time.ToLocalTime():d MMMM yyyy h:mm tt}"; + Text = LocalisableString.Format("Played on {0}", + time.ToLocalTime().ToLocalisableString(prefer24HourTime.Value ? @"d MMMM yyyy HH:mm" : @"d MMMM yyyy h:mm tt")); } } } From f0246df1a9751da8826b215a69725f14571572f5 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Fri, 16 Dec 2022 09:58:58 +0900 Subject: [PATCH 1057/2991] only get; --- osu.Game/Screens/Edit/EditorBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 0a0557a992..1059654077 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -86,7 +86,7 @@ namespace osu.Game.Screens.Edit [Resolved] private EditorClock editorClock { get; set; } - public BindableInt PreviewTime; + public BindableInt PreviewTime { get; } private readonly IBeatmapProcessor beatmapProcessor; From 79e27c2d9d7dbeb1444de238a72686cb90c26053 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Fri, 16 Dec 2022 10:44:07 +0900 Subject: [PATCH 1058/2991] `PreviewTimePart` will not show if preview time is -1 --- .../Visual/Editing/TestScenePreviewTime.cs | 14 +++++++++++++- .../Timelines/Summary/Parts/PreviewTimePart.cs | 4 ++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs b/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs index f95851f646..213eb4b175 100644 --- a/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs +++ b/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs @@ -1,9 +1,12 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; using NUnit.Framework; +using osu.Framework.Testing; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; +using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts; namespace osu.Game.Tests.Visual.Editing { @@ -12,12 +15,21 @@ namespace osu.Game.Tests.Visual.Editing protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); [Test] - public void TestSetPreviewTimingPoint() + public void TestSceneSetPreviewTimingPoint() { AddStep("seek to 1000", () => EditorClock.Seek(1000)); AddAssert("time is 1000", () => EditorClock.CurrentTime == 1000); AddStep("set current time as preview point", () => Editor.SetCurrectTimeAsPreview()); AddAssert("preview time is 1000", () => EditorBeatmap.PreviewTime.Value == 1000); } + + [Test] + public void TestScenePreviewTimeline() + { + AddStep("set preview time to -1", () => EditorBeatmap.PreviewTime.Value = -1); + AddAssert("preview time line should not show", () => Editor.ChildrenOfType().Single().Alpha == 0); + AddStep("set preview time to 1000", () => EditorBeatmap.PreviewTime.Value = 1000); + AddAssert("preview time line should show", () => Editor.ChildrenOfType().Single().Alpha == 1); + } } } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs index a09d93fd5a..6149900fdc 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs @@ -14,6 +14,10 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { base.LoadBeatmap(beatmap); Add(new PreviewTimeVisualisation(beatmap.PreviewTime)); + beatmap.PreviewTime.BindValueChanged(s => + { + Alpha = s.NewValue == -1 ? 0 : 1; + }, true); } private partial class PreviewTimeVisualisation : PointVisualisation From a4d28aff6d73d28515c5a158d8a8152ac6be7eef Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Fri, 16 Dec 2022 10:48:56 +0900 Subject: [PATCH 1059/2991] fix typo --- osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs | 2 +- osu.Game/Screens/Edit/Editor.cs | 4 ++-- osu.Game/Tests/Visual/EditorTestScene.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs b/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs index 213eb4b175..ad49f3ac0a 100644 --- a/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs +++ b/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs @@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual.Editing { AddStep("seek to 1000", () => EditorClock.Seek(1000)); AddAssert("time is 1000", () => EditorClock.CurrentTime == 1000); - AddStep("set current time as preview point", () => Editor.SetCurrectTimeAsPreview()); + AddStep("set current time as preview point", () => Editor.SetCurrentTimeAsPreview()); AddAssert("preview time is 1000", () => EditorBeatmap.PreviewTime.Value == 1000); } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 16fff76ac7..62bb7d3133 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -327,7 +327,7 @@ namespace osu.Game.Screens.Edit { Items = new MenuItem[] { - new EditorMenuItem("Set Current Position as Preview Point", MenuItemType.Standard, SetCurrectTimeAsPreview) + new EditorMenuItem("Set Current Position as Preview Point", MenuItemType.Standard, SetCurrentTimeAsPreview) } } } @@ -808,7 +808,7 @@ namespace osu.Game.Screens.Edit protected void Redo() => changeHandler?.RestoreState(1); - protected void SetCurrectTimeAsPreview() + protected void SetCurrentTimeAsPreview() { editorBeatmap.PreviewTime.Value = (int)clock.CurrentTime; } diff --git a/osu.Game/Tests/Visual/EditorTestScene.cs b/osu.Game/Tests/Visual/EditorTestScene.cs index 9944a561ca..9c8ac65add 100644 --- a/osu.Game/Tests/Visual/EditorTestScene.cs +++ b/osu.Game/Tests/Visual/EditorTestScene.cs @@ -102,7 +102,7 @@ namespace osu.Game.Tests.Visual public new void Redo() => base.Redo(); - public new void SetCurrectTimeAsPreview() => base.SetCurrectTimeAsPreview(); + public new void SetCurrentTimeAsPreview() => base.SetCurrentTimeAsPreview(); public new bool Save() => base.Save(); From e63b544167f4d0aa8c7e808e7a5f38805b360915 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 16 Dec 2022 17:02:51 +0900 Subject: [PATCH 1060/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index c2c74e2c0e..0e5714e90f 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 31cd851c03..9e757b1802 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 9168c019ba..98d3e129d4 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -25,7 +25,7 @@ - + + true true - - osu.licenseheader - - - - - - - - - - - - @@ -61,4 +19,9 @@ + + + true + diff --git a/osu.Android/Properties/AndroidManifest.xml b/osu.Android/AndroidManifest.xml similarity index 98% rename from osu.Android/Properties/AndroidManifest.xml rename to osu.Android/AndroidManifest.xml index 165a64a424..be326be5eb 100644 --- a/osu.Android/Properties/AndroidManifest.xml +++ b/osu.Android/AndroidManifest.xml @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/osu.Android/OsuGameActivity.cs b/osu.Android/OsuGameActivity.cs index be40db7508..ca3d628447 100644 --- a/osu.Android/OsuGameActivity.cs +++ b/osu.Android/OsuGameActivity.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection; using System.Threading.Tasks; using Android.App; using Android.Content; @@ -74,11 +75,23 @@ namespace osu.Android Debug.Assert(Resources?.DisplayMetrics != null); Point displaySize = new Point(); +#pragma warning disable 618 // GetSize is deprecated WindowManager.DefaultDisplay.GetSize(displaySize); +#pragma warning restore 618 float smallestWidthDp = Math.Min(displaySize.X, displaySize.Y) / Resources.DisplayMetrics.Density; bool isTablet = smallestWidthDp >= 600f; RequestedOrientation = DefaultOrientation = isTablet ? ScreenOrientation.FullUser : ScreenOrientation.SensorLandscape; + + // Currently (SDK 6.0.200), BundleAssemblies is not runnable for net6-android. + // The assembly files are not available as files either after native AOT. + // Manually load them so that they can be loaded by RulesetStore.loadFromAppDomain. + // REMEMBER to fully uninstall previous version every time when investigating this! + // Don't forget osu.Game.Tests.Android too. + Assembly.Load("osu.Game.Rulesets.Osu"); + Assembly.Load("osu.Game.Rulesets.Taiko"); + Assembly.Load("osu.Game.Rulesets.Catch"); + Assembly.Load("osu.Game.Rulesets.Mania"); } protected override void OnNewIntent(Intent intent) => handleIntent(intent); @@ -127,7 +140,7 @@ namespace osu.Android cursor.MoveToFirst(); - int filenameColumn = cursor.GetColumnIndex(OpenableColumns.DisplayName); + int filenameColumn = cursor.GetColumnIndex(IOpenableColumns.DisplayName); string filename = cursor.GetString(filenameColumn); // SharpCompress requires archive streams to be seekable, which the stream opened by diff --git a/osu.Android/OsuGameAndroid.cs b/osu.Android/OsuGameAndroid.cs index 1c6f41a7ec..0227d2aec2 100644 --- a/osu.Android/OsuGameAndroid.cs +++ b/osu.Android/OsuGameAndroid.cs @@ -5,7 +5,7 @@ using System; using Android.App; -using Android.OS; +using Microsoft.Maui.Devices; using osu.Framework.Allocation; using osu.Framework.Android.Input; using osu.Framework.Input.Handlers; @@ -14,7 +14,6 @@ using osu.Game; using osu.Game.Overlays.Settings; using osu.Game.Updater; using osu.Game.Utils; -using Xamarin.Essentials; namespace osu.Android { @@ -48,7 +47,7 @@ namespace osu.Android // https://stackoverflow.com/questions/52977079/android-sdk-28-versioncode-in-packageinfo-has-been-deprecated string versionName = string.Empty; - if (Build.VERSION.SdkInt >= BuildVersionCodes.P) + if (OperatingSystem.IsAndroidVersionAtLeast(28)) { versionName = packageInfo.LongVersionCode.ToString(); // ensure we only read the trailing portion of long (the part we are interested in). diff --git a/osu.Android/osu.Android.csproj b/osu.Android/osu.Android.csproj index 004cc8c39c..de53e5dd59 100644 --- a/osu.Android/osu.Android.csproj +++ b/osu.Android/osu.Android.csproj @@ -1,73 +1,19 @@ - - + - Debug - AnyCPU - 8.0.30703 - 2.0 - {D1D5F9A8-B40B-40E6-B02F-482D03346D3D} - {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - {122416d6-6b49-4ee2-a1e8-b825f31c79fe} + net6.0-android + Exe osu.Android osu.Android - Properties\AndroidManifest.xml - armeabi-v7a;x86;arm64-v8a - false - - - cjk;mideast;other;rare;west - d8 - r8 - - - None - cjk;mideast;other;rare;west - true + true + + false - - - - - - + + + + + - - - - - - {58f6c80c-1253-4a0e-a465-b8c85ebeadf3} - osu.Game.Rulesets.Catch - - - {48f4582b-7687-4621-9cbe-5c24197cb536} - osu.Game.Rulesets.Mania - - - {c92a607b-1fdd-4954-9f92-03ff547d9080} - osu.Game.Rulesets.Osu - - - {f167e17a-7de6-4af5-b920-a5112296c695} - osu.Game.Rulesets.Taiko - - - {2a66dd92-adb1-4994-89e2-c94e04acda0d} - osu.Game - - - - - - - - 5.0.0 - - - - - - - \ No newline at end of file + diff --git a/osu.Game.Rulesets.Catch.Tests.Android/Properties/AndroidManifest.xml b/osu.Game.Rulesets.Catch.Tests.Android/AndroidManifest.xml similarity index 98% rename from osu.Game.Rulesets.Catch.Tests.Android/Properties/AndroidManifest.xml rename to osu.Game.Rulesets.Catch.Tests.Android/AndroidManifest.xml index f8c3fcd894..bf7c0bfeca 100644 --- a/osu.Game.Rulesets.Catch.Tests.Android/Properties/AndroidManifest.xml +++ b/osu.Game.Rulesets.Catch.Tests.Android/AndroidManifest.xml @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/osu.Game.Rulesets.Catch.Tests.Android/osu.Game.Rulesets.Catch.Tests.Android.csproj b/osu.Game.Rulesets.Catch.Tests.Android/osu.Game.Rulesets.Catch.Tests.Android.csproj index 94fdba4a3e..4ee3219442 100644 --- a/osu.Game.Rulesets.Catch.Tests.Android/osu.Game.Rulesets.Catch.Tests.Android.csproj +++ b/osu.Game.Rulesets.Catch.Tests.Android/osu.Game.Rulesets.Catch.Tests.Android.csproj @@ -1,49 +1,24 @@ - - + - Debug - AnyCPU - 8.0.30703 - 2.0 - {C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D} - {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - {122416d6-6b49-4ee2-a1e8-b825f31c79fe} + net6.0-android + Exe osu.Game.Rulesets.Catch.Tests osu.Game.Rulesets.Catch.Tests.Android - Properties\AndroidManifest.xml - armeabi-v7a;x86;arm64-v8a - - - None - cjk;mideast;other;rare;west - true - - - - - - - + %(RecursiveDir)%(Filename)%(Extension) + + + %(RecursiveDir)%(Filename)%(Extension) + Android\%(RecursiveDir)%(Filename)%(Extension) + - - {58f6c80c-1253-4a0e-a465-b8c85ebeadf3} - osu.Game.Rulesets.Catch - - - {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D} - osu.Game - + + - - - 5.0.0 - - - \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania.Tests.Android/Properties/AndroidManifest.xml b/osu.Game.Rulesets.Mania.Tests.Android/AndroidManifest.xml similarity index 98% rename from osu.Game.Rulesets.Mania.Tests.Android/Properties/AndroidManifest.xml rename to osu.Game.Rulesets.Mania.Tests.Android/AndroidManifest.xml index de7935b2ef..4a1545a423 100644 --- a/osu.Game.Rulesets.Mania.Tests.Android/Properties/AndroidManifest.xml +++ b/osu.Game.Rulesets.Mania.Tests.Android/AndroidManifest.xml @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania.Tests.Android/osu.Game.Rulesets.Mania.Tests.Android.csproj b/osu.Game.Rulesets.Mania.Tests.Android/osu.Game.Rulesets.Mania.Tests.Android.csproj index 9674186039..25335754d2 100644 --- a/osu.Game.Rulesets.Mania.Tests.Android/osu.Game.Rulesets.Mania.Tests.Android.csproj +++ b/osu.Game.Rulesets.Mania.Tests.Android/osu.Game.Rulesets.Mania.Tests.Android.csproj @@ -1,49 +1,24 @@ - - + - Debug - AnyCPU - 8.0.30703 - 2.0 - {531F1092-DB27-445D-AA33-2A77C7187C99} - {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - {122416d6-6b49-4ee2-a1e8-b825f31c79fe} + net6.0-android + Exe osu.Game.Rulesets.Mania.Tests osu.Game.Rulesets.Mania.Tests.Android - Properties\AndroidManifest.xml - armeabi-v7a;x86;arm64-v8a - - - None - cjk;mideast;other;rare;west - true - - - - - - - + %(RecursiveDir)%(Filename)%(Extension) + + + %(RecursiveDir)%(Filename)%(Extension) + Android\%(RecursiveDir)%(Filename)%(Extension) + - - {48f4582b-7687-4621-9cbe-5c24197cb536} - osu.Game.Rulesets.Mania - - - {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D} - osu.Game - + + - - - 5.0.0 - - - \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu.Tests.Android/Properties/AndroidManifest.xml b/osu.Game.Rulesets.Osu.Tests.Android/AndroidManifest.xml similarity index 98% rename from osu.Game.Rulesets.Osu.Tests.Android/Properties/AndroidManifest.xml rename to osu.Game.Rulesets.Osu.Tests.Android/AndroidManifest.xml index 3ce17ccc27..45d27dda70 100644 --- a/osu.Game.Rulesets.Osu.Tests.Android/Properties/AndroidManifest.xml +++ b/osu.Game.Rulesets.Osu.Tests.Android/AndroidManifest.xml @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu.Tests.Android/osu.Game.Rulesets.Osu.Tests.Android.csproj b/osu.Game.Rulesets.Osu.Tests.Android/osu.Game.Rulesets.Osu.Tests.Android.csproj index f4b673f10b..e8a46a9828 100644 --- a/osu.Game.Rulesets.Osu.Tests.Android/osu.Game.Rulesets.Osu.Tests.Android.csproj +++ b/osu.Game.Rulesets.Osu.Tests.Android/osu.Game.Rulesets.Osu.Tests.Android.csproj @@ -1,49 +1,27 @@ - - + - Debug - AnyCPU - 8.0.30703 - 2.0 - {90CAB706-39CB-4B93-9629-3218A6FF8E9B} - {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - {122416d6-6b49-4ee2-a1e8-b825f31c79fe} + net6.0-android + Exe osu.Game.Rulesets.Osu.Tests osu.Game.Rulesets.Osu.Tests.Android - Properties\AndroidManifest.xml - armeabi-v7a;x86;arm64-v8a - - - None - cjk;mideast;other;rare;west - true - - - - - - - + %(RecursiveDir)%(Filename)%(Extension) + + + %(RecursiveDir)%(Filename)%(Extension) + Android\%(RecursiveDir)%(Filename)%(Extension) + - - {c92a607b-1fdd-4954-9f92-03ff547d9080} - osu.Game.Rulesets.Osu - - - {2a66dd92-adb1-4994-89e2-c94e04acda0d} - osu.Game - + + - - 5.0.0 - + - \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko.Tests.Android/Properties/AndroidManifest.xml b/osu.Game.Rulesets.Taiko.Tests.Android/AndroidManifest.xml similarity index 98% rename from osu.Game.Rulesets.Taiko.Tests.Android/Properties/AndroidManifest.xml rename to osu.Game.Rulesets.Taiko.Tests.Android/AndroidManifest.xml index d9de0fde4e..452b9683ec 100644 --- a/osu.Game.Rulesets.Taiko.Tests.Android/Properties/AndroidManifest.xml +++ b/osu.Game.Rulesets.Taiko.Tests.Android/AndroidManifest.xml @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko.Tests.Android/osu.Game.Rulesets.Taiko.Tests.Android.csproj b/osu.Game.Rulesets.Taiko.Tests.Android/osu.Game.Rulesets.Taiko.Tests.Android.csproj index 4d4dabebe6..a639326ebd 100644 --- a/osu.Game.Rulesets.Taiko.Tests.Android/osu.Game.Rulesets.Taiko.Tests.Android.csproj +++ b/osu.Game.Rulesets.Taiko.Tests.Android/osu.Game.Rulesets.Taiko.Tests.Android.csproj @@ -1,49 +1,24 @@ - - + - Debug - AnyCPU - 8.0.30703 - 2.0 - {3701A0A1-8476-42C6-B5C4-D24129B4A484} - {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - {122416d6-6b49-4ee2-a1e8-b825f31c79fe} + net6.0-android + Exe osu.Game.Rulesets.Taiko.Tests osu.Game.Rulesets.Taiko.Tests.Android - Properties\AndroidManifest.xml - armeabi-v7a;x86;arm64-v8a - - - None - cjk;mideast;other;rare;west - true - - - - - - - + %(RecursiveDir)%(Filename)%(Extension) + + + %(RecursiveDir)%(Filename)%(Extension) + Android\%(RecursiveDir)%(Filename)%(Extension) + - - {f167e17a-7de6-4af5-b920-a5112296c695} - osu.Game.Rulesets.Taiko - - - {2a66dd92-adb1-4994-89e2-c94e04acda0d} - osu.Game - + + - - - 5.0.0 - - - \ No newline at end of file diff --git a/osu.Game.Tests.Android/Properties/AndroidManifest.xml b/osu.Game.Tests.Android/AndroidManifest.xml similarity index 98% rename from osu.Game.Tests.Android/Properties/AndroidManifest.xml rename to osu.Game.Tests.Android/AndroidManifest.xml index 4a63f0c357..f25b2e5328 100644 --- a/osu.Game.Tests.Android/Properties/AndroidManifest.xml +++ b/osu.Game.Tests.Android/AndroidManifest.xml @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/osu.Game.Tests.Android/MainActivity.cs b/osu.Game.Tests.Android/MainActivity.cs index 6c4f9bac58..bdb947fbb4 100644 --- a/osu.Game.Tests.Android/MainActivity.cs +++ b/osu.Game.Tests.Android/MainActivity.cs @@ -3,7 +3,9 @@ #nullable disable +using System.Reflection; using Android.App; +using Android.OS; using osu.Framework.Android; namespace osu.Game.Tests.Android @@ -12,5 +14,16 @@ namespace osu.Game.Tests.Android public class MainActivity : AndroidGameActivity { protected override Framework.Game CreateGame() => new OsuTestBrowser(); + + protected override void OnCreate(Bundle savedInstanceState) + { + base.OnCreate(savedInstanceState); + + // See the comment in OsuGameActivity + Assembly.Load("osu.Game.Rulesets.Osu"); + Assembly.Load("osu.Game.Rulesets.Taiko"); + Assembly.Load("osu.Game.Rulesets.Catch"); + Assembly.Load("osu.Game.Rulesets.Mania"); + } } } diff --git a/osu.Game.Tests.Android/osu.Game.Tests.Android.csproj b/osu.Game.Tests.Android/osu.Game.Tests.Android.csproj index afafec6b1f..b745d91980 100644 --- a/osu.Game.Tests.Android/osu.Game.Tests.Android.csproj +++ b/osu.Game.Tests.Android/osu.Game.Tests.Android.csproj @@ -1,88 +1,34 @@ - - + - Debug - AnyCPU - 8.0.30703 - 2.0 - {5CC222DC-5716-4499-B897-DCBDDA4A5CF9} - {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - {122416d6-6b49-4ee2-a1e8-b825f31c79fe} + net6.0-android + Exe osu.Game.Tests osu.Game.Tests.Android - Properties\AndroidManifest.xml - armeabi-v7a;x86;arm64-v8a - - - - - - $(NoWarn);CA2007 - - None - cjk;mideast;other;rare;west - true - - + %(RecursiveDir)%(Filename)%(Extension) - - + + %(RecursiveDir)%(Filename)%(Extension) - - - %(RecursiveDir)%(Filename)%(Extension) - - - %(RecursiveDir)%(Filename)%(Extension) - - - %(RecursiveDir)%(Filename)%(Extension) - - - %(RecursiveDir)%(Filename)%(Extension) - - - %(RecursiveDir)%(Filename)%(Extension) - - - %(RecursiveDir)%(Filename)%(Extension) - + Android\%(RecursiveDir)%(Filename)%(Extension) + - - {58f6c80c-1253-4a0e-a465-b8c85ebeadf3} - osu.Game.Rulesets.Catch - - - {48f4582b-7687-4621-9cbe-5c24197cb536} - osu.Game.Rulesets.Mania - - - {c92a607b-1fdd-4954-9f92-03ff547d9080} - osu.Game.Rulesets.Osu - - - {f167e17a-7de6-4af5-b920-a5112296c695} - osu.Game.Rulesets.Taiko - - - {2a66dd92-adb1-4994-89e2-c94e04acda0d} - osu.Game - + + + + + - - 5.0.0 - - diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs index 8d82843134..d925141510 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs @@ -189,7 +189,7 @@ namespace osu.Game.Tests.Visual.Online if (request is not CommentDeleteRequest req) return false; - req.TriggerFailure(new Exception()); + req.TriggerFailure(new InvalidOperationException()); delete = true; return false; }; diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneUpdateBeatmapSetButton.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneUpdateBeatmapSetButton.cs index e47b7e25a8..11d55bc0bd 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneUpdateBeatmapSetButton.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneUpdateBeatmapSetButton.cs @@ -136,7 +136,7 @@ namespace osu.Game.Tests.Visual.SongSelect if (testRequest.Progress >= 0.5f) { - testRequest.TriggerFailure(new Exception()); + testRequest.TriggerFailure(new InvalidOperationException()); return true; } } diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs index adebbe6181..4114a3ed1e 100644 --- a/osu.Game/Rulesets/RulesetStore.cs +++ b/osu.Game/Rulesets/RulesetStore.cs @@ -114,7 +114,10 @@ namespace osu.Game.Rulesets { try { - string[] files = Directory.GetFiles(RuntimeInfo.StartupDirectory, @$"{ruleset_library_prefix}.*.dll"); + // On net6-android (Debug), StartupDirectory can be different from where assemblies are placed. + // Search sub-directories too. + + string[] files = Directory.GetFiles(RuntimeInfo.StartupDirectory, @$"{ruleset_library_prefix}.*.dll", SearchOption.AllDirectories); foreach (string file in files.Where(f => !Path.GetFileName(f).Contains("Tests"))) loadRulesetFromFile(file); diff --git a/osu.sln b/osu.sln index aeec0843be..5b23ff9ae6 100644 --- a/osu.sln +++ b/osu.sln @@ -63,6 +63,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution CodeAnalysis\osu.ruleset = CodeAnalysis\osu.ruleset osu.sln.DotSettings = osu.sln.DotSettings osu.TestProject.props = osu.TestProject.props + global.json = global.json EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Benchmarks", "osu.Game.Benchmarks\osu.Game.Benchmarks.csproj", "{93632F2D-2BB4-46C1-A7B8-F8CF2FB27118}" From d3995693a012a2d1cd6f3306d41d44ec9c6a7084 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 19 Dec 2022 16:39:03 +0900 Subject: [PATCH 1077/2991] Use `maui-android` --- .github/workflows/ci.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 834b2b68a1..213c5082ab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -114,7 +114,7 @@ jobs: dotnet-version: "6.0.x" - name: Install .NET workloads - run: dotnet workload install android + run: dotnet workload install maui-android - name: Compile run: dotnet build -c Debug osu.Android.slnf diff --git a/appveyor.yml b/appveyor.yml index 3757cbf41f..ed48a997e8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,7 +11,7 @@ dotnet_csproj: before_build: - cmd: dotnet --info # Useful when version mismatch between CI and local - - cmd: dotnet workload install android # Change to `dotnet workload restore` once there's no old projects + - cmd: dotnet workload install maui-android # Change to `dotnet workload restore` once there's no old projects - cmd: dotnet workload install maui-ios # Change to `dotnet workload restore` once there's no old projects - cmd: nuget restore -verbosity quiet # Only nuget.exe knows both new (.NET Core) and old (Xamarin) projects From 8a01a2261277047aad86b2ce7620026150490cd1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 19 Dec 2022 16:41:04 +0900 Subject: [PATCH 1078/2991] Fix two null refrences in `OsuGame` --- osu.Game/OsuGame.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index db521cd379..a0a45e18a8 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -333,7 +333,7 @@ namespace osu.Game /// The link to load. public void HandleLink(LinkDetails link) => Schedule(() => { - string argString = link.Argument.ToString(); + string argString = link.Argument.ToString() ?? string.Empty; switch (link.Action) { @@ -1042,6 +1042,8 @@ namespace osu.Game { if (entry.Level < LogLevel.Important || entry.Target > LoggingTarget.Database) return; + Debug.Assert(entry.Target != null); + const int short_term_display_limit = 3; if (recentLogCount < short_term_display_limit) @@ -1054,7 +1056,7 @@ namespace osu.Game } else if (recentLogCount == short_term_display_limit) { - string logFile = $@"{entry.Target.ToString().ToLowerInvariant()}.log"; + string logFile = $@"{entry.Target.Value.ToString().ToLowerInvariant()}.log"; Schedule(() => Notifications.Post(new SimpleNotification { From 4a7d7c6ed96a1208841d9dea928078e424b71c40 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 19 Dec 2022 16:42:21 +0900 Subject: [PATCH 1079/2991] Use `MaxBy` in all locations that can and update inspection level to match `dotnet-build` --- osu.Game.Rulesets.Catch/Edit/CatchDistanceSnapGrid.cs | 4 +--- osu.Game.Tournament/Screens/Ladder/LadderScreen.cs | 4 ++-- osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs | 4 ++-- osu.Game/Rulesets/RulesetStore.cs | 5 +---- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 2 +- osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs | 4 +--- osu.Game/Scoring/ScoreImporter.cs | 3 +-- .../Screens/Edit/Compose/Components/BeatDivisorControl.cs | 2 +- osu.Game/Screens/Edit/Compose/ComposeScreen.cs | 2 +- .../OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs | 4 +--- osu.Game/Storyboards/Storyboard.cs | 4 ++-- osu.Game/Storyboards/StoryboardSprite.cs | 2 +- osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs | 4 +--- osu.sln.DotSettings | 1 + 14 files changed, 17 insertions(+), 28 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchDistanceSnapGrid.cs b/osu.Game.Rulesets.Catch/Edit/CatchDistanceSnapGrid.cs index e5cdcf706c..43918bda57 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchDistanceSnapGrid.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchDistanceSnapGrid.cs @@ -121,9 +121,7 @@ namespace osu.Game.Rulesets.Catch.Edit return new SnapResult(originPosition, StartTime); } - return enumerateSnappingCandidates(time) - .OrderBy(pos => Vector2.DistanceSquared(screenSpacePosition, pos.ScreenSpacePosition)) - .FirstOrDefault(); + return enumerateSnappingCandidates(time).MinBy(pos => Vector2.DistanceSquared(screenSpacePosition, pos.ScreenSpacePosition)); } private IEnumerable enumerateSnappingCandidates(double time) diff --git a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs index f976f2b16b..176c06c0e5 100644 --- a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs +++ b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs @@ -158,7 +158,7 @@ namespace osu.Game.Tournament.Screens.Ladder foreach (var round in LadderInfo.Rounds) { - var topMatch = MatchesContainer.Where(p => !p.Match.Losers.Value && p.Match.Round.Value == round).OrderBy(p => p.Y).FirstOrDefault(); + var topMatch = MatchesContainer.Where(p => !p.Match.Losers.Value && p.Match.Round.Value == round).MinBy(p => p.Y); if (topMatch == null) continue; @@ -172,7 +172,7 @@ namespace osu.Game.Tournament.Screens.Ladder foreach (var round in LadderInfo.Rounds) { - var topMatch = MatchesContainer.Where(p => p.Match.Losers.Value && p.Match.Round.Value == round).OrderBy(p => p.Y).FirstOrDefault(); + var topMatch = MatchesContainer.Where(p => p.Match.Losers.Value && p.Match.Round.Value == round).MinBy(p => p.Y); if (topMatch == null) continue; diff --git a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs index 5d308bd2bb..55119c800a 100644 --- a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs +++ b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs @@ -70,14 +70,14 @@ namespace osu.Game.Beatmaps.ControlPoints /// [JsonIgnore] public double BPMMaximum => - 60000 / (TimingPoints.OrderBy(c => c.BeatLength).FirstOrDefault() ?? TimingControlPoint.DEFAULT).BeatLength; + 60000 / (TimingPoints.MinBy(c => c.BeatLength) ?? TimingControlPoint.DEFAULT).BeatLength; /// /// Finds the minimum BPM represented by any timing control point. /// [JsonIgnore] public double BPMMinimum => - 60000 / (TimingPoints.OrderByDescending(c => c.BeatLength).FirstOrDefault() ?? TimingControlPoint.DEFAULT).BeatLength; + 60000 / (TimingPoints.MaxBy(c => c.BeatLength) ?? TimingControlPoint.DEFAULT).BeatLength; /// /// Remove all s and return to a pristine state. diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs index 4114a3ed1e..881b09bd1b 100644 --- a/osu.Game/Rulesets/RulesetStore.cs +++ b/osu.Game/Rulesets/RulesetStore.cs @@ -75,10 +75,7 @@ namespace osu.Game.Rulesets return false; return args.Name.Contains(name, StringComparison.Ordinal); - }) - // Pick the greatest assembly version. - .OrderByDescending(a => a.GetName().Version) - .FirstOrDefault(); + }).MaxBy(a => a.GetName().Version); if (domainAssembly != null) return domainAssembly; diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index b048566c8a..4228840461 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -534,7 +534,7 @@ namespace osu.Game.Rulesets.Scoring break; default: - maxResult = maxBasicResult ??= ruleset.GetHitResults().OrderByDescending(kvp => Judgement.ToNumericResult(kvp.result)).First().result; + maxResult = maxBasicResult ??= ruleset.GetHitResults().MaxBy(kvp => Judgement.ToNumericResult(kvp.result)).result; break; } diff --git a/osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs b/osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs index d068f8d016..d2244df3b8 100644 --- a/osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs +++ b/osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs @@ -79,9 +79,7 @@ namespace osu.Game.Rulesets.UI // We need to use lifetime entries to find the next object (we can't just use `hitObjectContainer.Objects` due to pooling - it may even be empty). // If required, we can make this lookup more efficient by adding support to get next-future-entry in LifetimeEntryManager. fallbackObject = hitObjectContainer.Entries - .Where(e => e.Result?.HasResult != true) - .OrderBy(e => e.HitObject.StartTime) - .FirstOrDefault(); + .Where(e => e.Result?.HasResult != true).MinBy(e => e.HitObject.StartTime); // In the case there are no unjudged objects, the last hit object should be used instead. fallbackObject ??= hitObjectContainer.Entries.LastOrDefault(); diff --git a/osu.Game/Scoring/ScoreImporter.cs b/osu.Game/Scoring/ScoreImporter.cs index 4656f02897..797d80b7fa 100644 --- a/osu.Game/Scoring/ScoreImporter.cs +++ b/osu.Game/Scoring/ScoreImporter.cs @@ -101,8 +101,7 @@ namespace osu.Game.Scoring // Populate the maximum statistics. HitResult maxBasicResult = rulesetInstance.GetHitResults() .Select(h => h.result) - .Where(h => h.IsBasic()) - .OrderByDescending(Judgement.ToNumericResult).First(); + .Where(h => h.IsBasic()).MaxBy(Judgement.ToNumericResult); foreach ((HitResult result, int count) in score.Statistics) { diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs index 903c117422..9f422d5aa9 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs @@ -479,7 +479,7 @@ namespace osu.Game.Screens.Edit.Compose.Components // copied from SliderBar so we can do custom spacing logic. float xPosition = (ToLocalSpace(screenSpaceMousePosition).X - RangePadding) / UsableWidth; - CurrentNumber.Value = beatDivisor.ValidDivisors.Value.Presets.OrderBy(d => Math.Abs(getMappedPosition(d) - xPosition)).First(); + CurrentNumber.Value = beatDivisor.ValidDivisors.Value.Presets.MinBy(d => Math.Abs(getMappedPosition(d) - xPosition)); OnUserChange(Current.Value); } diff --git a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs index 3af7a400e2..dc026f7eac 100644 --- a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs +++ b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs @@ -152,7 +152,7 @@ namespace osu.Game.Screens.Edit.Compose if (composer == null) return string.Empty; - double displayTime = EditorBeatmap.SelectedHitObjects.OrderBy(h => h.StartTime).FirstOrDefault()?.StartTime ?? clock.CurrentTime; + double displayTime = EditorBeatmap.SelectedHitObjects.MinBy(h => h.StartTime)?.StartTime ?? clock.CurrentTime; string selectionAsString = composer.ConvertSelectionToString(); return !string.IsNullOrEmpty(selectionAsString) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs index 33ca806696..2d2aa0f1d5 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs @@ -171,9 +171,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate if (!isCandidateAudioSource(currentAudioSource?.SpectatorPlayerClock)) { - currentAudioSource = instances.Where(i => isCandidateAudioSource(i.SpectatorPlayerClock)) - .OrderBy(i => Math.Abs(i.SpectatorPlayerClock.CurrentTime - syncManager.CurrentMasterTime)) - .FirstOrDefault(); + currentAudioSource = instances.Where(i => isCandidateAudioSource(i.SpectatorPlayerClock)).MinBy(i => Math.Abs(i.SpectatorPlayerClock.CurrentTime - syncManager.CurrentMasterTime)); // Only bind adjustments if there's actually a valid source, else just use the previous ones to ensure no sudden changes to audio. if (currentAudioSource != null) diff --git a/osu.Game/Storyboards/Storyboard.cs b/osu.Game/Storyboards/Storyboard.cs index 8133244e89..566e064aad 100644 --- a/osu.Game/Storyboards/Storyboard.cs +++ b/osu.Game/Storyboards/Storyboard.cs @@ -32,7 +32,7 @@ namespace osu.Game.Storyboards /// /// This iterates all elements and as such should be used sparingly or stored locally. /// - public double? EarliestEventTime => Layers.SelectMany(l => l.Elements).OrderBy(e => e.StartTime).FirstOrDefault()?.StartTime; + public double? EarliestEventTime => Layers.SelectMany(l => l.Elements).MinBy(e => e.StartTime)?.StartTime; /// /// Across all layers, find the latest point in time that a storyboard element ends at. @@ -42,7 +42,7 @@ namespace osu.Game.Storyboards /// This iterates all elements and as such should be used sparingly or stored locally. /// Videos and samples return StartTime as their EndTIme. /// - public double? LatestEventTime => Layers.SelectMany(l => l.Elements).OrderBy(e => e.GetEndTime()).LastOrDefault()?.GetEndTime(); + public double? LatestEventTime => Layers.SelectMany(l => l.Elements).MaxBy(e => e.GetEndTime())?.GetEndTime(); /// /// Depth of the currently front-most storyboard layer, excluding the overlay layer. diff --git a/osu.Game/Storyboards/StoryboardSprite.cs b/osu.Game/Storyboards/StoryboardSprite.cs index cd7788bb08..5b7b194be7 100644 --- a/osu.Game/Storyboards/StoryboardSprite.cs +++ b/osu.Game/Storyboards/StoryboardSprite.cs @@ -48,7 +48,7 @@ namespace osu.Game.Storyboards if (alphaCommands.Count > 0) { - var firstAlpha = alphaCommands.OrderBy(t => t.startTime).First(); + var firstAlpha = alphaCommands.MinBy(t => t.startTime); if (firstAlpha.isZeroStartValue) return firstAlpha.startTime; diff --git a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs index 765c665966..ad5e3f6c4d 100644 --- a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs +++ b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs @@ -108,9 +108,7 @@ namespace osu.Game.Tests.Visual.Multiplayer // simulate the server's automatic assignment of users to teams on join. // the "best" team is the one with the least users on it. int bestTeam = teamVersus.Teams - .Select(team => (teamID: team.ID, userCount: ServerRoom.Users.Count(u => (u.MatchState as TeamVersusUserState)?.TeamID == team.ID))) - .OrderBy(pair => pair.userCount) - .First().teamID; + .Select(team => (teamID: team.ID, userCount: ServerRoom.Users.Count(u => (u.MatchState as TeamVersusUserState)?.TeamID == team.ID))).MinBy(pair => pair.userCount).teamID; user.MatchState = new TeamVersusUserState { TeamID = bestTeam }; ((IMultiplayerClient)this).MatchUserStateChanged(clone(user.UserID), clone(user.MatchState)).WaitSafely(); diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 154ad0fe8c..ef3b08e1f5 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -218,6 +218,7 @@ WARNING WARNING WARNING + WARNING WARNING HINT WARNING From 407b0a0ad3c29948162df5eae5e230335f93de7b Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 19 Dec 2022 11:30:23 +0100 Subject: [PATCH 1080/2991] Address issues from Joehuu review --- .../Select/FooterV2/FooterButtonModsV2.cs | 2 +- .../Select/FooterV2/FooterButtonRandomV2.cs | 4 +-- .../Screens/Select/FooterV2/FooterButtonV2.cs | 30 +++++++++++-------- osu.Game/Screens/Select/FooterV2/FooterV2.cs | 11 ++----- 4 files changed, 22 insertions(+), 25 deletions(-) diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonModsV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonModsV2.cs index daa1de2e7b..b8c9f0b34b 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterButtonModsV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonModsV2.cs @@ -13,7 +13,7 @@ namespace osu.Game.Screens.Select.FooterV2 private void load(OsuColour colour) { Text = "Mods"; - Icon = FontAwesome.Solid.ArrowsAlt; + Icon = FontAwesome.Solid.ExchangeAlt; AccentColour = colour.Lime1; } } diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs index 3ecf616a16..ebb9c4b6e5 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs @@ -41,7 +41,7 @@ namespace osu.Game.Screens.Select.FooterV2 { randomSpriteText = new OsuSpriteText { - Font = OsuFont.TorusAlternate.With(size: 16), + Font = OsuFont.TorusAlternate.With(size: 19), AlwaysPresent = true, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -49,7 +49,7 @@ namespace osu.Game.Screens.Select.FooterV2 }, rewindSpriteText = new OsuSpriteText { - Font = OsuFont.TorusAlternate.With(size: 16), + Font = OsuFont.TorusAlternate.With(size: 19), AlwaysPresent = true, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs index 7fb9bf42bd..d7d018afc3 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs @@ -23,12 +23,13 @@ namespace osu.Game.Screens.Select.FooterV2 { public partial class FooterButtonV2 : OsuClickableContainer, IKeyBindingHandler { - private const int button_height = 120; + private const int button_height = 90; private const int button_width = 140; private const int corner_radius = 10; private const int transition_length = 500; - public const float SHEAR_WIDTH = 16; + //Accounts for corner radius margin on bottom, would be 12 + public const float SHEAR_WIDTH = 13.5f; public Bindable OverlayState = new Bindable(); @@ -63,7 +64,7 @@ namespace osu.Game.Screens.Select.FooterV2 private SpriteIcon icon = null!; protected Container TextContainer = null!; private Box bar = null!; - private Box backGroundBox = null!; + private Box backgroundBox = null!; [BackgroundDependencyLoader] private void load() @@ -81,7 +82,7 @@ namespace osu.Game.Screens.Select.FooterV2 CornerRadius = corner_radius; InternalChildren = new Drawable[] { - backGroundBox = new Box + backgroundBox = new Box { Colour = colourProvider.Background3, RelativeSizeAxes = Axes.Both @@ -90,6 +91,8 @@ namespace osu.Game.Screens.Select.FooterV2 //For elements that should not be sheared. new Container { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, Shear = -SHEAR, RelativeSizeAxes = Axes.Both, Children = new Drawable[] @@ -98,18 +101,18 @@ namespace osu.Game.Screens.Select.FooterV2 { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - Position = new Vector2(-SHEAR_WIDTH * (52f / button_height), 42), + Y = 42, AutoSizeAxes = Axes.Both, Child = text = new OsuSpriteText { - Font = OsuFont.TorusAlternate.With(size: 16), + //figma design says the size is 16, but due to the issues with font sizes 19 matches better + Font = OsuFont.TorusAlternate.With(size: 19), AlwaysPresent = true } }, icon = new SpriteIcon { - //We want to offset this by the same amount as the text for aesthetic purposes - Position = new Vector2(-SHEAR_WIDTH * (52f / button_height), 12), + Y = 12, Size = new Vector2(20), Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre @@ -117,7 +120,7 @@ namespace osu.Game.Screens.Select.FooterV2 new Container { //Offset the bar to centre it with consideration for the shearing - Position = new Vector2(-SHEAR_WIDTH * (80f / button_height), -40), + Position = new Vector2(-0.15f * 35, -10), Anchor = Anchor.BottomCentre, Origin = Anchor.Centre, Size = new Vector2(120, 6), @@ -136,6 +139,7 @@ namespace osu.Game.Screens.Select.FooterV2 protected override void LoadComplete() { base.LoadComplete(); + Enabled.BindValueChanged(_ => updateDisplay(), true); OverlayState.BindValueChanged(_ => updateDisplay()); } @@ -190,23 +194,23 @@ namespace osu.Game.Screens.Select.FooterV2 { if (!Enabled.Value) { - backGroundBox.FadeColour(colourProvider.Background3.Darken(0.3f), transition_length, Easing.OutQuint); + backgroundBox.FadeColour(colourProvider.Background3.Darken(0.3f), transition_length, Easing.OutQuint); return; } switch (OverlayState.Value) { case Visibility.Visible: - backGroundBox.FadeColour(buttonAccentColour.Darken(0.5f), transition_length, Easing.OutQuint); + backgroundBox.FadeColour(buttonAccentColour.Darken(0.5f), transition_length, Easing.OutQuint); return; case Visibility.Hidden: - backGroundBox.FadeColour(buttonAccentColour, transition_length, Easing.OutQuint); + backgroundBox.FadeColour(buttonAccentColour, transition_length, Easing.OutQuint); break; } //Hover logic. - backGroundBox.FadeColour(isHovered && Enabled.Value ? colourProvider.Background3.Lighten(.3f) : colourProvider.Background3, transition_length, Easing.OutQuint); + backgroundBox.FadeColour(isHovered && Enabled.Value ? colourProvider.Background3.Lighten(.3f) : colourProvider.Background3, transition_length, Easing.OutQuint); } } } diff --git a/osu.Game/Screens/Select/FooterV2/FooterV2.cs b/osu.Game/Screens/Select/FooterV2/FooterV2.cs index 8ac26c2e58..7e2d9d6695 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterV2.cs @@ -6,14 +6,13 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osuTK; namespace osu.Game.Screens.Select.FooterV2 { - public partial class FooterV2 : Container + public partial class FooterV2 : InputBlockingContainer { //Should be 60, setting to 50 for now for the sake of matching the current BackButton height. private const int height = 50; @@ -62,7 +61,7 @@ namespace osu.Game.Screens.Select.FooterV2 { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - Position = new Vector2(TwoLayerButton.SIZE_EXTENDED.X + padding, 40), + Position = new Vector2(TwoLayerButton.SIZE_EXTENDED.X + padding, 10), RelativeSizeAxes = Axes.Y, AutoSizeAxes = Axes.X, Direction = FillDirection.Horizontal, @@ -81,11 +80,5 @@ namespace osu.Game.Screens.Select.FooterV2 } }; } - - protected override bool OnMouseDown(MouseDownEvent e) => true; - - protected override bool OnClick(ClickEvent e) => true; - - protected override bool OnHover(HoverEvent e) => true; } } From 12c77cca26b66c70e8efb0ae8d9a594c62b27fb8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 19 Dec 2022 15:44:10 +0900 Subject: [PATCH 1081/2991] Remove `rollForward` rule for now --- global.json | 6 ------ osu.sln | 1 - 2 files changed, 7 deletions(-) delete mode 100644 global.json diff --git a/global.json b/global.json deleted file mode 100644 index f20ff84190..0000000000 --- a/global.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "sdk": { - "version": "6.0.300", - "rollForward": "major" - } -} diff --git a/osu.sln b/osu.sln index 5b23ff9ae6..aeec0843be 100644 --- a/osu.sln +++ b/osu.sln @@ -63,7 +63,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution CodeAnalysis\osu.ruleset = CodeAnalysis\osu.ruleset osu.sln.DotSettings = osu.sln.DotSettings osu.TestProject.props = osu.TestProject.props - global.json = global.json EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Benchmarks", "osu.Game.Benchmarks\osu.Game.Benchmarks.csproj", "{93632F2D-2BB4-46C1-A7B8-F8CF2FB27118}" From 99ad78cdd631e5b999dd8ebcef6e978906fcb63c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 19 Dec 2022 22:01:13 +0900 Subject: [PATCH 1082/2991] Remove no longer necessary workarounds from mobile props files --- osu.Android.props | 4 ---- osu.iOS.props | 9 --------- 2 files changed, 13 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 5da7eae380..a0ad0cdcdc 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -12,10 +12,6 @@ - - - - diff --git a/osu.iOS.props b/osu.iOS.props index 98d3e129d4..4dac17c024 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -15,15 +15,6 @@ iossimulator-x64 - - - - none - - - none - - From ecac6299c6679d6c29133cb9fab88e53520b7104 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 19 Dec 2022 22:01:20 +0900 Subject: [PATCH 1083/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index a0ad0cdcdc..31670bedb5 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -10,7 +10,7 @@ true - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8bb68faf7b..8b4fa2dc6b 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 4dac17c024..0ff4fafb31 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -16,7 +16,7 @@ iossimulator-x64 - + - - - <_LinkerFrameworks Remove="Quartz"/> - - From 2249c97a6f1232f9c626ff0648fbf2c43714281a Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 19 Dec 2022 18:27:19 +0300 Subject: [PATCH 1085/2991] Pin certain system package versions to avoid downgrade errors --- osu.iOS.props | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.iOS.props b/osu.iOS.props index b5f470eda1..c6798cd5e4 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -17,5 +17,10 @@ + + + + + From 626f4b0dfd0b22b02eaf3ab5c046a1597b62085b Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 19 Dec 2022 16:35:20 +0100 Subject: [PATCH 1086/2991] fix test failures, improve button logic --- .../Select/FooterV2/FooterButtonOptionsV2.cs | 2 + .../Select/FooterV2/FooterButtonRandomV2.cs | 3 +- .../Screens/Select/FooterV2/FooterButtonV2.cs | 57 +++++++------------ osu.Game/Screens/Select/FooterV2/FooterV2.cs | 2 + 4 files changed, 28 insertions(+), 36 deletions(-) diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonOptionsV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonOptionsV2.cs index be0fdef9db..87cca0042a 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterButtonOptionsV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonOptionsV2.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; +using osu.Game.Input.Bindings; namespace osu.Game.Screens.Select.FooterV2 { @@ -15,6 +16,7 @@ namespace osu.Game.Screens.Select.FooterV2 Text = "Options"; Icon = FontAwesome.Solid.Cog; AccentColour = colour.Purple1; + Hotkey = GlobalAction.ToggleBeatmapOptions; } } } diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs index ebb9c4b6e5..e3882588d9 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonRandomV2.cs @@ -73,7 +73,8 @@ namespace osu.Game.Screens.Select.FooterV2 Text = rewindSpriteText.Text, AlwaysPresent = true, // make sure the button is sized large enough to always show this Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre + Origin = Anchor.BottomCentre, + Font = OsuFont.TorusAlternate.With(size: 19), }); fallingRewind.FadeOutFromOne(fade_time, Easing.In); diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs index d7d018afc3..ea4db1f8fa 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs @@ -60,14 +60,14 @@ namespace osu.Game.Screens.Select.FooterV2 set => text.Text = value; } - private SpriteText text = null!; - private SpriteIcon icon = null!; - protected Container TextContainer = null!; - private Box bar = null!; - private Box backgroundBox = null!; + private readonly SpriteText text; + private readonly SpriteIcon icon; - [BackgroundDependencyLoader] - private void load() + protected Container TextContainer; + private readonly Box bar; + private readonly Box backgroundBox; + + public FooterButtonV2() { EdgeEffect = new EdgeEffectParameters { @@ -146,46 +146,33 @@ namespace osu.Game.Screens.Select.FooterV2 public GlobalAction? Hotkey; - private bool isHovered; - protected override bool OnHover(HoverEvent e) { - isHovered = true; updateDisplay(); return true; } protected override void OnHoverLost(HoverLostEvent e) { - isHovered = false; updateDisplay(); } protected override bool OnMouseDown(MouseDownEvent e) { - if (!Enabled.Value) - return true; - - return base.OnMouseDown(e); + return !Enabled.Value || base.OnMouseDown(e); } protected override bool OnClick(ClickEvent e) { - if (!Enabled.Value) - return true; - - return base.OnClick(e); + return !Enabled.Value || base.OnClick(e); } public virtual bool OnPressed(KeyBindingPressEvent e) { - if (e.Action == Hotkey && !e.Repeat) - { - TriggerClick(); - return true; - } + if (e.Action != Hotkey || e.Repeat) return false; - return false; + TriggerClick(); + return true; } public virtual void OnReleased(KeyBindingReleaseEvent e) { } @@ -198,19 +185,19 @@ namespace osu.Game.Screens.Select.FooterV2 return; } - switch (OverlayState.Value) + if (OverlayState.Value == Visibility.Visible) { - case Visibility.Visible: - backgroundBox.FadeColour(buttonAccentColour.Darken(0.5f), transition_length, Easing.OutQuint); - return; - - case Visibility.Hidden: - backgroundBox.FadeColour(buttonAccentColour, transition_length, Easing.OutQuint); - break; + backgroundBox.FadeColour(buttonAccentColour.Darken(0.5f), transition_length, Easing.OutQuint); + return; } - //Hover logic. - backgroundBox.FadeColour(isHovered && Enabled.Value ? colourProvider.Background3.Lighten(.3f) : colourProvider.Background3, transition_length, Easing.OutQuint); + if (IsHovered) + { + backgroundBox.FadeColour(colourProvider.Background3.Lighten(0.3f), transition_length, Easing.OutQuint); + return; + } + + backgroundBox.FadeColour(colourProvider.Background3, transition_length, Easing.OutQuint); } } } diff --git a/osu.Game/Screens/Select/FooterV2/FooterV2.cs b/osu.Game/Screens/Select/FooterV2/FooterV2.cs index 7e2d9d6695..2bfa03d319 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterV2.cs @@ -20,6 +20,8 @@ namespace osu.Game.Screens.Select.FooterV2 private readonly List overlays = new List(); + /// The button to be added. + /// The to be toggled by this button. public void AddButton(FooterButtonV2 button, OverlayContainer? overlay = null) { if (overlay != null) From d47a8b2e26df2146e468e4606de0b3adf8690130 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 19 Dec 2022 18:42:51 +0300 Subject: [PATCH 1087/2991] Remove unnecessary discard --- osu.iOS/OsuGameIOS.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.iOS/OsuGameIOS.cs b/osu.iOS/OsuGameIOS.cs index cb3b260033..3e79bc6ad6 100644 --- a/osu.iOS/OsuGameIOS.cs +++ b/osu.iOS/OsuGameIOS.cs @@ -33,7 +33,7 @@ namespace osu.iOS { switch (handler) { - case IOSMouseHandler _: + case IOSMouseHandler: return new IOSMouseSettings(); default: From 36c620287b1a17faff7c6317dfa0159344b974ae Mon Sep 17 00:00:00 2001 From: Susko3 Date: Mon, 19 Dec 2022 18:11:05 +0100 Subject: [PATCH 1088/2991] Remove no longer needed `Linker.xml` configurations for mobile projects --- osu.Android.props | 3 --- osu.Android/Linker.xml | 7 ------- osu.iOS/Linker.xml | 31 ------------------------------- 3 files changed, 41 deletions(-) delete mode 100644 osu.Android/Linker.xml delete mode 100644 osu.iOS/Linker.xml diff --git a/osu.Android.props b/osu.Android.props index 31670bedb5..e934b2da6a 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -12,9 +12,6 @@ - - - diff --git a/osu.Android/Linker.xml b/osu.Android/Linker.xml deleted file mode 100644 index c7d31fe087..0000000000 --- a/osu.Android/Linker.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/osu.iOS/Linker.xml b/osu.iOS/Linker.xml deleted file mode 100644 index b55be3be39..0000000000 --- a/osu.iOS/Linker.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 186ccc64fd26e5e56a5cffbeff25302a9c3d2aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 19 Dec 2022 18:19:26 +0100 Subject: [PATCH 1089/2991] Fix welcome screen language buttons not working --- osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs index fe3aaeb9d8..f6133e3643 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs @@ -147,7 +147,7 @@ namespace osu.Game.Overlays.FirstRunSetup [BackgroundDependencyLoader] private void load() { - InternalChildren = new Drawable[] + AddRange(new Drawable[] { backgroundBox = new Box { @@ -162,7 +162,7 @@ namespace osu.Game.Overlays.FirstRunSetup Colour = colourProvider.Light1, Text = Language.GetDescription(), } - }; + }); } protected override void LoadComplete() From 0dce8996344e162e746bf783f43d2c193e4d146f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 19 Dec 2022 18:25:45 +0100 Subject: [PATCH 1090/2991] Throw on `OsuClickableContainer.ClearInternal()` invocations As they may cause critical failure due to getting rid of the `Content`. --- osu.Game/Graphics/Containers/OsuClickableContainer.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Graphics/Containers/OsuClickableContainer.cs b/osu.Game/Graphics/Containers/OsuClickableContainer.cs index 6ec393df4b..ce50dbdc39 100644 --- a/osu.Game/Graphics/Containers/OsuClickableContainer.cs +++ b/osu.Game/Graphics/Containers/OsuClickableContainer.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.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -46,5 +47,8 @@ namespace osu.Game.Graphics.Containers AddInternal(content); Add(CreateHoverSounds(sampleSet)); } + + protected override void ClearInternal(bool disposeChildren = true) => + throw new InvalidOperationException($"Clearing {nameof(InternalChildren)} will cause critical failure. Use {nameof(Clear)} instead."); } } From 6e55f2f779f69d942df61ca62676766c717d04b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 16 Dec 2022 20:57:27 +0100 Subject: [PATCH 1091/2991] Add test for markdown footnotes --- .../Visual/Online/TestSceneWikiMarkdownContainer.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs index b486f800c6..c0a7b9b921 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs @@ -199,6 +199,17 @@ Line after image"; }); } + [Test] + public void TestFootnotes() + { + AddStep("set content", () => markdownContainer.Text = @"This text has a footnote[^test]. + +Here's some more text[^test2] with another footnote! + +[^test]: This is a **footnote**. +[^test2]: This is another footnote [with a link](https://google.com/)!"); + } + private partial class TestMarkdownContainer : WikiMarkdownContainer { public LinkInline Link; From 112613c2f09c717d75ec32b30fab8ef3336bde5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 16 Dec 2022 20:59:14 +0100 Subject: [PATCH 1092/2991] Add styling for footnote links --- .../Footnotes/OsuMarkdownFootnoteLink.cs | 70 +++++++++++++++++ .../Footnotes/OsuMarkdownFootnoteTooltip.cs | 76 +++++++++++++++++++ .../Markdown/OsuMarkdownContainer.cs | 2 + .../Markdown/OsuMarkdownTextFlowContainer.cs | 4 + 4 files changed, 152 insertions(+) create mode 100644 osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteLink.cs create mode 100644 osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteTooltip.cs diff --git a/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteLink.cs b/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteLink.cs new file mode 100644 index 0000000000..b35c08e335 --- /dev/null +++ b/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteLink.cs @@ -0,0 +1,70 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using Markdig.Extensions.Footnotes; +using osu.Framework.Allocation; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers.Markdown; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; +using osu.Game.Overlays; + +namespace osu.Game.Graphics.Containers.Markdown.Footnotes +{ + public partial class OsuMarkdownFootnoteLink : OsuHoverContainer, IHasCustomTooltip + { + private readonly FootnoteLink footnoteLink; + + private SpriteText spriteText = null!; + + [Resolved] + private IMarkdownTextComponent parentTextComponent { get; set; } = null!; + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } = null!; + + [Resolved] + private OsuMarkdownContainer markdownContainer { get; set; } = null!; + + protected override IEnumerable EffectTargets => spriteText.Yield(); + + public OsuMarkdownFootnoteLink(FootnoteLink footnoteLink) + { + this.footnoteLink = footnoteLink; + + AutoSizeAxes = Axes.Both; + Action = () => { }; // TODO + } + + [BackgroundDependencyLoader] + private void load() + { + IdleColour = colourProvider.Light2; + HoverColour = colourProvider.Light1; + + spriteText = parentTextComponent.CreateSpriteText(); + + Add(spriteText.With(t => + { + float baseSize = t.Font.Size; + t.Font = t.Font.With(size: baseSize * 0.58f); + t.Margin = new MarginPadding { Bottom = 0.33f * baseSize }; + t.Text = LocalisableString.Format("[{0}]", footnoteLink.Index); + })); + } + + public object TooltipContent + { + get + { + var span = footnoteLink.Footnote.LastChild.Span; + return markdownContainer.Text.Substring(span.Start, span.Length); + } + } + + public ITooltip GetCustomTooltip() => new OsuMarkdownFootnoteTooltip(colourProvider); + } +} diff --git a/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteTooltip.cs b/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteTooltip.cs new file mode 100644 index 0000000000..af64913212 --- /dev/null +++ b/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteTooltip.cs @@ -0,0 +1,76 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Markdig.Extensions.Footnotes; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Containers.Markdown; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Shapes; +using osu.Game.Overlays; +using osuTK; + +namespace osu.Game.Graphics.Containers.Markdown.Footnotes +{ + public partial class OsuMarkdownFootnoteTooltip : CompositeDrawable, ITooltip + { + private readonly FootnoteMarkdownContainer markdownContainer; + + [Cached] + private OverlayColourProvider colourProvider; + + public OsuMarkdownFootnoteTooltip(OverlayColourProvider colourProvider) + { + this.colourProvider = colourProvider; + + Masking = true; + Width = 200; + AutoSizeAxes = Axes.Y; + CornerRadius = 4; + + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background6 + }, + markdownContainer = new FootnoteMarkdownContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + DocumentMargin = new MarginPadding(), + DocumentPadding = new MarginPadding { Horizontal = 10, Vertical = 5 } + } + }; + } + + public void Move(Vector2 pos) => Position = pos; + + public void SetContent(object content) => markdownContainer.SetContent((string)content); + + private partial class FootnoteMarkdownContainer : OsuMarkdownContainer + { + private string? lastFootnote; + + public void SetContent(string footnote) + { + if (footnote == lastFootnote) + return; + + lastFootnote = Text = footnote; + } + + public override MarkdownTextFlowContainer CreateTextFlow() => new FootnoteMarkdownTextFlowContainer(); + } + + private partial class FootnoteMarkdownTextFlowContainer : OsuMarkdownTextFlowContainer + { + protected override void AddFootnoteBacklink(FootnoteLink footnoteBacklink) + { + // we don't want footnote backlinks to show up in tooltips. + } + } + } +} diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs index e884b5db69..a7d518c693 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs @@ -11,6 +11,7 @@ using Markdig.Extensions.Footnotes; using Markdig.Extensions.Tables; using Markdig.Extensions.Yaml; using Markdig.Syntax; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers.Markdown; @@ -19,6 +20,7 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Graphics.Containers.Markdown { + [Cached] public partial class OsuMarkdownContainer : MarkdownContainer { /// diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs index 7de63fe09c..0cafb68648 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs @@ -6,6 +6,7 @@ using System; using System.Linq; using Markdig.Extensions.CustomContainers; +using Markdig.Extensions.Footnotes; using Markdig.Syntax.Inlines; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -13,6 +14,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers.Markdown; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics.Containers.Markdown.Footnotes; using osu.Game.Overlays; using osu.Game.Users; using osu.Game.Users.Drawables; @@ -36,6 +38,8 @@ namespace osu.Game.Graphics.Containers.Markdown Text = codeInline.Content }); + protected override void AddFootnoteLink(FootnoteLink footnoteLink) => AddDrawable(new OsuMarkdownFootnoteLink(footnoteLink)); + protected override SpriteText CreateEmphasisedSpriteText(bool bold, bool italic) => CreateSpriteText().With(t => t.Font = t.Font.With(weight: bold ? FontWeight.Bold : FontWeight.Regular, italics: italic)); From 73a4310935a857f18c455c25579aa8a212c453d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 16 Dec 2022 21:26:13 +0100 Subject: [PATCH 1093/2991] Add styling for footnote groups --- .../Markdown/Footnotes/OsuMarkdownFootnote.cs | 30 +++++++++++ .../Footnotes/OsuMarkdownFootnoteBacklink.cs | 52 +++++++++++++++++++ .../Markdown/OsuMarkdownContainer.cs | 7 +++ .../Markdown/OsuMarkdownTextFlowContainer.cs | 2 + 4 files changed, 91 insertions(+) create mode 100644 osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnote.cs create mode 100644 osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteBacklink.cs diff --git a/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnote.cs b/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnote.cs new file mode 100644 index 0000000000..e92d866eed --- /dev/null +++ b/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnote.cs @@ -0,0 +1,30 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Markdig.Extensions.Footnotes; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers.Markdown; +using osu.Framework.Graphics.Containers.Markdown.Footnotes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; + +namespace osu.Game.Graphics.Containers.Markdown.Footnotes +{ + public partial class OsuMarkdownFootnote : MarkdownFootnote + { + public OsuMarkdownFootnote(Footnote footnote) + : base(footnote) + { + } + + public override SpriteText CreateOrderMarker(int order) => CreateSpriteText().With(marker => + { + marker.Text = LocalisableString.Format("{0}.", order); + }); + + public override MarkdownTextFlowContainer CreateTextFlow() => base.CreateTextFlow().With(textFlow => + { + textFlow.Margin = new MarginPadding { Left = 30 }; + }); + } +} diff --git a/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteBacklink.cs b/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteBacklink.cs new file mode 100644 index 0000000000..a401eadaa3 --- /dev/null +++ b/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteBacklink.cs @@ -0,0 +1,52 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using Markdig.Extensions.Footnotes; +using osu.Framework.Allocation; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers.Markdown; +using osu.Framework.Graphics.Sprites; +using osu.Game.Overlays; +using osuTK; + +namespace osu.Game.Graphics.Containers.Markdown.Footnotes +{ + public partial class OsuMarkdownFootnoteBacklink : OsuHoverContainer + { + private readonly FootnoteLink backlink; + + private SpriteIcon spriteIcon = null!; + + [Resolved] + private IMarkdownTextComponent parentTextComponent { get; set; } = null!; + + protected override IEnumerable EffectTargets => spriteIcon.Yield(); + + public OsuMarkdownFootnoteBacklink(FootnoteLink backlink) + { + this.backlink = backlink; + AutoSizeAxes = Axes.X; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + float fontSize = parentTextComponent.CreateSpriteText().Font.Size; + Height = fontSize; + + IdleColour = colourProvider.Light2; + HoverColour = colourProvider.Light1; + + Add(spriteIcon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Margin = new MarginPadding { Left = 5 }, + Size = new Vector2(fontSize / 2), + Icon = FontAwesome.Solid.ArrowUp, + }); + } + } +} diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs index a7d518c693..65e1749261 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs @@ -15,8 +15,11 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers.Markdown; +using osu.Framework.Graphics.Containers.Markdown.Footnotes; using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics.Containers.Markdown.Footnotes; using osu.Game.Graphics.Sprites; +using osuTK; namespace osu.Game.Graphics.Containers.Markdown { @@ -101,6 +104,10 @@ namespace osu.Game.Graphics.Containers.Markdown return new OsuMarkdownUnorderedListItem(level); } + protected override MarkdownFootnoteGroup CreateFootnoteGroup(FootnoteGroup footnoteGroup) => base.CreateFootnoteGroup(footnoteGroup).With(g => g.Spacing = new Vector2(5)); + + protected override MarkdownFootnote CreateFootnote(Footnote footnote) => new OsuMarkdownFootnote(footnote); + // reference: https://github.com/ppy/osu-web/blob/05488a96b25b5a09f2d97c54c06dd2bae59d1dc8/app/Libraries/Markdown/OsuMarkdown.php#L301 protected override MarkdownPipeline CreateBuilder() { diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs index 0cafb68648..5f5b9acf56 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownTextFlowContainer.cs @@ -40,6 +40,8 @@ namespace osu.Game.Graphics.Containers.Markdown protected override void AddFootnoteLink(FootnoteLink footnoteLink) => AddDrawable(new OsuMarkdownFootnoteLink(footnoteLink)); + protected override void AddFootnoteBacklink(FootnoteLink footnoteBacklink) => AddDrawable(new OsuMarkdownFootnoteBacklink(footnoteBacklink)); + protected override SpriteText CreateEmphasisedSpriteText(bool bold, bool italic) => CreateSpriteText().With(t => t.Font = t.Font.With(weight: bold ? FontWeight.Bold : FontWeight.Regular, italics: italic)); From 3c1a46605ef59a6a8b633c5961d3d7989bfa4025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 16 Dec 2022 21:34:12 +0100 Subject: [PATCH 1094/2991] Set up test for two-way navigation testing --- .../Online/TestSceneWikiMarkdownContainer.cs | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs index c0a7b9b921..b1edea1e4e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs @@ -31,6 +31,8 @@ namespace osu.Game.Tests.Visual.Online [SetUp] public void Setup() => Schedule(() => { + OverlayScrollContainer scrollContainer; + Children = new Drawable[] { new Box @@ -38,15 +40,25 @@ namespace osu.Game.Tests.Visual.Online Colour = overlayColour.Background5, RelativeSizeAxes = Axes.Both, }, - new BasicScrollContainer + scrollContainer = new OverlayScrollContainer { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding(20), - Child = markdownContainer = new TestMarkdownContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - } + } + }; + + scrollContainer.Child = new DependencyProvidingContainer + { + CachedDependencies = new (Type, object)[] + { + (typeof(OverlayScrollContainer), scrollContainer) + }, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = markdownContainer = new TestMarkdownContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, } }; }); @@ -206,6 +218,16 @@ Line after image"; Here's some more text[^test2] with another footnote! +# Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam efficitur laoreet posuere. Ut accumsan tortor in ipsum tincidunt ultrices. Suspendisse a malesuada tellus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce a sagittis nibh. In et velit sit amet mauris aliquet consectetur quis vehicula lorem. Etiam sit amet tellus ac velit ornare maximus. Donec quis metus eget libero ullamcorper imperdiet id vitae arcu. Vivamus iaculis rhoncus purus malesuada mollis. Vestibulum dictum at nisi sed tincidunt. Suspendisse finibus, ipsum ut dapibus commodo, leo eros porttitor sapien, non scelerisque nisi ligula sed ex. Pellentesque magna orci, hendrerit eu iaculis sit amet, ullamcorper in urna. Vivamus dictum mauris orci, nec facilisis dolor fringilla eu. Sed at porttitor nisi, at venenatis urna. Ut at orci vitae libero semper ullamcorper eu ut risus. Mauris hendrerit varius enim, ut varius nisi feugiat mattis. + +## In at eros urna. Sed ipsum lorem, tempor sit amet purus in, vehicula pellentesque leo. Fusce volutpat pellentesque velit sit amet porttitor. Nulla eget erat ex. Praesent eu lacinia est, quis vehicula lacus. Donec consequat ultrices neque, at finibus quam efficitur vel. Vestibulum molestie nisl sit amet metus semper, at vestibulum massa rhoncus. Quisque imperdiet suscipit augue, et dignissim odio eleifend ut. + +Aliquam sed vestibulum mauris, ut lobortis elit. Sed quis lacinia erat. Nam ultricies, risus non pellentesque sollicitudin, mauris dolor tincidunt neque, ac porta ipsum dui quis libero. Integer eget velit neque. Vestibulum venenatis mauris vitae rutrum vestibulum. Maecenas suscipit eu purus eu tempus. Nam dui nisl, bibendum condimentum mollis et, gravida vel dui. Sed et eros rutrum, facilisis sapien eu, mattis ligula. Fusce finibus pulvinar dolor quis consequat. + +Donec ipsum felis, feugiat vel fermentum at, commodo eu sapien. Suspendisse nec enim vitae felis laoreet laoreet. Phasellus purus quam, fermentum a pharetra vel, tempor et urna. Integer vitae quam diam. Aliquam tincidunt tortor a iaculis convallis. Suspendisse potenti. Cras quis risus quam. Nullam tincidunt in lorem posuere sagittis. + +Phasellus eu nunc nec ligula semper fringilla. Aliquam magna neque, placerat sed urna tristique, laoreet pharetra nulla. Vivamus maximus turpis purus, eu viverra dolor sodales porttitor. Praesent bibendum sapien purus, sed ultricies dolor iaculis sed. Fusce congue hendrerit malesuada. Nulla nulla est, auctor ac fringilla sed, ornare a lorem. Donec quis velit imperdiet, imperdiet sem non, pellentesque sapien. Maecenas in orci id ipsum placerat facilisis non sed nisi. Duis dictum lorem sodales odio dictum eleifend. Vestibulum bibendum euismod quam, eget pharetra orci facilisis sed. Vivamus at diam non ipsum consequat tristique. Pellentesque gravida dignissim pellentesque. Donec ullamcorper lacinia orci, id consequat purus faucibus quis. Phasellus metus nunc, iaculis a interdum vel, congue sed erat. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Etiam eros libero, hendrerit luctus nulla vitae, luctus maximus nunc. + [^test]: This is a **footnote**. [^test2]: This is another footnote [with a link](https://google.com/)!"); } From 5fb2a83f12bf10f85cacc7b000847394a1691379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 16 Dec 2022 21:53:31 +0100 Subject: [PATCH 1095/2991] Add failing test case for footnote link navigation --- .../Online/TestSceneWikiMarkdownContainer.cs | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs index b1edea1e4e..3ec29d5e7c 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs @@ -16,13 +16,16 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Graphics.Containers.Markdown; +using osu.Game.Graphics.Containers.Markdown.Footnotes; using osu.Game.Overlays; using osu.Game.Overlays.Wiki.Markdown; +using osuTK.Input; namespace osu.Game.Tests.Visual.Online { - public partial class TestSceneWikiMarkdownContainer : OsuTestScene + public partial class TestSceneWikiMarkdownContainer : OsuManualInputManagerTestScene { + private OverlayScrollContainer scrollContainer; private TestMarkdownContainer markdownContainer; [Cached] @@ -31,8 +34,6 @@ namespace osu.Game.Tests.Visual.Online [SetUp] public void Setup() => Schedule(() => { - OverlayScrollContainer scrollContainer; - Children = new Drawable[] { new Box @@ -230,6 +231,31 @@ Phasellus eu nunc nec ligula semper fringilla. Aliquam magna neque, placerat sed [^test]: This is a **footnote**. [^test2]: This is another footnote [with a link](https://google.com/)!"); + AddStep("shrink scroll height", () => scrollContainer.Height = 0.5f); + + AddStep("press second footnote link", () => + { + InputManager.MoveMouseTo(markdownContainer.ChildrenOfType().ElementAt(1)); + InputManager.Click(MouseButton.Left); + }); + AddUntilStep("second footnote scrolled into view", () => + { + var footnote = markdownContainer.ChildrenOfType().ElementAt(1); + return scrollContainer.ScreenSpaceDrawQuad.Contains(footnote.ScreenSpaceDrawQuad.TopLeft) + && scrollContainer.ScreenSpaceDrawQuad.Contains(footnote.ScreenSpaceDrawQuad.BottomRight); + }); + + AddStep("press first footnote backlink", () => + { + InputManager.MoveMouseTo(markdownContainer.ChildrenOfType().First()); + InputManager.Click(MouseButton.Left); + }); + AddUntilStep("first footnote link scrolled into view", () => + { + var footnote = markdownContainer.ChildrenOfType().First(); + return scrollContainer.ScreenSpaceDrawQuad.Contains(footnote.ScreenSpaceDrawQuad.TopLeft) + && scrollContainer.ScreenSpaceDrawQuad.Contains(footnote.ScreenSpaceDrawQuad.BottomRight); + }); } private partial class TestMarkdownContainer : WikiMarkdownContainer From a88812861e933820a76fbd11b29f585f0b98268a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 16 Dec 2022 21:56:32 +0100 Subject: [PATCH 1096/2991] Implement bidirectional footnote link navigation --- .../Footnotes/OsuMarkdownFootnoteBacklink.cs | 18 ++++++++++---- .../Footnotes/OsuMarkdownFootnoteLink.cs | 24 +++++++++++++------ 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteBacklink.cs b/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteBacklink.cs index a401eadaa3..22c02ea720 100644 --- a/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteBacklink.cs +++ b/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteBacklink.cs @@ -2,12 +2,14 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.Linq; using Markdig.Extensions.Footnotes; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers.Markdown; using osu.Framework.Graphics.Sprites; +using osu.Framework.Testing; using osu.Game.Overlays; using osuTK; @@ -27,14 +29,13 @@ namespace osu.Game.Graphics.Containers.Markdown.Footnotes public OsuMarkdownFootnoteBacklink(FootnoteLink backlink) { this.backlink = backlink; - AutoSizeAxes = Axes.X; } - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) + [BackgroundDependencyLoader(true)] + private void load(OverlayColourProvider colourProvider, OsuMarkdownContainer markdownContainer, OverlayScrollContainer? scrollContainer) { float fontSize = parentTextComponent.CreateSpriteText().Font.Size; - Height = fontSize; + Size = new Vector2(fontSize); IdleColour = colourProvider.Light2; HoverColour = colourProvider.Light1; @@ -47,6 +48,15 @@ namespace osu.Game.Graphics.Containers.Markdown.Footnotes Size = new Vector2(fontSize / 2), Icon = FontAwesome.Solid.ArrowUp, }); + + if (scrollContainer != null) + { + Action = () => + { + var footnoteLink = markdownContainer.ChildrenOfType().Single(footnoteLink => footnoteLink.FootnoteLink.Index == backlink.Index); + scrollContainer.ScrollIntoView(footnoteLink); + }; + } } } } diff --git a/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteLink.cs b/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteLink.cs index b35c08e335..c9bd408e9e 100644 --- a/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteLink.cs +++ b/osu.Game/Graphics/Containers/Markdown/Footnotes/OsuMarkdownFootnoteLink.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.Linq; using Markdig.Extensions.Footnotes; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; @@ -10,13 +11,14 @@ using osu.Framework.Graphics.Containers.Markdown; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; +using osu.Framework.Testing; using osu.Game.Overlays; namespace osu.Game.Graphics.Containers.Markdown.Footnotes { public partial class OsuMarkdownFootnoteLink : OsuHoverContainer, IHasCustomTooltip { - private readonly FootnoteLink footnoteLink; + public readonly FootnoteLink FootnoteLink; private SpriteText spriteText = null!; @@ -33,14 +35,13 @@ namespace osu.Game.Graphics.Containers.Markdown.Footnotes public OsuMarkdownFootnoteLink(FootnoteLink footnoteLink) { - this.footnoteLink = footnoteLink; + FootnoteLink = footnoteLink; AutoSizeAxes = Axes.Both; - Action = () => { }; // TODO } - [BackgroundDependencyLoader] - private void load() + [BackgroundDependencyLoader(true)] + private void load(OsuMarkdownContainer markdownContainer, OverlayScrollContainer? scrollContainer) { IdleColour = colourProvider.Light2; HoverColour = colourProvider.Light1; @@ -52,15 +53,24 @@ namespace osu.Game.Graphics.Containers.Markdown.Footnotes float baseSize = t.Font.Size; t.Font = t.Font.With(size: baseSize * 0.58f); t.Margin = new MarginPadding { Bottom = 0.33f * baseSize }; - t.Text = LocalisableString.Format("[{0}]", footnoteLink.Index); + t.Text = LocalisableString.Format("[{0}]", FootnoteLink.Index); })); + + if (scrollContainer != null) + { + Action = () => + { + var footnote = markdownContainer.ChildrenOfType().Single(footnote => footnote.Footnote.Label == FootnoteLink.Footnote.Label); + scrollContainer.ScrollIntoView(footnote); + }; + } } public object TooltipContent { get { - var span = footnoteLink.Footnote.LastChild.Span; + var span = FootnoteLink.Footnote.LastChild.Span; return markdownContainer.Text.Substring(span.Start, span.Length); } } From db1380a346799cd00ef2a4a26227087cd5ae1d41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 19 Dec 2022 20:16:36 +0100 Subject: [PATCH 1097/2991] Refactor markdown extension management --- .../Markdown/OsuMarkdownContainer.cs | 48 +++------------ .../Markdown/OsuMarkdownContainerOptions.cs | 61 +++++++++++++++++++ .../Comments/CommentMarkdownContainer.cs | 5 +- .../Wiki/Markdown/WikiMarkdownContainer.cs | 7 ++- 4 files changed, 77 insertions(+), 44 deletions(-) create mode 100644 osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainerOptions.cs diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs index e884b5db69..7e9581c056 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs @@ -4,10 +4,6 @@ #nullable disable using Markdig; -using Markdig.Extensions.AutoLinks; -using Markdig.Extensions.CustomContainers; -using Markdig.Extensions.EmphasisExtras; -using Markdig.Extensions.Footnotes; using Markdig.Extensions.Tables; using Markdig.Extensions.Yaml; using Markdig.Syntax; @@ -21,24 +17,6 @@ namespace osu.Game.Graphics.Containers.Markdown { public partial class OsuMarkdownContainer : MarkdownContainer { - /// - /// Allows this markdown container to parse and link footnotes. - /// - /// - protected virtual bool Footnotes => false; - - /// - /// Allows this markdown container to make URL text clickable. - /// - /// - protected virtual bool Autolinks => false; - - /// - /// Allows this markdown container to parse custom containers (used for flags and infoboxes). - /// - /// - protected virtual bool CustomContainers => false; - public OsuMarkdownContainer() { LineSpacing = 21; @@ -99,25 +77,13 @@ namespace osu.Game.Graphics.Containers.Markdown return new OsuMarkdownUnorderedListItem(level); } - // reference: https://github.com/ppy/osu-web/blob/05488a96b25b5a09f2d97c54c06dd2bae59d1dc8/app/Libraries/Markdown/OsuMarkdown.php#L301 - protected override MarkdownPipeline CreateBuilder() - { - var pipeline = new MarkdownPipelineBuilder() - .UseAutoIdentifiers() - .UsePipeTables() - .UseEmphasisExtras(EmphasisExtraOptions.Strikethrough) - .UseYamlFrontMatter(); + protected sealed override MarkdownPipeline CreateBuilder() + => Options.BuildPipeline(); - if (Footnotes) - pipeline = pipeline.UseFootnotes(); - - if (Autolinks) - pipeline = pipeline.UseAutoLinks(); - - if (CustomContainers) - pipeline.UseCustomContainers(); - - return pipeline.Build(); - } + /// + /// Creates a instance which is used to determine + /// which CommonMark/Markdig extensions should be enabled for this . + /// + protected virtual OsuMarkdownContainerOptions Options => new OsuMarkdownContainerOptions(); } } diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainerOptions.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainerOptions.cs new file mode 100644 index 0000000000..f2fd0e06a6 --- /dev/null +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainerOptions.cs @@ -0,0 +1,61 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Markdig; +using Markdig.Extensions.AutoLinks; +using Markdig.Extensions.CustomContainers; +using Markdig.Extensions.EmphasisExtras; +using Markdig.Extensions.Footnotes; + +namespace osu.Game.Graphics.Containers.Markdown +{ + /// + /// Groups options of customising the set of available extensions to instances. + /// + public class OsuMarkdownContainerOptions + { + /// + /// Allows the to parse and link footnotes. + /// + /// + public bool Footnotes { get; init; } + + /// + /// Allows the container to make URL text clickable. + /// + /// + public bool Autolinks { get; init; } + + /// + /// Allows the to parse custom containers (used for flags and infoboxes). + /// + /// + public bool CustomContainers { get; init; } + + /// + /// Returns a prepared according to the options specified by the current instance. + /// + /// + /// Compare: https://github.com/ppy/osu-web/blob/05488a96b25b5a09f2d97c54c06dd2bae59d1dc8/app/Libraries/Markdown/OsuMarkdown.php#L301 + /// + public MarkdownPipeline BuildPipeline() + { + var pipeline = new MarkdownPipelineBuilder() + .UseAutoIdentifiers() + .UsePipeTables() + .UseEmphasisExtras(EmphasisExtraOptions.Strikethrough) + .UseYamlFrontMatter(); + + if (Footnotes) + pipeline = pipeline.UseFootnotes(); + + if (Autolinks) + pipeline = pipeline.UseAutoLinks(); + + if (CustomContainers) + pipeline.UseCustomContainers(); + + return pipeline.Build(); + } + } +} diff --git a/osu.Game/Overlays/Comments/CommentMarkdownContainer.cs b/osu.Game/Overlays/Comments/CommentMarkdownContainer.cs index 664946fc63..9cc20caa05 100644 --- a/osu.Game/Overlays/Comments/CommentMarkdownContainer.cs +++ b/osu.Game/Overlays/Comments/CommentMarkdownContainer.cs @@ -11,7 +11,10 @@ namespace osu.Game.Overlays.Comments { public partial class CommentMarkdownContainer : OsuMarkdownContainer { - protected override bool Autolinks => true; + protected override OsuMarkdownContainerOptions Options => new OsuMarkdownContainerOptions + { + Autolinks = true + }; protected override MarkdownHeading CreateHeading(HeadingBlock headingBlock) => new CommentMarkdownHeading(headingBlock); diff --git a/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownContainer.cs b/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownContainer.cs index 4ef9be90c9..bb296c5d41 100644 --- a/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownContainer.cs +++ b/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownContainer.cs @@ -16,8 +16,11 @@ namespace osu.Game.Overlays.Wiki.Markdown { public partial class WikiMarkdownContainer : OsuMarkdownContainer { - protected override bool Footnotes => true; - protected override bool CustomContainers => true; + protected override OsuMarkdownContainerOptions Options => new OsuMarkdownContainerOptions + { + Footnotes = true, + CustomContainers = true + }; public string CurrentPath { From 12aa2e96db35ebff527dc153760048e2c6bf0e24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 19 Dec 2022 21:21:18 +0100 Subject: [PATCH 1098/2991] Add test case covering failure --- .../Visual/Online/TestSceneWikiMarkdownContainer.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs index b486f800c6..6185c43f99 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs @@ -199,6 +199,16 @@ Line after image"; }); } + [Test] + public void TestHeadingWithIdAttribute() + { + AddStep("Add heading with ID", () => + { + markdownContainer.Text = "# This is a heading with an ID {#this-is-the-id}"; + }); + AddAssert("ID not visible", () => markdownContainer.ChildrenOfType().All(spriteText => spriteText.Text != "{#this-is-the-id}")); + } + private partial class TestMarkdownContainer : WikiMarkdownContainer { public LinkInline Link; From 7c282d9def40871269abd7532a9545d2b6383bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 19 Dec 2022 20:23:01 +0100 Subject: [PATCH 1099/2991] Enable generic attribute support for wiki markdown containers --- .../Extensions/BlockAttributeExtension.cs | 34 +++++++++++++++++++ .../Extensions/OsuMarkdownExtensions.cs | 21 ++++++++++++ .../Markdown/OsuMarkdownContainerOptions.cs | 12 ++++++- .../Wiki/Markdown/WikiMarkdownContainer.cs | 3 +- 4 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 osu.Game/Graphics/Containers/Markdown/Extensions/BlockAttributeExtension.cs create mode 100644 osu.Game/Graphics/Containers/Markdown/Extensions/OsuMarkdownExtensions.cs diff --git a/osu.Game/Graphics/Containers/Markdown/Extensions/BlockAttributeExtension.cs b/osu.Game/Graphics/Containers/Markdown/Extensions/BlockAttributeExtension.cs new file mode 100644 index 0000000000..caed4b26b9 --- /dev/null +++ b/osu.Game/Graphics/Containers/Markdown/Extensions/BlockAttributeExtension.cs @@ -0,0 +1,34 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Markdig; +using Markdig.Extensions.GenericAttributes; +using Markdig.Renderers; +using Markdig.Syntax; + +namespace osu.Game.Graphics.Containers.Markdown.Extensions +{ + /// + /// A variant of + /// which only handles generic attributes in the current markdown and ignores inline generic attributes. + /// + /// + /// For rationale, see implementation of . + /// + public class BlockAttributeExtension : IMarkdownExtension + { + private readonly GenericAttributesExtension genericAttributesExtension = new GenericAttributesExtension(); + + public void Setup(MarkdownPipelineBuilder pipeline) + { + genericAttributesExtension.Setup(pipeline); + + // GenericAttributesExtension registers a GenericAttributesParser in pipeline.InlineParsers. + // this conflicts with the CustomContainerExtension, leading to some custom containers (e.g. flags) not displaying. + // as a workaround, remove the inline parser here before it can do damage. + pipeline.InlineParsers.RemoveAll(parser => parser is GenericAttributesParser); + } + + public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) => genericAttributesExtension.Setup(pipeline, renderer); + } +} diff --git a/osu.Game/Graphics/Containers/Markdown/Extensions/OsuMarkdownExtensions.cs b/osu.Game/Graphics/Containers/Markdown/Extensions/OsuMarkdownExtensions.cs new file mode 100644 index 0000000000..10542abe71 --- /dev/null +++ b/osu.Game/Graphics/Containers/Markdown/Extensions/OsuMarkdownExtensions.cs @@ -0,0 +1,21 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Markdig; + +namespace osu.Game.Graphics.Containers.Markdown.Extensions +{ + public static class OsuMarkdownExtensions + { + /// + /// Uses the block attributes extension. + /// + /// The pipeline. + /// The modified pipeline. + public static MarkdownPipelineBuilder UseBlockAttributes(this MarkdownPipelineBuilder pipeline) + { + pipeline.Extensions.AddIfNotAlready(); + return pipeline; + } + } +} diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainerOptions.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainerOptions.cs index f2fd0e06a6..1648ffbf90 100644 --- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainerOptions.cs +++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainerOptions.cs @@ -6,6 +6,7 @@ using Markdig.Extensions.AutoLinks; using Markdig.Extensions.CustomContainers; using Markdig.Extensions.EmphasisExtras; using Markdig.Extensions.Footnotes; +using osu.Game.Graphics.Containers.Markdown.Extensions; namespace osu.Game.Graphics.Containers.Markdown { @@ -32,6 +33,12 @@ namespace osu.Game.Graphics.Containers.Markdown /// public bool CustomContainers { get; init; } + /// + /// Allows the to parse custom attributes in block elements (used e.g. for custom anchor names in the wiki). + /// + /// + public bool BlockAttributes { get; init; } + /// /// Returns a prepared according to the options specified by the current instance. /// @@ -53,7 +60,10 @@ namespace osu.Game.Graphics.Containers.Markdown pipeline = pipeline.UseAutoLinks(); if (CustomContainers) - pipeline.UseCustomContainers(); + pipeline = pipeline.UseCustomContainers(); + + if (BlockAttributes) + pipeline = pipeline.UseBlockAttributes(); return pipeline.Build(); } diff --git a/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownContainer.cs b/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownContainer.cs index bb296c5d41..7c36caa62f 100644 --- a/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownContainer.cs +++ b/osu.Game/Overlays/Wiki/Markdown/WikiMarkdownContainer.cs @@ -19,7 +19,8 @@ namespace osu.Game.Overlays.Wiki.Markdown protected override OsuMarkdownContainerOptions Options => new OsuMarkdownContainerOptions { Footnotes = true, - CustomContainers = true + CustomContainers = true, + BlockAttributes = true }; public string CurrentPath From 30b9f5d92e901279ae75ca997f47f12e19ecc196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 19 Dec 2022 21:31:54 +0100 Subject: [PATCH 1100/2991] Add test coverage for correct operation of flag extension --- osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs index 6185c43f99..b7989d3f44 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneWikiMarkdownContainer.cs @@ -18,6 +18,7 @@ using osu.Framework.Utils; using osu.Game.Graphics.Containers.Markdown; using osu.Game.Overlays; using osu.Game.Overlays.Wiki.Markdown; +using osu.Game.Users.Drawables; namespace osu.Game.Tests.Visual.Online { @@ -197,6 +198,7 @@ Line after image"; markdownContainer.CurrentPath = @"https://dev.ppy.sh"; markdownContainer.Text = "::{flag=\"AU\"}:: ::{flag=\"ZZ\"}::"; }); + AddAssert("Two flags visible", () => markdownContainer.ChildrenOfType().Count(), () => Is.EqualTo(2)); } [Test] From c200e7799418a2ca7c83b3e7f821918227eec845 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Mon, 19 Dec 2022 18:31:28 -0500 Subject: [PATCH 1101/2991] Add mania hidden mod configuration --- .../Mods/TestSceneManiaModHidden.cs | 19 +++++++++++++++++++ .../Mods/ManiaModHidden.cs | 12 ++++++++++++ .../Mods/ManiaModPlayfieldCover.cs | 4 +++- 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs diff --git a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs new file mode 100644 index 0000000000..65ee43dfaf --- /dev/null +++ b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs @@ -0,0 +1,19 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Rulesets.Mania.Mods; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Mania.Tests.Mods +{ + public partial class TestSceneManiaModHidden : ModTestScene + { + protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset(); + + [TestCase(0.5f)] + [TestCase(0.2f)] + [TestCase(0.8f)] + public void TestCoverage(float Coverage) => CreateModTest(new ModTestData { Mod = new ManiaModHidden { CoverageAmount = { Value = Coverage } }, PassCondition = () => true }); + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs index eeb6e94fc7..5dcb859f7a 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs @@ -4,7 +4,9 @@ using System; using System.Linq; using osu.Framework.Localisation; +using osu.Game.Configuration; using osu.Game.Rulesets.Mania.UI; +using osu.Framework.Bindables; namespace osu.Game.Rulesets.Mania.Mods { @@ -13,6 +15,16 @@ namespace osu.Game.Rulesets.Mania.Mods public override LocalisableString Description => @"Keys fade out before you hit them!"; public override double ScoreMultiplier => 1; + [SettingSource("Coverage", "How much of the playfield notes should be hidden for.")] + public BindableNumber CoverageAmount { get; } = new BindableFloat(0.5f) + { + Precision = 0.01f, + MinValue = 0.2f, + MaxValue = 0.8f, + Default = 0.5f, + }; + public override float Coverage => CoverageAmount.Value; + public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ManiaModFadeIn)).ToArray(); protected override CoverExpandDirection ExpandDirection => CoverExpandDirection.AgainstScroll; diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs index 6a94e5d371..635ad1f2e8 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs @@ -22,6 +22,8 @@ namespace osu.Game.Rulesets.Mania.Mods /// protected abstract CoverExpandDirection ExpandDirection { get; } + public virtual float Coverage {get => 0.5f;} + public virtual void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { ManiaPlayfield maniaPlayfield = (ManiaPlayfield)drawableRuleset.Playfield; @@ -36,7 +38,7 @@ namespace osu.Game.Rulesets.Mania.Mods { c.RelativeSizeAxes = Axes.Both; c.Direction = ExpandDirection; - c.Coverage = 0.5f; + c.Coverage = Coverage; })); } } From 42dbb0bfd077bfa0240f81193a302d884018cbd2 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Mon, 19 Dec 2022 19:24:38 -0500 Subject: [PATCH 1102/2991] fix formatting --- osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs index 635ad1f2e8..5e9c1a4ae7 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Mania.Mods /// protected abstract CoverExpandDirection ExpandDirection { get; } - public virtual float Coverage {get => 0.5f;} + public virtual float Coverage { get => 0.5f; } public virtual void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { From 01f09529a825d80c8e6ccb390b644b7586234a70 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 18 Dec 2022 22:52:21 -0800 Subject: [PATCH 1103/2991] Link beatmap set genre and language to listing filters --- osu.Game/Online/Chat/MessageFormatter.cs | 2 ++ osu.Game/OsuGame.cs | 12 ++++++++++++ .../BeatmapListing/BeatmapListingFilterControl.cs | 7 +++++++ osu.Game/Overlays/BeatmapListingOverlay.cs | 12 ++++++++++++ osu.Game/Overlays/BeatmapSet/MetadataSection.cs | 10 ++++++++++ 5 files changed, 43 insertions(+) diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index b9bca9dc20..523185a7cb 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -341,6 +341,8 @@ namespace osu.Game.Online.Chat OpenWiki, Custom, OpenChangelog, + FilterBeatmapSetGenre, + FilterBeatmapSetLanguage, } public class Link : IComparable diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index a0a45e18a8..4c47eda38b 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -356,6 +356,14 @@ namespace osu.Game SearchBeatmapSet(argString); break; + case LinkAction.FilterBeatmapSetGenre: + FilterBeatmapSetGenre(argString); + break; + + case LinkAction.FilterBeatmapSetLanguage: + FilterBeatmapSetLanguage(argString); + break; + case LinkAction.OpenEditorTimestamp: case LinkAction.JoinMultiplayerMatch: case LinkAction.Spectate: @@ -460,6 +468,10 @@ namespace osu.Game /// The query to search for. public void SearchBeatmapSet(string query) => waitForReady(() => beatmapListing, _ => beatmapListing.ShowWithSearch(query)); + public void FilterBeatmapSetGenre(string genre) => waitForReady(() => beatmapListing, _ => beatmapListing.ShowWithGenreFilter(genre)); + + public void FilterBeatmapSetLanguage(string language) => waitForReady(() => beatmapListing, _ => beatmapListing.ShowWithLanguageFilter(language)); + /// /// Show a wiki's page as an overlay /// diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs index c5c252fb5d..5eb1ff7024 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Humanizer; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; @@ -145,6 +146,12 @@ namespace osu.Game.Overlays.BeatmapListing public void Search(string query) => Schedule(() => searchControl.Query.Value = query); + public void FilterGenre(string genre) + => Schedule(() => searchControl.Genre.Value = genre.DehumanizeTo()); + + public void FilterLanguage(string language) + => Schedule(() => searchControl.Language.Value = language.DehumanizeTo()); + protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index d6d4f1a67b..010499df6f 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -110,6 +110,18 @@ namespace osu.Game.Overlays ScrollFlow.ScrollToStart(); } + public void ShowWithGenreFilter(string genre) + { + ShowWithSearch(string.Empty); + filterControl.FilterGenre(genre); + } + + public void ShowWithLanguageFilter(string language) + { + ShowWithSearch(string.Empty); + filterControl.FilterLanguage(language); + } + protected override BeatmapListingHeader CreateHeader() => new BeatmapListingHeader(); protected override Color4 BackgroundColour => ColourProvider.Background6; diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSection.cs b/osu.Game/Overlays/BeatmapSet/MetadataSection.cs index 6390c52ff3..caf1b7197c 100644 --- a/osu.Game/Overlays/BeatmapSet/MetadataSection.cs +++ b/osu.Game/Overlays/BeatmapSet/MetadataSection.cs @@ -4,6 +4,7 @@ #nullable disable using System; +using Humanizer; using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -12,6 +13,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Online.Chat; +using osu.Game.Overlays.BeatmapListing; using osuTK; using osuTK.Graphics; @@ -116,6 +118,14 @@ namespace osu.Game.Overlays.BeatmapSet break; + case MetadataType.Genre: + loaded.AddLink(text.DehumanizeTo().GetLocalisableDescription(), LinkAction.FilterBeatmapSetGenre, text); + break; + + case MetadataType.Language: + loaded.AddLink(text.DehumanizeTo().GetLocalisableDescription(), LinkAction.FilterBeatmapSetLanguage, text); + break; + default: loaded.AddText(text); break; From c119d41a2dac3c8d50304aeb7b16484281404212 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 20 Dec 2022 17:52:53 +0900 Subject: [PATCH 1104/2991] Only show song select for now at ui scale adjust first run screen Having both was a bit too much. Still not happy with this but it's a bit less sensory overload. I think while it's cool being able to show nested screens like this, it needs more thought to actually be a good experience. --- osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs b/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs index 63688841d0..a3969883e0 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs @@ -58,7 +58,7 @@ namespace osu.Game.Overlays.FirstRunSetup Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.None, - Size = new Vector2(screen_width, screen_width / 16f * 9 / 2), + Size = new Vector2(screen_width, screen_width / 16f * 9), Children = new Drawable[] { new GridContainer @@ -68,7 +68,6 @@ namespace osu.Game.Overlays.FirstRunSetup { new Drawable[] { - new SampleScreenContainer(new PinnedMainMenu()), new SampleScreenContainer(new NestedSongSelect()), }, // TODO: add more screens here in the future (gameplay / results) @@ -109,17 +108,6 @@ namespace osu.Game.Overlays.FirstRunSetup public override bool? AllowTrackAdjustments => false; } - private partial class PinnedMainMenu : MainMenu - { - public override void OnEntering(ScreenTransitionEvent e) - { - base.OnEntering(e); - - Buttons.ReturnToTopOnIdle = false; - Buttons.State = ButtonSystemState.TopLevel; - } - } - private partial class UIScaleSlider : OsuSliderBar { public override LocalisableString TooltipText => base.TooltipText + "x"; From 439b8ac56ae50fdb77f8d8fd174925a1a6b52324 Mon Sep 17 00:00:00 2001 From: wiskerz76 Date: Mon, 19 Dec 2022 16:33:35 -0500 Subject: [PATCH 1105/2991] Fix file select popup getting stuck when switching first run screens while selecting Closes #21663 Supersedes #21724 --- .../FirstRunSetup/ScreenImportFromStable.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index 04aa976ff1..8b85bb49a5 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -126,7 +126,8 @@ namespace osu.Game.Overlays.FirstRunSetup if (available) { - copyInformation.Text = "Data migration will use \"hard links\". No extra disk space will be used, and you can delete either data folder at any point without affecting the other installation."; + copyInformation.Text = + "Data migration will use \"hard links\". No extra disk space will be used, and you can delete either data folder at any point without affecting the other installation."; } else if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows) copyInformation.Text = "Lightweight linking of files is not supported on your operating system yet, so a copy of all files will be made during import."; @@ -173,6 +174,18 @@ namespace osu.Game.Overlays.FirstRunSetup c.Current.Disabled = !allow; } + public override void OnSuspending(ScreenTransitionEvent e) + { + stableLocatorTextBox.HidePopover(); + base.OnSuspending(e); + } + + public override bool OnExiting(ScreenExitEvent e) + { + stableLocatorTextBox.HidePopover(); + return base.OnExiting(e); + } + private partial class ImportCheckbox : SettingsCheckbox { public readonly StableContent StableContent; From 2f0c772dcb4d5110727de6389db3f1e9c31d474c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Dec 2022 15:52:29 +0900 Subject: [PATCH 1106/2991] Add argon pro skin --- .../Overlays/Settings/Sections/SkinSection.cs | 1 + osu.Game/Skinning/ArgonProSkin.cs | 48 +++++++++++++++++++ osu.Game/Skinning/ArgonSkin.cs | 6 +-- osu.Game/Skinning/SkinInfo.cs | 1 + osu.Game/Skinning/SkinManager.cs | 1 + osu.Game/Skinning/SkinnableSprite.cs | 1 + 6 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 osu.Game/Skinning/ArgonProSkin.cs diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 826a1e7404..f75656cc99 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -105,6 +105,7 @@ namespace osu.Game.Overlays.Settings.Sections dropdownItems.Clear(); dropdownItems.Add(sender.Single(s => s.ID == SkinInfo.ARGON_SKIN).ToLive(realm)); + dropdownItems.Add(sender.Single(s => s.ID == SkinInfo.ARGON_PRO_SKIN).ToLive(realm)); dropdownItems.Add(sender.Single(s => s.ID == SkinInfo.TRIANGLES_SKIN).ToLive(realm)); dropdownItems.Add(sender.Single(s => s.ID == SkinInfo.CLASSIC_SKIN).ToLive(realm)); diff --git a/osu.Game/Skinning/ArgonProSkin.cs b/osu.Game/Skinning/ArgonProSkin.cs new file mode 100644 index 0000000000..2bc8e55ec0 --- /dev/null +++ b/osu.Game/Skinning/ArgonProSkin.cs @@ -0,0 +1,48 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using JetBrains.Annotations; +using osu.Framework.Audio.Sample; +using osu.Game.Audio; +using osu.Game.Extensions; +using osu.Game.IO; + +namespace osu.Game.Skinning +{ + public class ArgonProSkin : ArgonSkin + { + public new static SkinInfo CreateInfo() => new SkinInfo + { + ID = Skinning.SkinInfo.ARGON_PRO_SKIN, + Name = "osu! \"argon\" pro (2022)", + Creator = "team osu!", + Protected = true, + InstantiationInfo = typeof(ArgonProSkin).GetInvariantInstantiationInfo() + }; + + public override ISample? GetSample(ISampleInfo sampleInfo) + { + foreach (string lookup in sampleInfo.LookupNames) + { + string remappedLookup = lookup.Replace("Gameplay/", "Gameplay/Pro/"); + + var sample = Samples?.Get(remappedLookup) ?? Resources.AudioManager?.Samples.Get(remappedLookup); + if (sample != null) + return sample; + } + + return null; + } + + public ArgonProSkin(IStorageResourceProvider resources) + : this(CreateInfo(), resources) + { + } + + [UsedImplicitly(ImplicitUseKindFlags.InstantiatedWithFixedConstructorSignature)] + public ArgonProSkin(SkinInfo skin, IStorageResourceProvider resources) + : base(skin, resources) + { + } + } +} diff --git a/osu.Game/Skinning/ArgonSkin.cs b/osu.Game/Skinning/ArgonSkin.cs index 6a0c4a23e5..d78147aaea 100644 --- a/osu.Game/Skinning/ArgonSkin.cs +++ b/osu.Game/Skinning/ArgonSkin.cs @@ -30,7 +30,7 @@ namespace osu.Game.Skinning InstantiationInfo = typeof(ArgonSkin).GetInvariantInstantiationInfo() }; - private readonly IStorageResourceProvider resources; + protected readonly IStorageResourceProvider Resources; public ArgonSkin(IStorageResourceProvider resources) : this(CreateInfo(), resources) @@ -41,7 +41,7 @@ namespace osu.Game.Skinning public ArgonSkin(SkinInfo skin, IStorageResourceProvider resources) : base(skin, resources) { - this.resources = resources; + Resources = resources; Configuration.CustomComboColours = new List { @@ -72,7 +72,7 @@ namespace osu.Game.Skinning { foreach (string lookup in sampleInfo.LookupNames) { - var sample = Samples?.Get(lookup) ?? resources.AudioManager?.Samples.Get(lookup); + var sample = Samples?.Get(lookup) ?? Resources.AudioManager?.Samples.Get(lookup); if (sample != null) return sample; } diff --git a/osu.Game/Skinning/SkinInfo.cs b/osu.Game/Skinning/SkinInfo.cs index 7b31c8fe88..9ad91f8725 100644 --- a/osu.Game/Skinning/SkinInfo.cs +++ b/osu.Game/Skinning/SkinInfo.cs @@ -20,6 +20,7 @@ namespace osu.Game.Skinning { internal static readonly Guid TRIANGLES_SKIN = new Guid("2991CFD8-2140-469A-BCB9-2EC23FBCE4AD"); internal static readonly Guid ARGON_SKIN = new Guid("CFFA69DE-B3E3-4DEE-8563-3C4F425C05D0"); + internal static readonly Guid ARGON_PRO_SKIN = new Guid("9FC9CF5D-0F16-4C71-8256-98868321AC43"); internal static readonly Guid CLASSIC_SKIN = new Guid("81F02CD3-EEC6-4865-AC23-FAE26A386187"); internal static readonly Guid RANDOM_SKIN = new Guid("D39DFEFB-477C-4372-B1EA-2BCEA5FB8908"); diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index 2ad62dbb61..f750bfad8a 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -84,6 +84,7 @@ namespace osu.Game.Skinning DefaultClassicSkin = new DefaultLegacySkin(this), trianglesSkin = new TrianglesSkin(this), argonSkin = new ArgonSkin(this), + new ArgonProSkin(this), }; // Ensure the default entries are present. diff --git a/osu.Game/Skinning/SkinnableSprite.cs b/osu.Game/Skinning/SkinnableSprite.cs index 1a8a3a26c9..a66f3e0549 100644 --- a/osu.Game/Skinning/SkinnableSprite.cs +++ b/osu.Game/Skinning/SkinnableSprite.cs @@ -111,6 +111,7 @@ namespace osu.Game.Skinning // Temporarily used to exclude undesirable ISkin implementations static bool isUserSkin(ISkin skin) => skin.GetType() == typeof(TrianglesSkin) + || skin.GetType() == typeof(ArgonProSkin) || skin.GetType() == typeof(ArgonSkin) || skin.GetType() == typeof(DefaultLegacySkin) || skin.GetType() == typeof(LegacySkin); From f7c854f1b0ebd59bac44c175dd54694c90ec4b39 Mon Sep 17 00:00:00 2001 From: Jamie Taylor Date: Tue, 20 Dec 2022 21:18:32 +0900 Subject: [PATCH 1107/2991] Change asset folder --- osu.Game/Skinning/ArgonProSkin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/ArgonProSkin.cs b/osu.Game/Skinning/ArgonProSkin.cs index 2bc8e55ec0..b753dd8fbe 100644 --- a/osu.Game/Skinning/ArgonProSkin.cs +++ b/osu.Game/Skinning/ArgonProSkin.cs @@ -24,7 +24,7 @@ namespace osu.Game.Skinning { foreach (string lookup in sampleInfo.LookupNames) { - string remappedLookup = lookup.Replace("Gameplay/", "Gameplay/Pro/"); + string remappedLookup = lookup.Replace(@"Gameplay/", @"Gameplay/ArgonPro/"); var sample = Samples?.Get(remappedLookup) ?? Resources.AudioManager?.Samples.Get(remappedLookup); if (sample != null) From b37f1cce3fc4bfd3c5408a8fe32a4fdc796f3b8d Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Tue, 20 Dec 2022 23:46:05 +0900 Subject: [PATCH 1108/2991] Added ability to report chat --- .../Visual/Online/TestSceneChatOverlay.cs | 38 +++++++ osu.Game/Overlays/Chat/ChatReportReason.cs | 36 ++++++ osu.Game/Overlays/Chat/DrawableUsername.cs | 16 ++- osu.Game/Overlays/Chat/ReportChatPopover.cs | 106 ++++++++++++++++++ osu.Game/Overlays/ChatOverlay.cs | 3 +- 5 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 osu.Game/Overlays/Chat/ChatReportReason.cs create mode 100644 osu.Game/Overlays/Chat/ReportChatPopover.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 8cc4eabcd7..44d739a6e3 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -30,6 +30,8 @@ using osu.Game.Overlays.Chat.Listing; using osu.Game.Overlays.Chat.ChannelList; using osuTK; using osuTK.Input; +using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Graphics.Sprites; namespace osu.Game.Tests.Visual.Online { @@ -530,6 +532,42 @@ namespace osu.Game.Tests.Visual.Online }); } + [Test] + public void TestChatReport() + { + AddStep("Show overlay with channel", () => + { + chatOverlay.Show(); + channelManager.CurrentChannel.Value = channelManager.JoinChannel(testChannel1); + }); + + AddAssert("Overlay is visible", () => chatOverlay.State.Value == Visibility.Visible); + waitForChannel1Visible(); + + AddStep("Right click username", () => + { + var username = this.ChildrenOfType().First(); + InputManager.MoveMouseTo(username); + InputManager.Click(MouseButton.Right); + }); + + AddStep("Click report", () => + { + var btn = this.ChildrenOfType().First(x => x.Text == "Report"); + InputManager.MoveMouseTo(btn); + InputManager.Click(MouseButton.Left); + }); + + AddStep("Try to report", () => + { + var btn = this.ChildrenOfType().Single().ChildrenOfType().Single(); + InputManager.MoveMouseTo(btn); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("Report message sended", () => channelManager.CurrentChannel.Value.Messages.Any(x => x.Content.Contains("!report"))); + } + private void joinTestChannel(int i) { AddStep($"Join test channel {i}", () => channelManager.JoinChannel(testChannels[i])); diff --git a/osu.Game/Overlays/Chat/ChatReportReason.cs b/osu.Game/Overlays/Chat/ChatReportReason.cs new file mode 100644 index 0000000000..55593d29ad --- /dev/null +++ b/osu.Game/Overlays/Chat/ChatReportReason.cs @@ -0,0 +1,36 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.ComponentModel; +using osu.Framework.Localisation; +using osu.Game.Resources.Localisation.Web; + +namespace osu.Game.Overlays.Chat +{ + public enum ChatReportReason + { + [Description("Insulting People")] + [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsInsults))] + Insults, + + [Description("Spam")] + [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsSpam))] + Spam, + + [Description("Cheating")] + [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsCheating))] + FoulPlay, + + [Description("Unwanted Content")] + [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsUnwantedContent))] + UnwantedContent, + + [Description("Nonsense")] + [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsNonsense))] + Nonsense, + + [Description("Other")] + [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsOther))] + Other + } +} diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs index 6bae498a6c..f70175f081 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; +using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -25,7 +26,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Chat { - public partial class DrawableUsername : OsuClickableContainer, IHasContextMenu + public partial class DrawableUsername : OsuClickableContainer, IHasContextMenu, IHasPopover { public Color4 AccentColour { get; } @@ -152,12 +153,20 @@ namespace osu.Game.Overlays.Chat }; if (!user.Equals(api.LocalUser.Value)) + { items.Add(new OsuMenuItem("Start Chat", MenuItemType.Standard, openUserChannel)); + items.Add(new OsuMenuItem("Report", MenuItemType.Destructive, this.ShowPopover)); + } return items.ToArray(); } } + private void report(ChatReportReason reason, string comments) + { + chatManager?.PostMessage($"!report {user.Username} ({reason.GetDescription()}): {comments}"); + } + private void openUserChannel() { chatManager?.OpenPrivateChannel(user); @@ -221,5 +230,10 @@ namespace osu.Game.Overlays.Chat Color4Extensions.FromHex("812a96"), Color4Extensions.FromHex("992861"), }; + + public Popover GetPopover() => new ReportChatPopover(user) + { + Action = report + }; } } diff --git a/osu.Game/Overlays/Chat/ReportChatPopover.cs b/osu.Game/Overlays/Chat/ReportChatPopover.cs new file mode 100644 index 0000000000..cf5e456874 --- /dev/null +++ b/osu.Game/Overlays/Chat/ReportChatPopover.cs @@ -0,0 +1,106 @@ +// 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.Allocation; +using osu.Framework.Audio; +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Resources.Localisation.Web; +using osuTK; + +namespace osu.Game.Overlays.Chat +{ + public partial class ReportChatPopover : OsuPopover + { + public Action? Action; + + private readonly APIUser? user; + + private OsuEnumDropdown reasonDropdown = null!; + private OsuTextBox commentsTextBox = null!; + + public ReportChatPopover(APIUser? user) + { + this.user = user; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours, AudioManager audio) + { + Child = new ReverseChildIDFillFlowContainer + { + Direction = FillDirection.Vertical, + Width = 500, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(7), + Children = new Drawable[] + { + new SpriteIcon + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Icon = FontAwesome.Solid.ExclamationTriangle, + Size = new Vector2(36), + }, + new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = ReportStrings.UserTitle(user?.Username ?? @"Someone"), + Font = OsuFont.Torus.With(size: 25), + Margin = new MarginPadding { Bottom = 10 } + }, + new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = UsersStrings.ReportReason, + }, + new Container + { + RelativeSizeAxes = Axes.X, + Height = 40, + Child = reasonDropdown = new OsuEnumDropdown + { + RelativeSizeAxes = Axes.X + } + }, + new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = UsersStrings.ReportComments, + }, + commentsTextBox = new OsuTextBox + { + RelativeSizeAxes = Axes.X, + PlaceholderText = UsersStrings.ReportPlaceholder, + }, + new RoundedButton + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Width = 200, + BackgroundColour = colours.Red3, + Text = UsersStrings.ReportActionsSend, + Action = () => + { + Action?.Invoke(reasonDropdown.Current.Value, commentsTextBox.Text); + this.HidePopover(); + }, + Margin = new MarginPadding { Bottom = 5, Top = 10 }, + } + } + }; + } + } +} diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index c539cdc5ec..c3a6ed0175 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -9,6 +9,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Input; using osu.Framework.Input.Bindings; @@ -122,7 +123,7 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.Y, Width = side_bar_width, }, - new Container + new PopoverContainer { RelativeSizeAxes = Axes.Both, Anchor = Anchor.TopRight, From 2c402d474035be888284b7318050aabb9abb3423 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 21 Dec 2022 01:24:41 +0900 Subject: [PATCH 1109/2991] Update resources --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8b4fa2dc6b..83dbf7e370 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ - + From ffa32307c3ef8c9917a210a31871b9000cf80246 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 21 Dec 2022 01:37:16 +0900 Subject: [PATCH 1110/2991] abstract ReportPopover --- .../Graphics/UserInterfaceV2/ReportPopover.cs | 114 ++++++++++++++++++ osu.Game/Overlays/Chat/ReportChatPopover.cs | 94 +-------------- .../Overlays/Comments/ReportCommentPopover.cs | 98 +-------------- 3 files changed, 119 insertions(+), 187 deletions(-) create mode 100644 osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs diff --git a/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs b/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs new file mode 100644 index 0000000000..44af108ab1 --- /dev/null +++ b/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs @@ -0,0 +1,114 @@ +// 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.Allocation; +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Resources.Localisation.Web; +using osuTK; + +namespace osu.Game.Graphics.UserInterfaceV2 +{ + public abstract partial class ReportPopover : OsuPopover + where T : struct, Enum + { + public Action? Action; + + private OsuEnumDropdown reasonDropdown = null!; + private OsuTextBox commentsTextBox = null!; + private RoundedButton submitButton = null!; + + public bool CanSubmitEmptyReason = false; + public LocalisableString Header; + + protected ReportPopover(LocalisableString headerString) + { + Header = headerString; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Child = new ReverseChildIDFillFlowContainer + { + Direction = FillDirection.Vertical, + Width = 500, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(7), + Children = new Drawable[] + { + new SpriteIcon + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Icon = FontAwesome.Solid.ExclamationTriangle, + Size = new Vector2(36), + }, + new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = Header, + Font = OsuFont.Torus.With(size: 25), + Margin = new MarginPadding { Bottom = 10 } + }, + new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = UsersStrings.ReportReason, + }, + new Container + { + RelativeSizeAxes = Axes.X, + Height = 40, + Child = reasonDropdown = new OsuEnumDropdown + { + RelativeSizeAxes = Axes.X + } + }, + new OsuSpriteText + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Text = UsersStrings.ReportComments, + }, + commentsTextBox = new OsuTextBox + { + RelativeSizeAxes = Axes.X, + PlaceholderText = UsersStrings.ReportPlaceholder, + }, + submitButton = new RoundedButton + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Width = 200, + BackgroundColour = colours.Red3, + Text = UsersStrings.ReportActionsSend, + Action = () => + { + Action?.Invoke(reasonDropdown.Current.Value, commentsTextBox.Text); + this.HidePopover(); + }, + Margin = new MarginPadding { Bottom = 5, Top = 10 }, + } + } + }; + + if (!CanSubmitEmptyReason) + { + commentsTextBox.Current.BindValueChanged(e => + { + submitButton.Enabled.Value = !string.IsNullOrWhiteSpace(e.NewValue); + }, true); + } + } + } +} diff --git a/osu.Game/Overlays/Chat/ReportChatPopover.cs b/osu.Game/Overlays/Chat/ReportChatPopover.cs index cf5e456874..79c3922795 100644 --- a/osu.Game/Overlays/Chat/ReportChatPopover.cs +++ b/osu.Game/Overlays/Chat/ReportChatPopover.cs @@ -1,106 +1,18 @@ // 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.Allocation; -using osu.Framework.Audio; -using osu.Framework.Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Online.API.Requests.Responses; using osu.Game.Resources.Localisation.Web; -using osuTK; namespace osu.Game.Overlays.Chat { - public partial class ReportChatPopover : OsuPopover + public partial class ReportChatPopover : ReportPopover { - public Action? Action; - - private readonly APIUser? user; - - private OsuEnumDropdown reasonDropdown = null!; - private OsuTextBox commentsTextBox = null!; - public ReportChatPopover(APIUser? user) + : base(ReportStrings.UserTitle(user?.Username ?? @"Someone")) { - this.user = user; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours, AudioManager audio) - { - Child = new ReverseChildIDFillFlowContainer - { - Direction = FillDirection.Vertical, - Width = 500, - AutoSizeAxes = Axes.Y, - Spacing = new Vector2(7), - Children = new Drawable[] - { - new SpriteIcon - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Icon = FontAwesome.Solid.ExclamationTriangle, - Size = new Vector2(36), - }, - new OsuSpriteText - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Text = ReportStrings.UserTitle(user?.Username ?? @"Someone"), - Font = OsuFont.Torus.With(size: 25), - Margin = new MarginPadding { Bottom = 10 } - }, - new OsuSpriteText - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Text = UsersStrings.ReportReason, - }, - new Container - { - RelativeSizeAxes = Axes.X, - Height = 40, - Child = reasonDropdown = new OsuEnumDropdown - { - RelativeSizeAxes = Axes.X - } - }, - new OsuSpriteText - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Text = UsersStrings.ReportComments, - }, - commentsTextBox = new OsuTextBox - { - RelativeSizeAxes = Axes.X, - PlaceholderText = UsersStrings.ReportPlaceholder, - }, - new RoundedButton - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Width = 200, - BackgroundColour = colours.Red3, - Text = UsersStrings.ReportActionsSend, - Action = () => - { - Action?.Invoke(reasonDropdown.Current.Value, commentsTextBox.Text); - this.HidePopover(); - }, - Margin = new MarginPadding { Bottom = 5, Top = 10 }, - } - } - }; + CanSubmitEmptyReason = true; } } } diff --git a/osu.Game/Overlays/Comments/ReportCommentPopover.cs b/osu.Game/Overlays/Comments/ReportCommentPopover.cs index f3b2a2f97c..e688dad755 100644 --- a/osu.Game/Overlays/Comments/ReportCommentPopover.cs +++ b/osu.Game/Overlays/Comments/ReportCommentPopover.cs @@ -1,111 +1,17 @@ // 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.Allocation; -using osu.Framework.Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Online.API.Requests.Responses; using osu.Game.Resources.Localisation.Web; -using osuTK; namespace osu.Game.Overlays.Comments { - public partial class ReportCommentPopover : OsuPopover + public partial class ReportCommentPopover : ReportPopover { - public Action? Action; - - private readonly Comment? comment; - - private OsuEnumDropdown reasonDropdown = null!; - private OsuTextBox commentsTextBox = null!; - private RoundedButton submitButton = null!; - public ReportCommentPopover(Comment? comment) + : base(ReportStrings.CommentTitle(comment?.User?.Username ?? comment?.LegacyName ?? @"Someone")) { - this.comment = comment; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - Child = new ReverseChildIDFillFlowContainer - { - Direction = FillDirection.Vertical, - Width = 500, - AutoSizeAxes = Axes.Y, - Spacing = new Vector2(7), - Children = new Drawable[] - { - new SpriteIcon - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Icon = FontAwesome.Solid.ExclamationTriangle, - Size = new Vector2(36), - }, - new OsuSpriteText - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Text = ReportStrings.CommentTitle(comment?.User?.Username ?? comment?.LegacyName ?? @"Someone"), - Font = OsuFont.Torus.With(size: 25), - Margin = new MarginPadding { Bottom = 10 } - }, - new OsuSpriteText - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Text = UsersStrings.ReportReason, - }, - new Container - { - RelativeSizeAxes = Axes.X, - Height = 40, - Child = reasonDropdown = new OsuEnumDropdown - { - RelativeSizeAxes = Axes.X - } - }, - new OsuSpriteText - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Text = UsersStrings.ReportComments, - }, - commentsTextBox = new OsuTextBox - { - RelativeSizeAxes = Axes.X, - PlaceholderText = UsersStrings.ReportPlaceholder, - }, - submitButton = new RoundedButton - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Width = 200, - BackgroundColour = colours.Red3, - Text = UsersStrings.ReportActionsSend, - Action = () => - { - Action?.Invoke(reasonDropdown.Current.Value, commentsTextBox.Text); - this.HidePopover(); - }, - Margin = new MarginPadding { Bottom = 5, Top = 10 }, - } - } - }; - - commentsTextBox.Current.BindValueChanged(e => - { - submitButton.Enabled.Value = !string.IsNullOrWhiteSpace(e.NewValue); - }, true); } } } From bf074adb137c2178eebd38dd285fbaec82c86364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 20 Dec 2022 18:24:26 +0100 Subject: [PATCH 1111/2991] Remove unused using directive --- osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs b/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs index a3969883e0..1bcb1bcdf4 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenUIScale.cs @@ -13,7 +13,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Textures; using osu.Framework.Localisation; -using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; From 4a1a023f9e7ca7a68841f1558cfa55dcb3a25cee Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Tue, 20 Dec 2022 13:33:33 -0500 Subject: [PATCH 1112/2991] Code quality improvements --- .../Mods/TestSceneManiaModHidden.cs | 2 +- osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs | 5 +++-- osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs index 65ee43dfaf..44d206d9e1 100644 --- a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs +++ b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs @@ -14,6 +14,6 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods [TestCase(0.5f)] [TestCase(0.2f)] [TestCase(0.8f)] - public void TestCoverage(float Coverage) => CreateModTest(new ModTestData { Mod = new ManiaModHidden { CoverageAmount = { Value = Coverage } }, PassCondition = () => true }); + public void TestCoverage(float coverage) => CreateModTest(new ModTestData { Mod = new ManiaModHidden { CoverageAmount = { Value = coverage } }, PassCondition = () => true }); } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs index 5dcb859f7a..76a102bda3 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Mods public override LocalisableString Description => @"Keys fade out before you hit them!"; public override double ScoreMultiplier => 1; - [SettingSource("Coverage", "How much of the playfield notes should be hidden for.")] + [SettingSource("Coverage", "The proportion of playfield height that notes will be hidden for.")] public BindableNumber CoverageAmount { get; } = new BindableFloat(0.5f) { Precision = 0.01f, @@ -23,7 +23,8 @@ namespace osu.Game.Rulesets.Mania.Mods MaxValue = 0.8f, Default = 0.5f, }; - public override float Coverage => CoverageAmount.Value; + + protected override float Coverage => CoverageAmount.Value; public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ManiaModFadeIn)).ToArray(); diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs index 5e9c1a4ae7..bfb70938b9 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Mania.Mods /// protected abstract CoverExpandDirection ExpandDirection { get; } - public virtual float Coverage { get => 0.5f; } + protected virtual float Coverage => 0.5f; public virtual void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { From cebd5f6dc2384d6468f56f31385cda8e7c035d0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 20 Dec 2022 20:36:27 +0100 Subject: [PATCH 1113/2991] Fix restore default button having a minuscule hit area Another casualty of edc78205d5312e9278f2a22ef156fd34af492595. This particular button was actually *relying* on receiving positional events from its entire bounding box rather than `Content`, in order for the button to be htitable more easily, which broke as other buttons were fixed to behave more in line with expectations. Upon closer inspection this is another case of a weird carried-over construction. The button doesn't really need to inherit `OsuButton` or do any of the arcane stuff that it was doing, so it's now a plain `OsuClickableContainer` with less `Content` hackery. --- .../Overlays/RestoreDefaultValueButton.cs | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/osu.Game/Overlays/RestoreDefaultValueButton.cs b/osu.Game/Overlays/RestoreDefaultValueButton.cs index 24dec44588..9d5e5db6e6 100644 --- a/osu.Game/Overlays/RestoreDefaultValueButton.cs +++ b/osu.Game/Overlays/RestoreDefaultValueButton.cs @@ -7,18 +7,20 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osuTK; namespace osu.Game.Overlays { - public partial class RestoreDefaultValueButton : OsuButton, IHasTooltip, IHasCurrentValue + public partial class RestoreDefaultValueButton : OsuClickableContainer, IHasCurrentValue { public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks; @@ -51,15 +53,32 @@ namespace osu.Game.Overlays private const float size = 4; + private CircularContainer circle = null!; + private Box background = null!; + + public RestoreDefaultValueButton() + : base(HoverSampleSet.Button) + { + } + [BackgroundDependencyLoader] private void load(OsuColour colour) { - BackgroundColour = colour.Lime1; + // size intentionally much larger than actual drawn content, so that the button is easier to click. Size = new Vector2(3 * size); - Content.RelativeSizeAxes = Axes.None; - Content.Size = new Vector2(size); - Content.CornerRadius = size / 2; + Add(circle = new CircularContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(size), + Masking = true, + Child = background = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colour.Lime1 + } + }); Alpha = 0f; @@ -77,7 +96,7 @@ namespace osu.Game.Overlays FinishTransforms(true); } - public LocalisableString TooltipText => "revert to default"; + public override LocalisableString TooltipText => "revert to default"; protected override bool OnHover(HoverEvent e) { @@ -104,8 +123,8 @@ namespace osu.Game.Overlays if (!Current.Disabled) { this.FadeTo(Current.IsDefault ? 0 : 1, fade_duration, Easing.OutQuint); - Background.FadeColour(IsHovered ? colours.Lime0 : colours.Lime1, fade_duration, Easing.OutQuint); - Content.TweenEdgeEffectTo(new EdgeEffectParameters + background.FadeColour(IsHovered ? colours.Lime0 : colours.Lime1, fade_duration, Easing.OutQuint); + circle.TweenEdgeEffectTo(new EdgeEffectParameters { Colour = (IsHovered ? colours.Lime1 : colours.Lime3).Opacity(0.4f), Radius = IsHovered ? 8 : 4, @@ -114,8 +133,8 @@ namespace osu.Game.Overlays } else { - Background.FadeColour(colours.Lime3, fade_duration, Easing.OutQuint); - Content.TweenEdgeEffectTo(new EdgeEffectParameters + background.FadeColour(colours.Lime3, fade_duration, Easing.OutQuint); + circle.TweenEdgeEffectTo(new EdgeEffectParameters { Colour = colours.Lime3.Opacity(0.1f), Radius = 2, From b03291330f2fb89dd482a53b62c23caeeb1b0757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 20 Dec 2022 21:23:50 +0100 Subject: [PATCH 1114/2991] Add score processed callback to spectator client --- osu.Game/Online/Spectator/ISpectatorClient.cs | 7 +++++++ osu.Game/Online/Spectator/OnlineSpectatorClient.cs | 1 + osu.Game/Online/Spectator/SpectatorClient.cs | 12 ++++++++++++ 3 files changed, 20 insertions(+) diff --git a/osu.Game/Online/Spectator/ISpectatorClient.cs b/osu.Game/Online/Spectator/ISpectatorClient.cs index ccba280001..605ebc4ef0 100644 --- a/osu.Game/Online/Spectator/ISpectatorClient.cs +++ b/osu.Game/Online/Spectator/ISpectatorClient.cs @@ -32,5 +32,12 @@ namespace osu.Game.Online.Spectator /// The user. /// The frame data. Task UserSentFrames(int userId, FrameDataBundle data); + + /// + /// Signals that a user's submitted score was fully processed. + /// + /// The ID of the user who achieved the score. + /// The ID of the score. + Task UserScoreProcessed(int userId, long scoreId); } } diff --git a/osu.Game/Online/Spectator/OnlineSpectatorClient.cs b/osu.Game/Online/Spectator/OnlineSpectatorClient.cs index 01b775549e..3118e05053 100644 --- a/osu.Game/Online/Spectator/OnlineSpectatorClient.cs +++ b/osu.Game/Online/Spectator/OnlineSpectatorClient.cs @@ -41,6 +41,7 @@ namespace osu.Game.Online.Spectator connection.On(nameof(ISpectatorClient.UserBeganPlaying), ((ISpectatorClient)this).UserBeganPlaying); connection.On(nameof(ISpectatorClient.UserSentFrames), ((ISpectatorClient)this).UserSentFrames); connection.On(nameof(ISpectatorClient.UserFinishedPlaying), ((ISpectatorClient)this).UserFinishedPlaying); + connection.On(nameof(ISpectatorClient.UserScoreProcessed), ((ISpectatorClient)this).UserScoreProcessed); }; IsConnected.BindTo(connector.IsConnected); diff --git a/osu.Game/Online/Spectator/SpectatorClient.cs b/osu.Game/Online/Spectator/SpectatorClient.cs index fce61c019b..b60cef2835 100644 --- a/osu.Game/Online/Spectator/SpectatorClient.cs +++ b/osu.Game/Online/Spectator/SpectatorClient.cs @@ -64,6 +64,11 @@ namespace osu.Game.Online.Spectator /// public virtual event Action? OnUserFinishedPlaying; + /// + /// Called whenever a user-submitted score has been fully processed. + /// + public virtual event Action? OnUserScoreProcessed; + /// /// A dictionary containing all users currently being watched, with the number of watching components for each user. /// @@ -160,6 +165,13 @@ namespace osu.Game.Online.Spectator return Task.CompletedTask; } + Task ISpectatorClient.UserScoreProcessed(int userId, long scoreId) + { + Schedule(() => OnUserScoreProcessed?.Invoke(userId, scoreId)); + + return Task.CompletedTask; + } + public void BeginPlaying(long? scoreToken, GameplayState state, Score score) { // This schedule is only here to match the one below in `EndPlaying`. From b06a7daf26e3656e10346b2059aa0800bab00cdb Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Tue, 20 Dec 2022 23:40:00 +0000 Subject: [PATCH 1115/2991] append date to score export filename --- osu.Game/Scoring/ScoreInfoExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Scoring/ScoreInfoExtensions.cs b/osu.Game/Scoring/ScoreInfoExtensions.cs index 7979ca8aaa..3cfdbe87c3 100644 --- a/osu.Game/Scoring/ScoreInfoExtensions.cs +++ b/osu.Game/Scoring/ScoreInfoExtensions.cs @@ -12,6 +12,6 @@ namespace osu.Game.Scoring /// /// A user-presentable display title representing this score. /// - public static string GetDisplayTitle(this IScoreInfo scoreInfo) => $"{scoreInfo.User.Username} playing {scoreInfo.Beatmap.GetDisplayTitle()}"; + public static string GetDisplayTitle(this IScoreInfo scoreInfo) => $"{scoreInfo.User.Username} playing {scoreInfo.Beatmap.GetDisplayTitle()} ({scoreInfo.Date.LocalDateTime:yyyy-MM-dd})"; } } From 1b2c821346da690e932b4d74fda4ac9307d99bb3 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 21 Dec 2022 15:44:02 +0900 Subject: [PATCH 1116/2991] showpopover directly --- .../Visual/Online/TestSceneChatOverlay.cs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 44d739a6e3..3a6cbdfb0f 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -12,6 +12,7 @@ using JetBrains.Annotations; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; @@ -544,19 +545,7 @@ namespace osu.Game.Tests.Visual.Online AddAssert("Overlay is visible", () => chatOverlay.State.Value == Visibility.Visible); waitForChannel1Visible(); - AddStep("Right click username", () => - { - var username = this.ChildrenOfType().First(); - InputManager.MoveMouseTo(username); - InputManager.Click(MouseButton.Right); - }); - - AddStep("Click report", () => - { - var btn = this.ChildrenOfType().First(x => x.Text == "Report"); - InputManager.MoveMouseTo(btn); - InputManager.Click(MouseButton.Left); - }); + AddStep("Show report popover", () => this.ChildrenOfType().First().ShowPopover()); AddStep("Try to report", () => { From 19f66c806e7a7df51dee54d8ff935cdf0b96e5a8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 21 Dec 2022 16:31:53 +0800 Subject: [PATCH 1117/2991] Fix language dropdown in settings not updating after changing language in first run dialog Closes #21744. --- .../Overlays/Settings/Sections/General/LanguageSettings.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs index a4ec919658..982cbec376 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs @@ -44,10 +44,13 @@ namespace osu.Game.Overlays.Settings.Sections.General }, }; - localisationParameters.BindValueChanged(p - => languageSelection.Current.Value = LanguageExtensions.GetLanguageFor(frameworkLocale.Value, p.NewValue), true); + frameworkLocale.BindValueChanged(_ => updateSelection()); + localisationParameters.BindValueChanged(_ => updateSelection(), true); languageSelection.Current.BindValueChanged(val => frameworkLocale.Value = val.NewValue.ToCultureCode()); } + + private void updateSelection() => + languageSelection.Current.Value = LanguageExtensions.GetLanguageFor(frameworkLocale.Value, localisationParameters.Value); } } From 1d39e8d0cecc26b4d5d89d392c48e8319b82156f Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Wed, 21 Dec 2022 10:18:47 -0800 Subject: [PATCH 1118/2991] Refactor `MetadataSection` to use generics and inheritance --- osu.Game/Overlays/BeatmapSet/Info.cs | 10 +- .../Overlays/BeatmapSet/MetadataSection.cs | 98 +++++++------------ .../BeatmapSet/MetadataSectionDescription.cs | 21 ++++ .../BeatmapSet/MetadataSectionGenre.cs | 25 +++++ .../BeatmapSet/MetadataSectionLanguage.cs | 25 +++++ .../BeatmapSet/MetadataSectionSource.cs | 25 +++++ .../BeatmapSet/MetadataSectionTags.cs | 35 +++++++ osu.Game/Screens/Select/BeatmapDetails.cs | 12 +-- 8 files changed, 180 insertions(+), 71 deletions(-) create mode 100644 osu.Game/Overlays/BeatmapSet/MetadataSectionDescription.cs create mode 100644 osu.Game/Overlays/BeatmapSet/MetadataSectionGenre.cs create mode 100644 osu.Game/Overlays/BeatmapSet/MetadataSectionLanguage.cs create mode 100644 osu.Game/Overlays/BeatmapSet/MetadataSectionSource.cs create mode 100644 osu.Game/Overlays/BeatmapSet/MetadataSectionTags.cs diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 514a4ea8cd..a5ebc6c1e4 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -59,7 +59,7 @@ namespace osu.Game.Overlays.BeatmapSet Child = new Container { RelativeSizeAxes = Axes.Both, - Child = new MetadataSection(MetadataType.Description), + Child = new MetadataSectionDescription(), }, }, new Container @@ -78,10 +78,10 @@ namespace osu.Game.Overlays.BeatmapSet Direction = FillDirection.Full, Children = new[] { - source = new MetadataSection(MetadataType.Source), - genre = new MetadataSection(MetadataType.Genre) { Width = 0.5f }, - language = new MetadataSection(MetadataType.Language) { Width = 0.5f }, - tags = new MetadataSection(MetadataType.Tags), + source = new MetadataSectionSource(), + genre = new MetadataSectionGenre { Width = 0.5f }, + language = new MetadataSectionLanguage { Width = 0.5f }, + tags = new MetadataSectionTags(), }, }, }, diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSection.cs b/osu.Game/Overlays/BeatmapSet/MetadataSection.cs index caf1b7197c..6af77f975e 100644 --- a/osu.Game/Overlays/BeatmapSet/MetadataSection.cs +++ b/osu.Game/Overlays/BeatmapSet/MetadataSection.cs @@ -1,10 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; -using Humanizer; using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -12,27 +9,45 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Game.Online.Chat; -using osu.Game.Overlays.BeatmapListing; using osuTK; using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet { - public partial class MetadataSection : Container + public abstract partial class MetadataSection : MetadataSection + { + public override string Text + { + set + { + if (string.IsNullOrEmpty(value)) + { + this.FadeOut(TRANSITION_DURATION); + return; + } + + base.Text = value; + } + } + + protected MetadataSection(MetadataType type, Action? searchAction = null) + : base(type, searchAction) + { + } + } + + public abstract partial class MetadataSection : Container { private readonly FillFlowContainer textContainer; - private readonly MetadataType type; - private TextFlowContainer textFlow; + private TextFlowContainer? textFlow; - private readonly Action searchAction; + protected readonly Action? SearchAction; - private const float transition_duration = 250; + protected const float TRANSITION_DURATION = 250; - public MetadataSection(MetadataType type, Action searchAction = null) + protected MetadataSection(MetadataType type, Action? searchAction = null) { - this.type = type; - this.searchAction = searchAction; + SearchAction = searchAction; Alpha = 0; @@ -55,7 +70,7 @@ namespace osu.Game.Overlays.BeatmapSet AutoSizeAxes = Axes.Y, Child = new OsuSpriteText { - Text = this.type.GetLocalisableDescription(), + Text = type.GetLocalisableDescription(), Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 14), }, }, @@ -63,23 +78,23 @@ namespace osu.Game.Overlays.BeatmapSet }; } - public string Text + public virtual T Text { set { - if (string.IsNullOrEmpty(value)) + if (value == null) { - this.FadeOut(transition_duration); + this.FadeOut(TRANSITION_DURATION); return; } - this.FadeIn(transition_duration); + this.FadeIn(TRANSITION_DURATION); setTextAsync(value); } } - private void setTextAsync(string text) + private void setTextAsync(T text) { LoadComponentAsync(new LinkFlowContainer(s => s.Font = s.Font.With(size: 14)) { @@ -90,52 +105,15 @@ namespace osu.Game.Overlays.BeatmapSet { textFlow?.Expire(); - switch (type) - { - case MetadataType.Tags: - string[] tags = text.Split(" "); - - for (int i = 0; i <= tags.Length - 1; i++) - { - string tag = tags[i]; - - if (searchAction != null) - loaded.AddLink(tag, () => searchAction(tag)); - else - loaded.AddLink(tag, LinkAction.SearchBeatmapSet, tag); - - if (i != tags.Length - 1) - loaded.AddText(" "); - } - - break; - - case MetadataType.Source: - if (searchAction != null) - loaded.AddLink(text, () => searchAction(text)); - else - loaded.AddLink(text, LinkAction.SearchBeatmapSet, text); - - break; - - case MetadataType.Genre: - loaded.AddLink(text.DehumanizeTo().GetLocalisableDescription(), LinkAction.FilterBeatmapSetGenre, text); - break; - - case MetadataType.Language: - loaded.AddLink(text.DehumanizeTo().GetLocalisableDescription(), LinkAction.FilterBeatmapSetLanguage, text); - break; - - default: - loaded.AddText(text); - break; - } + AddMetadata(text, loaded); textContainer.Add(textFlow = loaded); // fade in if we haven't yet. - textContainer.FadeIn(transition_duration); + textContainer.FadeIn(TRANSITION_DURATION); }); } + + protected abstract void AddMetadata(T text, LinkFlowContainer loaded); } } diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSectionDescription.cs b/osu.Game/Overlays/BeatmapSet/MetadataSectionDescription.cs new file mode 100644 index 0000000000..a9503cded3 --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/MetadataSectionDescription.cs @@ -0,0 +1,21 @@ +// 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.Game.Graphics.Containers; + +namespace osu.Game.Overlays.BeatmapSet +{ + public partial class MetadataSectionDescription : MetadataSection + { + public MetadataSectionDescription(Action? searchAction = null) + : base(MetadataType.Description, searchAction) + { + } + + protected override void AddMetadata(string text, LinkFlowContainer loaded) + { + loaded.AddText(text); + } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSectionGenre.cs b/osu.Game/Overlays/BeatmapSet/MetadataSectionGenre.cs new file mode 100644 index 0000000000..eaf2c9721f --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/MetadataSectionGenre.cs @@ -0,0 +1,25 @@ +// 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 Humanizer; +using osu.Framework.Extensions; +using osu.Game.Graphics.Containers; +using osu.Game.Online.Chat; +using osu.Game.Overlays.BeatmapListing; + +namespace osu.Game.Overlays.BeatmapSet +{ + public partial class MetadataSectionGenre : MetadataSection + { + public MetadataSectionGenre(Action? searchAction = null) + : base(MetadataType.Genre, searchAction) + { + } + + protected override void AddMetadata(string text, LinkFlowContainer loaded) + { + loaded.AddLink(text.DehumanizeTo().GetLocalisableDescription(), LinkAction.FilterBeatmapSetGenre, text); + } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSectionLanguage.cs b/osu.Game/Overlays/BeatmapSet/MetadataSectionLanguage.cs new file mode 100644 index 0000000000..6c68a5d682 --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/MetadataSectionLanguage.cs @@ -0,0 +1,25 @@ +// 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 Humanizer; +using osu.Framework.Extensions; +using osu.Game.Graphics.Containers; +using osu.Game.Online.Chat; +using osu.Game.Overlays.BeatmapListing; + +namespace osu.Game.Overlays.BeatmapSet +{ + public partial class MetadataSectionLanguage : MetadataSection + { + public MetadataSectionLanguage(Action? searchAction = null) + : base(MetadataType.Language, searchAction) + { + } + + protected override void AddMetadata(string text, LinkFlowContainer loaded) + { + loaded.AddLink(text.DehumanizeTo().GetLocalisableDescription(), LinkAction.FilterBeatmapSetLanguage, text); + } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSectionSource.cs b/osu.Game/Overlays/BeatmapSet/MetadataSectionSource.cs new file mode 100644 index 0000000000..6deb866f19 --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/MetadataSectionSource.cs @@ -0,0 +1,25 @@ +// 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.Game.Graphics.Containers; +using osu.Game.Online.Chat; + +namespace osu.Game.Overlays.BeatmapSet +{ + public partial class MetadataSectionSource : MetadataSection + { + public MetadataSectionSource(Action? searchAction = null) + : base(MetadataType.Source, searchAction) + { + } + + protected override void AddMetadata(string text, LinkFlowContainer loaded) + { + if (SearchAction != null) + loaded.AddLink(text, () => SearchAction(text)); + else + loaded.AddLink(text, LinkAction.SearchBeatmapSet, text); + } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSectionTags.cs b/osu.Game/Overlays/BeatmapSet/MetadataSectionTags.cs new file mode 100644 index 0000000000..1b384fcdd3 --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/MetadataSectionTags.cs @@ -0,0 +1,35 @@ +// 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.Game.Graphics.Containers; +using osu.Game.Online.Chat; + +namespace osu.Game.Overlays.BeatmapSet +{ + public partial class MetadataSectionTags : MetadataSection + { + public MetadataSectionTags(Action? searchAction = null) + : base(MetadataType.Tags, searchAction) + { + } + + protected override void AddMetadata(string text, LinkFlowContainer loaded) + { + string[] tags = text.Split(" "); + + for (int i = 0; i <= tags.Length - 1; i++) + { + string tag = tags[i]; + + if (SearchAction != null) + loaded.AddLink(tag, () => SearchAction(tag)); + else + loaded.AddLink(tag, LinkAction.SearchBeatmapSet, tag); + + if (i != tags.Length - 1) + loaded.AddText(" "); + } + } + } +} diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index 0a14df6480..b158bef8dc 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -141,9 +141,9 @@ namespace osu.Game.Screens.Select LayoutEasing = Easing.OutQuad, Children = new[] { - description = new MetadataSection(MetadataType.Description, searchOnSongSelect), - source = new MetadataSection(MetadataType.Source, searchOnSongSelect), - tags = new MetadataSection(MetadataType.Tags, searchOnSongSelect), + description = new MetadataSectionDescription(searchOnSongSelect), + source = new MetadataSectionSource(searchOnSongSelect), + tags = new MetadataSectionTags(searchOnSongSelect), }, }, }, @@ -187,9 +187,9 @@ namespace osu.Game.Screens.Select private void updateStatistics() { advanced.BeatmapInfo = BeatmapInfo; - description.Text = BeatmapInfo?.DifficultyName; - source.Text = BeatmapInfo?.Metadata.Source; - tags.Text = BeatmapInfo?.Metadata.Tags; + description.Text = BeatmapInfo?.DifficultyName ?? string.Empty; + source.Text = BeatmapInfo?.Metadata.Source ?? string.Empty; + tags.Text = BeatmapInfo?.Metadata.Tags ?? string.Empty; // failTimes may have been previously fetched if (ratings != null && failTimes != null) From 3ec31a5f51762fc1d9ed81256bc40a13597cf04e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 21 Dec 2022 19:30:21 +0100 Subject: [PATCH 1119/2991] Fix language selector in first run dialog not updating after changing language in settings --- .../Overlays/FirstRunSetup/ScreenWelcome.cs | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs index f6133e3643..4af40e5ad6 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs @@ -87,18 +87,21 @@ namespace osu.Game.Overlays.FirstRunSetup }); frameworkLocale = frameworkConfig.GetBindable(FrameworkSetting.Locale); + frameworkLocale.BindValueChanged(_ => onLanguageChange()); localisationParameters = localisation.CurrentParameters.GetBoundCopy(); - localisationParameters.BindValueChanged(p => - { - var language = LanguageExtensions.GetLanguageFor(frameworkLocale.Value, p.NewValue); + localisationParameters.BindValueChanged(_ => onLanguageChange(), true); + } - // Changing language may cause a short period of blocking the UI thread while the new glyphs are loaded. - // Scheduling ensures the button animation plays smoothly after any blocking operation completes. - // Note that a delay is required (the alternative would be a double-schedule; delay feels better). - updateSelectedDelegate?.Cancel(); - updateSelectedDelegate = Scheduler.AddDelayed(() => updateSelectedStates(language), 50); - }, true); + private void onLanguageChange() + { + var language = LanguageExtensions.GetLanguageFor(frameworkLocale.Value, localisationParameters.Value); + + // Changing language may cause a short period of blocking the UI thread while the new glyphs are loaded. + // Scheduling ensures the button animation plays smoothly after any blocking operation completes. + // Note that a delay is required (the alternative would be a double-schedule; delay feels better). + updateSelectedDelegate?.Cancel(); + updateSelectedDelegate = Scheduler.AddDelayed(() => updateSelectedStates(language), 50); } private void updateSelectedStates(Language language) From e1e6d76f308e6187246ba415f5188ccd7595f058 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Wed, 21 Dec 2022 11:02:04 -0800 Subject: [PATCH 1120/2991] Check id for genre/language instead and fallback to name if not defined --- .../Visual/Online/TestSceneBeatmapSetOverlay.cs | 2 ++ osu.Game/OsuGame.cs | 9 +++++---- .../BeatmapListing/BeatmapListingFilterControl.cs | 9 ++++----- osu.Game/Overlays/BeatmapListingOverlay.cs | 4 ++-- osu.Game/Overlays/BeatmapSet/Info.cs | 11 +++++++---- .../Overlays/BeatmapSet/MetadataSectionGenre.cs | 15 ++++++++++----- .../BeatmapSet/MetadataSectionLanguage.cs | 15 ++++++++++----- 7 files changed, 40 insertions(+), 25 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 3335f69dbb..7d978b9726 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -54,6 +54,8 @@ namespace osu.Game.Tests.Visual.Online { overlay.ShowBeatmapSet(new APIBeatmapSet { + Genre = new BeatmapSetOnlineGenre { Id = 15, Name = "Future genre" }, + Language = new BeatmapSetOnlineLanguage { Id = 15, Name = "Future language" }, OnlineID = 1235, Title = @"an awesome beatmap", Artist = @"naru narusegawa", diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 4c47eda38b..508281164f 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -46,6 +46,7 @@ using osu.Game.Online; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; using osu.Game.Overlays; +using osu.Game.Overlays.BeatmapListing; using osu.Game.Overlays.Music; using osu.Game.Overlays.Notifications; using osu.Game.Overlays.Toolbar; @@ -357,11 +358,11 @@ namespace osu.Game break; case LinkAction.FilterBeatmapSetGenre: - FilterBeatmapSetGenre(argString); + FilterBeatmapSetGenre((SearchGenre)link.Argument); break; case LinkAction.FilterBeatmapSetLanguage: - FilterBeatmapSetLanguage(argString); + FilterBeatmapSetLanguage((SearchLanguage)link.Argument); break; case LinkAction.OpenEditorTimestamp: @@ -468,9 +469,9 @@ namespace osu.Game /// The query to search for. public void SearchBeatmapSet(string query) => waitForReady(() => beatmapListing, _ => beatmapListing.ShowWithSearch(query)); - public void FilterBeatmapSetGenre(string genre) => waitForReady(() => beatmapListing, _ => beatmapListing.ShowWithGenreFilter(genre)); + public void FilterBeatmapSetGenre(SearchGenre genre) => waitForReady(() => beatmapListing, _ => beatmapListing.ShowWithGenreFilter(genre)); - public void FilterBeatmapSetLanguage(string language) => waitForReady(() => beatmapListing, _ => beatmapListing.ShowWithLanguageFilter(language)); + public void FilterBeatmapSetLanguage(SearchLanguage language) => waitForReady(() => beatmapListing, _ => beatmapListing.ShowWithLanguageFilter(language)); /// /// Show a wiki's page as an overlay diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs index 5eb1ff7024..37a29b1c50 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Humanizer; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; @@ -146,11 +145,11 @@ namespace osu.Game.Overlays.BeatmapListing public void Search(string query) => Schedule(() => searchControl.Query.Value = query); - public void FilterGenre(string genre) - => Schedule(() => searchControl.Genre.Value = genre.DehumanizeTo()); + public void FilterGenre(SearchGenre genre) + => Schedule(() => searchControl.Genre.Value = genre); - public void FilterLanguage(string language) - => Schedule(() => searchControl.Language.Value = language.DehumanizeTo()); + public void FilterLanguage(SearchLanguage language) + => Schedule(() => searchControl.Language.Value = language); protected override void LoadComplete() { diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index 010499df6f..73961487ed 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -110,13 +110,13 @@ namespace osu.Game.Overlays ScrollFlow.ScrollToStart(); } - public void ShowWithGenreFilter(string genre) + public void ShowWithGenreFilter(SearchGenre genre) { ShowWithSearch(string.Empty); filterControl.FilterGenre(genre); } - public void ShowWithLanguageFilter(string language) + public void ShowWithLanguageFilter(SearchLanguage language) { ShowWithSearch(string.Empty); filterControl.FilterLanguage(language); diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index a5ebc6c1e4..8a1384f0d3 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -8,6 +8,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Online.API.Requests.Responses; @@ -34,7 +35,9 @@ namespace osu.Game.Overlays.BeatmapSet public Info() { - MetadataSection source, tags, genre, language; + MetadataSection source, tags; + MetadataSectionGenre genre; + MetadataSectionLanguage language; OsuSpriteText notRankedPlaceholder; RelativeSizeAxes = Axes.X; @@ -76,7 +79,7 @@ namespace osu.Game.Overlays.BeatmapSet RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Full, - Children = new[] + Children = new Drawable[] { source = new MetadataSectionSource(), genre = new MetadataSectionGenre { Width = 0.5f }, @@ -120,8 +123,8 @@ namespace osu.Game.Overlays.BeatmapSet { source.Text = b.NewValue?.Source ?? string.Empty; tags.Text = b.NewValue?.Tags ?? string.Empty; - genre.Text = b.NewValue?.Genre.Name ?? string.Empty; - language.Text = b.NewValue?.Language.Name ?? string.Empty; + genre.Text = b.NewValue?.Genre ?? new BeatmapSetOnlineGenre { Id = 1 }; + language.Text = b.NewValue?.Language ?? new BeatmapSetOnlineLanguage { Id = 1 }; bool setHasLeaderboard = b.NewValue?.Status > 0; successRate.Alpha = setHasLeaderboard ? 1 : 0; notRankedPlaceholder.Alpha = setHasLeaderboard ? 0 : 1; diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSectionGenre.cs b/osu.Game/Overlays/BeatmapSet/MetadataSectionGenre.cs index eaf2c9721f..0e045b2bf1 100644 --- a/osu.Game/Overlays/BeatmapSet/MetadataSectionGenre.cs +++ b/osu.Game/Overlays/BeatmapSet/MetadataSectionGenre.cs @@ -2,24 +2,29 @@ // See the LICENCE file in the repository root for full licence text. using System; -using Humanizer; using osu.Framework.Extensions; +using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; using osu.Game.Online.Chat; using osu.Game.Overlays.BeatmapListing; namespace osu.Game.Overlays.BeatmapSet { - public partial class MetadataSectionGenre : MetadataSection + public partial class MetadataSectionGenre : MetadataSection { - public MetadataSectionGenre(Action? searchAction = null) + public MetadataSectionGenre(Action? searchAction = null) : base(MetadataType.Genre, searchAction) { } - protected override void AddMetadata(string text, LinkFlowContainer loaded) + protected override void AddMetadata(BeatmapSetOnlineGenre text, LinkFlowContainer loaded) { - loaded.AddLink(text.DehumanizeTo().GetLocalisableDescription(), LinkAction.FilterBeatmapSetGenre, text); + var genre = (SearchGenre)text.Id; + + if (Enum.IsDefined(genre)) + loaded.AddLink(genre.GetLocalisableDescription(), LinkAction.FilterBeatmapSetGenre, genre); + else + loaded.AddText(text.Name); } } } diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSectionLanguage.cs b/osu.Game/Overlays/BeatmapSet/MetadataSectionLanguage.cs index 6c68a5d682..6e59818b93 100644 --- a/osu.Game/Overlays/BeatmapSet/MetadataSectionLanguage.cs +++ b/osu.Game/Overlays/BeatmapSet/MetadataSectionLanguage.cs @@ -2,24 +2,29 @@ // See the LICENCE file in the repository root for full licence text. using System; -using Humanizer; using osu.Framework.Extensions; +using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; using osu.Game.Online.Chat; using osu.Game.Overlays.BeatmapListing; namespace osu.Game.Overlays.BeatmapSet { - public partial class MetadataSectionLanguage : MetadataSection + public partial class MetadataSectionLanguage : MetadataSection { - public MetadataSectionLanguage(Action? searchAction = null) + public MetadataSectionLanguage(Action? searchAction = null) : base(MetadataType.Language, searchAction) { } - protected override void AddMetadata(string text, LinkFlowContainer loaded) + protected override void AddMetadata(BeatmapSetOnlineLanguage text, LinkFlowContainer loaded) { - loaded.AddLink(text.DehumanizeTo().GetLocalisableDescription(), LinkAction.FilterBeatmapSetLanguage, text); + var language = (SearchLanguage)text.Id; + + if (Enum.IsDefined(language)) + loaded.AddLink(language.GetLocalisableDescription(), LinkAction.FilterBeatmapSetLanguage, language); + else + loaded.AddText(text.Name); } } } From 0a49c8c5d67b67c7148ba2ca9fe92c89bb070b46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 21 Dec 2022 20:03:46 +0100 Subject: [PATCH 1121/2991] Add missing unsubscriptions in multiple mania components --- osu.Game.Rulesets.Mania/UI/Column.cs | 3 +++ osu.Game.Rulesets.Mania/UI/Stage.cs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 6a31fb3fda..10460f52fd 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -134,6 +134,9 @@ namespace osu.Game.Rulesets.Mania.UI protected override void Dispose(bool isDisposing) { + // must happen before children are disposed in base call to prevent illegal accesses to the hit explosion pool. + NewResult -= OnNewResult; + base.Dispose(isDisposing); if (skin != null) diff --git a/osu.Game.Rulesets.Mania/UI/Stage.cs b/osu.Game.Rulesets.Mania/UI/Stage.cs index fc38a96a35..c1d3e85bf1 100644 --- a/osu.Game.Rulesets.Mania/UI/Stage.cs +++ b/osu.Game.Rulesets.Mania/UI/Stage.cs @@ -156,6 +156,9 @@ namespace osu.Game.Rulesets.Mania.UI protected override void Dispose(bool isDisposing) { + // must happen before children are disposed in base call to prevent illegal accesses to the judgement pool. + NewResult -= OnNewResult; + base.Dispose(isDisposing); if (currentSkin != null) From 6948035a3cc89d6cba9ad7263e73f89d1f94aacc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 21 Dec 2022 21:59:46 +0100 Subject: [PATCH 1122/2991] Ensure score submission attempt completion before notifying spectator server when exiting play early When a `SubmittingPlayer` gameplay session ends with the successful completion of a beatmap, `PrepareScoreForResultsAsync()` ensures that the score submission request is sent to and responded to by osu-web before calling `ISpectatorClient.EndPlaying()`. While previously this was mostly an implementation detail, this becomes important when considering that more and more server-side flows (replay upload, notifying about score processing completion) hook into `EndPlaying()`, and assume that by the point that message arrives at osu-spectator-server, the score has already been submitted and has been assigned a score ID that corresponds to the score submission token. As it turns out, in the early-exit path (when the user exits the play midway through, retries, or just fails), the same ordering guarantees were not provided. The score's submission ran concurrently to the spectator client `EndPlaying()` call, therefore creating a network race. osu-server-spectator components that implciitly relied on the ordering provided by the happy path, could therefore fail to unmap the score submission token to a score ID. Note that as written, the osu-server-spectator replay upload flow is not really affected by this, as it self-corrects by essentially polling the database and trying to unmap the score submission token to a score ID for up to 30 seconds. However, this change would have the benefit of reducing the polls required in such cases to just one DB retrieval. --- osu.Game/Screens/Play/SubmittingPlayer.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/SubmittingPlayer.cs b/osu.Game/Screens/Play/SubmittingPlayer.cs index 1eec71f33a..5fa6508a31 100644 --- a/osu.Game/Screens/Play/SubmittingPlayer.cs +++ b/osu.Game/Screens/Play/SubmittingPlayer.cs @@ -13,6 +13,7 @@ using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Online.API; +using osu.Game.Online.Multiplayer; using osu.Game.Online.Rooms; using osu.Game.Online.Spectator; using osu.Game.Rulesets.Scoring; @@ -158,8 +159,11 @@ namespace osu.Game.Screens.Play if (LoadedBeatmapSuccessfully) { - submitScore(Score.DeepClone()); - spectatorClient.EndPlaying(GameplayState); + Task.Run(async () => + { + await submitScore(Score.DeepClone()).ConfigureAwait(false); + spectatorClient.EndPlaying(GameplayState); + }).FireAndForget(); } return exiting; From 66a02374dae305eefddbb04b9864482457246622 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 22 Dec 2022 01:23:24 +0300 Subject: [PATCH 1123/2991] Clear cached waveform on track change in editor --- osu.Game/Beatmaps/WorkingBeatmap.cs | 8 +++++++- osu.Game/Screens/Edit/Setup/ResourcesSection.cs | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 393c4ba892..f454f08e87 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -48,7 +48,7 @@ namespace osu.Game.Beatmaps private readonly object beatmapFetchLock = new object(); - private readonly Lazy waveform; + private Lazy waveform; private readonly Lazy storyboard; private readonly Lazy skin; private Track track; // track is not Lazy as we allow transferring and loading multiple times. @@ -329,6 +329,12 @@ namespace osu.Game.Beatmaps #endregion + public void InvalidateWaveform() + { + if (waveform.IsValueCreated) + waveform = new Lazy(GetWaveform); + } + public override string ToString() => BeatmapInfo.ToString(); public abstract Stream GetStream(string storagePath); diff --git a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs index ca0f50cd34..01217021fd 100644 --- a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs +++ b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs @@ -118,7 +118,7 @@ namespace osu.Game.Screens.Edit.Setup } working.Value.Metadata.AudioFile = destination.Name; - + working.Value.InvalidateWaveform(); editorBeatmap.SaveState(); music.ReloadCurrentTrack(); From 7089bb6c2399ccb6c511acb6465b8ce3053b54c5 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 22 Dec 2022 01:23:59 +0300 Subject: [PATCH 1124/2991] Listen for track reload in timeline --- .../Compose/Components/Timeline/Timeline.cs | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 45f902d0de..d135d108de 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -15,6 +15,7 @@ using osu.Framework.Input.Events; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; +using osu.Game.Overlays; using osu.Game.Rulesets.Edit; using osuTK; using osuTK.Input; @@ -35,14 +36,15 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline public readonly Bindable TicksVisible = new Bindable(); - public readonly IBindable Beatmap = new Bindable(); - [Resolved] private EditorClock editorClock { get; set; } [Resolved] private EditorBeatmap editorBeatmap { get; set; } + [Resolved] + private MusicController musicController { get; set; } + /// /// The timeline's scroll position in the last frame. /// @@ -139,11 +141,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline waveformOpacity = config.GetBindable(OsuSetting.EditorWaveformOpacity); - Beatmap.BindTo(beatmap); - Beatmap.BindValueChanged(b => - { - waveform.Waveform = b.NewValue.Waveform; - }, true); + musicController.TrackChanged += onTrackReload; + waveform.Waveform = beatmap.Value.Waveform; Zoom = (float)(defaultTimelineZoom * editorBeatmap.BeatmapInfo.TimelineZoom); } @@ -181,6 +180,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private void updateWaveformOpacity() => waveform.FadeTo(WaveformVisible.Value ? waveformOpacity.Value : 0, 200, Easing.OutQuint); + private void onTrackReload(WorkingBeatmap beatmap, TrackChangeDirection tcd) + { + waveform.Waveform = beatmap.Waveform; + } + protected override void Update() { base.Update(); @@ -321,5 +325,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline double time = TimeAtPosition(Content.ToLocalSpace(screenSpacePosition).X); return new SnapResult(screenSpacePosition, beatSnapProvider.SnapTime(time)); } + + protected override void Dispose(bool isDisposing) + { + musicController.TrackChanged -= onTrackReload; + base.Dispose(isDisposing); + } } } From a18ece8610acee982222a611212345971b45632d Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 22 Dec 2022 01:24:23 +0300 Subject: [PATCH 1125/2991] Listen for track reload in timing screen --- .../Screens/Edit/Timing/TapTimingControl.cs | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs index 09b3851333..10db426416 100644 --- a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs +++ b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; +using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; @@ -29,9 +30,13 @@ namespace osu.Game.Screens.Edit.Timing [Resolved] private Bindable selectedGroup { get; set; } = null!; + [Resolved] + private MusicController musicController { get; set; } = null!; + private readonly BindableBool isHandlingTapping = new BindableBool(); private MetronomeDisplay metronome = null!; + private Container waveformContainer = null!; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider, OsuColour colours) @@ -88,7 +93,11 @@ namespace osu.Game.Screens.Edit.Timing Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, }, - new WaveformComparisonDisplay(), + waveformContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Child = new WaveformComparisonDisplay(), + } } }, } @@ -179,6 +188,13 @@ namespace osu.Game.Screens.Edit.Timing if (handling.NewValue) start(); }, true); + + musicController.TrackChanged += onTrackReload; + } + + private void onTrackReload(WorkingBeatmap beatmap, TrackChangeDirection tcd) + { + waveformContainer.Child = new WaveformComparisonDisplay(); } private void start() @@ -233,6 +249,12 @@ namespace osu.Game.Screens.Edit.Timing timing.BeatLength = 60000 / (timing.BPM + adjust); } + protected override void Dispose(bool isDisposing) + { + musicController.TrackChanged -= onTrackReload; + base.Dispose(isDisposing); + } + private partial class InlineButton : OsuButton { private readonly IconUsage icon; From f5b3988dd2bd7ccc82437e191592d89650d34a43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 22 Dec 2022 08:01:52 +0100 Subject: [PATCH 1126/2991] Add data structure for delivering statistics updates --- osu.Game/Online/Solo/SoloStatisticsUpdate.cs | 42 ++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 osu.Game/Online/Solo/SoloStatisticsUpdate.cs diff --git a/osu.Game/Online/Solo/SoloStatisticsUpdate.cs b/osu.Game/Online/Solo/SoloStatisticsUpdate.cs new file mode 100644 index 0000000000..cb9dac97c7 --- /dev/null +++ b/osu.Game/Online/Solo/SoloStatisticsUpdate.cs @@ -0,0 +1,42 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Scoring; +using osu.Game.Users; + +namespace osu.Game.Online.Solo +{ + /// + /// Contains data about the change in a user's profile statistics after completing a score. + /// + public class SoloStatisticsUpdate + { + /// + /// The score set by the user that triggered the update. + /// + public ScoreInfo Score { get; } + + /// + /// The user's profile statistics prior to the score being set. + /// + public UserStatistics Before { get; } + + /// + /// The user's profile statistics after the score was set. + /// + public UserStatistics After { get; } + + /// + /// Creates a new . + /// + /// The score set by the user that triggered the update. + /// The user's profile statistics prior to the score being set. + /// The user's profile statistics after the score was set. + public SoloStatisticsUpdate(ScoreInfo score, UserStatistics before, UserStatistics after) + { + Score = score; + Before = before; + After = after; + } + } +} From f2e8776529176f7ec1ab03d12ea4eee6a5a44f18 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 22 Dec 2022 15:35:53 +0300 Subject: [PATCH 1127/2991] Bind to clock instead of music controller --- .../Compose/Components/Timeline/Timeline.cs | 25 +++++++------------ .../Screens/Edit/Timing/TapTimingControl.cs | 21 ++++------------ 2 files changed, 14 insertions(+), 32 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index d135d108de..918b5f8109 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -5,6 +5,7 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -15,7 +16,6 @@ using osu.Framework.Input.Events; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; -using osu.Game.Overlays; using osu.Game.Rulesets.Edit; using osuTK; using osuTK.Input; @@ -42,9 +42,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved] private EditorBeatmap editorBeatmap { get; set; } - [Resolved] - private MusicController musicController { get; set; } - /// /// The timeline's scroll position in the last frame. /// @@ -94,6 +91,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private double trackLengthForZoom; + private readonly IBindable track = new Bindable(); + [BackgroundDependencyLoader] private void load(IBindable beatmap, OsuColour colours, OsuConfigManager config) { @@ -141,7 +140,12 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline waveformOpacity = config.GetBindable(OsuSetting.EditorWaveformOpacity); - musicController.TrackChanged += onTrackReload; + track.BindTo(editorClock.Track); + track.BindValueChanged(_ => + { + waveform.Waveform = beatmap.Value.Waveform; + }, true); + waveform.Waveform = beatmap.Value.Waveform; Zoom = (float)(defaultTimelineZoom * editorBeatmap.BeatmapInfo.TimelineZoom); @@ -180,11 +184,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private void updateWaveformOpacity() => waveform.FadeTo(WaveformVisible.Value ? waveformOpacity.Value : 0, 200, Easing.OutQuint); - private void onTrackReload(WorkingBeatmap beatmap, TrackChangeDirection tcd) - { - waveform.Waveform = beatmap.Waveform; - } - protected override void Update() { base.Update(); @@ -325,11 +324,5 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline double time = TimeAtPosition(Content.ToLocalSpace(screenSpacePosition).X); return new SnapResult(screenSpacePosition, beatSnapProvider.SnapTime(time)); } - - protected override void Dispose(bool isDisposing) - { - musicController.TrackChanged -= onTrackReload; - base.Dispose(isDisposing); - } } } diff --git a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs index 10db426416..36cd5f8b70 100644 --- a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs +++ b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs @@ -3,13 +3,13 @@ using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; -using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; @@ -30,8 +30,7 @@ namespace osu.Game.Screens.Edit.Timing [Resolved] private Bindable selectedGroup { get; set; } = null!; - [Resolved] - private MusicController musicController { get; set; } = null!; + private readonly IBindable track = new Bindable(); private readonly BindableBool isHandlingTapping = new BindableBool(); @@ -39,7 +38,7 @@ namespace osu.Game.Screens.Edit.Timing private Container waveformContainer = null!; [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider, OsuColour colours) + private void load(OverlayColourProvider colourProvider, OsuColour colours, EditorClock clock) { const float padding = 10; @@ -189,12 +188,8 @@ namespace osu.Game.Screens.Edit.Timing start(); }, true); - musicController.TrackChanged += onTrackReload; - } - - private void onTrackReload(WorkingBeatmap beatmap, TrackChangeDirection tcd) - { - waveformContainer.Child = new WaveformComparisonDisplay(); + track.BindTo(clock.Track); + track.ValueChanged += _ => waveformContainer.Child = new WaveformComparisonDisplay(); } private void start() @@ -249,12 +244,6 @@ namespace osu.Game.Screens.Edit.Timing timing.BeatLength = 60000 / (timing.BPM + adjust); } - protected override void Dispose(bool isDisposing) - { - musicController.TrackChanged -= onTrackReload; - base.Dispose(isDisposing); - } - private partial class InlineButton : OsuButton { private readonly IconUsage icon; From d0645ce15173c32e45886bac43dfb5bd09df69df Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 22 Dec 2022 15:59:51 +0300 Subject: [PATCH 1128/2991] Rewrite waveform invalidation --- osu.Game/Beatmaps/WorkingBeatmap.cs | 23 +++++++++++-------- .../Screens/Edit/Setup/ResourcesSection.cs | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index f454f08e87..e61ec3f2a8 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -34,8 +34,6 @@ namespace osu.Game.Beatmaps // TODO: remove once the fallback lookup is not required (and access via `working.BeatmapInfo.Metadata` directly). public BeatmapMetadata Metadata => BeatmapInfo.Metadata; - public Waveform Waveform => waveform.Value; - public Storyboard Storyboard => storyboard.Value; public Texture Background => GetBackground(); // Texture uses ref counting, so we want to return a new instance every usage. @@ -48,7 +46,7 @@ namespace osu.Game.Beatmaps private readonly object beatmapFetchLock = new object(); - private Lazy waveform; + private Waveform waveform; private readonly Lazy storyboard; private readonly Lazy skin; private Track track; // track is not Lazy as we allow transferring and loading multiple times. @@ -60,7 +58,6 @@ namespace osu.Game.Beatmaps BeatmapInfo = beatmapInfo; BeatmapSetInfo = beatmapInfo.BeatmapSet ?? new BeatmapSetInfo(); - waveform = new Lazy(GetWaveform); storyboard = new Lazy(GetStoryboard); skin = new Lazy(GetSkin); } @@ -171,6 +168,18 @@ namespace osu.Game.Beatmaps #endregion + #region Waveform + + public Waveform Waveform => waveform ??= GetWaveform(); + + /// + /// Reloads waveform of beatmap's track even if one is already cached. + /// + /// Newly loaded waveform. + public Waveform LoadWaveform() => waveform = GetWaveform(); + + #endregion + #region Beatmap public virtual bool BeatmapLoaded => beatmapLoadTask?.IsCompleted ?? false; @@ -329,12 +338,6 @@ namespace osu.Game.Beatmaps #endregion - public void InvalidateWaveform() - { - if (waveform.IsValueCreated) - waveform = new Lazy(GetWaveform); - } - public override string ToString() => BeatmapInfo.ToString(); public abstract Stream GetStream(string storagePath); diff --git a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs index 01217021fd..36ac9883ba 100644 --- a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs +++ b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs @@ -118,7 +118,7 @@ namespace osu.Game.Screens.Edit.Setup } working.Value.Metadata.AudioFile = destination.Name; - working.Value.InvalidateWaveform(); + working.Value.LoadWaveform(); editorBeatmap.SaveState(); music.ReloadCurrentTrack(); From 422fdd8ae5a3f8deae62b788fb41d84f8e8608e8 Mon Sep 17 00:00:00 2001 From: Flutterish Date: Thu, 22 Dec 2022 16:56:27 +0100 Subject: [PATCH 1129/2991] dont post notifications from custom log targets --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index a0a45e18a8..af58a72ae8 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1040,7 +1040,7 @@ namespace osu.Game Logger.NewEntry += entry => { - if (entry.Level < LogLevel.Important || entry.Target > LoggingTarget.Database) return; + if (entry.Level < LogLevel.Important || entry.Target is null or > LoggingTarget.Database) return; Debug.Assert(entry.Target != null); From 5df440e20eb8389e14e029879af28d1bab630a94 Mon Sep 17 00:00:00 2001 From: Flutterish Date: Thu, 22 Dec 2022 17:27:55 +0100 Subject: [PATCH 1130/2991] dont use `is..or` syntax --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index af58a72ae8..b5e1023ac6 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1040,7 +1040,7 @@ namespace osu.Game Logger.NewEntry += entry => { - if (entry.Level < LogLevel.Important || entry.Target is null or > LoggingTarget.Database) return; + if (entry.Level < LogLevel.Important || entry.Target == null || entry.Target > LoggingTarget.Database) return; Debug.Assert(entry.Target != null); From 8be6350c019bddbb8064d73aa013ffbc71e58c09 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 22 Dec 2022 20:07:53 +0300 Subject: [PATCH 1131/2991] Remove no longer necessary assert --- osu.Game/OsuGame.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index b5e1023ac6..de9a009f44 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1040,9 +1040,7 @@ namespace osu.Game Logger.NewEntry += entry => { - if (entry.Level < LogLevel.Important || entry.Target == null || entry.Target > LoggingTarget.Database) return; - - Debug.Assert(entry.Target != null); + if (entry.Level < LogLevel.Important || entry.Target > LoggingTarget.Database || entry.Target == null) return; const int short_term_display_limit = 3; From 20370bd5ae4c9350697c357642102861dae7efc4 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 22 Dec 2022 20:49:09 +0300 Subject: [PATCH 1132/2991] Invalidate waveform on track load --- osu.Game/Beatmaps/WorkingBeatmap.cs | 15 ++++++++------- osu.Game/Screens/Edit/Setup/ResourcesSection.cs | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index e61ec3f2a8..345220a3a3 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -105,7 +105,14 @@ namespace osu.Game.Beatmaps public virtual bool TrackLoaded => track != null; - public Track LoadTrack() => track = GetBeatmapTrack() ?? GetVirtualTrack(1000); + public Track LoadTrack() + { + // track could be changed, clearing waveform cache + waveform = null; + + track = GetBeatmapTrack() ?? GetVirtualTrack(1000); + return track; + } public void PrepareTrackForPreview(bool looping, double offsetFromPreviewPoint = 0) { @@ -172,12 +179,6 @@ namespace osu.Game.Beatmaps public Waveform Waveform => waveform ??= GetWaveform(); - /// - /// Reloads waveform of beatmap's track even if one is already cached. - /// - /// Newly loaded waveform. - public Waveform LoadWaveform() => waveform = GetWaveform(); - #endregion #region Beatmap diff --git a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs index 36ac9883ba..ca0f50cd34 100644 --- a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs +++ b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs @@ -118,7 +118,7 @@ namespace osu.Game.Screens.Edit.Setup } working.Value.Metadata.AudioFile = destination.Name; - working.Value.LoadWaveform(); + editorBeatmap.SaveState(); music.ReloadCurrentTrack(); From ac872fac9e562b4e4cba19ecf5a8bc31ba269f4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 22 Dec 2022 09:04:53 +0100 Subject: [PATCH 1133/2991] Implement solo statistics watcher --- osu.Game/Online/Solo/SoloStatisticsWatcher.cs | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 osu.Game/Online/Solo/SoloStatisticsWatcher.cs diff --git a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs new file mode 100644 index 0000000000..197ad410a9 --- /dev/null +++ b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs @@ -0,0 +1,140 @@ +// 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.Diagnostics; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; +using osu.Framework.Graphics; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Spectator; +using osu.Game.Scoring; +using osu.Game.Users; + +namespace osu.Game.Online.Solo +{ + /// + /// A persistent component that binds to the spectator server and API in order to deliver updates about the logged in user's gameplay statistics. + /// + public partial class SoloStatisticsWatcher : Component + { + [Resolved] + private SpectatorClient spectatorClient { get; set; } = null!; + + [Resolved] + private IAPIProvider api { get; set; } = null!; + + private readonly Dictionary callbacks = new Dictionary(); + private readonly HashSet scoresWithoutCallback = new HashSet(); + + private readonly Dictionary latestStatistics = new Dictionary(); + + protected override void LoadComplete() + { + base.LoadComplete(); + + api.LocalUser.BindValueChanged(user => onUserChanged(user.NewValue), true); + spectatorClient.OnUserScoreProcessed += userScoreProcessed; + } + + /// + /// Registers for a user statistics update after the given has been processed server-side. + /// + /// The score to listen for the statistics update for. + /// The callback to be invoked once the statistics update has been prepared. + public void RegisterForStatisticsUpdateAfter(ScoreInfo score, Action onUpdateReady) => Schedule(() => + { + if (!api.IsLoggedIn) + return; + + var callback = new StatisticsUpdateCallback(score, onUpdateReady); + + if (scoresWithoutCallback.Remove(score.OnlineID)) + { + requestStatisticsUpdate(api.LocalUser.Value.Id, callback); + return; + } + + callbacks[score.OnlineID] = callback; + }); + + private void onUserChanged(APIUser? localUser) => Schedule(() => + { + callbacks.Clear(); + scoresWithoutCallback.Clear(); + latestStatistics.Clear(); + + if (!api.IsLoggedIn) + return; + + Debug.Assert(localUser != null && localUser.OnlineID > 1); + + var userRequest = new GetUsersRequest(new[] { localUser.OnlineID }); + userRequest.Success += response => Schedule(() => + { + foreach (var rulesetStats in response.Users.Single().RulesetsStatistics) + latestStatistics.Add(rulesetStats.Key, rulesetStats.Value); + }); + api.Queue(userRequest); + }); + + private void userScoreProcessed(int userId, long scoreId) + { + if (userId != api.LocalUser.Value?.OnlineID) + return; + + if (!callbacks.TryGetValue(scoreId, out var callback)) + { + scoresWithoutCallback.Add(scoreId); + return; + } + + requestStatisticsUpdate(userId, callback); + callbacks.Remove(scoreId); + } + + private void requestStatisticsUpdate(int userId, StatisticsUpdateCallback callback) + { + var request = new GetUserRequest(userId, callback.Score.Ruleset); + request.Success += user => Schedule(() => dispatchStatisticsUpdate(callback, user.Statistics)); + api.Queue(request); + } + + private void dispatchStatisticsUpdate(StatisticsUpdateCallback callback, UserStatistics updatedStatistics) + { + string rulesetName = callback.Score.Ruleset.ShortName; + + if (!latestStatistics.TryGetValue(rulesetName, out var latestRulesetStatistics)) + return; + + var update = new SoloStatisticsUpdate(callback.Score, latestRulesetStatistics, updatedStatistics); + callback.OnUpdateReady.Invoke(update); + + latestStatistics[rulesetName] = updatedStatistics; + } + + protected override void Dispose(bool isDisposing) + { + if (spectatorClient.IsNotNull()) + spectatorClient.OnUserScoreProcessed -= userScoreProcessed; + + base.Dispose(isDisposing); + } + + private class StatisticsUpdateCallback + { + public ScoreInfo Score { get; } + public Action OnUpdateReady { get; } + + public StatisticsUpdateCallback(ScoreInfo score, Action onUpdateReady) + { + Score = score; + OnUpdateReady = onUpdateReady; + } + } + } +} From 722cf48614fb696a8f9f8ff01512da826edeac90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 22 Dec 2022 10:14:37 +0100 Subject: [PATCH 1134/2991] Add test coverage for statistics watcher --- .../Online/TestSceneSoloStatisticsWatcher.cs | 241 ++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneSoloStatisticsWatcher.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneSoloStatisticsWatcher.cs b/osu.Game.Tests/Visual/Online/TestSceneSoloStatisticsWatcher.cs new file mode 100644 index 0000000000..0797113ca1 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneSoloStatisticsWatcher.cs @@ -0,0 +1,241 @@ +// 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 NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Testing; +using osu.Game.Models; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Solo; +using osu.Game.Online.Spectator; +using osu.Game.Rulesets.Osu; +using osu.Game.Scoring; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual.Online +{ + [HeadlessTest] + public partial class TestSceneSoloStatisticsWatcher : OsuTestScene + { + protected override bool UseOnlineAPI => false; + + private SoloStatisticsWatcher watcher = null!; + + [Resolved] + private SpectatorClient spectatorClient { get; set; } = null!; + + private DummyAPIAccess dummyAPI => (DummyAPIAccess)API; + + private Action? handleGetUsersRequest; + private Action? handleGetUserRequest; + + [SetUpSteps] + public void SetUpSteps() + { + AddStep("set up request handling", () => + { + handleGetUserRequest = null; + handleGetUsersRequest = null; + + dummyAPI.HandleRequest = request => + { + switch (request) + { + case GetUsersRequest getUsersRequest: + handleGetUsersRequest?.Invoke(getUsersRequest); + return true; + + case GetUserRequest getUserRequest: + handleGetUserRequest?.Invoke(getUserRequest); + return true; + + default: + return false; + } + }; + }); + + AddStep("create watcher", () => + { + Child = watcher = new SoloStatisticsWatcher(); + }); + } + + [Test] + public void TestStatisticsUpdateFiredAfterRegistrationAddedAndScoreProcessed() + { + AddStep("fetch initial stats", () => + { + handleGetUsersRequest = req => req.TriggerSuccess(createInitialUserResponse(1234)); + dummyAPI.LocalUser.Value = new APIUser { Id = 1234 }; + }); + + SoloStatisticsUpdate? update = null; + + AddStep("register for updates", () => watcher.RegisterForStatisticsUpdateAfter( + new ScoreInfo(Beatmap.Value.BeatmapInfo, new OsuRuleset().RulesetInfo, new RealmUser()) + { + Ruleset = new OsuRuleset().RulesetInfo, + OnlineID = 5678 + }, + receivedUpdate => update = receivedUpdate)); + + AddStep("feign score processing", + () => handleGetUserRequest = + req => req.TriggerSuccess(createIncrementalUserResponse(1234, 5_000_000))); + + AddStep("signal score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(1234, 5678)); + AddUntilStep("update received", () => update != null); + AddAssert("values before are correct", () => update?.Before.TotalScore, () => Is.EqualTo(4_000_000)); + AddAssert("values after are correct", () => update?.After.TotalScore, () => Is.EqualTo(5_000_000)); + } + + [Test] + public void TestStatisticsUpdateFiredAfterScoreProcessedAndRegistrationAdded() + { + AddStep("fetch initial stats", () => + { + handleGetUsersRequest = req => req.TriggerSuccess(createInitialUserResponse(1235)); + dummyAPI.LocalUser.Value = new APIUser { Id = 1235 }; + }); + + AddStep("feign score processing", + () => handleGetUserRequest = + req => req.TriggerSuccess(createIncrementalUserResponse(1235, 5_000_000))); + AddStep("signal score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(1235, 5678)); + + SoloStatisticsUpdate? update = null; + + // note ordering - this test checks that even if the registration is late, it will receive data. + AddStep("register for updates", () => watcher.RegisterForStatisticsUpdateAfter( + new ScoreInfo(Beatmap.Value.BeatmapInfo, new OsuRuleset().RulesetInfo, new RealmUser()) + { + Ruleset = new OsuRuleset().RulesetInfo, + OnlineID = 5678 + }, + receivedUpdate => update = receivedUpdate)); + AddUntilStep("update received", () => update != null); + AddAssert("values before are correct", () => update?.Before.TotalScore, () => Is.EqualTo(4_000_000)); + AddAssert("values after are correct", () => update?.After.TotalScore, () => Is.EqualTo(5_000_000)); + } + + [Test] + public void TestStatisticsUpdateNotFiredIfUserLoggedOut() + { + AddStep("fetch initial stats", () => + { + handleGetUsersRequest = req => req.TriggerSuccess(createInitialUserResponse(1236)); + dummyAPI.LocalUser.Value = new APIUser { Id = 1236 }; + }); + + SoloStatisticsUpdate? update = null; + + AddStep("register for updates", () => watcher.RegisterForStatisticsUpdateAfter( + new ScoreInfo(Beatmap.Value.BeatmapInfo, new OsuRuleset().RulesetInfo, new RealmUser()) + { + Ruleset = new OsuRuleset().RulesetInfo, + OnlineID = 5678 + }, + receivedUpdate => update = receivedUpdate)); + + AddStep("feign score processing", + () => handleGetUserRequest = + req => req.TriggerSuccess(createIncrementalUserResponse(1236, 5_000_000))); + + AddStep("log out user", () => dummyAPI.Logout()); + + AddStep("signal score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(1236, 5678)); + AddWaitStep("wait a bit", 5); + AddAssert("update not received", () => update == null); + } + + [Test] + public void TestStatisticsUpdateNotFiredIfAnotherUserLoggedIn() + { + AddStep("fetch initial stats", () => + { + handleGetUsersRequest = req => req.TriggerSuccess(createInitialUserResponse(1237)); + dummyAPI.LocalUser.Value = new APIUser { Id = 1237 }; + }); + + SoloStatisticsUpdate? update = null; + + AddStep("register for updates", () => watcher.RegisterForStatisticsUpdateAfter( + new ScoreInfo(Beatmap.Value.BeatmapInfo, new OsuRuleset().RulesetInfo, new RealmUser()) + { + Ruleset = new OsuRuleset().RulesetInfo, + OnlineID = 5678 + }, + receivedUpdate => update = receivedUpdate)); + + AddStep("feign score processing", + () => handleGetUserRequest = + req => req.TriggerSuccess(createIncrementalUserResponse(1237, 5_000_000))); + + AddStep("log out user", () => dummyAPI.LocalUser.Value = new APIUser { Id = 5555 }); + + AddStep("signal score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(1237, 5678)); + AddWaitStep("wait a bit", 5); + AddAssert("update not received", () => update == null); + } + + [Test] + public void TestStatisticsUpdateNotFiredIfScoreIdDoesNotMatch() + { + AddStep("fetch initial stats", () => + { + handleGetUsersRequest = req => req.TriggerSuccess(createInitialUserResponse(1238)); + dummyAPI.LocalUser.Value = new APIUser { Id = 1238 }; + }); + + SoloStatisticsUpdate? update = null; + + AddStep("register for updates", () => watcher.RegisterForStatisticsUpdateAfter( + new ScoreInfo(Beatmap.Value.BeatmapInfo, new OsuRuleset().RulesetInfo, new RealmUser()) + { + Ruleset = new OsuRuleset().RulesetInfo, + OnlineID = 5678 + }, + receivedUpdate => update = receivedUpdate)); + + AddStep("feign score processing", + () => handleGetUserRequest = + req => req.TriggerSuccess(createIncrementalUserResponse(1238, 5_000_000))); + + AddStep("signal score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(1238, 9012)); + AddWaitStep("wait a bit", 5); + AddAssert("update not received", () => update == null); + } + + private GetUsersResponse createInitialUserResponse(int userId) => new GetUsersResponse + { + Users = new List + { + new APIUser + { + Id = userId, + RulesetsStatistics = new Dictionary + { + ["osu"] = new UserStatistics { TotalScore = 4_000_000 }, + ["taiko"] = new UserStatistics { TotalScore = 3_000_000 }, + ["fruits"] = new UserStatistics { TotalScore = 2_000_000 }, + ["mania"] = new UserStatistics { TotalScore = 1_000_000 } + } + } + } + }; + + private APIUser createIncrementalUserResponse(int userId, long totalScore) => new APIUser + { + Id = userId, + Statistics = new UserStatistics + { + TotalScore = totalScore + } + }; + } +} From 48dc2332fd5bc60d977897e3a4d6477dc8b0deec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 22 Dec 2022 11:10:33 +0100 Subject: [PATCH 1135/2991] Refactor test to be easier to work with --- .../Online/TestSceneSoloStatisticsWatcher.cs | 241 +++++++++--------- .../Online/API/Requests/GetUsersRequest.cs | 6 +- osu.Game/Online/Solo/SoloStatisticsWatcher.cs | 2 +- 3 files changed, 130 insertions(+), 119 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneSoloStatisticsWatcher.cs b/osu.Game.Tests/Visual/Online/TestSceneSoloStatisticsWatcher.cs index 0797113ca1..008d54be63 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneSoloStatisticsWatcher.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneSoloStatisticsWatcher.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Testing; @@ -12,6 +13,7 @@ using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Solo; using osu.Game.Online.Spectator; +using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; using osu.Game.Scoring; using osu.Game.Users; @@ -33,9 +35,12 @@ namespace osu.Game.Tests.Visual.Online private Action? handleGetUsersRequest; private Action? handleGetUserRequest; + private readonly Dictionary<(int userId, string rulesetName), UserStatistics> serverSideStatistics = new Dictionary<(int userId, string rulesetName), UserStatistics>(); + [SetUpSteps] public void SetUpSteps() { + AddStep("clear server-side stats", () => serverSideStatistics.Clear()); AddStep("set up request handling", () => { handleGetUserRequest = null; @@ -46,11 +51,52 @@ namespace osu.Game.Tests.Visual.Online switch (request) { case GetUsersRequest getUsersRequest: - handleGetUsersRequest?.Invoke(getUsersRequest); + if (handleGetUsersRequest != null) + { + handleGetUsersRequest?.Invoke(getUsersRequest); + } + else + { + int userId = getUsersRequest.UserIds.Single(); + var response = new GetUsersResponse + { + Users = new List + { + new APIUser + { + Id = userId, + RulesetsStatistics = new Dictionary + { + ["osu"] = tryGetStatistics(userId, "osu"), + ["taiko"] = tryGetStatistics(userId, "taiko"), + ["fruits"] = tryGetStatistics(userId, "fruits"), + ["mania"] = tryGetStatistics(userId, "mania"), + } + } + } + }; + getUsersRequest.TriggerSuccess(response); + } + return true; case GetUserRequest getUserRequest: - handleGetUserRequest?.Invoke(getUserRequest); + if (handleGetUserRequest != null) + { + handleGetUserRequest.Invoke(getUserRequest); + } + else + { + int userId = int.Parse(getUserRequest.Lookup); + string rulesetName = getUserRequest.Ruleset.ShortName; + var response = new APIUser + { + Id = userId, + Statistics = tryGetStatistics(userId, rulesetName) + }; + getUserRequest.TriggerSuccess(response); + } + return true; default: @@ -65,120 +111,90 @@ namespace osu.Game.Tests.Visual.Online }); } + private UserStatistics tryGetStatistics(int userId, string rulesetName) + => serverSideStatistics.TryGetValue((userId, rulesetName), out var stats) ? stats : new UserStatistics(); + [Test] public void TestStatisticsUpdateFiredAfterRegistrationAddedAndScoreProcessed() { - AddStep("fetch initial stats", () => - { - handleGetUsersRequest = req => req.TriggerSuccess(createInitialUserResponse(1234)); - dummyAPI.LocalUser.Value = new APIUser { Id = 1234 }; - }); + int userId = getUserId(); + long scoreId = getScoreId(); + setUpUser(userId); + + var ruleset = new OsuRuleset().RulesetInfo; SoloStatisticsUpdate? update = null; + registerForUpdates(scoreId, ruleset, receivedUpdate => update = receivedUpdate); - AddStep("register for updates", () => watcher.RegisterForStatisticsUpdateAfter( - new ScoreInfo(Beatmap.Value.BeatmapInfo, new OsuRuleset().RulesetInfo, new RealmUser()) - { - Ruleset = new OsuRuleset().RulesetInfo, - OnlineID = 5678 - }, - receivedUpdate => update = receivedUpdate)); + feignScoreProcessing(userId, ruleset, 5_000_000); - AddStep("feign score processing", - () => handleGetUserRequest = - req => req.TriggerSuccess(createIncrementalUserResponse(1234, 5_000_000))); - - AddStep("signal score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(1234, 5678)); + AddStep("signal score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(userId, scoreId)); AddUntilStep("update received", () => update != null); - AddAssert("values before are correct", () => update?.Before.TotalScore, () => Is.EqualTo(4_000_000)); - AddAssert("values after are correct", () => update?.After.TotalScore, () => Is.EqualTo(5_000_000)); + AddAssert("values before are correct", () => update!.Before.TotalScore, () => Is.EqualTo(4_000_000)); + AddAssert("values after are correct", () => update!.After.TotalScore, () => Is.EqualTo(5_000_000)); } [Test] public void TestStatisticsUpdateFiredAfterScoreProcessedAndRegistrationAdded() { - AddStep("fetch initial stats", () => - { - handleGetUsersRequest = req => req.TriggerSuccess(createInitialUserResponse(1235)); - dummyAPI.LocalUser.Value = new APIUser { Id = 1235 }; - }); + int userId = getUserId(); + setUpUser(userId); - AddStep("feign score processing", - () => handleGetUserRequest = - req => req.TriggerSuccess(createIncrementalUserResponse(1235, 5_000_000))); - AddStep("signal score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(1235, 5678)); + long scoreId = getScoreId(); + var ruleset = new OsuRuleset().RulesetInfo; + + // note ordering - in this test processing completes *before* the registration is added. + feignScoreProcessing(userId, ruleset, 5_000_000); SoloStatisticsUpdate? update = null; + registerForUpdates(scoreId, ruleset, receivedUpdate => update = receivedUpdate); - // note ordering - this test checks that even if the registration is late, it will receive data. - AddStep("register for updates", () => watcher.RegisterForStatisticsUpdateAfter( - new ScoreInfo(Beatmap.Value.BeatmapInfo, new OsuRuleset().RulesetInfo, new RealmUser()) - { - Ruleset = new OsuRuleset().RulesetInfo, - OnlineID = 5678 - }, - receivedUpdate => update = receivedUpdate)); + AddStep("signal score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(userId, scoreId)); AddUntilStep("update received", () => update != null); - AddAssert("values before are correct", () => update?.Before.TotalScore, () => Is.EqualTo(4_000_000)); - AddAssert("values after are correct", () => update?.After.TotalScore, () => Is.EqualTo(5_000_000)); + AddAssert("values before are correct", () => update!.Before.TotalScore, () => Is.EqualTo(4_000_000)); + AddAssert("values after are correct", () => update!.After.TotalScore, () => Is.EqualTo(5_000_000)); } [Test] public void TestStatisticsUpdateNotFiredIfUserLoggedOut() { - AddStep("fetch initial stats", () => - { - handleGetUsersRequest = req => req.TriggerSuccess(createInitialUserResponse(1236)); - dummyAPI.LocalUser.Value = new APIUser { Id = 1236 }; - }); + int userId = getUserId(); + setUpUser(userId); + + long scoreId = getScoreId(); + var ruleset = new OsuRuleset().RulesetInfo; SoloStatisticsUpdate? update = null; + registerForUpdates(scoreId, ruleset, receivedUpdate => update = receivedUpdate); - AddStep("register for updates", () => watcher.RegisterForStatisticsUpdateAfter( - new ScoreInfo(Beatmap.Value.BeatmapInfo, new OsuRuleset().RulesetInfo, new RealmUser()) - { - Ruleset = new OsuRuleset().RulesetInfo, - OnlineID = 5678 - }, - receivedUpdate => update = receivedUpdate)); - - AddStep("feign score processing", - () => handleGetUserRequest = - req => req.TriggerSuccess(createIncrementalUserResponse(1236, 5_000_000))); + feignScoreProcessing(userId, ruleset, 5_000_000); AddStep("log out user", () => dummyAPI.Logout()); - AddStep("signal score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(1236, 5678)); + AddStep("signal score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(userId, scoreId)); AddWaitStep("wait a bit", 5); AddAssert("update not received", () => update == null); + + AddStep("log in user", () => dummyAPI.Login("user", "password")); } [Test] public void TestStatisticsUpdateNotFiredIfAnotherUserLoggedIn() { - AddStep("fetch initial stats", () => - { - handleGetUsersRequest = req => req.TriggerSuccess(createInitialUserResponse(1237)); - dummyAPI.LocalUser.Value = new APIUser { Id = 1237 }; - }); + int userId = getUserId(); + setUpUser(userId); + + long scoreId = getScoreId(); + var ruleset = new OsuRuleset().RulesetInfo; SoloStatisticsUpdate? update = null; + registerForUpdates(scoreId, ruleset, receivedUpdate => update = receivedUpdate); - AddStep("register for updates", () => watcher.RegisterForStatisticsUpdateAfter( - new ScoreInfo(Beatmap.Value.BeatmapInfo, new OsuRuleset().RulesetInfo, new RealmUser()) - { - Ruleset = new OsuRuleset().RulesetInfo, - OnlineID = 5678 - }, - receivedUpdate => update = receivedUpdate)); + feignScoreProcessing(userId, ruleset, 5_000_000); - AddStep("feign score processing", - () => handleGetUserRequest = - req => req.TriggerSuccess(createIncrementalUserResponse(1237, 5_000_000))); + AddStep("change user", () => dummyAPI.LocalUser.Value = new APIUser { Id = getUserId() }); - AddStep("log out user", () => dummyAPI.LocalUser.Value = new APIUser { Id = 5555 }); - - AddStep("signal score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(1237, 5678)); + AddStep("signal score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(userId, scoreId)); AddWaitStep("wait a bit", 5); AddAssert("update not received", () => update == null); } @@ -186,56 +202,51 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestStatisticsUpdateNotFiredIfScoreIdDoesNotMatch() { - AddStep("fetch initial stats", () => - { - handleGetUsersRequest = req => req.TriggerSuccess(createInitialUserResponse(1238)); - dummyAPI.LocalUser.Value = new APIUser { Id = 1238 }; - }); + int userId = getUserId(); + setUpUser(userId); + + long scoreId = getScoreId(); + var ruleset = new OsuRuleset().RulesetInfo; SoloStatisticsUpdate? update = null; + registerForUpdates(scoreId, ruleset, receivedUpdate => update = receivedUpdate); - AddStep("register for updates", () => watcher.RegisterForStatisticsUpdateAfter( - new ScoreInfo(Beatmap.Value.BeatmapInfo, new OsuRuleset().RulesetInfo, new RealmUser()) - { - Ruleset = new OsuRuleset().RulesetInfo, - OnlineID = 5678 - }, - receivedUpdate => update = receivedUpdate)); + feignScoreProcessing(userId, ruleset, 5_000_000); - AddStep("feign score processing", - () => handleGetUserRequest = - req => req.TriggerSuccess(createIncrementalUserResponse(1238, 5_000_000))); - - AddStep("signal score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(1238, 9012)); + AddStep("signal another score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(userId, getScoreId())); AddWaitStep("wait a bit", 5); AddAssert("update not received", () => update == null); } - private GetUsersResponse createInitialUserResponse(int userId) => new GetUsersResponse - { - Users = new List - { - new APIUser - { - Id = userId, - RulesetsStatistics = new Dictionary - { - ["osu"] = new UserStatistics { TotalScore = 4_000_000 }, - ["taiko"] = new UserStatistics { TotalScore = 3_000_000 }, - ["fruits"] = new UserStatistics { TotalScore = 2_000_000 }, - ["mania"] = new UserStatistics { TotalScore = 1_000_000 } - } - } - } - }; + private int nextUserId = 2000; + private long nextScoreId = 50000; - private APIUser createIncrementalUserResponse(int userId, long totalScore) => new APIUser + private int getUserId() => ++nextUserId; + private long getScoreId() => ++nextScoreId; + + private void setUpUser(int userId) { - Id = userId, - Statistics = new UserStatistics + AddStep("fetch initial stats", () => { - TotalScore = totalScore - } - }; + serverSideStatistics[(userId, "osu")] = new UserStatistics { TotalScore = 4_000_000 }; + serverSideStatistics[(userId, "taiko")] = new UserStatistics { TotalScore = 3_000_000 }; + serverSideStatistics[(userId, "fruits")] = new UserStatistics { TotalScore = 2_000_000 }; + serverSideStatistics[(userId, "mania")] = new UserStatistics { TotalScore = 1_000_000 }; + + dummyAPI.LocalUser.Value = new APIUser { Id = userId }; + }); + } + + private void registerForUpdates(long scoreId, RulesetInfo rulesetInfo, Action onUpdateReady) => + AddStep("register for updates", () => watcher.RegisterForStatisticsUpdateAfter( + new ScoreInfo(Beatmap.Value.BeatmapInfo, new OsuRuleset().RulesetInfo, new RealmUser()) + { + Ruleset = rulesetInfo, + OnlineID = scoreId + }, + onUpdateReady)); + + private void feignScoreProcessing(int userId, RulesetInfo rulesetInfo, long newTotalScore) + => AddStep("feign score processing", () => serverSideStatistics[(userId, rulesetInfo.ShortName)] = new UserStatistics { TotalScore = newTotalScore }); } } diff --git a/osu.Game/Online/API/Requests/GetUsersRequest.cs b/osu.Game/Online/API/Requests/GetUsersRequest.cs index bbaf241384..b57bb215aa 100644 --- a/osu.Game/Online/API/Requests/GetUsersRequest.cs +++ b/osu.Game/Online/API/Requests/GetUsersRequest.cs @@ -9,7 +9,7 @@ namespace osu.Game.Online.API.Requests { public class GetUsersRequest : APIRequest { - private readonly int[] userIds; + public readonly int[] UserIds; private const int max_ids_per_request = 50; @@ -18,9 +18,9 @@ namespace osu.Game.Online.API.Requests if (userIds.Length > max_ids_per_request) throw new ArgumentException($"{nameof(GetUsersRequest)} calls only support up to {max_ids_per_request} IDs at once"); - this.userIds = userIds; + UserIds = userIds; } - protected override string Target => "users/?ids[]=" + string.Join("&ids[]=", userIds); + protected override string Target => "users/?ids[]=" + string.Join("&ids[]=", UserIds); } } diff --git a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs index 197ad410a9..1befbe2af0 100644 --- a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs +++ b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs @@ -71,7 +71,7 @@ namespace osu.Game.Online.Solo if (!api.IsLoggedIn) return; - Debug.Assert(localUser != null && localUser.OnlineID > 1); + Debug.Assert(localUser != null); var userRequest = new GetUsersRequest(new[] { localUser.OnlineID }); userRequest.Success += response => Schedule(() => From fa2d50fe3164612e17bedb6d1892294cc9af0a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 22 Dec 2022 19:29:51 +0100 Subject: [PATCH 1136/2991] Limit tracking unhandled scores to just the last one --- osu.Game/Online/Solo/SoloStatisticsWatcher.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs index 1befbe2af0..48f39504a3 100644 --- a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs +++ b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs @@ -29,7 +29,7 @@ namespace osu.Game.Online.Solo private IAPIProvider api { get; set; } = null!; private readonly Dictionary callbacks = new Dictionary(); - private readonly HashSet scoresWithoutCallback = new HashSet(); + private long? lastProcessedScoreId; private readonly Dictionary latestStatistics = new Dictionary(); @@ -53,7 +53,7 @@ namespace osu.Game.Online.Solo var callback = new StatisticsUpdateCallback(score, onUpdateReady); - if (scoresWithoutCallback.Remove(score.OnlineID)) + if (lastProcessedScoreId == score.OnlineID) { requestStatisticsUpdate(api.LocalUser.Value.Id, callback); return; @@ -65,7 +65,7 @@ namespace osu.Game.Online.Solo private void onUserChanged(APIUser? localUser) => Schedule(() => { callbacks.Clear(); - scoresWithoutCallback.Clear(); + lastProcessedScoreId = null; latestStatistics.Clear(); if (!api.IsLoggedIn) @@ -87,11 +87,10 @@ namespace osu.Game.Online.Solo if (userId != api.LocalUser.Value?.OnlineID) return; + lastProcessedScoreId = scoreId; + if (!callbacks.TryGetValue(scoreId, out var callback)) - { - scoresWithoutCallback.Add(scoreId); return; - } requestStatisticsUpdate(userId, callback); callbacks.Remove(scoreId); From 27afeb9e301d0392be3a22155643389468c04448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 22 Dec 2022 19:46:41 +0100 Subject: [PATCH 1137/2991] Add test coverage of merging ignored score updates --- .../Online/TestSceneSoloStatisticsWatcher.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneSoloStatisticsWatcher.cs b/osu.Game.Tests/Visual/Online/TestSceneSoloStatisticsWatcher.cs index 008d54be63..b1badc6282 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneSoloStatisticsWatcher.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneSoloStatisticsWatcher.cs @@ -218,6 +218,34 @@ namespace osu.Game.Tests.Visual.Online AddAssert("update not received", () => update == null); } + // the behaviour exercised in this test may not be final, it is mostly assumed for simplicity. + // in the long run we may want each score's update to be entirely isolated from others, rather than have prior unobserved updates merge into the latest. + [Test] + public void TestIgnoredScoreUpdateIsMergedIntoNextOne() + { + int userId = getUserId(); + setUpUser(userId); + + long firstScoreId = getScoreId(); + var ruleset = new OsuRuleset().RulesetInfo; + + feignScoreProcessing(userId, ruleset, 5_000_000); + + AddStep("signal score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(userId, firstScoreId)); + + long secondScoreId = getScoreId(); + + feignScoreProcessing(userId, ruleset, 6_000_000); + + SoloStatisticsUpdate? update = null; + registerForUpdates(secondScoreId, ruleset, receivedUpdate => update = receivedUpdate); + + AddStep("signal score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(userId, secondScoreId)); + AddUntilStep("update received", () => update != null); + AddAssert("values before are correct", () => update!.Before.TotalScore, () => Is.EqualTo(4_000_000)); + AddAssert("values after are correct", () => update!.After.TotalScore, () => Is.EqualTo(6_000_000)); + } + private int nextUserId = 2000; private long nextScoreId = 50000; From 08d2fbeb8e99cc2ed2b658f1ce1d30f859108c2b Mon Sep 17 00:00:00 2001 From: Berkan Diler Date: Thu, 22 Dec 2022 21:27:59 +0100 Subject: [PATCH 1138/2991] Use new ArgumentNullException.ThrowIfNull throw-helper API --- .../Beatmaps/Patterns/Legacy/PatternGenerator.cs | 4 ++-- .../Beatmaps/Patterns/PatternGenerator.cs | 6 +++--- osu.Game.Rulesets.Mania/MathUtils/LegacySortHelper.cs | 3 +-- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 3 +-- osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs | 4 ++-- osu.Game.Tournament/Components/TournamentBeatmapPanel.cs | 2 +- osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs | 3 +-- osu.Game/Beatmaps/Drawables/BeatmapBackgroundSprite.cs | 3 +-- osu.Game/Beatmaps/Drawables/OnlineBeatmapSetCover.cs | 3 +-- osu.Game/Beatmaps/Formats/Decoder.cs | 3 +-- osu.Game/Graphics/Containers/LogoTrackingContainer.cs | 3 +-- osu.Game/Graphics/UserInterface/Nub.cs | 3 +-- osu.Game/IO/FileAbstraction/StreamFileAbstraction.cs | 3 +-- osu.Game/Online/Chat/ChannelManager.cs | 6 ++---- osu.Game/Overlays/ChangelogOverlay.cs | 6 +++--- osu.Game/Overlays/OnScreenDisplay.cs | 4 ++-- osu.Game/Overlays/Volume/MuteButton.cs | 3 +-- osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs | 3 +-- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 3 +-- osu.Game/Rulesets/UI/JudgementContainer.cs | 2 +- osu.Game/Scoring/ScoreImporter.cs | 4 ++-- osu.Game/Screens/Menu/LogoVisualisation.cs | 2 +- osu.Game/Screens/Play/HUD/ModDisplay.cs | 3 +-- osu.Game/Screens/Play/HUD/ModFlowDisplay.cs | 3 +-- osu.Game/Screens/Play/KeyCounterDisplay.cs | 2 +- osu.Game/Users/Drawables/DrawableFlag.cs | 3 +-- osu.Game/Users/UserPanel.cs | 3 +-- 27 files changed, 36 insertions(+), 54 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs index 308238d87a..77f93b4ef9 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs @@ -35,8 +35,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy protected PatternGenerator(LegacyRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, IBeatmap originalBeatmap) : base(hitObject, beatmap, previousPattern) { - if (random == null) throw new ArgumentNullException(nameof(random)); - if (originalBeatmap == null) throw new ArgumentNullException(nameof(originalBeatmap)); + ArgumentNullException.ThrowIfNull(random); + ArgumentNullException.ThrowIfNull(originalBeatmap); Random = random; OriginalBeatmap = originalBeatmap; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs index b2e89c3410..931673f337 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs @@ -33,9 +33,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns protected PatternGenerator(HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern) { - if (hitObject == null) throw new ArgumentNullException(nameof(hitObject)); - if (beatmap == null) throw new ArgumentNullException(nameof(beatmap)); - if (previousPattern == null) throw new ArgumentNullException(nameof(previousPattern)); + ArgumentNullException.ThrowIfNull(hitObject); + ArgumentNullException.ThrowIfNull(beatmap); + ArgumentNullException.ThrowIfNull(previousPattern); HitObject = hitObject; Beatmap = beatmap; diff --git a/osu.Game.Rulesets.Mania/MathUtils/LegacySortHelper.cs b/osu.Game.Rulesets.Mania/MathUtils/LegacySortHelper.cs index 1a67117c03..4d93826240 100644 --- a/osu.Game.Rulesets.Mania/MathUtils/LegacySortHelper.cs +++ b/osu.Game.Rulesets.Mania/MathUtils/LegacySortHelper.cs @@ -22,8 +22,7 @@ namespace osu.Game.Rulesets.Mania.MathUtils public static void Sort(T[] keys, IComparer comparer) { - if (keys == null) - throw new ArgumentNullException(nameof(keys)); + ArgumentNullException.ThrowIfNull(keys); if (keys.Length == 0) return; diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 01e9926ad7..e3ebadc836 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -29,8 +29,7 @@ namespace osu.Game.Rulesets.Mania.UI public ManiaPlayfield(List stageDefinitions) { - if (stageDefinitions == null) - throw new ArgumentNullException(nameof(stageDefinitions)); + ArgumentNullException.ThrowIfNull(stageDefinitions); if (stageDefinitions.Count <= 0) throw new ArgumentException("Can't have zero or fewer stages."); diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs index 2f62968029..74e16f7e0b 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGeneratorBase.cs @@ -84,8 +84,8 @@ namespace osu.Game.Rulesets.Osu.Replays { public int Compare(ReplayFrame? f1, ReplayFrame? f2) { - if (f1 == null) throw new ArgumentNullException(nameof(f1)); - if (f2 == null) throw new ArgumentNullException(nameof(f2)); + ArgumentNullException.ThrowIfNull(f1); + ArgumentNullException.ThrowIfNull(f2); return f1.Time.CompareTo(f2.Time); } diff --git a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs index 52769321a9..1157b50377 100644 --- a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs +++ b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs @@ -32,7 +32,7 @@ namespace osu.Game.Tournament.Components public TournamentBeatmapPanel(TournamentBeatmap beatmap, string mod = null) { - if (beatmap == null) throw new ArgumentNullException(nameof(beatmap)); + ArgumentNullException.ThrowIfNull(beatmap); Beatmap = beatmap; this.mod = mod; diff --git a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs index 55119c800a..29b7191ecf 100644 --- a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs +++ b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs @@ -211,8 +211,7 @@ namespace osu.Game.Beatmaps.ControlPoints public static T BinarySearch(IReadOnlyList list, double time) where T : class, IControlPoint { - if (list == null) - throw new ArgumentNullException(nameof(list)); + ArgumentNullException.ThrowIfNull(list); if (list.Count == 0) return null; diff --git a/osu.Game/Beatmaps/Drawables/BeatmapBackgroundSprite.cs b/osu.Game/Beatmaps/Drawables/BeatmapBackgroundSprite.cs index d31a7ae2fe..767504fcb1 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapBackgroundSprite.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapBackgroundSprite.cs @@ -15,8 +15,7 @@ namespace osu.Game.Beatmaps.Drawables public BeatmapBackgroundSprite(IWorkingBeatmap working) { - if (working == null) - throw new ArgumentNullException(nameof(working)); + ArgumentNullException.ThrowIfNull(working); this.working = working; } diff --git a/osu.Game/Beatmaps/Drawables/OnlineBeatmapSetCover.cs b/osu.Game/Beatmaps/Drawables/OnlineBeatmapSetCover.cs index e4ffc1d553..fc7c14e734 100644 --- a/osu.Game/Beatmaps/Drawables/OnlineBeatmapSetCover.cs +++ b/osu.Game/Beatmaps/Drawables/OnlineBeatmapSetCover.cs @@ -18,8 +18,7 @@ namespace osu.Game.Beatmaps.Drawables public OnlineBeatmapSetCover(IBeatmapSetOnlineInfo set, BeatmapSetCoverType type = BeatmapSetCoverType.Cover) { - if (set == null) - throw new ArgumentNullException(nameof(set)); + ArgumentNullException.ThrowIfNull(set); this.set = set; this.type = type; diff --git a/osu.Game/Beatmaps/Formats/Decoder.cs b/osu.Game/Beatmaps/Formats/Decoder.cs index ca1bcc97fd..4f0f11d053 100644 --- a/osu.Game/Beatmaps/Formats/Decoder.cs +++ b/osu.Game/Beatmaps/Formats/Decoder.cs @@ -57,8 +57,7 @@ namespace osu.Game.Beatmaps.Formats public static Decoder GetDecoder(LineBufferedReader stream) where T : new() { - if (stream == null) - throw new ArgumentNullException(nameof(stream)); + ArgumentNullException.ThrowIfNull(stream); if (!decoders.TryGetValue(typeof(T), out var typedDecoders)) throw new IOException(@"Unknown decoder type"); diff --git a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs index 735b8b4e7d..984d60d35e 100644 --- a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs +++ b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs @@ -36,8 +36,7 @@ namespace osu.Game.Graphics.Containers /// The easing type of the initial transform. public void StartTracking(OsuLogo logo, double duration = 0, Easing easing = Easing.None) { - if (logo == null) - throw new ArgumentNullException(nameof(logo)); + ArgumentNullException.ThrowIfNull(logo); if (logo.IsTracking && Logo == null) throw new InvalidOperationException($"Cannot track an instance of {typeof(OsuLogo)} to multiple {typeof(LogoTrackingContainer)}s"); diff --git a/osu.Game/Graphics/UserInterface/Nub.cs b/osu.Game/Graphics/UserInterface/Nub.cs index 4f56872f42..7921dcf593 100644 --- a/osu.Game/Graphics/UserInterface/Nub.cs +++ b/osu.Game/Graphics/UserInterface/Nub.cs @@ -114,8 +114,7 @@ namespace osu.Game.Graphics.UserInterface get => current; set { - if (value == null) - throw new ArgumentNullException(nameof(value)); + ArgumentNullException.ThrowIfNull(value); current.UnbindBindings(); current.BindTo(value); diff --git a/osu.Game/IO/FileAbstraction/StreamFileAbstraction.cs b/osu.Game/IO/FileAbstraction/StreamFileAbstraction.cs index 8e6c3e5f3d..d47f936eb3 100644 --- a/osu.Game/IO/FileAbstraction/StreamFileAbstraction.cs +++ b/osu.Game/IO/FileAbstraction/StreamFileAbstraction.cs @@ -23,8 +23,7 @@ namespace osu.Game.IO.FileAbstraction public void CloseStream(Stream stream) { - if (stream == null) - throw new ArgumentNullException(nameof(stream)); + ArgumentNullException.ThrowIfNull(stream); stream.Close(); } diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index a4661dcbd7..5d55374373 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -118,8 +118,7 @@ namespace osu.Game.Online.Chat /// public void OpenChannel(string name) { - if (name == null) - throw new ArgumentNullException(nameof(name)); + ArgumentNullException.ThrowIfNull(name); CurrentChannel.Value = AvailableChannels.FirstOrDefault(c => c.Name == name) ?? throw new ChannelNotFoundException(name); } @@ -130,8 +129,7 @@ namespace osu.Game.Online.Chat /// The user the private channel is opened with. public void OpenPrivateChannel(APIUser user) { - if (user == null) - throw new ArgumentNullException(nameof(user)); + ArgumentNullException.ThrowIfNull(user); if (user.Id == api.LocalUser.Value.Id) return; diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs index 90863a90a2..671d649dcf 100644 --- a/osu.Game/Overlays/ChangelogOverlay.cs +++ b/osu.Game/Overlays/ChangelogOverlay.cs @@ -70,7 +70,7 @@ namespace osu.Game.Overlays /// are specified, the header will instantly display them. public void ShowBuild([NotNull] APIChangelogBuild build) { - if (build == null) throw new ArgumentNullException(nameof(build)); + ArgumentNullException.ThrowIfNull(build); Current.Value = build; Show(); @@ -78,8 +78,8 @@ namespace osu.Game.Overlays public void ShowBuild([NotNull] string updateStream, [NotNull] string version) { - if (updateStream == null) throw new ArgumentNullException(nameof(updateStream)); - if (version == null) throw new ArgumentNullException(nameof(version)); + ArgumentNullException.ThrowIfNull(updateStream); + ArgumentNullException.ThrowIfNull(version); performAfterFetch(() => { diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index d60077cfa9..4f2dba7b2c 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -58,7 +58,7 @@ namespace osu.Game.Overlays /// If is already being tracked from the same . public void BeginTracking(object source, ITrackableConfigManager configManager) { - if (configManager == null) throw new ArgumentNullException(nameof(configManager)); + ArgumentNullException.ThrowIfNull(configManager); if (trackedConfigManagers.ContainsKey((source, configManager))) throw new InvalidOperationException($"{nameof(configManager)} is already registered."); @@ -82,7 +82,7 @@ namespace osu.Game.Overlays /// If is not being tracked from the same . public void StopTracking(object source, ITrackableConfigManager configManager) { - if (configManager == null) throw new ArgumentNullException(nameof(configManager)); + ArgumentNullException.ThrowIfNull(configManager); if (!trackedConfigManagers.TryGetValue((source, configManager), out var existing)) return; diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index 3bea1c840e..9cc346a38b 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -28,8 +28,7 @@ namespace osu.Game.Overlays.Volume get => current; set { - if (value == null) - throw new ArgumentNullException(nameof(value)); + ArgumentNullException.ThrowIfNull(value); current.UnbindBindings(); current.BindTo(value); diff --git a/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs b/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs index 9d9c10b3ea..38ced4c9e7 100644 --- a/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs +++ b/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs @@ -126,8 +126,7 @@ namespace osu.Game.Rulesets.Mods get => this; set { - if (value == null) - throw new ArgumentNullException(nameof(value)); + ArgumentNullException.ThrowIfNull(value); if (currentBound != null) UnbindFrom(currentBound); BindTo(currentBound = value); diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 096132d024..be5a7f71e7 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -208,8 +208,7 @@ namespace osu.Game.Rulesets.Objects.Drawables /// public void Apply([NotNull] HitObject hitObject) { - if (hitObject == null) - throw new ArgumentNullException($"Cannot apply a null {nameof(HitObject)}."); + ArgumentNullException.ThrowIfNull(hitObject); Apply(new SyntheticHitObjectEntry(hitObject)); } diff --git a/osu.Game/Rulesets/UI/JudgementContainer.cs b/osu.Game/Rulesets/UI/JudgementContainer.cs index 8381e6d6b5..7181e80206 100644 --- a/osu.Game/Rulesets/UI/JudgementContainer.cs +++ b/osu.Game/Rulesets/UI/JudgementContainer.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.UI { public override void Add(T judgement) { - if (judgement == null) throw new ArgumentNullException(nameof(judgement)); + ArgumentNullException.ThrowIfNull(judgement); // remove any existing judgements for the judged object. // this can be the case when rewinding. diff --git a/osu.Game/Scoring/ScoreImporter.cs b/osu.Game/Scoring/ScoreImporter.cs index 797d80b7fa..a3d7fe5de0 100644 --- a/osu.Game/Scoring/ScoreImporter.cs +++ b/osu.Game/Scoring/ScoreImporter.cs @@ -71,8 +71,8 @@ namespace osu.Game.Scoring // These properties are known to be non-null, but these final checks ensure a null hasn't come from somewhere (or the refetch has failed). // Under no circumstance do we want these to be written to realm as null. - if (model.BeatmapInfo == null) throw new ArgumentNullException(nameof(model.BeatmapInfo)); - if (model.Ruleset == null) throw new ArgumentNullException(nameof(model.Ruleset)); + ArgumentNullException.ThrowIfNull(model.BeatmapInfo); + ArgumentNullException.ThrowIfNull(model.Ruleset); PopulateMaximumStatistics(model); diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index c67850bdf6..5000a97b3d 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -147,7 +147,7 @@ namespace osu.Game.Screens.Menu private void addAmplitudesFromSource(IHasAmplitudes source) { - if (source == null) throw new ArgumentNullException(nameof(source)); + ArgumentNullException.ThrowIfNull(source); var amplitudes = source.CurrentAmplitudes.FrequencyAmplitudes.Span; diff --git a/osu.Game/Screens/Play/HUD/ModDisplay.cs b/osu.Game/Screens/Play/HUD/ModDisplay.cs index 3b50a22e3c..8b2b8f9464 100644 --- a/osu.Game/Screens/Play/HUD/ModDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ModDisplay.cs @@ -33,8 +33,7 @@ namespace osu.Game.Screens.Play.HUD get => current.Current; set { - if (value == null) - throw new ArgumentNullException(nameof(value)); + ArgumentNullException.ThrowIfNull(value); current.Current = value; } diff --git a/osu.Game/Screens/Play/HUD/ModFlowDisplay.cs b/osu.Game/Screens/Play/HUD/ModFlowDisplay.cs index 23030e640b..38027c64ac 100644 --- a/osu.Game/Screens/Play/HUD/ModFlowDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ModFlowDisplay.cs @@ -30,8 +30,7 @@ namespace osu.Game.Screens.Play.HUD get => current.Current; set { - if (value == null) - throw new ArgumentNullException(nameof(value)); + ArgumentNullException.ThrowIfNull(value); current.Current = value; } diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs index d9ad3cfaf7..bb50d4a539 100644 --- a/osu.Game/Screens/Play/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs @@ -54,7 +54,7 @@ namespace osu.Game.Screens.Play public override void Add(KeyCounter key) { - if (key == null) throw new ArgumentNullException(nameof(key)); + ArgumentNullException.ThrowIfNull(key); base.Add(key); key.IsCounting = IsCounting; diff --git a/osu.Game/Users/Drawables/DrawableFlag.cs b/osu.Game/Users/Drawables/DrawableFlag.cs index 0d209f47e8..929a29251d 100644 --- a/osu.Game/Users/Drawables/DrawableFlag.cs +++ b/osu.Game/Users/Drawables/DrawableFlag.cs @@ -27,8 +27,7 @@ namespace osu.Game.Users.Drawables [BackgroundDependencyLoader] private void load(TextureStore ts) { - if (ts == null) - throw new ArgumentNullException(nameof(ts)); + ArgumentNullException.ThrowIfNull(ts); string textureName = countryCode == CountryCode.Unknown ? "__" : countryCode.ToString(); Texture = ts.Get($@"Flags/{textureName}") ?? ts.Get(@"Flags/__"); diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index e7af127a30..2f7232d5ea 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -36,8 +36,7 @@ namespace osu.Game.Users protected UserPanel(APIUser user) : base(HoverSampleSet.Button) { - if (user == null) - throw new ArgumentNullException(nameof(user)); + ArgumentNullException.ThrowIfNull(user); User = user; } From 30de9ba795a94810411db4791403c03876b13393 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 23 Dec 2022 00:35:59 +0300 Subject: [PATCH 1139/2991] Dispose previous waveform on track reload --- osu.Game/Beatmaps/WorkingBeatmap.cs | 9 ++++++--- .../Screens/Edit/Compose/Components/Timeline/Timeline.cs | 7 +------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 345220a3a3..ab790617bb 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -46,10 +46,11 @@ namespace osu.Game.Beatmaps private readonly object beatmapFetchLock = new object(); - private Waveform waveform; private readonly Lazy storyboard; private readonly Lazy skin; + private Track track; // track is not Lazy as we allow transferring and loading multiple times. + private Waveform waveform; // waveform is also not Lazy as the track may change. protected WorkingBeatmap(BeatmapInfo beatmapInfo, AudioManager audioManager) { @@ -107,10 +108,12 @@ namespace osu.Game.Beatmaps public Track LoadTrack() { - // track could be changed, clearing waveform cache + track = GetBeatmapTrack() ?? GetVirtualTrack(1000); + + // the track may have changed, recycle the current waveform. + waveform?.Dispose(); waveform = null; - track = GetBeatmapTrack() ?? GetVirtualTrack(1000); return track; } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 918b5f8109..75de15fe56 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -141,12 +141,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline waveformOpacity = config.GetBindable(OsuSetting.EditorWaveformOpacity); track.BindTo(editorClock.Track); - track.BindValueChanged(_ => - { - waveform.Waveform = beatmap.Value.Waveform; - }, true); - - waveform.Waveform = beatmap.Value.Waveform; + track.BindValueChanged(_ => waveform.Waveform = beatmap.Value.Waveform, true); Zoom = (float)(defaultTimelineZoom * editorBeatmap.BeatmapInfo.TimelineZoom); } From a6650136269a8d8841fabea30bf9310fc07e639f Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 23 Dec 2022 00:56:37 +0300 Subject: [PATCH 1140/2991] Add failing test case --- .../TestSceneZoomableScrollContainer.cs | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneZoomableScrollContainer.cs b/osu.Game.Tests/Visual/Editing/TestSceneZoomableScrollContainer.cs index 6bc2922253..a141e4d431 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneZoomableScrollContainer.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneZoomableScrollContainer.cs @@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual.Editing { public partial class TestSceneZoomableScrollContainer : OsuManualInputManagerTestScene { - private ZoomableScrollContainer scrollContainer; + private TestZoomableScrollContainer scrollContainer; private Drawable innerBox; [SetUpSteps] @@ -47,7 +47,7 @@ namespace osu.Game.Tests.Visual.Editing RelativeSizeAxes = Axes.Both, Colour = OsuColour.Gray(30) }, - scrollContainer = new ZoomableScrollContainer(1, 60, 1) + scrollContainer = new TestZoomableScrollContainer(1, 60, 1) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -93,6 +93,14 @@ namespace osu.Game.Tests.Visual.Editing AddAssert("Inner container width matches scroll container", () => innerBox.DrawWidth == scrollContainer.DrawWidth); } + [Test] + public void TestWidthUpdatesOnSecondZoomSetup() + { + AddAssert("Inner container width = 1x", () => innerBox.DrawWidth == scrollContainer.DrawWidth); + AddStep("reload zoom", () => scrollContainer.SetupZoom(10, 10, 60)); + AddAssert("Inner container width = 10x", () => innerBox.DrawWidth == scrollContainer.DrawWidth * 10); + } + [Test] public void TestZoom0() { @@ -190,5 +198,15 @@ namespace osu.Game.Tests.Visual.Editing private Quad scrollQuad => scrollContainer.ScreenSpaceDrawQuad; private Quad boxQuad => innerBox.ScreenSpaceDrawQuad; + + private partial class TestZoomableScrollContainer : ZoomableScrollContainer + { + public TestZoomableScrollContainer(int minimum, float maximum, float initial) + : base(minimum, maximum, initial) + { + } + + public new void SetupZoom(float initial, float minimum, float maximum) => base.SetupZoom(initial, minimum, maximum); + } } } From 0cb9b7983498cbc313a070174868a487a254e247 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 23 Dec 2022 00:56:02 +0300 Subject: [PATCH 1141/2991] Fix `ZoomableScrollContainer` potentially not updating content width on setup --- .../Compose/Components/Timeline/ZoomableScrollContainer.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs index 28f7731354..951f4129d4 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs @@ -99,9 +99,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline minZoom = minimum; maxZoom = maximum; - CurrentZoom = zoomTarget = initial; - isZoomSetUp = true; + CurrentZoom = zoomTarget = initial; + zoomedContentWidthCache.Invalidate(); + + isZoomSetUp = true; zoomedContent.Show(); } From f25439e359b0fb67c66b1a1e85a19fa461029a23 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 23 Dec 2022 01:54:49 +0300 Subject: [PATCH 1142/2991] Move track change subscription to LoadComplete --- osu.Game/Screens/Edit/Timing/TapTimingControl.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs index 36cd5f8b70..0d29b69d96 100644 --- a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs +++ b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs @@ -189,6 +189,10 @@ namespace osu.Game.Screens.Edit.Timing }, true); track.BindTo(clock.Track); + } + + protected override void LoadComplete() + { track.ValueChanged += _ => waveformContainer.Child = new WaveformComparisonDisplay(); } From 5eccafe19046c331468c6c6e2c9b47c84ead38a2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 23 Dec 2022 16:45:40 +0800 Subject: [PATCH 1143/2991] Fix wiki overlay showing error message when load is cancelled --- osu.Game/Overlays/WikiOverlay.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/WikiOverlay.cs b/osu.Game/Overlays/WikiOverlay.cs index a06c180948..9ccd0af2b6 100644 --- a/osu.Game/Overlays/WikiOverlay.cs +++ b/osu.Game/Overlays/WikiOverlay.cs @@ -118,7 +118,11 @@ namespace osu.Game.Overlays Loading.Show(); request.Success += response => Schedule(() => onSuccess(response)); - request.Failure += _ => Schedule(onFail); + request.Failure += ex => + { + if (ex is not OperationCanceledException) + Schedule(onFail); + }; api.PerformAsync(request); } From a677c8be0651e3440f0f21a0546160100f9be035 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 23 Dec 2022 21:17:42 +0800 Subject: [PATCH 1144/2991] Change path on error --- osu.Game/Overlays/WikiOverlay.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Overlays/WikiOverlay.cs b/osu.Game/Overlays/WikiOverlay.cs index 9ccd0af2b6..a9a131e481 100644 --- a/osu.Game/Overlays/WikiOverlay.cs +++ b/osu.Game/Overlays/WikiOverlay.cs @@ -21,6 +21,8 @@ namespace osu.Game.Overlays { private const string index_path = @"main_page"; + public string CurrentPath => path.Value; + private readonly Bindable path = new Bindable(index_path); private readonly Bindable wikiData = new Bindable(); @@ -105,6 +107,9 @@ namespace osu.Game.Overlays if (e.NewValue == wikiData.Value?.Path) return; + if (e.NewValue == "error") + return; + cancellationToken?.Cancel(); request?.Cancel(); @@ -152,6 +157,7 @@ namespace osu.Game.Overlays private void onFail() { + path.Value = "error"; LoadDisplay(articlePage = new WikiArticlePage($@"{api.WebsiteRootUrl}/wiki/", $"Something went wrong when trying to fetch page \"{path.Value}\".\n\n[Return to the main page](Main_Page).")); } From 4a69cb4aae964ea8bd61178337e2b203a0e5cdc8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 23 Dec 2022 21:19:04 +0800 Subject: [PATCH 1145/2991] Add test coverage of wiki cancellation not causing error --- osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs index 620fd710e3..4ad03c052f 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs @@ -4,6 +4,7 @@ #nullable disable using System; +using System.Linq; using System.Net; using NUnit.Framework; using osu.Game.Online.API; @@ -29,6 +30,15 @@ namespace osu.Game.Tests.Visual.Online AddStep("Show main page", () => wiki.Show()); } + [Test] + public void TestCancellationDoesntShowError() + { + AddStep("Show main page", () => wiki.Show()); + AddStep("Show another page", () => wiki.ShowPage("Article_styling_criteria/Formatting")); + + AddUntilStep("Current path is not error", () => wiki.CurrentPath != "error"); + } + [Test] public void TestArticlePage() { From 137a32ade66cf6bc2b3e0a7cffcfbe1049a072c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 23 Dec 2022 16:39:35 +0100 Subject: [PATCH 1146/2991] Remove unused using directive --- osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs index 4ad03c052f..806d231cb4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs @@ -4,7 +4,6 @@ #nullable disable using System; -using System.Linq; using System.Net; using NUnit.Framework; using osu.Game.Online.API; From 3dfbb47b010aa6351951310dc9b008ce3cd2b6cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 23 Dec 2022 16:42:24 +0100 Subject: [PATCH 1147/2991] Add test coverage for wrong error message --- osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs index 806d231cb4..b0e4303ca4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs @@ -4,8 +4,11 @@ #nullable disable using System; +using System.Linq; using System.Net; using NUnit.Framework; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Testing; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; @@ -65,7 +68,9 @@ namespace osu.Game.Tests.Visual.Online public void TestErrorPage() { setUpWikiResponse(responseArticlePage); - AddStep("Show Error Page", () => wiki.ShowPage("Error")); + AddStep("Show nonexistent page", () => wiki.ShowPage("This_page_will_error_out")); + AddUntilStep("Wait for error page", () => wiki.CurrentPath == "error"); + AddUntilStep("Error message correct", () => wiki.ChildrenOfType().Any(text => text.Text == "\"This_page_will_error_out\".")); } private void setUpWikiResponse(APIWikiPage r, string redirectionPath = null) From 9a2cc043611ab6e78feef7c18958747baa795061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 23 Dec 2022 16:42:46 +0100 Subject: [PATCH 1148/2991] Fix wrong path being used in fail handler --- osu.Game/Overlays/WikiOverlay.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/WikiOverlay.cs b/osu.Game/Overlays/WikiOverlay.cs index a9a131e481..88dc2cd7a4 100644 --- a/osu.Game/Overlays/WikiOverlay.cs +++ b/osu.Game/Overlays/WikiOverlay.cs @@ -126,7 +126,7 @@ namespace osu.Game.Overlays request.Failure += ex => { if (ex is not OperationCanceledException) - Schedule(onFail); + Schedule(onFail, request.Path); }; api.PerformAsync(request); @@ -155,11 +155,11 @@ namespace osu.Game.Overlays } } - private void onFail() + private void onFail(string originalPath) { path.Value = "error"; LoadDisplay(articlePage = new WikiArticlePage($@"{api.WebsiteRootUrl}/wiki/", - $"Something went wrong when trying to fetch page \"{path.Value}\".\n\n[Return to the main page](Main_Page).")); + $"Something went wrong when trying to fetch page \"{originalPath}\".\n\n[Return to the main page](Main_Page).")); } private void showParentPage() From 494886ef9277f4c9a626553fa08c21797eab362e Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Fri, 23 Dec 2022 11:11:15 -0800 Subject: [PATCH 1149/2991] Rename `Text` to `Metadata` --- osu.Game/Overlays/BeatmapSet/Info.cs | 8 ++++---- osu.Game/Overlays/BeatmapSet/MetadataSection.cs | 14 +++++++------- .../BeatmapSet/MetadataSectionDescription.cs | 4 ++-- .../Overlays/BeatmapSet/MetadataSectionGenre.cs | 6 +++--- .../Overlays/BeatmapSet/MetadataSectionLanguage.cs | 6 +++--- .../Overlays/BeatmapSet/MetadataSectionSource.cs | 6 +++--- .../Overlays/BeatmapSet/MetadataSectionTags.cs | 4 ++-- osu.Game/Screens/Select/BeatmapDetails.cs | 6 +++--- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 8a1384f0d3..8126db3be0 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -121,10 +121,10 @@ namespace osu.Game.Overlays.BeatmapSet BeatmapSet.ValueChanged += b => { - source.Text = b.NewValue?.Source ?? string.Empty; - tags.Text = b.NewValue?.Tags ?? string.Empty; - genre.Text = b.NewValue?.Genre ?? new BeatmapSetOnlineGenre { Id = 1 }; - language.Text = b.NewValue?.Language ?? new BeatmapSetOnlineLanguage { Id = 1 }; + source.Metadata = b.NewValue?.Source ?? string.Empty; + tags.Metadata = b.NewValue?.Tags ?? string.Empty; + genre.Metadata = b.NewValue?.Genre ?? new BeatmapSetOnlineGenre { Id = 1 }; + language.Metadata = b.NewValue?.Language ?? new BeatmapSetOnlineLanguage { Id = 1 }; bool setHasLeaderboard = b.NewValue?.Status > 0; successRate.Alpha = setHasLeaderboard ? 1 : 0; notRankedPlaceholder.Alpha = setHasLeaderboard ? 0 : 1; diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSection.cs b/osu.Game/Overlays/BeatmapSet/MetadataSection.cs index 6af77f975e..d32d8e83fb 100644 --- a/osu.Game/Overlays/BeatmapSet/MetadataSection.cs +++ b/osu.Game/Overlays/BeatmapSet/MetadataSection.cs @@ -16,7 +16,7 @@ namespace osu.Game.Overlays.BeatmapSet { public abstract partial class MetadataSection : MetadataSection { - public override string Text + public override string Metadata { set { @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.BeatmapSet return; } - base.Text = value; + base.Metadata = value; } } @@ -78,7 +78,7 @@ namespace osu.Game.Overlays.BeatmapSet }; } - public virtual T Text + public virtual T Metadata { set { @@ -90,11 +90,11 @@ namespace osu.Game.Overlays.BeatmapSet this.FadeIn(TRANSITION_DURATION); - setTextAsync(value); + setTextFlowAsync(value); } } - private void setTextAsync(T text) + private void setTextFlowAsync(T metadata) { LoadComponentAsync(new LinkFlowContainer(s => s.Font = s.Font.With(size: 14)) { @@ -105,7 +105,7 @@ namespace osu.Game.Overlays.BeatmapSet { textFlow?.Expire(); - AddMetadata(text, loaded); + AddMetadata(metadata, loaded); textContainer.Add(textFlow = loaded); @@ -114,6 +114,6 @@ namespace osu.Game.Overlays.BeatmapSet }); } - protected abstract void AddMetadata(T text, LinkFlowContainer loaded); + protected abstract void AddMetadata(T metadata, LinkFlowContainer loaded); } } diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSectionDescription.cs b/osu.Game/Overlays/BeatmapSet/MetadataSectionDescription.cs index a9503cded3..e6837951c9 100644 --- a/osu.Game/Overlays/BeatmapSet/MetadataSectionDescription.cs +++ b/osu.Game/Overlays/BeatmapSet/MetadataSectionDescription.cs @@ -13,9 +13,9 @@ namespace osu.Game.Overlays.BeatmapSet { } - protected override void AddMetadata(string text, LinkFlowContainer loaded) + protected override void AddMetadata(string metadata, LinkFlowContainer loaded) { - loaded.AddText(text); + loaded.AddText(metadata); } } } diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSectionGenre.cs b/osu.Game/Overlays/BeatmapSet/MetadataSectionGenre.cs index 0e045b2bf1..d41115f2b8 100644 --- a/osu.Game/Overlays/BeatmapSet/MetadataSectionGenre.cs +++ b/osu.Game/Overlays/BeatmapSet/MetadataSectionGenre.cs @@ -17,14 +17,14 @@ namespace osu.Game.Overlays.BeatmapSet { } - protected override void AddMetadata(BeatmapSetOnlineGenre text, LinkFlowContainer loaded) + protected override void AddMetadata(BeatmapSetOnlineGenre metadata, LinkFlowContainer loaded) { - var genre = (SearchGenre)text.Id; + var genre = (SearchGenre)metadata.Id; if (Enum.IsDefined(genre)) loaded.AddLink(genre.GetLocalisableDescription(), LinkAction.FilterBeatmapSetGenre, genre); else - loaded.AddText(text.Name); + loaded.AddText(metadata.Name); } } } diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSectionLanguage.cs b/osu.Game/Overlays/BeatmapSet/MetadataSectionLanguage.cs index 6e59818b93..e831b1eaca 100644 --- a/osu.Game/Overlays/BeatmapSet/MetadataSectionLanguage.cs +++ b/osu.Game/Overlays/BeatmapSet/MetadataSectionLanguage.cs @@ -17,14 +17,14 @@ namespace osu.Game.Overlays.BeatmapSet { } - protected override void AddMetadata(BeatmapSetOnlineLanguage text, LinkFlowContainer loaded) + protected override void AddMetadata(BeatmapSetOnlineLanguage metadata, LinkFlowContainer loaded) { - var language = (SearchLanguage)text.Id; + var language = (SearchLanguage)metadata.Id; if (Enum.IsDefined(language)) loaded.AddLink(language.GetLocalisableDescription(), LinkAction.FilterBeatmapSetLanguage, language); else - loaded.AddText(text.Name); + loaded.AddText(metadata.Name); } } } diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSectionSource.cs b/osu.Game/Overlays/BeatmapSet/MetadataSectionSource.cs index 6deb866f19..544dc0dfe4 100644 --- a/osu.Game/Overlays/BeatmapSet/MetadataSectionSource.cs +++ b/osu.Game/Overlays/BeatmapSet/MetadataSectionSource.cs @@ -14,12 +14,12 @@ namespace osu.Game.Overlays.BeatmapSet { } - protected override void AddMetadata(string text, LinkFlowContainer loaded) + protected override void AddMetadata(string metadata, LinkFlowContainer loaded) { if (SearchAction != null) - loaded.AddLink(text, () => SearchAction(text)); + loaded.AddLink(metadata, () => SearchAction(metadata)); else - loaded.AddLink(text, LinkAction.SearchBeatmapSet, text); + loaded.AddLink(metadata, LinkAction.SearchBeatmapSet, metadata); } } } diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSectionTags.cs b/osu.Game/Overlays/BeatmapSet/MetadataSectionTags.cs index 1b384fcdd3..fc16ba19d8 100644 --- a/osu.Game/Overlays/BeatmapSet/MetadataSectionTags.cs +++ b/osu.Game/Overlays/BeatmapSet/MetadataSectionTags.cs @@ -14,9 +14,9 @@ namespace osu.Game.Overlays.BeatmapSet { } - protected override void AddMetadata(string text, LinkFlowContainer loaded) + protected override void AddMetadata(string metadata, LinkFlowContainer loaded) { - string[] tags = text.Split(" "); + string[] tags = metadata.Split(" "); for (int i = 0; i <= tags.Length - 1; i++) { diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index b158bef8dc..712b610515 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -187,9 +187,9 @@ namespace osu.Game.Screens.Select private void updateStatistics() { advanced.BeatmapInfo = BeatmapInfo; - description.Text = BeatmapInfo?.DifficultyName ?? string.Empty; - source.Text = BeatmapInfo?.Metadata.Source ?? string.Empty; - tags.Text = BeatmapInfo?.Metadata.Tags ?? string.Empty; + description.Metadata = BeatmapInfo?.DifficultyName ?? string.Empty; + source.Metadata = BeatmapInfo?.Metadata.Source ?? string.Empty; + tags.Metadata = BeatmapInfo?.Metadata.Tags ?? string.Empty; // failTimes may have been previously fetched if (ratings != null && failTimes != null) From 2dbcf05fe4317713f7d0d35034deeef48ba78c83 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Fri, 23 Dec 2022 11:13:27 -0800 Subject: [PATCH 1150/2991] Use enum values as ids in fallback instead --- osu.Game/Overlays/BeatmapSet/Info.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 8126db3be0..d184f0d0fd 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -12,6 +12,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays.BeatmapListing; namespace osu.Game.Overlays.BeatmapSet { @@ -123,8 +124,8 @@ namespace osu.Game.Overlays.BeatmapSet { source.Metadata = b.NewValue?.Source ?? string.Empty; tags.Metadata = b.NewValue?.Tags ?? string.Empty; - genre.Metadata = b.NewValue?.Genre ?? new BeatmapSetOnlineGenre { Id = 1 }; - language.Metadata = b.NewValue?.Language ?? new BeatmapSetOnlineLanguage { Id = 1 }; + genre.Metadata = b.NewValue?.Genre ?? new BeatmapSetOnlineGenre { Id = (int)SearchGenre.Unspecified }; + language.Metadata = b.NewValue?.Language ?? new BeatmapSetOnlineLanguage { Id = (int)SearchLanguage.Unspecified }; bool setHasLeaderboard = b.NewValue?.Status > 0; successRate.Alpha = setHasLeaderboard ? 1 : 0; notRankedPlaceholder.Alpha = setHasLeaderboard ? 0 : 1; From 727ac00f6d5b744c6e83be66b7a6a98c7d6a984c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 24 Dec 2022 03:22:04 +0800 Subject: [PATCH 1151/2991] Combine base class for `JudgementPiece` --- .../Skinning/Argon/ArgonJudgementPiece.cs | 11 ++----- .../Skinning/Argon/ArgonJudgementPiece.cs | 11 ++----- .../Skinning/Argon/ArgonJudgementPiece.cs | 11 ++----- .../Skinning/Argon/ArgonJudgementPiece.cs | 11 ++----- .../Judgements/DefaultJudgementPiece.cs | 12 ++------ .../Rulesets/Judgements/JudgementPiece.cs | 29 +++++++++++++++++++ 6 files changed, 39 insertions(+), 46 deletions(-) create mode 100644 osu.Game/Rulesets/Judgements/JudgementPiece.cs diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonJudgementPiece.cs index 82d10e500d..5cb03f6536 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonJudgementPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonJudgementPiece.cs @@ -3,11 +3,9 @@ using System; using osu.Framework.Allocation; -using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Framework.Utils; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -18,20 +16,16 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Skinning.Argon { - public partial class ArgonJudgementPiece : CompositeDrawable, IAnimatableJudgement + public partial class ArgonJudgementPiece : JudgementPiece, IAnimatableJudgement { - protected readonly HitResult Result; - - protected SpriteText JudgementText { get; private set; } = null!; - private RingExplosion? ringExplosion; [Resolved] private OsuColour colours { get; set; } = null!; public ArgonJudgementPiece(HitResult result) + : base(result) { - Result = result; Origin = Anchor.Centre; Y = 160; } @@ -47,7 +41,6 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Text = Result.GetDescription().ToUpperInvariant(), Colour = colours.ForHitResult(Result), Blending = BlendingParameters.Additive, Spacing = new Vector2(10, 0), diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonJudgementPiece.cs index 2dbf475c7e..870a142ca7 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonJudgementPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonJudgementPiece.cs @@ -3,11 +3,9 @@ using System; using osu.Framework.Allocation; -using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Framework.Utils; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -18,20 +16,16 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Skinning.Argon { - public partial class ArgonJudgementPiece : CompositeDrawable, IAnimatableJudgement + public partial class ArgonJudgementPiece : JudgementPiece, IAnimatableJudgement { - protected readonly HitResult Result; - - protected SpriteText JudgementText { get; private set; } = null!; - private RingExplosion? ringExplosion; [Resolved] private OsuColour colours { get; set; } = null!; public ArgonJudgementPiece(HitResult result) + : base(result) { - Result = result; Origin = Anchor.Centre; Y = 160; } @@ -47,7 +41,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Text = Result.GetDescription().ToUpperInvariant(), Colour = colours.ForHitResult(Result), Blending = BlendingParameters.Additive, Spacing = new Vector2(10, 0), diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPiece.cs index f5f410210b..7b1a0d8d08 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPiece.cs @@ -3,10 +3,8 @@ using System; using osu.Framework.Allocation; -using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; using osu.Framework.Utils; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -17,20 +15,16 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Skinning.Argon { - public partial class ArgonJudgementPiece : CompositeDrawable, IAnimatableJudgement + public partial class ArgonJudgementPiece : JudgementPiece, IAnimatableJudgement { - protected readonly HitResult Result; - - protected SpriteText JudgementText { get; private set; } = null!; - private RingExplosion? ringExplosion; [Resolved] private OsuColour colours { get; set; } = null!; public ArgonJudgementPiece(HitResult result) + : base(result) { - Result = result; Origin = Anchor.Centre; } @@ -45,7 +39,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Text = Result.GetDescription().ToUpperInvariant(), Colour = colours.ForHitResult(Result), Blending = BlendingParameters.Additive, Spacing = new Vector2(5, 0), diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs index 6756001089..e8240911b0 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs @@ -3,11 +3,9 @@ using System; using osu.Framework.Allocation; -using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Framework.Utils; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -18,20 +16,16 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon { - public partial class ArgonJudgementPiece : CompositeDrawable, IAnimatableJudgement + public partial class ArgonJudgementPiece : JudgementPiece, IAnimatableJudgement { - protected readonly HitResult Result; - - protected SpriteText JudgementText { get; private set; } = null!; - private RingExplosion? ringExplosion; [Resolved] private OsuColour colours { get; set; } = null!; public ArgonJudgementPiece(HitResult result) + : base(result) { - Result = result; RelativePositionAxes = Axes.Both; RelativeSizeAxes = Axes.Both; } @@ -45,7 +39,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Text = Result.GetDescription().ToUpperInvariant(), Colour = colours.ForHitResult(Result), Blending = BlendingParameters.Additive, Spacing = new Vector2(10, 0), diff --git a/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs b/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs index 2b8bd08ede..485e2b409d 100644 --- a/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs +++ b/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs @@ -4,10 +4,7 @@ #nullable disable using osu.Framework.Allocation; -using osu.Framework.Extensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Scoring; @@ -15,18 +12,14 @@ using osuTK; namespace osu.Game.Rulesets.Judgements { - public partial class DefaultJudgementPiece : CompositeDrawable, IAnimatableJudgement + public partial class DefaultJudgementPiece : JudgementPiece, IAnimatableJudgement { - protected readonly HitResult Result; - - protected SpriteText JudgementText { get; private set; } - [Resolved] private OsuColour colours { get; set; } public DefaultJudgementPiece(HitResult result) + : base(result) { - Result = result; Origin = Anchor.Centre; } @@ -41,7 +34,6 @@ namespace osu.Game.Rulesets.Judgements { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Text = Result.GetDescription().ToUpperInvariant(), Colour = colours.ForHitResult(Result), Font = OsuFont.Numeric.With(size: 20), Scale = new Vector2(0.85f, 1), diff --git a/osu.Game/Rulesets/Judgements/JudgementPiece.cs b/osu.Game/Rulesets/Judgements/JudgementPiece.cs new file mode 100644 index 0000000000..4e9b495cb5 --- /dev/null +++ b/osu.Game/Rulesets/Judgements/JudgementPiece.cs @@ -0,0 +1,29 @@ +// 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.Extensions; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Judgements +{ + public abstract partial class JudgementPiece : CompositeDrawable + { + protected readonly HitResult Result; + + protected SpriteText JudgementText { get; set; } = null!; + + protected JudgementPiece(HitResult result) + { + Result = result; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + JudgementText.Text = Result.GetDescription().ToUpperInvariant(); + } + } +} From e8a0f8996cfbf76747647c2ab1a0573007393063 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 24 Dec 2022 03:35:27 +0800 Subject: [PATCH 1152/2991] Remove unused osu!catch `ArgonJudgementPiece` --- .../Skinning/Argon/ArgonJudgementPiece.cs | 186 ------------------ 1 file changed, 186 deletions(-) delete mode 100644 osu.Game.Rulesets.Catch/Skinning/Argon/ArgonJudgementPiece.cs diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonJudgementPiece.cs deleted file mode 100644 index 5cb03f6536..0000000000 --- a/osu.Game.Rulesets.Catch/Skinning/Argon/ArgonJudgementPiece.cs +++ /dev/null @@ -1,186 +0,0 @@ -// 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.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Utils; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Rulesets.Judgements; -using osu.Game.Rulesets.Scoring; -using osuTK; -using osuTK.Graphics; - -namespace osu.Game.Rulesets.Catch.Skinning.Argon -{ - public partial class ArgonJudgementPiece : JudgementPiece, IAnimatableJudgement - { - private RingExplosion? ringExplosion; - - [Resolved] - private OsuColour colours { get; set; } = null!; - - public ArgonJudgementPiece(HitResult result) - : base(result) - { - Origin = Anchor.Centre; - Y = 160; - } - - [BackgroundDependencyLoader] - private void load() - { - AutoSizeAxes = Axes.Both; - - InternalChildren = new Drawable[] - { - JudgementText = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Colour = colours.ForHitResult(Result), - Blending = BlendingParameters.Additive, - Spacing = new Vector2(10, 0), - Font = OsuFont.Default.With(size: 28, weight: FontWeight.Regular), - }, - }; - - if (Result.IsHit()) - { - AddInternal(ringExplosion = new RingExplosion(Result) - { - Colour = colours.ForHitResult(Result), - }); - } - } - - /// - /// Plays the default animation for this judgement piece. - /// - /// - /// The base implementation only handles fade (for all result types) and misses. - /// Individual rulesets are recommended to implement their appropriate hit animations. - /// - public virtual void PlayAnimation() - { - switch (Result) - { - default: - JudgementText - .ScaleTo(Vector2.One) - .ScaleTo(new Vector2(1.4f), 1800, Easing.OutQuint); - break; - - case HitResult.Miss: - this.ScaleTo(1.6f); - this.ScaleTo(1, 100, Easing.In); - - this.MoveTo(Vector2.Zero); - this.MoveToOffset(new Vector2(0, 100), 800, Easing.InQuint); - - this.RotateTo(0); - this.RotateTo(40, 800, Easing.InQuint); - break; - } - - this.FadeOutFromOne(800); - - ringExplosion?.PlayAnimation(); - } - - public Drawable? GetAboveHitObjectsProxiedContent() => null; - - private partial class RingExplosion : CompositeDrawable - { - private readonly float travel = 52; - - public RingExplosion(HitResult result) - { - const float thickness = 4; - - const float small_size = 9; - const float large_size = 14; - - Anchor = Anchor.Centre; - Origin = Anchor.Centre; - - Blending = BlendingParameters.Additive; - - int countSmall = 0; - int countLarge = 0; - - switch (result) - { - case HitResult.Meh: - countSmall = 3; - travel *= 0.3f; - break; - - case HitResult.Ok: - case HitResult.Good: - countSmall = 4; - travel *= 0.6f; - break; - - case HitResult.Great: - case HitResult.Perfect: - countSmall = 4; - countLarge = 4; - break; - } - - for (int i = 0; i < countSmall; i++) - AddInternal(new RingPiece(thickness) { Size = new Vector2(small_size) }); - - for (int i = 0; i < countLarge; i++) - AddInternal(new RingPiece(thickness) { Size = new Vector2(large_size) }); - } - - public void PlayAnimation() - { - foreach (var c in InternalChildren) - { - const float start_position_ratio = 0.3f; - - float direction = RNG.NextSingle(0, 360); - float distance = RNG.NextSingle(travel / 2, travel); - - c.MoveTo(new Vector2( - MathF.Cos(direction) * distance * start_position_ratio, - MathF.Sin(direction) * distance * start_position_ratio - )); - - c.MoveTo(new Vector2( - MathF.Cos(direction) * distance, - MathF.Sin(direction) * distance - ), 600, Easing.OutQuint); - } - - this.FadeOutFromOne(1000, Easing.OutQuint); - } - - public partial class RingPiece : CircularContainer - { - public RingPiece(float thickness = 9) - { - Anchor = Anchor.Centre; - Origin = Anchor.Centre; - - Masking = true; - BorderThickness = thickness; - BorderColour = Color4.White; - - Child = new Box - { - AlwaysPresent = true, - Alpha = 0, - RelativeSizeAxes = Axes.Both - }; - } - } - } - } -} From 03603f8b548bc6869dac942543db678edf9ecc7a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 24 Dec 2022 03:35:44 +0800 Subject: [PATCH 1153/2991] Don't show great or higher judgements when using argon "pro" skin --- .../Skinning/Argon/ManiaArgonSkinTransformer.cs | 4 ++++ .../Skinning/Argon/OsuArgonSkinTransformer.cs | 4 ++++ .../Skinning/Argon/TaikoArgonSkinTransformer.cs | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs index eb7f63fbe2..057b7eb0d9 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs @@ -27,6 +27,10 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon switch (lookup) { case GameplaySkinComponentLookup resultComponent: + // This should eventually be moved to a skin setting, when supported. + if (Skin is ArgonProSkin && resultComponent.Component >= HitResult.Great) + return Drawable.Empty(); + return new ArgonJudgementPiece(resultComponent.Component); case ManiaSkinComponentLookup maniaComponent: diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs index 86194d2c43..f98a47097d 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs @@ -19,6 +19,10 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon switch (lookup) { case GameplaySkinComponentLookup resultComponent: + // This should eventually be moved to a skin setting, when supported. + if (Skin is ArgonProSkin && resultComponent.Component >= HitResult.Great) + return Drawable.Empty(); + return new ArgonJudgementPiece(resultComponent.Component); case OsuSkinComponentLookup osuComponent: diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs index a5d091a1c8..780018af4e 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/TaikoArgonSkinTransformer.cs @@ -19,6 +19,10 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon switch (component) { case GameplaySkinComponentLookup resultComponent: + // This should eventually be moved to a skin setting, when supported. + if (Skin is ArgonProSkin && resultComponent.Component >= HitResult.Great) + return Drawable.Empty(); + return new ArgonJudgementPiece(resultComponent.Component); case TaikoSkinComponentLookup taikoComponent: From 3e782c5f5fd6eee9a34150aeaeb9aefbd9db97f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 23 Dec 2022 23:46:41 +0100 Subject: [PATCH 1154/2991] Extract interface for solo statistics watcher --- .../Online/Solo/ISoloStatisticsWatcher.cs | 23 +++++++++++++++++++ osu.Game/Online/Solo/SoloStatisticsWatcher.cs | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Online/Solo/ISoloStatisticsWatcher.cs diff --git a/osu.Game/Online/Solo/ISoloStatisticsWatcher.cs b/osu.Game/Online/Solo/ISoloStatisticsWatcher.cs new file mode 100644 index 0000000000..84986297bf --- /dev/null +++ b/osu.Game/Online/Solo/ISoloStatisticsWatcher.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 osu.Framework.Allocation; +using osu.Game.Scoring; + +namespace osu.Game.Online.Solo +{ + /// + /// A component that delivers updates to the logged in user's gameplay statistics after completed scores. + /// + [Cached] + public interface ISoloStatisticsWatcher + { + /// + /// Registers for a user statistics update after the given has been processed server-side. + /// + /// The score to listen for the statistics update for. + /// The callback to be invoked once the statistics update has been prepared. + void RegisterForStatisticsUpdateAfter(ScoreInfo score, Action onUpdateReady); + } +} diff --git a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs index 48f39504a3..6a9a20e58d 100644 --- a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs +++ b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs @@ -20,7 +20,7 @@ namespace osu.Game.Online.Solo /// /// A persistent component that binds to the spectator server and API in order to deliver updates about the logged in user's gameplay statistics. /// - public partial class SoloStatisticsWatcher : Component + public partial class SoloStatisticsWatcher : Component, ISoloStatisticsWatcher { [Resolved] private SpectatorClient spectatorClient { get; set; } = null!; From 498d00935bff763f0d5a7fcb5344f177e510ddb6 Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Fri, 23 Dec 2022 23:01:04 +0000 Subject: [PATCH 1155/2991] limit date appending to `LegacyScoreExporter` only --- osu.Game/Database/LegacyExporter.cs | 2 +- osu.Game/Database/LegacyScoreExporter.cs | 20 ++++++++++++++++++++ osu.Game/Scoring/ScoreInfoExtensions.cs | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 374f9f557a..02219c4dfa 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -37,7 +37,7 @@ namespace osu.Game.Database /// Exports an item to a legacy (.zip based) package. /// /// The item to export. - public void Export(TModel item) + public virtual void Export(TModel item) { string itemFilename = item.GetDisplayString().GetValidFilename(); diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index 6fa02b957d..fc80693765 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -3,11 +3,13 @@ #nullable disable +using System.Collections.Generic; using System.IO; using System.Linq; using osu.Framework.Platform; using osu.Game.Extensions; using osu.Game.Scoring; +using osu.Game.Utils; namespace osu.Game.Database { @@ -15,9 +17,27 @@ namespace osu.Game.Database { protected override string FileExtension => ".osr"; + private readonly Storage exportStorage; + public LegacyScoreExporter(Storage storage) : base(storage) { + exportStorage = storage.GetStorageForDirectory(@"exports"); + } + + private string GetScoreExportString(ScoreInfo score) => $"{score.GetDisplayString()} ({score.Date.LocalDateTime:yyyy-MM-dd})"; + + public override void Export(ScoreInfo score) + { + string scoreExportTitle = GetScoreExportString(score).GetValidFilename(); + + IEnumerable existingExports = exportStorage.GetFiles("", $"{scoreExportTitle}*{FileExtension}"); + + string scoreExportFilename = NamingUtils.GetNextBestFilename(existingExports, $"{scoreExportTitle}{FileExtension}"); + using (var stream = exportStorage.CreateFileSafely(scoreExportFilename)) + ExportModelTo(score, stream); + + exportStorage.PresentFileExternally(scoreExportFilename); } public override void ExportModelTo(ScoreInfo model, Stream outputStream) diff --git a/osu.Game/Scoring/ScoreInfoExtensions.cs b/osu.Game/Scoring/ScoreInfoExtensions.cs index 3cfdbe87c3..7979ca8aaa 100644 --- a/osu.Game/Scoring/ScoreInfoExtensions.cs +++ b/osu.Game/Scoring/ScoreInfoExtensions.cs @@ -12,6 +12,6 @@ namespace osu.Game.Scoring /// /// A user-presentable display title representing this score. /// - public static string GetDisplayTitle(this IScoreInfo scoreInfo) => $"{scoreInfo.User.Username} playing {scoreInfo.Beatmap.GetDisplayTitle()} ({scoreInfo.Date.LocalDateTime:yyyy-MM-dd})"; + public static string GetDisplayTitle(this IScoreInfo scoreInfo) => $"{scoreInfo.User.Username} playing {scoreInfo.Beatmap.GetDisplayTitle()}"; } } From c7f248e13c7ce98c093f8f41cad30d3b9d7ca621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 23 Dec 2022 14:27:22 +0100 Subject: [PATCH 1156/2991] Implement overall ranking display for solo results screen --- .../Visual/Ranking/TestSceneOverallRanking.cs | 142 +++++++++++++++++ .../Statistics/User/AccuracyChangeRow.cs | 35 +++++ .../Statistics/User/GlobalRankChangeRow.cs | 58 +++++++ .../Statistics/User/MaximumComboChangeRow.cs | 34 +++++ .../Ranking/Statistics/User/OverallRanking.cs | 90 +++++++++++ .../User/PerformancePointsChangeRow.cs | 56 +++++++ .../Statistics/User/RankedScoreChangeRow.cs | 35 +++++ .../Statistics/User/RankingChangeRow.cs | 144 ++++++++++++++++++ .../Statistics/User/TotalScoreChangeRow.cs | 35 +++++ 9 files changed, 629 insertions(+) create mode 100644 osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs create mode 100644 osu.Game/Screens/Ranking/Statistics/User/AccuracyChangeRow.cs create mode 100644 osu.Game/Screens/Ranking/Statistics/User/GlobalRankChangeRow.cs create mode 100644 osu.Game/Screens/Ranking/Statistics/User/MaximumComboChangeRow.cs create mode 100644 osu.Game/Screens/Ranking/Statistics/User/OverallRanking.cs create mode 100644 osu.Game/Screens/Ranking/Statistics/User/PerformancePointsChangeRow.cs create mode 100644 osu.Game/Screens/Ranking/Statistics/User/RankedScoreChangeRow.cs create mode 100644 osu.Game/Screens/Ranking/Statistics/User/RankingChangeRow.cs create mode 100644 osu.Game/Screens/Ranking/Statistics/User/TotalScoreChangeRow.cs diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs b/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs new file mode 100644 index 0000000000..8d2147056c --- /dev/null +++ b/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs @@ -0,0 +1,142 @@ +// 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.Diagnostics; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Online.Solo; +using osu.Game.Scoring; +using osu.Game.Users; +using OverallRanking = osu.Game.Screens.Ranking.Statistics.User.OverallRanking; + +namespace osu.Game.Tests.Visual.Ranking +{ + public partial class TestSceneOverallRanking : OsuTestScene + { + [Cached(typeof(ISoloStatisticsWatcher))] + private MockSoloStatisticsWatcher soloStatisticsWatcher { get; } = new MockSoloStatisticsWatcher(); + + [Test] + public void TestUpdatePending() + { + createDisplay(); + } + + [Test] + public void TestAllIncreased() + { + createDisplay(); + AddStep("trigger update success", () => + { + soloStatisticsWatcher.TriggerSuccess( + new UserStatistics + { + GlobalRank = 12_345, + Accuracy = 0.9899, + MaxCombo = 2_322, + RankedScore = 23_123_543_456, + TotalScore = 123_123_543_456, + PP = 5_072 + }, + new UserStatistics + { + GlobalRank = 1_234, + Accuracy = 0.9907, + MaxCombo = 2_352, + RankedScore = 23_124_231_435, + TotalScore = 123_124_231_435, + PP = 5_434 + }); + }); + } + + [Test] + public void TestAllDecreased() + { + createDisplay(); + AddStep("trigger update success", () => + { + soloStatisticsWatcher.TriggerSuccess( + new UserStatistics + { + GlobalRank = 1_234, + Accuracy = 0.9907, + MaxCombo = 2_352, + RankedScore = 23_124_231_435, + TotalScore = 123_124_231_435, + PP = 5_434 + }, + new UserStatistics + { + GlobalRank = 12_345, + Accuracy = 0.9899, + MaxCombo = 2_322, + RankedScore = 23_123_543_456, + TotalScore = 123_123_543_456, + PP = 5_072 + }); + }); + } + + [Test] + public void TestNoChanges() + { + var statistics = new UserStatistics + { + GlobalRank = 12_345, + Accuracy = 0.9899, + MaxCombo = 2_322, + RankedScore = 23_123_543_456, + TotalScore = 123_123_543_456, + PP = 5_072 + }; + + createDisplay(); + AddStep("trigger update success", () => soloStatisticsWatcher.TriggerSuccess(statistics, statistics)); + } + + [Test] + public void TestNotRanked() + { + var statistics = new UserStatistics + { + GlobalRank = null, + Accuracy = 0.9899, + MaxCombo = 2_322, + RankedScore = 23_123_543_456, + TotalScore = 123_123_543_456, + PP = null + }; + + createDisplay(); + AddStep("trigger update success", () => soloStatisticsWatcher.TriggerSuccess(statistics, statistics)); + } + + private void createDisplay() => AddStep("create display", () => Child = new OverallRanking(new ScoreInfo()) + { + Width = 400, + Anchor = Anchor.Centre, + Origin = Anchor.Centre + }); + + private class MockSoloStatisticsWatcher : ISoloStatisticsWatcher + { + private ScoreInfo? score; + private Action? onUpdateReady; + + public void RegisterForStatisticsUpdateAfter(ScoreInfo score, Action onUpdateReady) + { + this.score = score; + this.onUpdateReady = onUpdateReady; + } + + public void TriggerSuccess(UserStatistics before, UserStatistics after) + { + Debug.Assert(score != null && onUpdateReady != null); + onUpdateReady.Invoke(new SoloStatisticsUpdate(score, before, after)); + } + } + } +} diff --git a/osu.Game/Screens/Ranking/Statistics/User/AccuracyChangeRow.cs b/osu.Game/Screens/Ranking/Statistics/User/AccuracyChangeRow.cs new file mode 100644 index 0000000000..0f5dd9074a --- /dev/null +++ b/osu.Game/Screens/Ranking/Statistics/User/AccuracyChangeRow.cs @@ -0,0 +1,35 @@ +// 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.Localisation; +using osu.Game.Resources.Localisation.Web; +using osu.Game.Utils; + +namespace osu.Game.Screens.Ranking.Statistics.User +{ + public partial class AccuracyChangeRow : RankingChangeRow + { + public AccuracyChangeRow() + : base(stats => stats.Accuracy) + { + } + + protected override LocalisableString Label => UsersStrings.ShowStatsHitAccuracy; + + protected override LocalisableString FormatCurrentValue(double current) => current.FormatAccuracy(); + + protected override int CalculateDifference(double previous, double current, out LocalisableString formattedDifference) + { + double difference = current - previous; + + if (difference < 0) + formattedDifference = difference.FormatAccuracy(); + else if (difference > 0) + formattedDifference = LocalisableString.Interpolate($@"+{difference.FormatAccuracy()}"); + else + formattedDifference = string.Empty; + + return current.CompareTo(previous); + } + } +} diff --git a/osu.Game/Screens/Ranking/Statistics/User/GlobalRankChangeRow.cs b/osu.Game/Screens/Ranking/Statistics/User/GlobalRankChangeRow.cs new file mode 100644 index 0000000000..0d91d6f8f9 --- /dev/null +++ b/osu.Game/Screens/Ranking/Statistics/User/GlobalRankChangeRow.cs @@ -0,0 +1,58 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Diagnostics; +using osu.Framework.Localisation; +using osu.Game.Resources.Localisation.Web; +using osu.Game.Utils; + +namespace osu.Game.Screens.Ranking.Statistics.User +{ + public partial class GlobalRankChangeRow : RankingChangeRow + { + public GlobalRankChangeRow() + : base(stats => stats.GlobalRank) + { + } + + protected override LocalisableString Label => UsersStrings.ShowRankGlobalSimple; + + protected override LocalisableString FormatCurrentValue(int? current) + => current == null ? string.Empty : current.Value.FormatRank(); + + protected override int CalculateDifference(int? previous, int? current, out LocalisableString formattedDifference) + { + if (previous == null && current == null) + { + formattedDifference = string.Empty; + return 0; + } + + if (previous == null && current != null) + { + formattedDifference = LocalisableString.Interpolate($"+{current.Value.FormatRank()}"); + return 1; + } + + if (previous != null && current == null) + { + formattedDifference = LocalisableString.Interpolate($"-{previous.Value.FormatRank()}"); + return -1; + } + + Debug.Assert(previous != null && current != null); + + // note that ranks work backwards, i.e. lower rank is _better_. + int difference = previous.Value - current.Value; + + if (difference < 0) + formattedDifference = difference.FormatRank(); + else if (difference > 0) + formattedDifference = LocalisableString.Interpolate($"+{difference.FormatRank()}"); + else + formattedDifference = string.Empty; + + return difference; + } + } +} diff --git a/osu.Game/Screens/Ranking/Statistics/User/MaximumComboChangeRow.cs b/osu.Game/Screens/Ranking/Statistics/User/MaximumComboChangeRow.cs new file mode 100644 index 0000000000..37e3cec52f --- /dev/null +++ b/osu.Game/Screens/Ranking/Statistics/User/MaximumComboChangeRow.cs @@ -0,0 +1,34 @@ +// 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.Localisation; +using osu.Game.Resources.Localisation.Web; + +namespace osu.Game.Screens.Ranking.Statistics.User +{ + public partial class MaximumComboChangeRow : RankingChangeRow + { + public MaximumComboChangeRow() + : base(stats => stats.MaxCombo) + { + } + + protected override LocalisableString Label => UsersStrings.ShowStatsMaximumCombo; + + protected override LocalisableString FormatCurrentValue(int current) => LocalisableString.Interpolate($@"{current:N0}x"); + + protected override int CalculateDifference(int previous, int current, out LocalisableString formattedDifference) + { + int difference = current - previous; + + if (difference < 0) + formattedDifference = LocalisableString.Interpolate($@"{difference:N0}x"); + else if (difference > 0) + formattedDifference = LocalisableString.Interpolate($@"+{difference:N0}x"); + else + formattedDifference = string.Empty; + + return current.CompareTo(previous); + } + } +} diff --git a/osu.Game/Screens/Ranking/Statistics/User/OverallRanking.cs b/osu.Game/Screens/Ranking/Statistics/User/OverallRanking.cs new file mode 100644 index 0000000000..499deb92be --- /dev/null +++ b/osu.Game/Screens/Ranking/Statistics/User/OverallRanking.cs @@ -0,0 +1,90 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.Solo; +using osu.Game.Scoring; +using osuTK; + +namespace osu.Game.Screens.Ranking.Statistics.User +{ + public partial class OverallRanking : CompositeDrawable + { + private const float transition_duration = 300; + + private readonly ScoreInfo score; + + private readonly Bindable statisticsUpdate = new Bindable(); + + private LoadingLayer loadingLayer = null!; + private FillFlowContainer content = null!; + + [Resolved] + private ISoloStatisticsWatcher statisticsWatcher { get; set; } = null!; + + public OverallRanking(ScoreInfo score) + { + this.score = score; + } + + [BackgroundDependencyLoader] + private void load() + { + AutoSizeAxes = Axes.Y; + AutoSizeEasing = Easing.OutQuint; + AutoSizeDuration = transition_duration; + + InternalChildren = new Drawable[] + { + loadingLayer = new LoadingLayer(withBox: false) + { + RelativeSizeAxes = Axes.Both, + }, + content = new FillFlowContainer + { + AlwaysPresent = true, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(10), + Children = new Drawable[] + { + new GlobalRankChangeRow { StatisticsUpdate = { BindTarget = statisticsUpdate } }, + new AccuracyChangeRow { StatisticsUpdate = { BindTarget = statisticsUpdate } }, + new MaximumComboChangeRow { StatisticsUpdate = { BindTarget = statisticsUpdate } }, + new RankedScoreChangeRow { StatisticsUpdate = { BindTarget = statisticsUpdate } }, + new TotalScoreChangeRow { StatisticsUpdate = { BindTarget = statisticsUpdate } }, + new PerformancePointsChangeRow { StatisticsUpdate = { BindTarget = statisticsUpdate } } + } + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + statisticsWatcher.RegisterForStatisticsUpdateAfter(score, update => statisticsUpdate.Value = update); + statisticsUpdate.BindValueChanged(onUpdateReceived, true); + FinishTransforms(true); + } + + private void onUpdateReceived(ValueChangedEvent update) + { + if (update.NewValue == null) + { + loadingLayer.Show(); + content.FadeOut(transition_duration, Easing.OutQuint); + } + else + { + loadingLayer.Hide(); + content.FadeIn(transition_duration, Easing.OutQuint); + } + } + } +} diff --git a/osu.Game/Screens/Ranking/Statistics/User/PerformancePointsChangeRow.cs b/osu.Game/Screens/Ranking/Statistics/User/PerformancePointsChangeRow.cs new file mode 100644 index 0000000000..c1faf1a3e3 --- /dev/null +++ b/osu.Game/Screens/Ranking/Statistics/User/PerformancePointsChangeRow.cs @@ -0,0 +1,56 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Diagnostics; +using osu.Framework.Localisation; +using osu.Game.Resources.Localisation.Web; + +namespace osu.Game.Screens.Ranking.Statistics.User +{ + public partial class PerformancePointsChangeRow : RankingChangeRow + { + public PerformancePointsChangeRow() + : base(stats => stats.PP) + { + } + + protected override LocalisableString Label => RankingsStrings.StatPerformance; + + protected override LocalisableString FormatCurrentValue(decimal? current) + => current == null ? string.Empty : LocalisableString.Interpolate($@"{current:N0}pp"); + + protected override int CalculateDifference(decimal? previous, decimal? current, out LocalisableString formattedDifference) + { + if (previous == null && current == null) + { + formattedDifference = string.Empty; + return 0; + } + + if (previous == null && current != null) + { + formattedDifference = LocalisableString.Interpolate($"+{current.Value:N0}pp"); + return 1; + } + + if (previous != null && current == null) + { + formattedDifference = LocalisableString.Interpolate($"-{previous.Value:N0}pp"); + return -1; + } + + Debug.Assert(previous != null && current != null); + + decimal difference = current.Value - previous.Value; + + if (difference < 0) + formattedDifference = LocalisableString.Interpolate($@"{difference:N0}pp"); + else if (difference > 0) + formattedDifference = LocalisableString.Interpolate($@"+{difference:N0}pp"); + else + formattedDifference = string.Empty; + + return current.Value.CompareTo(previous.Value); + } + } +} diff --git a/osu.Game/Screens/Ranking/Statistics/User/RankedScoreChangeRow.cs b/osu.Game/Screens/Ranking/Statistics/User/RankedScoreChangeRow.cs new file mode 100644 index 0000000000..1cdf22bd75 --- /dev/null +++ b/osu.Game/Screens/Ranking/Statistics/User/RankedScoreChangeRow.cs @@ -0,0 +1,35 @@ +// 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.Extensions.LocalisationExtensions; +using osu.Framework.Localisation; +using osu.Game.Resources.Localisation.Web; + +namespace osu.Game.Screens.Ranking.Statistics.User +{ + public partial class RankedScoreChangeRow : RankingChangeRow + { + public RankedScoreChangeRow() + : base(stats => stats.RankedScore) + { + } + + protected override LocalisableString Label => UsersStrings.ShowStatsRankedScore; + + protected override LocalisableString FormatCurrentValue(long current) => current.ToLocalisableString(@"N0"); + + protected override int CalculateDifference(long previous, long current, out LocalisableString formattedDifference) + { + long difference = current - previous; + + if (difference < 0) + formattedDifference = difference.ToLocalisableString(@"N0"); + else if (difference > 0) + formattedDifference = LocalisableString.Interpolate($@"+{difference:N0}"); + else + formattedDifference = string.Empty; + + return current.CompareTo(previous); + } + } +} diff --git a/osu.Game/Screens/Ranking/Statistics/User/RankingChangeRow.cs b/osu.Game/Screens/Ranking/Statistics/User/RankingChangeRow.cs new file mode 100644 index 0000000000..5348b4a522 --- /dev/null +++ b/osu.Game/Screens/Ranking/Statistics/User/RankingChangeRow.cs @@ -0,0 +1,144 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Online.Solo; +using osu.Game.Users; +using osuTK; + +namespace osu.Game.Screens.Ranking.Statistics.User +{ + public abstract partial class RankingChangeRow : CompositeDrawable + { + public Bindable StatisticsUpdate { get; } = new Bindable(); + + private readonly Func accessor; + + private OsuSpriteText currentValueText = null!; + private SpriteIcon changeIcon = null!; + private OsuSpriteText changeText = null!; + + [Resolved] + private OsuColour colours { get; set; } = null!; + + protected RankingChangeRow( + Func accessor) + { + this.accessor = accessor; + } + + [BackgroundDependencyLoader] + private void load() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + InternalChildren = new Drawable[] + { + new OsuSpriteText + { + Text = Label, + Font = OsuFont.Default.With(size: 18) + }, + new FillFlowContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Direction = FillDirection.Vertical, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + new FillFlowContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + Spacing = new Vector2(5), + Children = new Drawable[] + { + changeIcon = new SpriteIcon + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Size = new Vector2(18) + }, + currentValueText = new OsuSpriteText + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Font = OsuFont.Default.With(size: 18, weight: FontWeight.Bold) + }, + } + }, + changeText = new OsuSpriteText + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Font = OsuFont.Default.With(weight: FontWeight.Bold) + } + } + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + StatisticsUpdate.BindValueChanged(onStatisticsUpdate, true); + } + + private void onStatisticsUpdate(ValueChangedEvent statisticsUpdate) + { + var update = statisticsUpdate.NewValue; + + if (update == null) + return; + + T previousValue = accessor.Invoke(update.Before); + T currentValue = accessor.Invoke(update.After); + int comparisonResult = CalculateDifference(previousValue, currentValue, out var formattedDifference); + + Colour4 comparisonColour; + IconUsage icon; + + if (comparisonResult < 0) + { + comparisonColour = colours.Red1; + icon = FontAwesome.Solid.ArrowDown; + } + else if (comparisonResult > 0) + { + comparisonColour = colours.Lime1; + icon = FontAwesome.Solid.ArrowUp; + } + else + { + comparisonColour = colours.Orange1; + icon = FontAwesome.Solid.Minus; + } + + currentValueText.Text = FormatCurrentValue(currentValue); + + changeIcon.Icon = icon; + changeIcon.Colour = comparisonColour; + + changeText.Text = formattedDifference; + changeText.Colour = comparisonColour; + } + + protected abstract LocalisableString Label { get; } + + protected abstract LocalisableString FormatCurrentValue(T current); + protected abstract int CalculateDifference(T previous, T current, out LocalisableString formattedDifference); + } +} diff --git a/osu.Game/Screens/Ranking/Statistics/User/TotalScoreChangeRow.cs b/osu.Game/Screens/Ranking/Statistics/User/TotalScoreChangeRow.cs new file mode 100644 index 0000000000..346de18e14 --- /dev/null +++ b/osu.Game/Screens/Ranking/Statistics/User/TotalScoreChangeRow.cs @@ -0,0 +1,35 @@ +// 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.Extensions.LocalisationExtensions; +using osu.Framework.Localisation; +using osu.Game.Resources.Localisation.Web; + +namespace osu.Game.Screens.Ranking.Statistics.User +{ + public partial class TotalScoreChangeRow : RankingChangeRow + { + public TotalScoreChangeRow() + : base(stats => stats.TotalScore) + { + } + + protected override LocalisableString Label => UsersStrings.ShowStatsTotalScore; + + protected override LocalisableString FormatCurrentValue(long current) => current.ToLocalisableString(@"N0"); + + protected override int CalculateDifference(long previous, long current, out LocalisableString formattedDifference) + { + long difference = current - previous; + + if (difference < 0) + formattedDifference = difference.ToLocalisableString(@"N0"); + else if (difference > 0) + formattedDifference = LocalisableString.Interpolate($@"+{difference:N0}"); + else + formattedDifference = string.Empty; + + return current.CompareTo(previous); + } + } +} From 5e9fb1063a9ad5c4775205497cd5a4904f01c699 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 24 Dec 2022 12:22:36 +0800 Subject: [PATCH 1157/2991] Move judgement text creation to base class and tidy things up --- .../Skinning/Argon/ArgonJudgementPiece.cs | 28 ++++++++--------- .../Skinning/Argon/ArgonJudgementPiece.cs | 28 ++++++++--------- .../Skinning/Argon/ArgonJudgementPiece.cs | 26 ++++++++-------- .../Judgements/DefaultJudgementPiece.cs | 30 +++++++------------ .../Rulesets/Judgements/JudgementPiece.cs | 15 ++++++++-- 5 files changed, 61 insertions(+), 66 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonJudgementPiece.cs index 870a142ca7..4ce3c50f7c 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonJudgementPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonJudgementPiece.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; using osu.Framework.Utils; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -26,6 +27,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon public ArgonJudgementPiece(HitResult result) : base(result) { + AutoSizeAxes = Axes.Both; + Origin = Anchor.Centre; Y = 160; } @@ -33,21 +36,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon [BackgroundDependencyLoader] private void load() { - AutoSizeAxes = Axes.Both; - - InternalChildren = new Drawable[] - { - JudgementText = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Colour = colours.ForHitResult(Result), - Blending = BlendingParameters.Additive, - Spacing = new Vector2(10, 0), - Font = OsuFont.Default.With(size: 28, weight: FontWeight.Regular), - }, - }; - if (Result.IsHit()) { AddInternal(ringExplosion = new RingExplosion(Result) @@ -57,6 +45,16 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon } } + protected override SpriteText CreateJudgementText() => + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Blending = BlendingParameters.Additive, + Spacing = new Vector2(10, 0), + Font = OsuFont.Default.With(size: 28, weight: FontWeight.Regular), + }; + /// /// Plays the default animation for this judgement piece. /// diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPiece.cs index 7b1a0d8d08..6f55d93eff 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPiece.cs @@ -5,6 +5,7 @@ using System; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Framework.Utils; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -25,27 +26,14 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon public ArgonJudgementPiece(HitResult result) : base(result) { + AutoSizeAxes = Axes.Both; + Origin = Anchor.Centre; } [BackgroundDependencyLoader] private void load() { - AutoSizeAxes = Axes.Both; - - InternalChildren = new Drawable[] - { - JudgementText = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Colour = colours.ForHitResult(Result), - Blending = BlendingParameters.Additive, - Spacing = new Vector2(5, 0), - Font = OsuFont.Default.With(size: 20, weight: FontWeight.Bold), - }, - }; - if (Result.IsHit()) { AddInternal(ringExplosion = new RingExplosion(Result) @@ -55,6 +43,16 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon } } + protected override SpriteText CreateJudgementText() => + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Blending = BlendingParameters.Additive, + Spacing = new Vector2(5, 0), + Font = OsuFont.Default.With(size: 20, weight: FontWeight.Bold), + }; + /// /// Plays the default animation for this judgement piece. /// diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs index e8240911b0..bbd62ff85b 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; using osu.Framework.Utils; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -33,20 +34,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon [BackgroundDependencyLoader] private void load() { - InternalChildren = new Drawable[] - { - JudgementText = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Colour = colours.ForHitResult(Result), - Blending = BlendingParameters.Additive, - Spacing = new Vector2(10, 0), - RelativePositionAxes = Axes.Both, - Font = OsuFont.Default.With(size: 20, weight: FontWeight.Regular), - }, - }; - if (Result.IsHit()) { AddInternal(ringExplosion = new RingExplosion(Result) @@ -57,6 +44,17 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon } } + protected override SpriteText CreateJudgementText() => + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Blending = BlendingParameters.Additive, + Spacing = new Vector2(10, 0), + RelativePositionAxes = Axes.Both, + Font = OsuFont.Default.With(size: 20, weight: FontWeight.Regular), + }; + /// /// Plays the default animation for this judgement piece. /// diff --git a/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs b/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs index 485e2b409d..6551752826 100644 --- a/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs +++ b/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs @@ -1,10 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Scoring; @@ -15,31 +14,24 @@ namespace osu.Game.Rulesets.Judgements public partial class DefaultJudgementPiece : JudgementPiece, IAnimatableJudgement { [Resolved] - private OsuColour colours { get; set; } + private OsuColour colours { get; set; } = null!; public DefaultJudgementPiece(HitResult result) : base(result) { + AutoSizeAxes = Axes.Both; + Origin = Anchor.Centre; } - [BackgroundDependencyLoader] - private void load() - { - AutoSizeAxes = Axes.Both; - - InternalChildren = new Drawable[] + protected override SpriteText CreateJudgementText() => + new OsuSpriteText { - JudgementText = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Colour = colours.ForHitResult(Result), - Font = OsuFont.Numeric.With(size: 20), - Scale = new Vector2(0.85f, 1), - } + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.Numeric.With(size: 20), + Scale = new Vector2(0.85f, 1), }; - } /// /// Plays the default animation for this judgement piece. @@ -67,6 +59,6 @@ namespace osu.Game.Rulesets.Judgements this.FadeOutFromOne(800); } - public Drawable GetAboveHitObjectsProxiedContent() => null; + public Drawable? GetAboveHitObjectsProxiedContent() => null; } } diff --git a/osu.Game/Rulesets/Judgements/JudgementPiece.cs b/osu.Game/Rulesets/Judgements/JudgementPiece.cs index 4e9b495cb5..9c31c6aa34 100644 --- a/osu.Game/Rulesets/Judgements/JudgementPiece.cs +++ b/osu.Game/Rulesets/Judgements/JudgementPiece.cs @@ -1,9 +1,11 @@ // 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.Allocation; using osu.Framework.Extensions; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Judgements @@ -12,18 +14,25 @@ namespace osu.Game.Rulesets.Judgements { protected readonly HitResult Result; - protected SpriteText JudgementText { get; set; } = null!; + protected SpriteText JudgementText { get; private set; } = null!; + + [Resolved] + private OsuColour colours { get; set; } = null!; protected JudgementPiece(HitResult result) { Result = result; } - protected override void LoadComplete() + [BackgroundDependencyLoader] + private void load() { - base.LoadComplete(); + JudgementText = CreateJudgementText(); + JudgementText.Colour = colours.ForHitResult(Result); JudgementText.Text = Result.GetDescription().ToUpperInvariant(); } + + protected abstract SpriteText CreateJudgementText(); } } From 91bde14fb345c034589738e8361fd5ad39df991a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 24 Dec 2022 15:42:22 +0800 Subject: [PATCH 1158/2991] Add button to settings to show lazer upgrade guide --- .../Settings/Sections/GeneralSection.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs index c62d44fd30..2ca932f2ac 100644 --- a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs +++ b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs @@ -1,12 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; +using osu.Game.Graphics; using osu.Game.Localisation; using osu.Game.Overlays.Settings.Sections.General; @@ -15,7 +14,10 @@ namespace osu.Game.Overlays.Settings.Sections public partial class GeneralSection : SettingsSection { [Resolved(CanBeNull = true)] - private FirstRunSetupOverlay firstRunSetupOverlay { get; set; } + private FirstRunSetupOverlay? firstRunSetupOverlay { get; set; } + + [Resolved(CanBeNull = true)] + private OsuGame? game { get; set; } public override LocalisableString Header => GeneralSettingsStrings.GeneralSectionHeader; @@ -24,15 +26,24 @@ namespace osu.Game.Overlays.Settings.Sections Icon = FontAwesome.Solid.Cog }; - public GeneralSection() + [BackgroundDependencyLoader] + private void load(OsuColour colours) { Children = new Drawable[] { new SettingsButton { Text = GeneralSettingsStrings.RunSetupWizard, + TooltipText = FirstRunSetupOverlayStrings.FirstRunSetupDescription, Action = () => firstRunSetupOverlay?.Show(), }, + new SettingsButton + { + Text = "Learn more about lazer", + TooltipText = "Check out the feature comparison and FAQ", + BackgroundColour = colours.YellowDark, + Action = () => game?.ShowWiki(@"Help_centre/Upgrading_to_lazer") + }, new LanguageSettings(), new UpdateSettings(), }; From f973befcd4f0f24701917117b5a9fe41d345b7fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 24 Dec 2022 09:34:30 +0100 Subject: [PATCH 1159/2991] Remove unused resolved member --- osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs b/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs index 6551752826..d5f586dc35 100644 --- a/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs +++ b/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.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 osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; @@ -13,9 +12,6 @@ namespace osu.Game.Rulesets.Judgements { public partial class DefaultJudgementPiece : JudgementPiece, IAnimatableJudgement { - [Resolved] - private OsuColour colours { get; set; } = null!; - public DefaultJudgementPiece(HitResult result) : base(result) { From 80de5dac66776d9da6348ff60421bb1e0c66a49f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 24 Dec 2022 09:37:40 +0100 Subject: [PATCH 1160/2991] Fix judgement text never being added to hierarchy --- osu.Game/Rulesets/Judgements/JudgementPiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Judgements/JudgementPiece.cs b/osu.Game/Rulesets/Judgements/JudgementPiece.cs index 9c31c6aa34..03f211c318 100644 --- a/osu.Game/Rulesets/Judgements/JudgementPiece.cs +++ b/osu.Game/Rulesets/Judgements/JudgementPiece.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Judgements [BackgroundDependencyLoader] private void load() { - JudgementText = CreateJudgementText(); + AddInternal(JudgementText = CreateJudgementText()); JudgementText.Colour = colours.ForHitResult(Result); JudgementText.Text = Result.GetDescription().ToUpperInvariant(); From 4e5109a6495668f118e7466c5d1ec8cc2b8c435b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 24 Dec 2022 10:27:28 +0100 Subject: [PATCH 1161/2991] Use plain bindable flow instead of binding to watcher directly --- .../Visual/Ranking/TestSceneOverallRanking.cs | 113 +++++++----------- .../Online/Solo/ISoloStatisticsWatcher.cs | 23 ---- osu.Game/Online/Solo/SoloStatisticsWatcher.cs | 2 +- .../Ranking/Statistics/User/OverallRanking.cs | 20 ++-- 4 files changed, 53 insertions(+), 105 deletions(-) delete mode 100644 osu.Game/Online/Solo/ISoloStatisticsWatcher.cs diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs b/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs index 8d2147056c..11bb61affb 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs @@ -1,10 +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 System.Diagnostics; using NUnit.Framework; -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Online.Solo; using osu.Game.Scoring; @@ -15,8 +12,7 @@ namespace osu.Game.Tests.Visual.Ranking { public partial class TestSceneOverallRanking : OsuTestScene { - [Cached(typeof(ISoloStatisticsWatcher))] - private MockSoloStatisticsWatcher soloStatisticsWatcher { get; } = new MockSoloStatisticsWatcher(); + private OverallRanking overallRanking = null!; [Test] public void TestUpdatePending() @@ -28,56 +24,50 @@ namespace osu.Game.Tests.Visual.Ranking public void TestAllIncreased() { createDisplay(); - AddStep("trigger update success", () => - { - soloStatisticsWatcher.TriggerSuccess( - new UserStatistics - { - GlobalRank = 12_345, - Accuracy = 0.9899, - MaxCombo = 2_322, - RankedScore = 23_123_543_456, - TotalScore = 123_123_543_456, - PP = 5_072 - }, - new UserStatistics - { - GlobalRank = 1_234, - Accuracy = 0.9907, - MaxCombo = 2_352, - RankedScore = 23_124_231_435, - TotalScore = 123_124_231_435, - PP = 5_434 - }); - }); + displayUpdate( + new UserStatistics + { + GlobalRank = 12_345, + Accuracy = 0.9899, + MaxCombo = 2_322, + RankedScore = 23_123_543_456, + TotalScore = 123_123_543_456, + PP = 5_072 + }, + new UserStatistics + { + GlobalRank = 1_234, + Accuracy = 0.9907, + MaxCombo = 2_352, + RankedScore = 23_124_231_435, + TotalScore = 123_124_231_435, + PP = 5_434 + }); } [Test] public void TestAllDecreased() { createDisplay(); - AddStep("trigger update success", () => - { - soloStatisticsWatcher.TriggerSuccess( - new UserStatistics - { - GlobalRank = 1_234, - Accuracy = 0.9907, - MaxCombo = 2_352, - RankedScore = 23_124_231_435, - TotalScore = 123_124_231_435, - PP = 5_434 - }, - new UserStatistics - { - GlobalRank = 12_345, - Accuracy = 0.9899, - MaxCombo = 2_322, - RankedScore = 23_123_543_456, - TotalScore = 123_123_543_456, - PP = 5_072 - }); - }); + displayUpdate( + new UserStatistics + { + GlobalRank = 1_234, + Accuracy = 0.9907, + MaxCombo = 2_352, + RankedScore = 23_124_231_435, + TotalScore = 123_124_231_435, + PP = 5_434 + }, + new UserStatistics + { + GlobalRank = 12_345, + Accuracy = 0.9899, + MaxCombo = 2_322, + RankedScore = 23_123_543_456, + TotalScore = 123_123_543_456, + PP = 5_072 + }); } [Test] @@ -94,7 +84,7 @@ namespace osu.Game.Tests.Visual.Ranking }; createDisplay(); - AddStep("trigger update success", () => soloStatisticsWatcher.TriggerSuccess(statistics, statistics)); + displayUpdate(statistics, statistics); } [Test] @@ -111,32 +101,17 @@ namespace osu.Game.Tests.Visual.Ranking }; createDisplay(); - AddStep("trigger update success", () => soloStatisticsWatcher.TriggerSuccess(statistics, statistics)); + displayUpdate(statistics, statistics); } - private void createDisplay() => AddStep("create display", () => Child = new OverallRanking(new ScoreInfo()) + private void createDisplay() => AddStep("create display", () => Child = overallRanking = new OverallRanking(new ScoreInfo()) { Width = 400, Anchor = Anchor.Centre, Origin = Anchor.Centre }); - private class MockSoloStatisticsWatcher : ISoloStatisticsWatcher - { - private ScoreInfo? score; - private Action? onUpdateReady; - - public void RegisterForStatisticsUpdateAfter(ScoreInfo score, Action onUpdateReady) - { - this.score = score; - this.onUpdateReady = onUpdateReady; - } - - public void TriggerSuccess(UserStatistics before, UserStatistics after) - { - Debug.Assert(score != null && onUpdateReady != null); - onUpdateReady.Invoke(new SoloStatisticsUpdate(score, before, after)); - } - } + private void displayUpdate(UserStatistics before, UserStatistics after) => + AddStep("display update", () => overallRanking.StatisticsUpdate.Value = new SoloStatisticsUpdate(new ScoreInfo(), before, after)); } } diff --git a/osu.Game/Online/Solo/ISoloStatisticsWatcher.cs b/osu.Game/Online/Solo/ISoloStatisticsWatcher.cs deleted file mode 100644 index 84986297bf..0000000000 --- a/osu.Game/Online/Solo/ISoloStatisticsWatcher.cs +++ /dev/null @@ -1,23 +0,0 @@ -// 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.Allocation; -using osu.Game.Scoring; - -namespace osu.Game.Online.Solo -{ - /// - /// A component that delivers updates to the logged in user's gameplay statistics after completed scores. - /// - [Cached] - public interface ISoloStatisticsWatcher - { - /// - /// Registers for a user statistics update after the given has been processed server-side. - /// - /// The score to listen for the statistics update for. - /// The callback to be invoked once the statistics update has been prepared. - void RegisterForStatisticsUpdateAfter(ScoreInfo score, Action onUpdateReady); - } -} diff --git a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs index 6a9a20e58d..48f39504a3 100644 --- a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs +++ b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs @@ -20,7 +20,7 @@ namespace osu.Game.Online.Solo /// /// A persistent component that binds to the spectator server and API in order to deliver updates about the logged in user's gameplay statistics. /// - public partial class SoloStatisticsWatcher : Component, ISoloStatisticsWatcher + public partial class SoloStatisticsWatcher : Component { [Resolved] private SpectatorClient spectatorClient { get; set; } = null!; diff --git a/osu.Game/Screens/Ranking/Statistics/User/OverallRanking.cs b/osu.Game/Screens/Ranking/Statistics/User/OverallRanking.cs index 499deb92be..8f922f8015 100644 --- a/osu.Game/Screens/Ranking/Statistics/User/OverallRanking.cs +++ b/osu.Game/Screens/Ranking/Statistics/User/OverallRanking.cs @@ -18,14 +18,11 @@ namespace osu.Game.Screens.Ranking.Statistics.User private readonly ScoreInfo score; - private readonly Bindable statisticsUpdate = new Bindable(); + public Bindable StatisticsUpdate { get; } = new Bindable(); private LoadingLayer loadingLayer = null!; private FillFlowContainer content = null!; - [Resolved] - private ISoloStatisticsWatcher statisticsWatcher { get; set; } = null!; - public OverallRanking(ScoreInfo score) { this.score = score; @@ -53,12 +50,12 @@ namespace osu.Game.Screens.Ranking.Statistics.User Spacing = new Vector2(10), Children = new Drawable[] { - new GlobalRankChangeRow { StatisticsUpdate = { BindTarget = statisticsUpdate } }, - new AccuracyChangeRow { StatisticsUpdate = { BindTarget = statisticsUpdate } }, - new MaximumComboChangeRow { StatisticsUpdate = { BindTarget = statisticsUpdate } }, - new RankedScoreChangeRow { StatisticsUpdate = { BindTarget = statisticsUpdate } }, - new TotalScoreChangeRow { StatisticsUpdate = { BindTarget = statisticsUpdate } }, - new PerformancePointsChangeRow { StatisticsUpdate = { BindTarget = statisticsUpdate } } + new GlobalRankChangeRow { StatisticsUpdate = { BindTarget = StatisticsUpdate } }, + new AccuracyChangeRow { StatisticsUpdate = { BindTarget = StatisticsUpdate } }, + new MaximumComboChangeRow { StatisticsUpdate = { BindTarget = StatisticsUpdate } }, + new RankedScoreChangeRow { StatisticsUpdate = { BindTarget = StatisticsUpdate } }, + new TotalScoreChangeRow { StatisticsUpdate = { BindTarget = StatisticsUpdate } }, + new PerformancePointsChangeRow { StatisticsUpdate = { BindTarget = StatisticsUpdate } } } } }; @@ -68,8 +65,7 @@ namespace osu.Game.Screens.Ranking.Statistics.User { base.LoadComplete(); - statisticsWatcher.RegisterForStatisticsUpdateAfter(score, update => statisticsUpdate.Value = update); - statisticsUpdate.BindValueChanged(onUpdateReceived, true); + StatisticsUpdate.BindValueChanged(onUpdateReceived, true); FinishTransforms(true); } From 2c060ac8d44bbf0857e3177cbfd9ab4babf332fb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 24 Dec 2022 17:32:04 +0800 Subject: [PATCH 1162/2991] Add localisation support for new button's strings --- osu.Game/Localisation/GeneralSettingsStrings.cs | 10 ++++++++++ osu.Game/Overlays/Settings/Sections/GeneralSection.cs | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game/Localisation/GeneralSettingsStrings.cs b/osu.Game/Localisation/GeneralSettingsStrings.cs index 3278b20983..a525af508b 100644 --- a/osu.Game/Localisation/GeneralSettingsStrings.cs +++ b/osu.Game/Localisation/GeneralSettingsStrings.cs @@ -64,6 +64,16 @@ namespace osu.Game.Localisation /// public static LocalisableString RunSetupWizard => new TranslatableString(getKey(@"run_setup_wizard"), @"Run setup wizard"); + /// + /// "Learn more about lazer" + /// + public static LocalisableString LearnMoreAboutLazer => new TranslatableString(getKey(@"learn_more_about_lazer"), @"Learn more about lazer"); + + /// + /// "Check out the feature comparison and FAQ" + /// + public static LocalisableString LearnMoreAboutLazerTooltip => new TranslatableString(getKey(@"check_out_the_feature_comparison"), @"Check out the feature comparison and FAQ"); + /// /// "You are running the latest release ({0})" /// diff --git a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs index 2ca932f2ac..84c1f3cfb6 100644 --- a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs +++ b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs @@ -39,8 +39,8 @@ namespace osu.Game.Overlays.Settings.Sections }, new SettingsButton { - Text = "Learn more about lazer", - TooltipText = "Check out the feature comparison and FAQ", + Text = GeneralSectionStrings.LearnMoreAboutLazer, + TooltipText = GeneralSectionStrings.CheckOutTheFeatureComparison, BackgroundColour = colours.YellowDark, Action = () => game?.ShowWiki(@"Help_centre/Upgrading_to_lazer") }, From 301eb71e22dc81e88d0537ac1299ce224648f81c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 24 Dec 2022 10:39:05 +0100 Subject: [PATCH 1163/2991] Fix wrong member names --- osu.Game/Overlays/Settings/Sections/GeneralSection.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs index 84c1f3cfb6..d4fd78f0c8 100644 --- a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs +++ b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs @@ -39,8 +39,8 @@ namespace osu.Game.Overlays.Settings.Sections }, new SettingsButton { - Text = GeneralSectionStrings.LearnMoreAboutLazer, - TooltipText = GeneralSectionStrings.CheckOutTheFeatureComparison, + Text = GeneralSettingsStrings.LearnMoreAboutLazer, + TooltipText = GeneralSettingsStrings.LearnMoreAboutLazerTooltip, BackgroundColour = colours.YellowDark, Action = () => game?.ShowWiki(@"Help_centre/Upgrading_to_lazer") }, From 83a50816b6b1b2b922d34a8d59553a205312571c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 24 Dec 2022 10:44:38 +0100 Subject: [PATCH 1164/2991] Remove unused constructor param --- osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs | 2 +- .../Screens/Ranking/Statistics/User/OverallRanking.cs | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs b/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs index 11bb61affb..c2d7b33079 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs @@ -104,7 +104,7 @@ namespace osu.Game.Tests.Visual.Ranking displayUpdate(statistics, statistics); } - private void createDisplay() => AddStep("create display", () => Child = overallRanking = new OverallRanking(new ScoreInfo()) + private void createDisplay() => AddStep("create display", () => Child = overallRanking = new OverallRanking { Width = 400, Anchor = Anchor.Centre, diff --git a/osu.Game/Screens/Ranking/Statistics/User/OverallRanking.cs b/osu.Game/Screens/Ranking/Statistics/User/OverallRanking.cs index 8f922f8015..447f206128 100644 --- a/osu.Game/Screens/Ranking/Statistics/User/OverallRanking.cs +++ b/osu.Game/Screens/Ranking/Statistics/User/OverallRanking.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Solo; -using osu.Game.Scoring; using osuTK; namespace osu.Game.Screens.Ranking.Statistics.User @@ -16,18 +15,11 @@ namespace osu.Game.Screens.Ranking.Statistics.User { private const float transition_duration = 300; - private readonly ScoreInfo score; - public Bindable StatisticsUpdate { get; } = new Bindable(); private LoadingLayer loadingLayer = null!; private FillFlowContainer content = null!; - public OverallRanking(ScoreInfo score) - { - this.score = score; - } - [BackgroundDependencyLoader] private void load() { From d6e079a2b4e09cb80a30189c84a57c9eb3605f83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 24 Dec 2022 11:28:46 +0100 Subject: [PATCH 1165/2991] Ignore statistics update requests from third-party rulesets for now --- osu.Game/Online/Solo/SoloStatisticsWatcher.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs index 48f39504a3..1209747132 100644 --- a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs +++ b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs @@ -8,6 +8,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; +using osu.Game.Extensions; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; @@ -51,6 +52,9 @@ namespace osu.Game.Online.Solo if (!api.IsLoggedIn) return; + if (!score.Ruleset.IsLegacyRuleset()) + return; + var callback = new StatisticsUpdateCallback(score, onUpdateReady); if (lastProcessedScoreId == score.OnlineID) From fd9110a61e8424384ad90fbea0def6101e3ed430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 24 Dec 2022 13:28:25 +0100 Subject: [PATCH 1166/2991] Fix solo statistics watcher firing requests for invalid user with id 1 Can happen during login flow (see `APIAccess.attemptConnect()`). --- osu.Game/Online/Solo/SoloStatisticsWatcher.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs index 1209747132..0dfe8ebb8d 100644 --- a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs +++ b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.ObjectExtensions; @@ -72,11 +71,9 @@ namespace osu.Game.Online.Solo lastProcessedScoreId = null; latestStatistics.Clear(); - if (!api.IsLoggedIn) + if (localUser == null || localUser.OnlineID <= 1) return; - Debug.Assert(localUser != null); - var userRequest = new GetUsersRequest(new[] { localUser.OnlineID }); userRequest.Success += response => Schedule(() => { From 3c26016b61bd43e85c386c69e447665aece584e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 24 Dec 2022 13:30:54 +0100 Subject: [PATCH 1167/2991] Ensure latest stats are cleared on successful profile fetch --- osu.Game/Online/Solo/SoloStatisticsWatcher.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs index 0dfe8ebb8d..268483ab91 100644 --- a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs +++ b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs @@ -77,6 +77,7 @@ namespace osu.Game.Online.Solo var userRequest = new GetUsersRequest(new[] { localUser.OnlineID }); userRequest.Success += response => Schedule(() => { + latestStatistics.Clear(); foreach (var rulesetStats in response.Users.Single().RulesetsStatistics) latestStatistics.Add(rulesetStats.Key, rulesetStats.Value); }); From 6c4ca387e01fcbbe82b1b29c49e0b0011f2cb1d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 24 Dec 2022 13:42:32 +0100 Subject: [PATCH 1168/2991] Fix wrong handling of missing ruleset statistics --- osu.Game/Online/Solo/SoloStatisticsWatcher.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs index 268483ab91..383f6a202d 100644 --- a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs +++ b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs @@ -31,7 +31,7 @@ namespace osu.Game.Online.Solo private readonly Dictionary callbacks = new Dictionary(); private long? lastProcessedScoreId; - private readonly Dictionary latestStatistics = new Dictionary(); + private Dictionary? latestStatistics; protected override void LoadComplete() { @@ -69,7 +69,7 @@ namespace osu.Game.Online.Solo { callbacks.Clear(); lastProcessedScoreId = null; - latestStatistics.Clear(); + latestStatistics = null; if (localUser == null || localUser.OnlineID <= 1) return; @@ -77,7 +77,7 @@ namespace osu.Game.Online.Solo var userRequest = new GetUsersRequest(new[] { localUser.OnlineID }); userRequest.Success += response => Schedule(() => { - latestStatistics.Clear(); + latestStatistics = new Dictionary(); foreach (var rulesetStats in response.Users.Single().RulesetsStatistics) latestStatistics.Add(rulesetStats.Key, rulesetStats.Value); }); @@ -109,9 +109,12 @@ namespace osu.Game.Online.Solo { string rulesetName = callback.Score.Ruleset.ShortName; - if (!latestStatistics.TryGetValue(rulesetName, out var latestRulesetStatistics)) + if (latestStatistics == null) return; + latestStatistics.TryGetValue(rulesetName, out UserStatistics? latestRulesetStatistics); + latestRulesetStatistics ??= new UserStatistics(); + var update = new SoloStatisticsUpdate(callback.Score, latestRulesetStatistics, updatedStatistics); callback.OnUpdateReady.Invoke(update); From 78c47a3695a9e8c1bbfa1ef8f07eb7ae2f3df5f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 24 Dec 2022 13:45:04 +0100 Subject: [PATCH 1169/2991] Add callback to dictionary rather than overwrite Attempting to overwrite will henceforth throw an exception. --- osu.Game/Online/Solo/SoloStatisticsWatcher.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs index 383f6a202d..33344044b9 100644 --- a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs +++ b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs @@ -62,7 +62,7 @@ namespace osu.Game.Online.Solo return; } - callbacks[score.OnlineID] = callback; + callbacks.Add(score.OnlineID, callback); }); private void onUserChanged(APIUser? localUser) => Schedule(() => From 600ada46be2099891910cc303b3c1113c67f7fd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 24 Dec 2022 10:35:42 +0100 Subject: [PATCH 1170/2991] Add protected method for customising statistics panel --- osu.Game/Screens/Ranking/ResultsScreen.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Ranking/ResultsScreen.cs b/osu.Game/Screens/Ranking/ResultsScreen.cs index f3aca43a9d..78239e0dbe 100644 --- a/osu.Game/Screens/Ranking/ResultsScreen.cs +++ b/osu.Game/Screens/Ranking/ResultsScreen.cs @@ -96,11 +96,11 @@ namespace osu.Game.Screens.Ranking RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - statisticsPanel = new StatisticsPanel + statisticsPanel = CreateStatisticsPanel().With(panel => { - RelativeSizeAxes = Axes.Both, - Score = { BindTarget = SelectedScore } - }, + panel.RelativeSizeAxes = Axes.Both; + panel.Score.BindTarget = SelectedScore; + }), ScorePanelList = new ScorePanelList { RelativeSizeAxes = Axes.Both, @@ -231,6 +231,11 @@ namespace osu.Game.Screens.Ranking /// An responsible for the fetch operation. This will be queued and performed automatically. protected virtual APIRequest FetchNextPage(int direction, Action> scoresCallback) => null; + /// + /// Creates the to be used to display extended information about scores. + /// + protected virtual StatisticsPanel CreateStatisticsPanel() => new StatisticsPanel(); + private void fetchScoresCallback(IEnumerable scores) => Schedule(() => { foreach (var s in scores) From 3abdf557eaf431ac5643254665caf1b8c44df21d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 24 Dec 2022 10:51:09 +0100 Subject: [PATCH 1171/2991] Add protected method for customising statistics panel rows --- osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs index 91102d6647..4c22afd8f7 100644 --- a/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs +++ b/osu.Game/Screens/Ranking/Statistics/StatisticsPanel.cs @@ -100,7 +100,7 @@ namespace osu.Game.Screens.Ranking.Statistics bool hitEventsAvailable = newScore.HitEvents.Count != 0; Container container; - var statisticRows = newScore.Ruleset.CreateInstance().CreateStatisticsForScore(newScore, task.GetResultSafely()); + var statisticRows = CreateStatisticRows(newScore, task.GetResultSafely()); if (!hitEventsAvailable && statisticRows.SelectMany(r => r.Columns).All(c => c.RequiresHitEvents)) { @@ -218,6 +218,14 @@ namespace osu.Game.Screens.Ranking.Statistics }), localCancellationSource.Token); } + /// + /// Creates the s to be displayed in this panel for a given . + /// + /// The score to create the rows for. + /// The beatmap on which the score was set. + protected virtual ICollection CreateStatisticRows(ScoreInfo newScore, IBeatmap playableBeatmap) + => newScore.Ruleset.CreateInstance().CreateStatisticsForScore(newScore, playableBeatmap); + protected override bool OnClick(ClickEvent e) { ToggleVisibility(); From da519acb20efa3f91eb504c1e1eb4fcf2a68ed2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 24 Dec 2022 10:58:38 +0100 Subject: [PATCH 1172/2991] Add overall ranking display to solo results --- osu.Game/Screens/Ranking/SoloResultsScreen.cs | 20 ++++++++ .../Ranking/Statistics/SoloStatisticsPanel.cs | 51 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 osu.Game/Screens/Ranking/Statistics/SoloStatisticsPanel.cs diff --git a/osu.Game/Screens/Ranking/SoloResultsScreen.cs b/osu.Game/Screens/Ranking/SoloResultsScreen.cs index 3774cf16b1..6d4feeb0db 100644 --- a/osu.Game/Screens/Ranking/SoloResultsScreen.cs +++ b/osu.Game/Screens/Ranking/SoloResultsScreen.cs @@ -7,11 +7,14 @@ using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Online.API; using osu.Game.Online.API.Requests; +using osu.Game.Online.Solo; using osu.Game.Rulesets; using osu.Game.Scoring; +using osu.Game.Screens.Ranking.Statistics; namespace osu.Game.Screens.Ranking { @@ -22,11 +25,28 @@ namespace osu.Game.Screens.Ranking [Resolved] private RulesetStore rulesets { get; set; } + [Resolved] + private SoloStatisticsWatcher soloStatisticsWatcher { get; set; } + + private readonly Bindable statisticsUpdate = new Bindable(); + public SoloResultsScreen(ScoreInfo score, bool allowRetry) : base(score, allowRetry) { } + protected override void LoadComplete() + { + base.LoadComplete(); + + soloStatisticsWatcher.RegisterForStatisticsUpdateAfter(Score, update => statisticsUpdate.Value = update); + } + + protected override StatisticsPanel CreateStatisticsPanel() => new SoloStatisticsPanel(Score) + { + StatisticsUpdate = { BindTarget = statisticsUpdate } + }; + protected override APIRequest FetchScores(Action> scoresCallback) { if (Score.BeatmapInfo.OnlineID <= 0 || Score.BeatmapInfo.Status <= BeatmapOnlineStatus.Pending) diff --git a/osu.Game/Screens/Ranking/Statistics/SoloStatisticsPanel.cs b/osu.Game/Screens/Ranking/Statistics/SoloStatisticsPanel.cs new file mode 100644 index 0000000000..4741ea2ea3 --- /dev/null +++ b/osu.Game/Screens/Ranking/Statistics/SoloStatisticsPanel.cs @@ -0,0 +1,51 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Game.Beatmaps; +using osu.Game.Online.Solo; +using osu.Game.Scoring; +using osu.Game.Screens.Ranking.Statistics.User; + +namespace osu.Game.Screens.Ranking.Statistics +{ + public partial class SoloStatisticsPanel : StatisticsPanel + { + private readonly ScoreInfo achievedScore; + + public SoloStatisticsPanel(ScoreInfo achievedScore) + { + this.achievedScore = achievedScore; + } + + public Bindable StatisticsUpdate { get; } = new Bindable(); + + protected override ICollection CreateStatisticRows(ScoreInfo newScore, IBeatmap playableBeatmap) + { + var rows = base.CreateStatisticRows(newScore, playableBeatmap); + + if (newScore.UserID == achievedScore.UserID && newScore.OnlineID == achievedScore.OnlineID) + { + rows = rows.Append(new StatisticRow + { + Columns = new[] + { + new StatisticItem("Overall Ranking", () => new OverallRanking + { + RelativeSizeAxes = Axes.X, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Width = 0.5f, + StatisticsUpdate = { BindTarget = StatisticsUpdate } + }) + } + }).ToArray(); + } + + return rows; + } + } +} From 145130ba80f21d778c7b3f5d6aa2b95b989b5222 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 24 Dec 2022 11:20:31 +0100 Subject: [PATCH 1173/2991] Register solo statistics watcher at game level --- osu.Game/OsuGameBase.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 7586dc6407..36fd5a4177 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -46,6 +46,7 @@ using osu.Game.Online.API; using osu.Game.Online.Chat; using osu.Game.Online.Metadata; using osu.Game.Online.Multiplayer; +using osu.Game.Online.Solo; using osu.Game.Online.Spectator; using osu.Game.Overlays; using osu.Game.Overlays.Settings; @@ -193,6 +194,7 @@ namespace osu.Game protected MultiplayerClient MultiplayerClient { get; private set; } private MetadataClient metadataClient; + private SoloStatisticsWatcher soloStatisticsWatcher; private RealmAccess realm; @@ -301,6 +303,7 @@ namespace osu.Game dependencies.CacheAs(spectatorClient = new OnlineSpectatorClient(endpoints)); dependencies.CacheAs(MultiplayerClient = new OnlineMultiplayerClient(endpoints)); dependencies.CacheAs(metadataClient = new OnlineMetadataClient(endpoints)); + dependencies.CacheAs(soloStatisticsWatcher = new SoloStatisticsWatcher()); AddInternal(new BeatmapOnlineChangeIngest(beatmapUpdater, realm, metadataClient)); @@ -346,6 +349,7 @@ namespace osu.Game AddInternal(spectatorClient); AddInternal(MultiplayerClient); AddInternal(metadataClient); + AddInternal(soloStatisticsWatcher); AddInternal(rulesetConfigCache); From 36a6f3685ebdf6a50d3fb40ec2268fce0f23589b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 24 Dec 2022 11:27:42 +0100 Subject: [PATCH 1174/2991] Don't show global rankings display when not logged in --- osu.Game/Screens/Ranking/Statistics/SoloStatisticsPanel.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Ranking/Statistics/SoloStatisticsPanel.cs b/osu.Game/Screens/Ranking/Statistics/SoloStatisticsPanel.cs index 4741ea2ea3..57d072b7de 100644 --- a/osu.Game/Screens/Ranking/Statistics/SoloStatisticsPanel.cs +++ b/osu.Game/Screens/Ranking/Statistics/SoloStatisticsPanel.cs @@ -27,7 +27,10 @@ namespace osu.Game.Screens.Ranking.Statistics { var rows = base.CreateStatisticRows(newScore, playableBeatmap); - if (newScore.UserID == achievedScore.UserID && newScore.OnlineID == achievedScore.OnlineID) + if (newScore.UserID > 1 + && newScore.UserID == achievedScore.UserID + && newScore.OnlineID > 0 + && newScore.OnlineID == achievedScore.OnlineID) { rows = rows.Append(new StatisticRow { From 8c7814aaf0d296886644206b8633cce64e76ff12 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 24 Dec 2022 21:48:04 +0800 Subject: [PATCH 1175/2991] Fix weird using statement --- osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs b/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs index c2d7b33079..2edc577a95 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs @@ -5,8 +5,8 @@ using NUnit.Framework; using osu.Framework.Graphics; using osu.Game.Online.Solo; using osu.Game.Scoring; +using osu.Game.Screens.Ranking.Statistics.User; using osu.Game.Users; -using OverallRanking = osu.Game.Screens.Ranking.Statistics.User.OverallRanking; namespace osu.Game.Tests.Visual.Ranking { From 9d073f42283f4da57e1b219a34b22c062a14b59d Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 24 Dec 2022 11:26:09 -0800 Subject: [PATCH 1176/2991] Link beatmap set title and artist to listing search --- osu.Game/OsuGame.cs | 5 +++- .../BeatmapSet/BeatmapSetHeaderContent.cs | 29 ++++++++++++++----- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index de9a009f44..b55b943023 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -353,7 +353,10 @@ namespace osu.Game break; case LinkAction.SearchBeatmapSet: - SearchBeatmapSet(argString); + if (link.Argument is RomanisableString romanisable) + SearchBeatmapSet(romanisable.GetPreferred(frameworkConfig.GetBindable(FrameworkSetting.ShowUnicode).Value)); + else + SearchBeatmapSet(argString); break; case LinkAction.OpenEditorTimestamp: diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs index 0318dad0e3..6977110ad4 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs @@ -16,11 +16,12 @@ using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Online; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Chat; using osu.Game.Overlays.BeatmapSet.Buttons; using osuTK; @@ -41,7 +42,7 @@ namespace osu.Game.Overlays.BeatmapSet private readonly UpdateableOnlineBeatmapSetCover cover; private readonly Box coverGradient; - private readonly OsuSpriteText title, artist; + private readonly LinkFlowContainer title, artist; private readonly AuthorInfo author; private readonly ExplicitContentBeatmapBadge explicitContent; @@ -127,9 +128,12 @@ namespace osu.Game.Overlays.BeatmapSet Margin = new MarginPadding { Top = 15 }, Children = new Drawable[] { - title = new OsuSpriteText + title = new LinkFlowContainer(s => { - Font = OsuFont.GetFont(size: 30, weight: FontWeight.SemiBold, italics: true) + s.Font = OsuFont.GetFont(size: 30, weight: FontWeight.SemiBold, italics: true); + }) + { + AutoSizeAxes = Axes.Both, }, externalLink = new ExternalLinkButton { @@ -160,9 +164,12 @@ namespace osu.Game.Overlays.BeatmapSet Margin = new MarginPadding { Bottom = 20 }, Children = new Drawable[] { - artist = new OsuSpriteText + artist = new LinkFlowContainer(s => { - Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true), + s.Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true); + }) + { + AutoSizeAxes = Axes.Both, }, featuredArtist = new FeaturedArtistBeatmapBadge { @@ -275,8 +282,14 @@ namespace osu.Game.Overlays.BeatmapSet loading.Hide(); - title.Text = new RomanisableString(setInfo.NewValue.TitleUnicode, setInfo.NewValue.Title); - artist.Text = new RomanisableString(setInfo.NewValue.ArtistUnicode, setInfo.NewValue.Artist); + var titleText = new RomanisableString(setInfo.NewValue.TitleUnicode, setInfo.NewValue.Title); + var artistText = new RomanisableString(setInfo.NewValue.ArtistUnicode, setInfo.NewValue.Artist); + + title.Clear(); + artist.Clear(); + + title.AddLink(titleText, LinkAction.SearchBeatmapSet, titleText); + artist.AddLink(artistText, LinkAction.SearchBeatmapSet, artistText); explicitContent.Alpha = setInfo.NewValue.HasExplicitContent ? 1 : 0; spotlight.Alpha = setInfo.NewValue.FeaturedInSpotlight ? 1 : 0; From df645ef3cb8de16a67ac8e92831830bf10d5da16 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 24 Dec 2022 11:42:05 -0800 Subject: [PATCH 1177/2991] Change title/artist idle colour to white --- .../BeatmapSet/BeatmapSetHeaderContent.cs | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs index 6977110ad4..357c9bc55d 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs @@ -3,6 +3,7 @@ #nullable disable +using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -12,6 +13,7 @@ using osu.Framework.Graphics.Colour; using osu.Game.Graphics.Cursor; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; @@ -24,6 +26,7 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; using osu.Game.Overlays.BeatmapSet.Buttons; using osuTK; +using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet { @@ -128,7 +131,7 @@ namespace osu.Game.Overlays.BeatmapSet Margin = new MarginPadding { Top = 15 }, Children = new Drawable[] { - title = new LinkFlowContainer(s => + title = new MetadataFlowContainer(s => { s.Font = OsuFont.GetFont(size: 30, weight: FontWeight.SemiBold, italics: true); }) @@ -164,7 +167,7 @@ namespace osu.Game.Overlays.BeatmapSet Margin = new MarginPadding { Bottom = 20 }, Children = new Drawable[] { - artist = new LinkFlowContainer(s => + artist = new MetadataFlowContainer(s => { s.Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true); }) @@ -340,5 +343,29 @@ namespace osu.Game.Overlays.BeatmapSet break; } } + + public partial class MetadataFlowContainer : LinkFlowContainer + { + public MetadataFlowContainer(Action defaultCreationParameters = null) + : base(defaultCreationParameters) + { + } + + protected override DrawableLinkCompiler CreateLinkCompiler(ITextPart textPart) => new MetadataLinkCompiler(textPart); + + public partial class MetadataLinkCompiler : DrawableLinkCompiler + { + public MetadataLinkCompiler(ITextPart part) + : base(part) + { + } + + [BackgroundDependencyLoader] + private void load() + { + IdleColour = Color4.White; + } + } + } } } From 4f6b3644f3208293b1e659d79942de42a5505561 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 24 Dec 2022 12:40:32 -0800 Subject: [PATCH 1178/2991] Fix title/artist overflowing to right side --- .../BeatmapSet/BeatmapSetHeaderContent.cs | 121 +++++++++--------- 1 file changed, 62 insertions(+), 59 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs index 357c9bc55d..b305e6ef05 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs @@ -48,9 +48,10 @@ namespace osu.Game.Overlays.BeatmapSet private readonly LinkFlowContainer title, artist; private readonly AuthorInfo author; - private readonly ExplicitContentBeatmapBadge explicitContent; - private readonly SpotlightBeatmapBadge spotlight; - private readonly FeaturedArtistBeatmapBadge featuredArtist; + private ExplicitContentBeatmapBadge explicitContent; + private SpotlightBeatmapBadge spotlight; + private FeaturedArtistBeatmapBadge featuredArtist; + private ExternalLinkButton externalLink; private readonly FillFlowContainer downloadButtonsContainer; private readonly BeatmapAvailability beatmapAvailability; @@ -69,8 +70,6 @@ namespace osu.Game.Overlays.BeatmapSet public BeatmapSetHeaderContent() { - ExternalLinkButton externalLink; - RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; InternalChild = new Container @@ -124,64 +123,19 @@ namespace osu.Game.Overlays.BeatmapSet AutoSizeAxes = Axes.Y, Child = Picker = new BeatmapPicker(), }, - new FillFlowContainer + title = new MetadataFlowContainer(s => + { + s.Font = OsuFont.GetFont(size: 30, weight: FontWeight.SemiBold, italics: true); + }) { - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, Margin = new MarginPadding { Top = 15 }, - Children = new Drawable[] - { - title = new MetadataFlowContainer(s => - { - s.Font = OsuFont.GetFont(size: 30, weight: FontWeight.SemiBold, italics: true); - }) - { - AutoSizeAxes = Axes.Both, - }, - externalLink = new ExternalLinkButton - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Left = 5, Bottom = 4 }, // To better lineup with the font - }, - explicitContent = new ExplicitContentBeatmapBadge - { - Alpha = 0f, - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Left = 10, Bottom = 4 }, - }, - spotlight = new SpotlightBeatmapBadge - { - Alpha = 0f, - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Left = 10, Bottom = 4 }, - } - } }, - new FillFlowContainer + artist = new MetadataFlowContainer(s => + { + s.Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true); + }) { - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, Margin = new MarginPadding { Bottom = 20 }, - Children = new Drawable[] - { - artist = new MetadataFlowContainer(s => - { - s.Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true); - }) - { - AutoSizeAxes = Axes.Both, - }, - featuredArtist = new FeaturedArtistBeatmapBadge - { - Alpha = 0f, - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Left = 10 } - } - } }, new Container { @@ -247,12 +201,17 @@ namespace osu.Game.Overlays.BeatmapSet Picker.Beatmap.ValueChanged += b => { Details.BeatmapInfo = b.NewValue; - externalLink.Link = $@"{api.WebsiteRootUrl}/beatmapsets/{BeatmapSet.Value?.OnlineID}#{b.NewValue?.Ruleset.ShortName}/{b.NewValue?.OnlineID}"; + updateExternalLink(); onlineStatusPill.Status = b.NewValue?.Status ?? BeatmapOnlineStatus.None; }; } + private void updateExternalLink() + { + if (externalLink != null) externalLink.Link = $@"{api.WebsiteRootUrl}/beatmapsets/{BeatmapSet.Value?.OnlineID}#{Picker.Beatmap.Value?.Ruleset.ShortName}/{Picker.Beatmap.Value?.OnlineID}"; + } + [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { @@ -292,8 +251,49 @@ namespace osu.Game.Overlays.BeatmapSet artist.Clear(); title.AddLink(titleText, LinkAction.SearchBeatmapSet, titleText); + + title.AddArbitraryDrawable(new Container + { + AutoSizeAxes = Axes.Both, + Child = externalLink = new ExternalLinkButton + { + Margin = new MarginPadding { Left = 5 }, + } + }); + + title.AddArbitraryDrawable(new Container + { + AutoSizeAxes = Axes.Both, + Child = explicitContent = new ExplicitContentBeatmapBadge + { + Alpha = 0f, + Margin = new MarginPadding { Left = 10 }, + } + }); + + title.AddArbitraryDrawable(new Container + { + AutoSizeAxes = Axes.Both, + Child = spotlight = new SpotlightBeatmapBadge + { + Alpha = 0f, + Margin = new MarginPadding { Left = 10 }, + } + }); + artist.AddLink(artistText, LinkAction.SearchBeatmapSet, artistText); + artist.AddArbitraryDrawable(new Container + { + AutoSizeAxes = Axes.Both, + Child = featuredArtist = new FeaturedArtistBeatmapBadge + { + Alpha = 0f, + Margin = new MarginPadding { Left = 10 } + } + }); + + updateExternalLink(); explicitContent.Alpha = setInfo.NewValue.HasExplicitContent ? 1 : 0; spotlight.Alpha = setInfo.NewValue.FeaturedInSpotlight ? 1 : 0; featuredArtist.Alpha = setInfo.NewValue.TrackId != null ? 1 : 0; @@ -349,6 +349,9 @@ namespace osu.Game.Overlays.BeatmapSet public MetadataFlowContainer(Action defaultCreationParameters = null) : base(defaultCreationParameters) { + TextAnchor = Anchor.CentreLeft; + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; } protected override DrawableLinkCompiler CreateLinkCompiler(ITextPart textPart) => new MetadataLinkCompiler(textPart); From ae967e08b0c3cd07714d397c9bf0a58224b63b53 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 24 Dec 2022 13:27:46 -0800 Subject: [PATCH 1179/2991] Add badges when needed instead of using alpha --- .../BeatmapSet/BeatmapSetHeaderContent.cs | 42 ++++++++----------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs index b305e6ef05..043844b56b 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs @@ -261,42 +261,36 @@ namespace osu.Game.Overlays.BeatmapSet } }); - title.AddArbitraryDrawable(new Container + if (setInfo.NewValue.HasExplicitContent) { - AutoSizeAxes = Axes.Both, - Child = explicitContent = new ExplicitContentBeatmapBadge + title.AddArbitraryDrawable(new Container { - Alpha = 0f, - Margin = new MarginPadding { Left = 10 }, - } - }); + AutoSizeAxes = Axes.Both, + Child = explicitContent = new ExplicitContentBeatmapBadge { Margin = new MarginPadding { Left = 10 } }, + }); + } - title.AddArbitraryDrawable(new Container + if (setInfo.NewValue.FeaturedInSpotlight) { - AutoSizeAxes = Axes.Both, - Child = spotlight = new SpotlightBeatmapBadge + title.AddArbitraryDrawable(new Container { - Alpha = 0f, - Margin = new MarginPadding { Left = 10 }, - } - }); + AutoSizeAxes = Axes.Both, + Child = spotlight = new SpotlightBeatmapBadge { Margin = new MarginPadding { Left = 10 } }, + }); + } artist.AddLink(artistText, LinkAction.SearchBeatmapSet, artistText); - artist.AddArbitraryDrawable(new Container + if (setInfo.NewValue.TrackId != null) { - AutoSizeAxes = Axes.Both, - Child = featuredArtist = new FeaturedArtistBeatmapBadge + artist.AddArbitraryDrawable(new Container { - Alpha = 0f, - Margin = new MarginPadding { Left = 10 } - } - }); + AutoSizeAxes = Axes.Both, + Child = featuredArtist = new FeaturedArtistBeatmapBadge { Margin = new MarginPadding { Left = 10 } } + }); + } updateExternalLink(); - explicitContent.Alpha = setInfo.NewValue.HasExplicitContent ? 1 : 0; - spotlight.Alpha = setInfo.NewValue.FeaturedInSpotlight ? 1 : 0; - featuredArtist.Alpha = setInfo.NewValue.TrackId != null ? 1 : 0; onlineStatusPill.FadeIn(500, Easing.OutQuint); From b871d6f078ebfff9eb859011693de8f439d41462 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 24 Dec 2022 13:35:17 -0800 Subject: [PATCH 1180/2991] Remove unused fields --- osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs index 043844b56b..13506bfd1c 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs @@ -48,9 +48,6 @@ namespace osu.Game.Overlays.BeatmapSet private readonly LinkFlowContainer title, artist; private readonly AuthorInfo author; - private ExplicitContentBeatmapBadge explicitContent; - private SpotlightBeatmapBadge spotlight; - private FeaturedArtistBeatmapBadge featuredArtist; private ExternalLinkButton externalLink; private readonly FillFlowContainer downloadButtonsContainer; @@ -266,7 +263,7 @@ namespace osu.Game.Overlays.BeatmapSet title.AddArbitraryDrawable(new Container { AutoSizeAxes = Axes.Both, - Child = explicitContent = new ExplicitContentBeatmapBadge { Margin = new MarginPadding { Left = 10 } }, + Child = new ExplicitContentBeatmapBadge { Margin = new MarginPadding { Left = 10 } }, }); } @@ -275,7 +272,7 @@ namespace osu.Game.Overlays.BeatmapSet title.AddArbitraryDrawable(new Container { AutoSizeAxes = Axes.Both, - Child = spotlight = new SpotlightBeatmapBadge { Margin = new MarginPadding { Left = 10 } }, + Child = new SpotlightBeatmapBadge { Margin = new MarginPadding { Left = 10 } }, }); } @@ -286,7 +283,7 @@ namespace osu.Game.Overlays.BeatmapSet artist.AddArbitraryDrawable(new Container { AutoSizeAxes = Axes.Both, - Child = featuredArtist = new FeaturedArtistBeatmapBadge { Margin = new MarginPadding { Left = 10 } } + Child = new FeaturedArtistBeatmapBadge { Margin = new MarginPadding { Left = 10 } } }); } From d392d1a5c08daa0d3f857e75f1d18fbbb160138c Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Sat, 24 Dec 2022 22:18:42 +0000 Subject: [PATCH 1181/2991] override a sub-method instead of the whole `Export()` --- osu.Game/Database/LegacyExporter.cs | 10 +++++----- osu.Game/Database/LegacyScoreExporter.cs | 22 +++++----------------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 02219c4dfa..3f305fb420 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -33,17 +33,17 @@ namespace osu.Game.Database UserFileStorage = storage.GetStorageForDirectory(@"files"); } + protected virtual string GetItemExportString(TModel item) => item.GetDisplayString().GetValidFilename(); + /// /// Exports an item to a legacy (.zip based) package. /// /// The item to export. - public virtual void Export(TModel item) + public void Export(TModel item) { - string itemFilename = item.GetDisplayString().GetValidFilename(); + IEnumerable existingExports = exportStorage.GetFiles("", $"{GetItemExportString(item)}*{FileExtension}"); - IEnumerable existingExports = exportStorage.GetFiles("", $"{itemFilename}*{FileExtension}"); - - string filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); + string filename = NamingUtils.GetNextBestFilename(existingExports, $"{GetItemExportString(item)}{FileExtension}"); using (var stream = exportStorage.CreateFileSafely(filename)) ExportModelTo(item, stream); diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index fc80693765..e176449fd0 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -3,13 +3,11 @@ #nullable disable -using System.Collections.Generic; using System.IO; using System.Linq; using osu.Framework.Platform; using osu.Game.Extensions; using osu.Game.Scoring; -using osu.Game.Utils; namespace osu.Game.Database { @@ -17,27 +15,17 @@ namespace osu.Game.Database { protected override string FileExtension => ".osr"; - private readonly Storage exportStorage; - public LegacyScoreExporter(Storage storage) : base(storage) { - exportStorage = storage.GetStorageForDirectory(@"exports"); } - private string GetScoreExportString(ScoreInfo score) => $"{score.GetDisplayString()} ({score.Date.LocalDateTime:yyyy-MM-dd})"; - - public override void Export(ScoreInfo score) + protected override string GetItemExportString(ScoreInfo score) { - string scoreExportTitle = GetScoreExportString(score).GetValidFilename(); - - IEnumerable existingExports = exportStorage.GetFiles("", $"{scoreExportTitle}*{FileExtension}"); - - string scoreExportFilename = NamingUtils.GetNextBestFilename(existingExports, $"{scoreExportTitle}{FileExtension}"); - using (var stream = exportStorage.CreateFileSafely(scoreExportFilename)) - ExportModelTo(score, stream); - - exportStorage.PresentFileExternally(scoreExportFilename); + string scoreString = score.GetDisplayString(); + string filename = $"{scoreString} ({score.Date.LocalDateTime:yyyy-MM-dd})"; + + return filename.GetValidFilename(); } public override void ExportModelTo(ScoreInfo model, Stream outputStream) From 5232588a1f07529814a36439880585db96b225bd Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 24 Dec 2022 20:04:45 -0800 Subject: [PATCH 1182/2991] Use `PerformFromScreen` to exit sub screens instead --- .../Navigation/TestSceneScreenNavigation.cs | 2 +- osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 89cd766842..66c4cf8686 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -83,7 +83,7 @@ namespace osu.Game.Tests.Visual.Navigation AddStep("go back to song select", () => { - InputManager.MoveMouseTo(playlistScreen.ChildrenOfType().Single(b => b.Text == "Edit playlist")); + InputManager.MoveMouseTo(playlistScreen.ChildrenOfType().Single(b => b.Text == "Edit playlist")); InputManager.Click(MouseButton.Left); }); diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs index ff888710fe..4a3549b33e 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs @@ -45,6 +45,9 @@ namespace osu.Game.Screens.OnlinePlay [Resolved] protected IAPIProvider API { get; private set; } + [Resolved(canBeNull: true)] + private IPerformFromScreenRunner performer { get; set; } + protected OnlinePlayScreen() { Anchor = Anchor.Centre; @@ -148,13 +151,17 @@ namespace osu.Game.Screens.OnlinePlay public override bool OnExiting(ScreenExitEvent e) { - while (screenStack.CurrentScreen is not LoungeSubScreen) + if (screenStack.CurrentScreen is not LoungeSubScreen) { - var lastSubScreen = screenStack.CurrentScreen; - if (((Drawable)lastSubScreen)?.IsLoaded == true) - screenStack.Exit(); + if (performer != null) + { + performer.PerformFromScreen(_ => e.Destination.MakeCurrent(), new[] { typeof(LoungeSubScreen) }); + return true; + } - if (lastSubScreen == screenStack.CurrentScreen) return true; + // TODO: make isolated tests work with IPerformFromScreenRunner + if ((screenStack.CurrentScreen as Drawable)?.IsLoaded == true && screenStack.CurrentScreen.OnExiting(e)) + return true; } RoomManager.PartRoom(); From e6f9d6202c4dd174ba21804d17c41fb185f73837 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 25 Dec 2022 23:40:01 +0800 Subject: [PATCH 1183/2991] Update appveyor deploy image --- appveyor_deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor_deploy.yml b/appveyor_deploy.yml index adf98848bc..175c8d0f1b 100644 --- a/appveyor_deploy.yml +++ b/appveyor_deploy.yml @@ -1,6 +1,6 @@ clone_depth: 1 version: '{build}' -image: Visual Studio 2019 +image: Visual Studio 2022 test: off skip_non_tags: true configuration: Release @@ -83,4 +83,4 @@ artifacts: deploy: - provider: Environment - name: nuget \ No newline at end of file + name: nuget From 2c2f347e2585c00742f8ad852550b2938805bd75 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 25 Dec 2022 09:57:42 -0800 Subject: [PATCH 1184/2991] Add context menus to overlay panels/cards --- .../Beatmaps/Drawables/Cards/BeatmapCard.cs | 9 ++++- osu.Game/Overlays/Chat/DrawableUsername.cs | 5 +-- osu.Game/Overlays/News/NewsCard.cs | 9 ++++- osu.Game/Overlays/OnlineOverlay.cs | 10 ++++-- osu.Game/Users/UserPanel.cs | 36 +++++++++++++++++-- 5 files changed, 60 insertions(+), 9 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs index 00f9a6b3d5..7e5b734979 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs @@ -5,6 +5,8 @@ using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; @@ -14,7 +16,7 @@ using osu.Game.Overlays; namespace osu.Game.Beatmaps.Drawables.Cards { - public abstract partial class BeatmapCard : OsuClickableContainer + public abstract partial class BeatmapCard : OsuClickableContainer, IHasContextMenu { public const float TRANSITION_DURATION = 400; public const float CORNER_RADIUS = 10; @@ -96,5 +98,10 @@ namespace osu.Game.Beatmaps.Drawables.Cards throw new ArgumentOutOfRangeException(nameof(size), size, @"Unsupported card size"); } } + + public MenuItem[] ContextMenuItems => new MenuItem[] + { + new OsuMenuItem("View beatmap", MenuItemType.Highlighted, Action), + }; } } diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs index 6bae498a6c..8005677dc2 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -20,6 +20,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; +using osu.Game.Resources.Localisation.Web; using osuTK; using osuTK.Graphics; @@ -148,11 +149,11 @@ namespace osu.Game.Overlays.Chat List items = new List { - new OsuMenuItem("View Profile", MenuItemType.Highlighted, openUserProfile) + new OsuMenuItem("View profile", MenuItemType.Highlighted, openUserProfile) }; if (!user.Equals(api.LocalUser.Value)) - items.Add(new OsuMenuItem("Start Chat", MenuItemType.Standard, openUserChannel)); + items.Add(new OsuMenuItem(UsersStrings.CardSendMessage, MenuItemType.Standard, openUserChannel)); return items.ToArray(); } diff --git a/osu.Game/Overlays/News/NewsCard.cs b/osu.Game/Overlays/News/NewsCard.cs index e0be5cc4a9..f18ce7ff06 100644 --- a/osu.Game/Overlays/News/NewsCard.cs +++ b/osu.Game/Overlays/News/NewsCard.cs @@ -12,16 +12,18 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Framework.Platform; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.News { - public partial class NewsCard : OsuHoverContainer + public partial class NewsCard : OsuHoverContainer, IHasContextMenu { protected override IEnumerable EffectTargets => new[] { background }; @@ -161,5 +163,10 @@ namespace osu.Game.Overlays.News DateTimeOffset IHasCustomTooltip.TooltipContent => date; } + + public MenuItem[] ContextMenuItems => new MenuItem[] + { + new OsuMenuItem("View news in browser", MenuItemType.Highlighted, Action), + }; } } diff --git a/osu.Game/Overlays/OnlineOverlay.cs b/osu.Game/Overlays/OnlineOverlay.cs index 0e0ce56446..ff225bd4ab 100644 --- a/osu.Game/Overlays/OnlineOverlay.cs +++ b/osu.Game/Overlays/OnlineOverlay.cs @@ -7,6 +7,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; +using osu.Game.Graphics.Cursor; using osu.Game.Graphics.UserInterface; using osu.Game.Online; @@ -46,10 +47,15 @@ namespace osu.Game.Overlays Children = new Drawable[] { Header.With(h => h.Depth = float.MinValue), - content = new PopoverContainer + new OsuContextMenuContainer { RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y + AutoSizeAxes = Axes.Y, + Child = content = new PopoverContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y + } } } } diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index 2f7232d5ea..2e9a870399 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -4,6 +4,7 @@ #nullable disable using System; +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; @@ -15,7 +16,10 @@ using osu.Game.Graphics.UserInterface; using osu.Framework.Graphics.Cursor; using osu.Game.Graphics.Containers; using JetBrains.Annotations; +using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Chat; +using osu.Game.Resources.Localisation.Web; namespace osu.Game.Users { @@ -44,6 +48,15 @@ namespace osu.Game.Users [Resolved(canBeNull: true)] private UserProfileOverlay profileOverlay { get; set; } + [Resolved] + private IAPIProvider api { get; set; } + + [Resolved] + private ChannelManager channelManager { get; set; } + + [Resolved] + private ChatOverlay chatOverlay { get; set; } + [Resolved(canBeNull: true)] protected OverlayColourProvider ColourProvider { get; private set; } @@ -89,9 +102,26 @@ namespace osu.Game.Users Text = User.Username, }; - public MenuItem[] ContextMenuItems => new MenuItem[] + public MenuItem[] ContextMenuItems { - new OsuMenuItem("View Profile", MenuItemType.Highlighted, ViewProfile), - }; + get + { + List items = new List + { + new OsuMenuItem("View profile", MenuItemType.Highlighted, ViewProfile) + }; + + if (!User.Equals(api.LocalUser.Value)) + { + items.Add(new OsuMenuItem(UsersStrings.CardSendMessage, MenuItemType.Standard, () => + { + channelManager?.OpenPrivateChannel(User); + chatOverlay?.Show(); + })); + } + + return items.ToArray(); + } + } } } From b9dfb8b60208c51073352c071fd45c6db6a44f43 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 25 Dec 2022 10:07:42 -0800 Subject: [PATCH 1185/2991] Add localisation for context menu strings --- .../Beatmaps/Drawables/Cards/BeatmapCard.cs | 3 ++- osu.Game/Localisation/ContextMenuStrings.cs | 24 +++++++++++++++++++ osu.Game/Overlays/Chat/DrawableUsername.cs | 3 ++- osu.Game/Users/UserPanel.cs | 3 ++- 4 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 osu.Game/Localisation/ContextMenuStrings.cs diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs index 7e5b734979..94b2956b4e 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs @@ -13,6 +13,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Online; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; +using osu.Game.Localisation; namespace osu.Game.Beatmaps.Drawables.Cards { @@ -101,7 +102,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards public MenuItem[] ContextMenuItems => new MenuItem[] { - new OsuMenuItem("View beatmap", MenuItemType.Highlighted, Action), + new OsuMenuItem(ContextMenuStrings.ViewBeatmap, MenuItemType.Highlighted, Action), }; } } diff --git a/osu.Game/Localisation/ContextMenuStrings.cs b/osu.Game/Localisation/ContextMenuStrings.cs new file mode 100644 index 0000000000..8bc213016b --- /dev/null +++ b/osu.Game/Localisation/ContextMenuStrings.cs @@ -0,0 +1,24 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class ContextMenuStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.ContextMenu"; + + /// + /// "View profile" + /// + public static LocalisableString ViewProfile => new TranslatableString(getKey(@"view_profile"), @"View profile"); + + /// + /// "View beatmap" + /// + public static LocalisableString ViewBeatmap => new TranslatableString(getKey(@"view_beatmap"), @"View beatmap"); + + private static string getKey(string key) => $@"{prefix}:{key}"; + } +} diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs index 8005677dc2..8cd16047f3 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -17,6 +17,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; @@ -149,7 +150,7 @@ namespace osu.Game.Overlays.Chat List items = new List { - new OsuMenuItem("View profile", MenuItemType.Highlighted, openUserProfile) + new OsuMenuItem(ContextMenuStrings.ViewProfile, MenuItemType.Highlighted, openUserProfile) }; if (!user.Equals(api.LocalUser.Value)) diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index 2e9a870399..5c070bae3b 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -20,6 +20,7 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; using osu.Game.Resources.Localisation.Web; +using osu.Game.Localisation; namespace osu.Game.Users { @@ -108,7 +109,7 @@ namespace osu.Game.Users { List items = new List { - new OsuMenuItem("View profile", MenuItemType.Highlighted, ViewProfile) + new OsuMenuItem(ContextMenuStrings.ViewProfile, MenuItemType.Highlighted, ViewProfile) }; if (!User.Equals(api.LocalUser.Value)) From 272288c9aa2e6b8a04be72392960ab9fe33ae3a0 Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Sun, 25 Dec 2022 21:50:56 +0000 Subject: [PATCH 1186/2991] fix code style and naming --- osu.Game/Database/LegacyExporter.cs | 8 +++++--- osu.Game/Database/LegacyScoreExporter.cs | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 3f305fb420..09d6913dd9 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -33,7 +33,7 @@ namespace osu.Game.Database UserFileStorage = storage.GetStorageForDirectory(@"files"); } - protected virtual string GetItemExportString(TModel item) => item.GetDisplayString().GetValidFilename(); + protected virtual string GetFilename(TModel item) => item.GetDisplayString(); /// /// Exports an item to a legacy (.zip based) package. @@ -41,9 +41,11 @@ namespace osu.Game.Database /// The item to export. public void Export(TModel item) { - IEnumerable existingExports = exportStorage.GetFiles("", $"{GetItemExportString(item)}*{FileExtension}"); + string itemFilename = GetFilename(item).GetValidFilename(); - string filename = NamingUtils.GetNextBestFilename(existingExports, $"{GetItemExportString(item)}{FileExtension}"); + IEnumerable existingExports = exportStorage.GetFiles("", $"{itemFilename}*{FileExtension}"); + + string filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); using (var stream = exportStorage.CreateFileSafely(filename)) ExportModelTo(item, stream); diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index e176449fd0..7c0ba7c6ee 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -20,12 +20,12 @@ namespace osu.Game.Database { } - protected override string GetItemExportString(ScoreInfo score) + protected override string GetFilename(ScoreInfo score) { string scoreString = score.GetDisplayString(); string filename = $"{scoreString} ({score.Date.LocalDateTime:yyyy-MM-dd})"; - - return filename.GetValidFilename(); + + return filename; } public override void ExportModelTo(ScoreInfo model, Stream outputStream) From bbb22479a8aefd1b040d236dde395c0220ed4bc4 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 25 Dec 2022 21:32:47 +0100 Subject: [PATCH 1187/2991] Add "ModBubbles" for the osu ruleset. --- .../Mods/TestSceneOsuModBubbles.cs | 19 ++ osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs | 228 ++++++++++++++++++ osu.Game.Rulesets.Osu/OsuRuleset.cs | 3 +- osu.Game/Rulesets/Mods/ModFlashlight.cs | 3 + 4 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModBubbles.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModBubbles.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModBubbles.cs new file mode 100644 index 0000000000..e72a1f79f5 --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModBubbles.cs @@ -0,0 +1,19 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Rulesets.Osu.Mods; + +namespace osu.Game.Rulesets.Osu.Tests.Mods +{ + public partial class TestSceneOsuModBubbles : OsuModTestScene + { + [Test] + public void TestOsuModBubbles() => CreateModTest(new ModTestData + { + Mod = new OsuModBubbles(), + Autoplay = true, + PassCondition = () => true + }); + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs new file mode 100644 index 0000000000..c51ebde383 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs @@ -0,0 +1,228 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Performance; +using osu.Framework.Graphics.Pooling; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Localisation; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Objects.Pooling; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.UI; +using osu.Game.Scoring; +using osuTK; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public partial class OsuModBubbles : ModWithVisibilityAdjustment, IApplicableToDrawableRuleset, IApplicableToScoreProcessor + { + public override string Name => "Bubbles"; + + public override string Acronym => "BB"; + + public override LocalisableString Description => "Dont let their popping distract you!"; + + public override double ScoreMultiplier => 1; + + public override ModType Type => ModType.Fun; + + // Compatibility with these seems potentially feasible in the future, blocked for now because they dont work as one would expect + public override Type[] IncompatibleMods => new[] { typeof(OsuModBarrelRoll), typeof(OsuModMagnetised), typeof(OsuModRepel) }; + + private PlayfieldAdjustmentContainer adjustmentContainer = null!; + private BubbleContainer bubbleContainer = null!; + + private readonly Bindable currentCombo = new BindableInt(); + + private float maxSize; + private float bubbleRadius; + private double bubbleFade; + + public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank; + + public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) + { + currentCombo.BindTo(scoreProcessor.Combo); + currentCombo.BindValueChanged(combo => + maxSize = Math.Min(1.75f, (float)(1.25 + 0.005 * combo.NewValue)), true); + } + + public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) + { + // Multiplying by 2 results in an initial size that is too large, hence 1.85 has been chosen + bubbleRadius = (float)(drawableRuleset.Beatmap.HitObjects.OfType().First().Radius * 1.85f); + bubbleFade = drawableRuleset.Beatmap.HitObjects.OfType().First().TimeFadeIn * 2; + + // We want to hide the judgements since they are obscured by the BubbleDrawable (due to layering) + drawableRuleset.Playfield.DisplayJudgements.Value = false; + + adjustmentContainer = drawableRuleset.CreatePlayfieldAdjustmentContainer(); + + adjustmentContainer.Add(bubbleContainer = new BubbleContainer()); + drawableRuleset.KeyBindingInputManager.Add(adjustmentContainer); + } + + protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) => applyBubbleState(hitObject); + + protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) => applyBubbleState(hitObject); + + private void applyBubbleState(DrawableHitObject drawableObject) + { + if (drawableObject is not DrawableOsuHitObject drawableOsuObject || !drawableObject.Judged) return; + + OsuHitObject hitObject = drawableOsuObject.HitObject; + + switch (drawableOsuObject) + { + //Needs to be done explicitly to avoid being handled by DrawableHitCircle below + case DrawableSliderHead: + addBubbleContainer(hitObject.Position); + break; + + //Stack leniency causes placement issues if this isn't handled as such. + case DrawableHitCircle hitCircle: + addBubbleContainer(hitCircle.Position); + break; + + case DrawableSpinnerTick: + case DrawableSlider: + return; + + default: + addBubbleContainer(hitObject.Position); + break; + } + + void addBubbleContainer(Vector2 position) => bubbleContainer.Add(new BubbleLifeTimeEntry + { + LifetimeStart = bubbleContainer.Time.Current, + Colour = drawableOsuObject.AccentColour.Value, + Position = position, + InitialSize = new Vector2(bubbleRadius), + MaxSize = maxSize, + FadeTime = bubbleFade, + IsHit = drawableOsuObject.IsHit + } + ); + } + + #region Pooled Bubble drawable + + //LifetimeEntry flow is necessary to allow for correct rewind behaviour, can probably be made generic later if more mods are made requiring it + //Todo: find solution to bubbles rewinding in "groups" + private sealed partial class BubbleContainer : PooledDrawableWithLifetimeContainer + { + protected override bool RemoveRewoundEntry => true; + + private readonly DrawablePool pool; + + public BubbleContainer() + { + RelativeSizeAxes = Axes.Both; + AddInternal(pool = new DrawablePool(10, 1000)); + } + + protected override BubbleObject GetDrawable(BubbleLifeTimeEntry entry) => pool.Get(d => d.Apply(entry)); + } + + private sealed partial class BubbleObject : PoolableDrawableWithLifetime + { + private readonly BubbleDrawable bubbleDrawable; + + public BubbleObject() + { + InternalChild = bubbleDrawable = new BubbleDrawable(); + } + + protected override void OnApply(BubbleLifeTimeEntry entry) + { + base.OnApply(entry); + if (IsLoaded) + apply(entry); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + apply(Entry); + } + + private void apply(BubbleLifeTimeEntry? entry) + { + if (entry == null) + return; + + ApplyTransformsAt(float.MinValue, true); + ClearTransforms(true); + + Position = entry.Position; + + bubbleDrawable.Animate(entry); + + LifetimeEnd = bubbleDrawable.LatestTransformEndTime; + } + } + + private partial class BubbleDrawable : CompositeDrawable + { + [BackgroundDependencyLoader] + private void load() + { + InternalChild = new Circle + { + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Masking = true, + EdgeEffect = new EdgeEffectParameters + { + Colour = Colour4.Black.Opacity(0.05f), + Type = EdgeEffectType.Shadow, + Radius = 5 + } + }; + } + + public void Animate(BubbleLifeTimeEntry entry) + { + Size = entry.InitialSize; + this + .ScaleTo(entry.MaxSize, entry.FadeTime * 6, Easing.OutSine) + .FadeColour(entry.IsHit ? entry.Colour : Colour4.Black, entry.FadeTime, Easing.OutSine) + .Delay(entry.FadeTime) + .FadeColour(entry.IsHit ? entry.Colour.Darken(.4f) : Colour4.Black, entry.FadeTime * 5, Easing.OutSine) + .Then() + .ScaleTo(entry.MaxSize * 1.5f, entry.FadeTime, Easing.OutSine) + .FadeTo(0, entry.FadeTime, Easing.OutQuint); + } + } + + private class BubbleLifeTimeEntry : LifetimeEntry + { + public Vector2 InitialSize { get; set; } + + public float MaxSize { get; set; } + + public Vector2 Position { get; set; } + + public Colour4 Colour { get; set; } + + // FadeTime is based on the approach rate of the beatmap. + public double FadeTime { get; set; } + + // Whether the corresponding HitObject was hit + public bool IsHit { get; set; } + } + + #endregion + } +} diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 79a566e33c..0df1e4dfca 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -202,7 +202,8 @@ namespace osu.Game.Rulesets.Osu new OsuModNoScope(), new MultiMod(new OsuModMagnetised(), new OsuModRepel()), new ModAdaptiveSpeed(), - new OsuModFreezeFrame() + new OsuModFreezeFrame(), + new OsuModBubbles() }; case ModType.System: diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index 45fa55c7f2..2c9ef357b5 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -83,6 +83,9 @@ namespace osu.Game.Rulesets.Mods flashlight.Combo.BindTo(Combo); drawableRuleset.KeyBindingInputManager.Add(flashlight); + + // Stop flashlight from being drawn underneath other mods that generate HitObjects. + drawableRuleset.KeyBindingInputManager.ChangeChildDepth(flashlight, -1); } protected abstract Flashlight CreateFlashlight(); From 8a108b143e10bf80162eb0109aad7a68ae9692fc Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 25 Dec 2022 21:33:10 +0100 Subject: [PATCH 1188/2991] Address mod incompatibilities --- osu.Game.Rulesets.Osu/Mods/OsuModBarrelRoll.cs | 3 +++ osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs | 17 +++++++++++------ osu.Game.Rulesets.Osu/Mods/OsuModMagnetised.cs | 2 +- osu.Game.Rulesets.Osu/Mods/OsuModRepel.cs | 2 +- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBarrelRoll.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBarrelRoll.cs index 9e71f657ce..2394cf92fc 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBarrelRoll.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBarrelRoll.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.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects; @@ -10,6 +11,8 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModBarrelRoll : ModBarrelRoll, IApplicableToDrawableHitObject { + public override Type[] IncompatibleMods => new[] { typeof(OsuModBubbles) }; + public void ApplyToDrawableHitObject(DrawableHitObject d) { d.OnUpdate += _ => diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs index c51ebde383..2e4d574148 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs @@ -86,12 +86,12 @@ namespace osu.Game.Rulesets.Osu.Mods { //Needs to be done explicitly to avoid being handled by DrawableHitCircle below case DrawableSliderHead: - addBubbleContainer(hitObject.Position); + addBubbleContainer(hitObject.Position, drawableOsuObject); break; //Stack leniency causes placement issues if this isn't handled as such. case DrawableHitCircle hitCircle: - addBubbleContainer(hitCircle.Position); + addBubbleContainer(hitCircle.Position, drawableOsuObject); break; case DrawableSpinnerTick: @@ -99,19 +99,24 @@ namespace osu.Game.Rulesets.Osu.Mods return; default: - addBubbleContainer(hitObject.Position); + addBubbleContainer(hitObject.Position, drawableOsuObject); break; } + } - void addBubbleContainer(Vector2 position) => bubbleContainer.Add(new BubbleLifeTimeEntry + private void addBubbleContainer(Vector2 position, DrawableHitObject hitObject) + { + bubbleContainer.Add + ( + new BubbleLifeTimeEntry { LifetimeStart = bubbleContainer.Time.Current, - Colour = drawableOsuObject.AccentColour.Value, + Colour = hitObject.AccentColour.Value, Position = position, InitialSize = new Vector2(bubbleRadius), MaxSize = maxSize, FadeTime = bubbleFade, - IsHit = drawableOsuObject.IsHit + IsHit = hitObject.IsHit } ); } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModMagnetised.cs b/osu.Game.Rulesets.Osu/Mods/OsuModMagnetised.cs index 38d90eb121..c8c4cd6a14 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModMagnetised.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModMagnetised.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Fun; public override LocalisableString Description => "No need to chase the circles – your cursor is a magnet!"; public override double ScoreMultiplier => 0.5; - public override Type[] IncompatibleMods => new[] { typeof(OsuModAutopilot), typeof(OsuModWiggle), typeof(OsuModTransform), typeof(ModAutoplay), typeof(OsuModRelax), typeof(OsuModRepel) }; + public override Type[] IncompatibleMods => new[] { typeof(OsuModAutopilot), typeof(OsuModWiggle), typeof(OsuModTransform), typeof(ModAutoplay), typeof(OsuModRelax), typeof(OsuModRepel), typeof(OsuModBubbles) }; [SettingSource("Attraction strength", "How strong the pull is.", 0)] public BindableFloat AttractionStrength { get; } = new BindableFloat(0.5f) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRepel.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRepel.cs index 31a6b69d6b..28d459cedb 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRepel.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRepel.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override ModType Type => ModType.Fun; public override LocalisableString Description => "Hit objects run away!"; public override double ScoreMultiplier => 1; - public override Type[] IncompatibleMods => new[] { typeof(OsuModAutopilot), typeof(OsuModWiggle), typeof(OsuModTransform), typeof(ModAutoplay), typeof(OsuModMagnetised) }; + public override Type[] IncompatibleMods => new[] { typeof(OsuModAutopilot), typeof(OsuModWiggle), typeof(OsuModTransform), typeof(ModAutoplay), typeof(OsuModMagnetised), typeof(OsuModBubbles) }; [SettingSource("Repulsion strength", "How strong the repulsion is.", 0)] public BindableFloat RepulsionStrength { get; } = new BindableFloat(0.5f) From 1a571e1c7f36b86c81c68486245f11ef19a884a0 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 25 Dec 2022 15:03:08 -0800 Subject: [PATCH 1189/2991] Remove nullable disable on user panel --- osu.Game/Users/UserPanel.cs | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index 5c070bae3b..e2dc511391 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using osu.Framework.Allocation; @@ -15,7 +13,6 @@ using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; using osu.Framework.Graphics.Cursor; using osu.Game.Graphics.Containers; -using JetBrains.Annotations; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; @@ -32,11 +29,11 @@ namespace osu.Game.Users /// Perform an action in addition to showing the user's profile. /// This should be used to perform auxiliary tasks and not as a primary action for clicking a user panel (to maintain a consistent UX). /// - public new Action Action; + public new Action? Action; - protected Action ViewProfile { get; private set; } + protected Action ViewProfile { get; private set; } = null!; - protected Drawable Background { get; private set; } + protected Drawable Background { get; private set; } = null!; protected UserPanel(APIUser user) : base(HoverSampleSet.Button) @@ -46,23 +43,23 @@ namespace osu.Game.Users User = user; } - [Resolved(canBeNull: true)] - private UserProfileOverlay profileOverlay { get; set; } + [Resolved] + private UserProfileOverlay? profileOverlay { get; set; } [Resolved] - private IAPIProvider api { get; set; } + private IAPIProvider api { get; set; } = null!; [Resolved] - private ChannelManager channelManager { get; set; } + private ChannelManager? channelManager { get; set; } [Resolved] - private ChatOverlay chatOverlay { get; set; } - - [Resolved(canBeNull: true)] - protected OverlayColourProvider ColourProvider { get; private set; } + private ChatOverlay? chatOverlay { get; set; } [Resolved] - protected OsuColour Colours { get; private set; } + protected OverlayColourProvider? ColourProvider { get; private set; } + + [Resolved] + protected OsuColour Colours { get; private set; } = null!; [BackgroundDependencyLoader] private void load() @@ -93,7 +90,6 @@ namespace osu.Game.Users }; } - [NotNull] protected abstract Drawable CreateLayout(); protected OsuSpriteText CreateUsername() => new OsuSpriteText From 8e899c2e9278db719507918405e7d2c315ae93c9 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 25 Dec 2022 16:03:44 -0800 Subject: [PATCH 1190/2991] Use localisation parameters to find preferred string instead --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index b55b943023..983277135d 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -354,7 +354,7 @@ namespace osu.Game case LinkAction.SearchBeatmapSet: if (link.Argument is RomanisableString romanisable) - SearchBeatmapSet(romanisable.GetPreferred(frameworkConfig.GetBindable(FrameworkSetting.ShowUnicode).Value)); + SearchBeatmapSet(romanisable.GetPreferred(Localisation.CurrentParameters.Value.PreferOriginalScript)); else SearchBeatmapSet(argString); break; From f959b02dc85d750b2d05ec13183d548e66e4252c Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 25 Dec 2022 16:05:59 -0800 Subject: [PATCH 1191/2991] Use empty drawables for spacing badges instead --- .../BeatmapSet/BeatmapSetHeaderContent.cs | 31 +++++-------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs index 13506bfd1c..17836b558c 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs @@ -249,42 +249,27 @@ namespace osu.Game.Overlays.BeatmapSet title.AddLink(titleText, LinkAction.SearchBeatmapSet, titleText); - title.AddArbitraryDrawable(new Container - { - AutoSizeAxes = Axes.Both, - Child = externalLink = new ExternalLinkButton - { - Margin = new MarginPadding { Left = 5 }, - } - }); + title.AddArbitraryDrawable(Empty().With(d => d.Width = 5)); + title.AddArbitraryDrawable(externalLink = new ExternalLinkButton()); if (setInfo.NewValue.HasExplicitContent) { - title.AddArbitraryDrawable(new Container - { - AutoSizeAxes = Axes.Both, - Child = new ExplicitContentBeatmapBadge { Margin = new MarginPadding { Left = 10 } }, - }); + title.AddArbitraryDrawable(Empty().With(d => d.Width = 10)); + title.AddArbitraryDrawable(new ExplicitContentBeatmapBadge()); } if (setInfo.NewValue.FeaturedInSpotlight) { - title.AddArbitraryDrawable(new Container - { - AutoSizeAxes = Axes.Both, - Child = new SpotlightBeatmapBadge { Margin = new MarginPadding { Left = 10 } }, - }); + title.AddArbitraryDrawable(Empty().With(d => d.Width = 10)); + title.AddArbitraryDrawable(new SpotlightBeatmapBadge()); } artist.AddLink(artistText, LinkAction.SearchBeatmapSet, artistText); if (setInfo.NewValue.TrackId != null) { - artist.AddArbitraryDrawable(new Container - { - AutoSizeAxes = Axes.Both, - Child = new FeaturedArtistBeatmapBadge { Margin = new MarginPadding { Left = 10 } } - }); + artist.AddArbitraryDrawable(Empty().With(d => d.Width = 10)); + artist.AddArbitraryDrawable(new FeaturedArtistBeatmapBadge()); } updateExternalLink(); From 973fd90af2b334229e89f87aa31790daa6bef2f1 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 25 Dec 2022 16:15:02 -0800 Subject: [PATCH 1192/2991] Fix parameters with the same default value inspection --- osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs | 4 ++-- .../Visual/Gameplay/TestScenePlayerScoreSubmission.cs | 2 +- osu.Game/Graphics/OsuFont.cs | 2 +- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs index 32d0cc8939..1e9f931b74 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs @@ -160,9 +160,9 @@ namespace osu.Game.Rulesets.Osu.Tests static bool assertSamples(HitObject hitObject) => hitObject.Samples.All(s => s.Name != HitSampleInfo.HIT_CLAP && s.Name != HitSampleInfo.HIT_WHISTLE); } - private Drawable testSimpleBig(int repeats = 0) => createSlider(2, repeats: repeats); + private Drawable testSimpleBig(int repeats = 0) => createSlider(repeats: repeats); - private Drawable testSimpleBigLargeStackOffset(int repeats = 0) => createSlider(2, repeats: repeats, stackHeight: 10); + private Drawable testSimpleBigLargeStackOffset(int repeats = 0) => createSlider(repeats: repeats, stackHeight: 10); private Drawable testDistanceOverflow(int repeats = 0) { diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerScoreSubmission.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerScoreSubmission.cs index 2fbdfbc198..d5031bc606 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerScoreSubmission.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerScoreSubmission.cs @@ -257,7 +257,7 @@ namespace osu.Game.Tests.Visual.Gameplay { prepareTestAPI(true); - createPlayerTest(false, createRuleset: () => new OsuRuleset + createPlayerTest(createRuleset: () => new OsuRuleset { RulesetInfo = { diff --git a/osu.Game/Graphics/OsuFont.cs b/osu.Game/Graphics/OsuFont.cs index 038ea0f5d7..12e82469e8 100644 --- a/osu.Game/Graphics/OsuFont.cs +++ b/osu.Game/Graphics/OsuFont.cs @@ -21,7 +21,7 @@ namespace osu.Game.Graphics public static FontUsage Numeric => GetFont(Typeface.Venera, weight: FontWeight.Bold); - public static FontUsage Torus => GetFont(Typeface.Torus, weight: FontWeight.Regular); + public static FontUsage Torus => GetFont(weight: FontWeight.Regular); public static FontUsage TorusAlternate => GetFont(Typeface.TorusAlternate, weight: FontWeight.Regular); diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 006eec2838..425f40258e 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -95,8 +95,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores new TableColumn(BeatmapsetsStrings.ShowScoreboardHeadersScore, Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)), new TableColumn(BeatmapsetsStrings.ShowScoreboardHeadersAccuracy, Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, minSize: 60, maxSize: 70)), new TableColumn("", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, 25)), // flag - new TableColumn(BeatmapsetsStrings.ShowScoreboardHeadersPlayer, Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 125)), - new TableColumn(BeatmapsetsStrings.ShowScoreboardHeadersCombo, Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 70, maxSize: 120)) + new TableColumn(BeatmapsetsStrings.ShowScoreboardHeadersPlayer, Anchor.CentreLeft, new Dimension(minSize: 125)), + new TableColumn(BeatmapsetsStrings.ShowScoreboardHeadersCombo, Anchor.CentreLeft, new Dimension(minSize: 70, maxSize: 120)) }; // All statistics across all scores, unordered. @@ -116,7 +116,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores var displayName = ruleset.GetDisplayNameForHitResult(result); - columns.Add(new TableColumn(displayName, Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 35, maxSize: 60))); + columns.Add(new TableColumn(displayName, Anchor.CentreLeft, new Dimension(minSize: 35, maxSize: 60))); statisticResultTypes.Add((result, displayName)); } From a10628e2702a7dbda3d38b35c422928f70416a73 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 25 Dec 2022 20:46:59 -0800 Subject: [PATCH 1193/2991] Change severity of `RedundantArgumentDefaultValue` to hint --- osu.sln.DotSettings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index ef3b08e1f5..367dfccb71 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -146,7 +146,7 @@ HINT HINT WARNING - WARNING + HINT WARNING WARNING WARNING From 144144c40ce3954126c493dbc7e220eab620eed2 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 25 Dec 2022 20:44:13 -0800 Subject: [PATCH 1194/2991] Revert removing redundant font parameter --- osu.Game/Graphics/OsuFont.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/OsuFont.cs b/osu.Game/Graphics/OsuFont.cs index 12e82469e8..038ea0f5d7 100644 --- a/osu.Game/Graphics/OsuFont.cs +++ b/osu.Game/Graphics/OsuFont.cs @@ -21,7 +21,7 @@ namespace osu.Game.Graphics public static FontUsage Numeric => GetFont(Typeface.Venera, weight: FontWeight.Bold); - public static FontUsage Torus => GetFont(weight: FontWeight.Regular); + public static FontUsage Torus => GetFont(Typeface.Torus, weight: FontWeight.Regular); public static FontUsage TorusAlternate => GetFont(Typeface.TorusAlternate, weight: FontWeight.Regular); From 0dba25e0abce94fe01ead03dfc30e511f511c8b0 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 25 Dec 2022 21:56:22 -0800 Subject: [PATCH 1195/2991] Refactor to just exit sub screens until lounge sub screen Co-Authored-By: Salman Ahmed --- osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs index 4a3549b33e..3d80248306 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs @@ -45,9 +45,6 @@ namespace osu.Game.Screens.OnlinePlay [Resolved] protected IAPIProvider API { get; private set; } - [Resolved(canBeNull: true)] - private IPerformFromScreenRunner performer { get; set; } - protected OnlinePlayScreen() { Anchor = Anchor.Centre; @@ -151,17 +148,13 @@ namespace osu.Game.Screens.OnlinePlay public override bool OnExiting(ScreenExitEvent e) { - if (screenStack.CurrentScreen is not LoungeSubScreen) + while (screenStack.CurrentScreen != null && screenStack.CurrentScreen is not LoungeSubScreen) { - if (performer != null) - { - performer.PerformFromScreen(_ => e.Destination.MakeCurrent(), new[] { typeof(LoungeSubScreen) }); + var subScreen = (Screen)screenStack.CurrentScreen; + if (subScreen.IsLoaded && subScreen.OnExiting(e)) return true; - } - // TODO: make isolated tests work with IPerformFromScreenRunner - if ((screenStack.CurrentScreen as Drawable)?.IsLoaded == true && screenStack.CurrentScreen.OnExiting(e)) - return true; + subScreen.Exit(); } RoomManager.PartRoom(); From 5dd03c6c60553d2d73455c89095a4839224eac3f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 26 Dec 2022 21:53:52 +0800 Subject: [PATCH 1196/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index e934b2da6a..c6cf7812d1 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -10,7 +10,7 @@ true - + From fbff5d8d69892b255c78f47b32cdd71311bbaaa1 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 26 Dec 2022 16:16:52 +0100 Subject: [PATCH 1197/2991] Remove obsoleted "ForDifficultyRating" method --- osu.Game/Graphics/OsuColour.cs | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index 91161d5c71..c5659aaf57 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -22,38 +22,8 @@ namespace osu.Game.Graphics public static Color4 Gray(byte amt) => new Color4(amt, amt, amt, 255); /// - /// Retrieves the colour for a . + /// Retrieves the colour for a given point in the star range. /// - /// - /// Sourced from the @diff-{rating} variables in https://github.com/ppy/osu-web/blob/71fbab8936d79a7929d13854f5e854b4f383b236/resources/assets/less/variables.less. - /// - public Color4 ForDifficultyRating(DifficultyRating difficulty, bool useLighterColour = false) - { - switch (difficulty) - { - case DifficultyRating.Easy: - return Color4Extensions.FromHex("4ebfff"); - - case DifficultyRating.Normal: - return Color4Extensions.FromHex("66ff91"); - - case DifficultyRating.Hard: - return Color4Extensions.FromHex("f7e85d"); - - case DifficultyRating.Insane: - return Color4Extensions.FromHex("ff7e68"); - - case DifficultyRating.Expert: - return Color4Extensions.FromHex("fe3c71"); - - case DifficultyRating.ExpertPlus: - return Color4Extensions.FromHex("6662dd"); - - default: - throw new ArgumentOutOfRangeException(nameof(difficulty)); - } - } - public Color4 ForStarDifficulty(double starDifficulty) => ColourUtils.SampleFromLinearGradient(new[] { (0.1f, Color4Extensions.FromHex("aaaaaa")), From c7ca4bbba5a9fc9a6bc12efedb66cbc61531c416 Mon Sep 17 00:00:00 2001 From: Berkan Diler Date: Mon, 26 Dec 2022 20:36:39 +0100 Subject: [PATCH 1198/2991] Use generic Enum methods --- .../Skinning/Legacy/LegacyCatcherNew.cs | 2 +- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 2 +- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 2 +- osu.Game.Tests/Mods/MultiModIncompatibilityTest.cs | 2 +- osu.Game.Tournament/IPC/FileBasedIPC.cs | 2 +- osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 4 ++-- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 8 ++++---- osu.Game/Graphics/UserInterface/OsuEnumDropdown.cs | 2 +- .../Online/API/Requests/Responses/APIRecentActivity.cs | 4 ++-- osu.Game/Online/API/Requests/Responses/APIUser.cs | 2 +- osu.Game/OsuGame.cs | 2 +- osu.Game/OsuGameBase.cs | 2 +- osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs | 3 +-- osu.Game/Rulesets/Ruleset.cs | 2 +- osu.Game/Rulesets/Scoring/HitResult.cs | 2 +- osu.Game/Screens/Edit/Setup/DesignSection.cs | 2 +- osu.Game/Screens/Utility/LatencyCertifierScreen.cs | 2 +- osu.Game/Skinning/Components/BeatmapAttributeText.cs | 2 +- osu.Game/Skinning/Skin.cs | 2 +- 20 files changed, 25 insertions(+), 26 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs index b36d7f11cb..ab753d9c86 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy [BackgroundDependencyLoader] private void load(ISkinSource skin) { - foreach (var state in Enum.GetValues(typeof(CatcherAnimationState)).Cast()) + foreach (var state in Enum.GetValues()) { AddInternal(drawables[state] = getDrawableFor(state).With(d => { diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 122330d09b..ed02284a4b 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.UI HitPolicy = new StartTimeOrderedHitPolicy(); var hitWindows = new OsuHitWindows(); - foreach (var result in Enum.GetValues(typeof(HitResult)).OfType().Where(r => r > HitResult.None && hitWindows.IsHitResultAllowed(r))) + foreach (var result in Enum.GetValues().Where(r => r > HitResult.None && hitWindows.IsHitResultAllowed(r))) poolDictionary.Add(result, new DrawableJudgementPool(result, onJudgementLoaded)); AddRangeInternal(poolDictionary.Values); diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 9493de624a..9f9debe7d7 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -190,7 +190,7 @@ namespace osu.Game.Rulesets.Taiko.UI var hitWindows = new TaikoHitWindows(); - foreach (var result in Enum.GetValues(typeof(HitResult)).OfType().Where(r => hitWindows.IsHitResultAllowed(r))) + foreach (var result in Enum.GetValues().Where(r => hitWindows.IsHitResultAllowed(r))) { judgementPools.Add(result, new DrawablePool(15)); explosionPools.Add(result, new HitExplosionPool(result)); diff --git a/osu.Game.Tests/Mods/MultiModIncompatibilityTest.cs b/osu.Game.Tests/Mods/MultiModIncompatibilityTest.cs index b8a3828a64..ca5240a39d 100644 --- a/osu.Game.Tests/Mods/MultiModIncompatibilityTest.cs +++ b/osu.Game.Tests/Mods/MultiModIncompatibilityTest.cs @@ -60,6 +60,6 @@ namespace osu.Game.Tests.Mods /// This local helper is used rather than , because the aforementioned method flattens multi mods. /// > private static IEnumerable getMultiMods(Ruleset ruleset) - => Enum.GetValues(typeof(ModType)).Cast().SelectMany(ruleset.GetModsFor).OfType(); + => Enum.GetValues().SelectMany(ruleset.GetModsFor).OfType(); } } diff --git a/osu.Game.Tournament/IPC/FileBasedIPC.cs b/osu.Game.Tournament/IPC/FileBasedIPC.cs index 2d47560947..7babb3ea5a 100644 --- a/osu.Game.Tournament/IPC/FileBasedIPC.cs +++ b/osu.Game.Tournament/IPC/FileBasedIPC.cs @@ -127,7 +127,7 @@ namespace osu.Game.Tournament.IPC using (var stream = IPCStorage.GetStream(file_ipc_state_filename)) using (var sr = new StreamReader(stream)) { - State.Value = (TourneyState)Enum.Parse(typeof(TourneyState), sr.ReadLine().AsNonNull()); + State.Value = Enum.Parse(sr.ReadLine().AsNonNull()); } } catch (Exception) diff --git a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs index eb5c9a879a..c9d897ca11 100644 --- a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs @@ -43,7 +43,7 @@ namespace osu.Game.Tournament.Screens.Editors { var countries = new List(); - foreach (var country in Enum.GetValues(typeof(CountryCode)).Cast().Skip(1)) + foreach (var country in Enum.GetValues().Skip(1)) { countries.Add(new TournamentTeam { diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 5f0a2a0824..e865fe7575 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -160,7 +160,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"SampleSet": - defaultSampleBank = (LegacySampleBank)Enum.Parse(typeof(LegacySampleBank), pair.Value); + defaultSampleBank = Enum.Parse(pair.Value); break; case @"SampleVolume": @@ -218,7 +218,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"Countdown": - beatmap.BeatmapInfo.Countdown = (CountdownType)Enum.Parse(typeof(CountdownType), pair.Value); + beatmap.BeatmapInfo.Countdown = Enum.Parse(tpair.Value); break; case @"CountdownOffset": diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 2b4f377ab6..491fee642b 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -301,11 +301,11 @@ namespace osu.Game.Beatmaps.Formats } } - private string parseLayer(string value) => Enum.Parse(typeof(LegacyStoryLayer), value).ToString(); + private string parseLayer(string value) => Enum.Parse(value).ToString(); private Anchor parseOrigin(string value) { - var origin = (LegacyOrigins)Enum.Parse(typeof(LegacyOrigins), value); + var origin = Enum.Parse(value); switch (origin) { @@ -343,8 +343,8 @@ namespace osu.Game.Beatmaps.Formats private AnimationLoopType parseAnimationLoopType(string value) { - var parsed = (AnimationLoopType)Enum.Parse(typeof(AnimationLoopType), value); - return Enum.IsDefined(typeof(AnimationLoopType), parsed) ? parsed : AnimationLoopType.LoopForever; + var parsed = Enum.Parse(value); + return Enum.IsDefined(parsed) ? parsed : AnimationLoopType.LoopForever; } private void handleVariables(string line) diff --git a/osu.Game/Graphics/UserInterface/OsuEnumDropdown.cs b/osu.Game/Graphics/UserInterface/OsuEnumDropdown.cs index 9ef58f4c49..dc089e3410 100644 --- a/osu.Game/Graphics/UserInterface/OsuEnumDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuEnumDropdown.cs @@ -12,7 +12,7 @@ namespace osu.Game.Graphics.UserInterface { public OsuEnumDropdown() { - Items = (T[])Enum.GetValues(typeof(T)); + Items = Enum.GetValues(); } } } diff --git a/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs index 2def18926f..c6a8a85407 100644 --- a/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs +++ b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs @@ -21,7 +21,7 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty] private string type { - set => Type = (RecentActivityType)Enum.Parse(typeof(RecentActivityType), value.ToPascalCase()); + set => Type = Enum.Parse(value.ToPascalCase()); } public RecentActivityType Type; @@ -29,7 +29,7 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty] private string scoreRank { - set => ScoreRank = (ScoreRank)Enum.Parse(typeof(ScoreRank), value); + set => ScoreRank = Enum.Parse(value); } public ScoreRank ScoreRank; diff --git a/osu.Game/Online/API/Requests/Responses/APIUser.cs b/osu.Game/Online/API/Requests/Responses/APIUser.cs index 2b6193f661..37a1586e49 100644 --- a/osu.Game/Online/API/Requests/Responses/APIUser.cs +++ b/osu.Game/Online/API/Requests/Responses/APIUser.cs @@ -185,7 +185,7 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"playstyle")] private string[] playStyle { - set => PlayStyles = value?.Select(str => Enum.Parse(typeof(APIPlayStyle), str, true)).Cast().ToArray(); + set => PlayStyles = value?.Select(str => Enum.Parse(str, true)).Cast().ToArray(); } public APIPlayStyle[] PlayStyles; diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 983277135d..a81aa38911 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -726,7 +726,7 @@ namespace osu.Game { base.LoadComplete(); - var languages = Enum.GetValues(typeof(Language)).OfType(); + var languages = Enum.GetValues(); var mappings = languages.Select(language => { diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 36fd5a4177..36e248c1f2 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -607,7 +607,7 @@ namespace osu.Game try { - foreach (ModType type in Enum.GetValues(typeof(ModType))) + foreach (ModType type in Enum.GetValues()) { dict[type] = instance.GetModsFor(type) // Rulesets should never return null mods, but let's be defensive just in case. diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs index 4af40e5ad6..b8d802ad4b 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenWelcome.cs @@ -79,8 +79,7 @@ namespace osu.Game.Overlays.FirstRunSetup Direction = FillDirection.Full; Spacing = new Vector2(5); - ChildrenEnumerable = Enum.GetValues(typeof(Language)) - .Cast() + ChildrenEnumerable = Enum.GetValues() .Select(l => new LanguageButton(l) { Action = () => frameworkLocale.Value = l.ToCultureCode() diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index a73151362b..fcf7a78090 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -85,7 +85,7 @@ namespace osu.Game.Rulesets /// This comes with considerable allocation overhead. If only accessing for reference purposes (ie. not changing bindables / settings) /// use instead. /// - public IEnumerable CreateAllMods() => Enum.GetValues(typeof(ModType)).Cast() + public IEnumerable CreateAllMods() => Enum.GetValues() // Confine all mods of each mod type into a single IEnumerable .SelectMany(GetModsFor) // Filter out all null mods diff --git a/osu.Game/Rulesets/Scoring/HitResult.cs b/osu.Game/Rulesets/Scoring/HitResult.cs index 96e13e5861..83ed98768c 100644 --- a/osu.Game/Rulesets/Scoring/HitResult.cs +++ b/osu.Game/Rulesets/Scoring/HitResult.cs @@ -264,7 +264,7 @@ namespace osu.Game.Rulesets.Scoring /// /// An array of all scorable s. /// - public static readonly HitResult[] ALL_TYPES = ((HitResult[])Enum.GetValues(typeof(HitResult))).Except(new[] { HitResult.LegacyComboIncrease }).ToArray(); + public static readonly HitResult[] ALL_TYPES = Enum.GetValues().Except(new[] { HitResult.LegacyComboIncrease }).ToArray(); /// /// Whether a is valid within a given range. diff --git a/osu.Game/Screens/Edit/Setup/DesignSection.cs b/osu.Game/Screens/Edit/Setup/DesignSection.cs index 3428366510..fd70b0c142 100644 --- a/osu.Game/Screens/Edit/Setup/DesignSection.cs +++ b/osu.Game/Screens/Edit/Setup/DesignSection.cs @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Edit.Setup { Label = EditorSetupStrings.CountdownSpeed, Current = { Value = Beatmap.BeatmapInfo.Countdown != CountdownType.None ? Beatmap.BeatmapInfo.Countdown : CountdownType.Normal }, - Items = Enum.GetValues(typeof(CountdownType)).Cast().Where(type => type != CountdownType.None) + Items = Enum.GetValues().Where(type => type != CountdownType.None) }, CountdownOffset = new LabelledNumberBox { diff --git a/osu.Game/Screens/Utility/LatencyCertifierScreen.cs b/osu.Game/Screens/Utility/LatencyCertifierScreen.cs index 212cebeaf5..5c8e448931 100644 --- a/osu.Game/Screens/Utility/LatencyCertifierScreen.cs +++ b/osu.Game/Screens/Utility/LatencyCertifierScreen.cs @@ -237,7 +237,7 @@ namespace osu.Game.Screens.Utility switch (e.Key) { case Key.Space: - int availableModes = Enum.GetValues(typeof(LatencyVisualMode)).Length; + int availableModes = Enum.GetValues().Length; VisualMode.Value = (LatencyVisualMode)(((int)VisualMode.Value + 1) % availableModes); return true; diff --git a/osu.Game/Skinning/Components/BeatmapAttributeText.cs b/osu.Game/Skinning/Components/BeatmapAttributeText.cs index 0a5f0d22cb..8361619574 100644 --- a/osu.Game/Skinning/Components/BeatmapAttributeText.cs +++ b/osu.Game/Skinning/Components/BeatmapAttributeText.cs @@ -115,7 +115,7 @@ namespace osu.Game.Skinning.Components .Cast() .ToArray(); - foreach (var type in Enum.GetValues(typeof(BeatmapAttribute)).Cast()) + foreach (var type in Enum.GetValues()) { numberedTemplate = numberedTemplate.Replace($"{{{{{type}}}}}", $"{{{1 + (int)type}}}"); } diff --git a/osu.Game/Skinning/Skin.cs b/osu.Game/Skinning/Skin.cs index 25d1dc903c..19e8bc7092 100644 --- a/osu.Game/Skinning/Skin.cs +++ b/osu.Game/Skinning/Skin.cs @@ -97,7 +97,7 @@ namespace osu.Game.Skinning Configuration = new SkinConfiguration(); // skininfo files may be null for default skin. - foreach (GlobalSkinComponentLookup.LookupType skinnableTarget in Enum.GetValues(typeof(GlobalSkinComponentLookup.LookupType))) + foreach (GlobalSkinComponentLookup.LookupType skinnableTarget in Enum.GetValues()) { string filename = $"{skinnableTarget}.json"; From fcbb21c75eb35a1313f9e998bed1d335f09a40a2 Mon Sep 17 00:00:00 2001 From: Berkan Diler Date: Mon, 26 Dec 2022 20:38:35 +0100 Subject: [PATCH 1199/2991] Fix typo --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index e865fe7575..9c710b690e 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -218,7 +218,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"Countdown": - beatmap.BeatmapInfo.Countdown = Enum.Parse(tpair.Value); + beatmap.BeatmapInfo.Countdown = Enum.Parse(pair.Value); break; case @"CountdownOffset": From 335cb0205fb0729afb0c54744dd4992f7510bae7 Mon Sep 17 00:00:00 2001 From: Berkan Diler Date: Mon, 26 Dec 2022 22:50:36 +0100 Subject: [PATCH 1200/2991] Remove now unnecessary using --- osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs index ab753d9c86..f6b2c52498 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; From cb2b0d41788e03e0cad4830ca6d1c854a300d0e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 26 Dec 2022 23:12:53 +0100 Subject: [PATCH 1201/2991] Remove redundant type specs --- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 2 +- osu.Game/Online/API/Requests/Responses/APIUser.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 491fee642b..44dbb3cc9f 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -344,7 +344,7 @@ namespace osu.Game.Beatmaps.Formats private AnimationLoopType parseAnimationLoopType(string value) { var parsed = Enum.Parse(value); - return Enum.IsDefined(parsed) ? parsed : AnimationLoopType.LoopForever; + return Enum.IsDefined(parsed) ? parsed : AnimationLoopType.LoopForever; } private void handleVariables(string line) diff --git a/osu.Game/Online/API/Requests/Responses/APIUser.cs b/osu.Game/Online/API/Requests/Responses/APIUser.cs index 37a1586e49..9cb0c0704d 100644 --- a/osu.Game/Online/API/Requests/Responses/APIUser.cs +++ b/osu.Game/Online/API/Requests/Responses/APIUser.cs @@ -185,7 +185,7 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"playstyle")] private string[] playStyle { - set => PlayStyles = value?.Select(str => Enum.Parse(str, true)).Cast().ToArray(); + set => PlayStyles = value?.Select(str => Enum.Parse(str, true)).ToArray(); } public APIPlayStyle[] PlayStyles; From 01cf96e240d8a9d1ea99ec072797bdf10d0f6292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 26 Dec 2022 23:25:54 +0100 Subject: [PATCH 1202/2991] Only show global rankings on results screen when progressing from gameplay --- osu.Game/Screens/Play/Player.cs | 5 +++- osu.Game/Screens/Ranking/SoloResultsScreen.cs | 23 +++++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 4306d13ac2..05133fba35 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -1159,7 +1159,10 @@ namespace osu.Game.Screens.Play /// /// The to be displayed in the results screen. /// The . - protected virtual ResultsScreen CreateResults(ScoreInfo score) => new SoloResultsScreen(score, true); + protected virtual ResultsScreen CreateResults(ScoreInfo score) => new SoloResultsScreen(score, true) + { + ShowUserStatistics = true + }; private void fadeOut(bool instant = false) { diff --git a/osu.Game/Screens/Ranking/SoloResultsScreen.cs b/osu.Game/Screens/Ranking/SoloResultsScreen.cs index 6d4feeb0db..110e813e04 100644 --- a/osu.Game/Screens/Ranking/SoloResultsScreen.cs +++ b/osu.Game/Screens/Ranking/SoloResultsScreen.cs @@ -20,6 +20,12 @@ namespace osu.Game.Screens.Ranking { public partial class SoloResultsScreen : ResultsScreen { + /// + /// Whether the user's personal statistics should be shown on the extended statistics panel + /// after clicking the score panel associated with the being presented. + /// + public bool ShowUserStatistics { get; init; } + private GetScoresRequest getScoreRequest; [Resolved] @@ -39,13 +45,22 @@ namespace osu.Game.Screens.Ranking { base.LoadComplete(); - soloStatisticsWatcher.RegisterForStatisticsUpdateAfter(Score, update => statisticsUpdate.Value = update); + if (ShowUserStatistics) + soloStatisticsWatcher.RegisterForStatisticsUpdateAfter(Score, update => statisticsUpdate.Value = update); } - protected override StatisticsPanel CreateStatisticsPanel() => new SoloStatisticsPanel(Score) + protected override StatisticsPanel CreateStatisticsPanel() { - StatisticsUpdate = { BindTarget = statisticsUpdate } - }; + if (ShowUserStatistics) + { + return new SoloStatisticsPanel(Score) + { + StatisticsUpdate = { BindTarget = statisticsUpdate } + }; + } + + return base.CreateStatisticsPanel(); + } protected override APIRequest FetchScores(Action> scoresCallback) { From 84e3858a86bf6a613456ab37e8e73f406287a602 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 26 Dec 2022 15:37:46 -0800 Subject: [PATCH 1203/2991] Move context menu / popover container one level to account for header --- osu.Game/Overlays/OnlineOverlay.cs | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/OnlineOverlay.cs b/osu.Game/Overlays/OnlineOverlay.cs index ff225bd4ab..4fdf7cb2b6 100644 --- a/osu.Game/Overlays/OnlineOverlay.cs +++ b/osu.Game/Overlays/OnlineOverlay.cs @@ -39,25 +39,30 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.Both, ScrollbarVisible = false, - Child = new FillFlowContainer + Child = new OsuContextMenuContainer { - AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - Children = new Drawable[] + AutoSizeAxes = Axes.Y, + Child = new PopoverContainer { - Header.With(h => h.Depth = float.MinValue), - new OsuContextMenuContainer + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Child = content = new PopoverContainer + Direction = FillDirection.Vertical, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y + Header.With(h => h.Depth = float.MinValue), + content = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y + } } } - } + }, } }, Loading = new LoadingLayer(true) From 8bc8b0d0af3f2f8b8e043e4ffc85a660c64f6bac Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 26 Dec 2022 15:38:07 -0800 Subject: [PATCH 1204/2991] Remove redundant context menu container --- .../BeatmapSet/BeatmapSetHeaderContent.cs | 182 +++++++++--------- 1 file changed, 88 insertions(+), 94 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs index 0318dad0e3..3eec4b4731 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs @@ -9,7 +9,6 @@ using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; -using osu.Game.Graphics.Cursor; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; @@ -91,118 +90,113 @@ namespace osu.Game.Overlays.BeatmapSet }, }, }, - new OsuContextMenuContainer + new Container { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Child = new Container + Padding = new MarginPadding { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding + Vertical = BeatmapSetOverlay.Y_PADDING, + Left = BeatmapSetOverlay.X_PADDING, + Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH, + }, + Children = new Drawable[] + { + fadeContent = new FillFlowContainer { - Vertical = BeatmapSetOverlay.Y_PADDING, - Left = BeatmapSetOverlay.X_PADDING, - Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH, - }, - Children = new Drawable[] - { - fadeContent = new FillFlowContainer + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new Drawable[] + new Container { - new Container + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = Picker = new BeatmapPicker(), + }, + new FillFlowContainer + { + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Top = 15 }, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Child = Picker = new BeatmapPicker(), - }, - new FillFlowContainer - { - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Top = 15 }, - Children = new Drawable[] + title = new OsuSpriteText { - title = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 30, weight: FontWeight.SemiBold, italics: true) - }, - externalLink = new ExternalLinkButton - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Left = 5, Bottom = 4 }, // To better lineup with the font - }, - explicitContent = new ExplicitContentBeatmapBadge - { - Alpha = 0f, - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Left = 10, Bottom = 4 }, - }, - spotlight = new SpotlightBeatmapBadge - { - Alpha = 0f, - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Left = 10, Bottom = 4 }, - } + Font = OsuFont.GetFont(size: 30, weight: FontWeight.SemiBold, italics: true) + }, + externalLink = new ExternalLinkButton + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Margin = new MarginPadding { Left = 5, Bottom = 4 }, // To better lineup with the font + }, + explicitContent = new ExplicitContentBeatmapBadge + { + Alpha = 0f, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Margin = new MarginPadding { Left = 10, Bottom = 4 }, + }, + spotlight = new SpotlightBeatmapBadge + { + Alpha = 0f, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Margin = new MarginPadding { Left = 10, Bottom = 4 }, } - }, - new FillFlowContainer + } + }, + new FillFlowContainer + { + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Bottom = 20 }, + Children = new Drawable[] { - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Bottom = 20 }, - Children = new Drawable[] + artist = new OsuSpriteText { - artist = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true), - }, - featuredArtist = new FeaturedArtistBeatmapBadge - { - Alpha = 0f, - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Left = 10 } - } + Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true), + }, + featuredArtist = new FeaturedArtistBeatmapBadge + { + Alpha = 0f, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Margin = new MarginPadding { Left = 10 } } - }, - new Container + } + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = author = new AuthorInfo(), + }, + beatmapAvailability = new BeatmapAvailability(), + new Container + { + RelativeSizeAxes = Axes.X, + Height = buttons_height, + Margin = new MarginPadding { Top = 10 }, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Child = author = new AuthorInfo(), - }, - beatmapAvailability = new BeatmapAvailability(), - new Container - { - RelativeSizeAxes = Axes.X, - Height = buttons_height, - Margin = new MarginPadding { Top = 10 }, - Children = new Drawable[] + favouriteButton = new FavouriteButton { - favouriteButton = new FavouriteButton - { - BeatmapSet = { BindTarget = BeatmapSet } - }, - downloadButtonsContainer = new FillFlowContainer - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = buttons_height + buttons_spacing }, - Spacing = new Vector2(buttons_spacing), - }, + BeatmapSet = { BindTarget = BeatmapSet } + }, + downloadButtonsContainer = new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = buttons_height + buttons_spacing }, + Spacing = new Vector2(buttons_spacing), }, }, }, }, - } - }, + }, + } }, loading = new LoadingSpinner { From a0690e7ffb1bb1f2ea81ea65090a4b0b890b619b Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Mon, 26 Dec 2022 22:23:31 +0000 Subject: [PATCH 1205/2991] replay menus remembers expanded state no messing with readonly fields --- .../NonVisual/SessionStaticsTest.cs | 6 ++++++ osu.Game/Configuration/SessionStatics.cs | 4 ++++ .../Screens/Play/HUD/PlayerSettingsOverlay.cs | 19 ++++++++++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/NonVisual/SessionStaticsTest.cs b/osu.Game.Tests/NonVisual/SessionStaticsTest.cs index 5c8254b947..499c0e5d34 100644 --- a/osu.Game.Tests/NonVisual/SessionStaticsTest.cs +++ b/osu.Game.Tests/NonVisual/SessionStaticsTest.cs @@ -24,12 +24,16 @@ namespace osu.Game.Tests.NonVisual sessionStatics.SetValue(Static.MutedAudioNotificationShownOnce, true); sessionStatics.SetValue(Static.LowBatteryNotificationShownOnce, true); sessionStatics.SetValue(Static.LastHoverSoundPlaybackTime, (double?)1d); + sessionStatics.SetValue(Static.ReplayPlaybackSettingExpanded, false); + sessionStatics.SetValue(Static.ReplayVisualSettingsExpanded, true); sessionStatics.SetValue(Static.SeasonalBackgrounds, new APISeasonalBackgrounds { EndDate = new DateTimeOffset(2022, 1, 1, 0, 0, 0, TimeSpan.Zero) }); Assert.IsFalse(sessionStatics.GetBindable(Static.LoginOverlayDisplayed).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.MutedAudioNotificationShownOnce).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.LowBatteryNotificationShownOnce).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.LastHoverSoundPlaybackTime).IsDefault); + Assert.IsFalse(sessionStatics.GetBindable(Static.ReplayPlaybackSettingExpanded).IsDefault); + Assert.IsFalse(sessionStatics.GetBindable(Static.ReplayVisualSettingsExpanded).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.SeasonalBackgrounds).IsDefault); sessionStatics.ResetAfterInactivity(); @@ -39,6 +43,8 @@ namespace osu.Game.Tests.NonVisual Assert.IsTrue(sessionStatics.GetBindable(Static.LowBatteryNotificationShownOnce).IsDefault); // some statics should not reset despite inactivity. Assert.IsFalse(sessionStatics.GetBindable(Static.LastHoverSoundPlaybackTime).IsDefault); + Assert.IsFalse(sessionStatics.GetBindable(Static.ReplayPlaybackSettingExpanded).IsDefault); + Assert.IsFalse(sessionStatics.GetBindable(Static.ReplayVisualSettingsExpanded).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.SeasonalBackgrounds).IsDefault); } } diff --git a/osu.Game/Configuration/SessionStatics.cs b/osu.Game/Configuration/SessionStatics.cs index 12a30a0c84..f08658f182 100644 --- a/osu.Game/Configuration/SessionStatics.cs +++ b/osu.Game/Configuration/SessionStatics.cs @@ -20,6 +20,8 @@ namespace osu.Game.Configuration SetDefault(Static.MutedAudioNotificationShownOnce, false); SetDefault(Static.LowBatteryNotificationShownOnce, false); SetDefault(Static.LastHoverSoundPlaybackTime, (double?)null); + SetDefault(Static.ReplayPlaybackSettingExpanded, true); + SetDefault(Static.ReplayVisualSettingsExpanded, false); SetDefault(Static.SeasonalBackgrounds, null); } @@ -42,6 +44,8 @@ namespace osu.Game.Configuration LoginOverlayDisplayed, MutedAudioNotificationShownOnce, LowBatteryNotificationShownOnce, + ReplayPlaybackSettingExpanded, + ReplayVisualSettingsExpanded, /// /// Info about seasonal backgrounds available fetched from API - see . diff --git a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs index 5f6f040959..c4f07f77cd 100644 --- a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs +++ b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs @@ -3,12 +3,15 @@ #nullable disable +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; using osuTK; using osu.Game.Screens.Play.PlayerSettings; using osuTK.Input; +using osu.Game.Configuration; +using osu.Framework.Allocation; namespace osu.Game.Screens.Play.HUD { @@ -16,6 +19,10 @@ namespace osu.Game.Screens.Play.HUD { private const int fade_duration = 200; + private Bindable playbackMenuExpanded; + + private Bindable visualMenuExpanded; + public bool ReplayLoaded; public readonly PlaybackSettings PlaybackSettings; @@ -42,11 +49,21 @@ namespace osu.Game.Screens.Play.HUD //CollectionSettings = new CollectionSettings(), //DiscussionSettings = new DiscussionSettings(), PlaybackSettings = new PlaybackSettings(), - VisualSettings = new VisualSettings { Expanded = { Value = false } } + VisualSettings = new VisualSettings() } }; } + [BackgroundDependencyLoader] + private void load(SessionStatics statics) + { + playbackMenuExpanded = statics.GetBindable(Static.ReplayPlaybackSettingExpanded); + visualMenuExpanded = statics.GetBindable(Static.ReplayVisualSettingsExpanded); + + PlaybackSettings.Expanded.BindTo(playbackMenuExpanded); + VisualSettings.Expanded.BindTo(visualMenuExpanded); + } + protected override void PopIn() => this.FadeIn(fade_duration); protected override void PopOut() => this.FadeOut(fade_duration); From 777ffcf805f07954377832a869472afee8c09a0a Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 26 Dec 2022 20:45:32 -0800 Subject: [PATCH 1206/2991] Highlight "open" option on external link button context menu --- osu.Game/Graphics/UserInterface/ExternalLinkButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/ExternalLinkButton.cs b/osu.Game/Graphics/UserInterface/ExternalLinkButton.cs index efbbaaca85..4eccb37613 100644 --- a/osu.Game/Graphics/UserInterface/ExternalLinkButton.cs +++ b/osu.Game/Graphics/UserInterface/ExternalLinkButton.cs @@ -82,7 +82,7 @@ namespace osu.Game.Graphics.UserInterface if (Link != null) { - items.Add(new OsuMenuItem("Open", MenuItemType.Standard, () => host.OpenUrlExternally(Link))); + items.Add(new OsuMenuItem("Open", MenuItemType.Highlighted, () => host.OpenUrlExternally(Link))); items.Add(new OsuMenuItem("Copy URL", MenuItemType.Standard, copyUrl)); } From 182f36c434bd2b60895403cf07a1adde88912067 Mon Sep 17 00:00:00 2001 From: Berkan Diler Date: Tue, 27 Dec 2022 09:41:58 +0100 Subject: [PATCH 1207/2991] Use StringSplitOptions.TrimEntries for string.Split() when possible --- .../Screens/Drawings/Components/StorageBackedTeamList.cs | 8 ++++---- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 8 +------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tournament/Screens/Drawings/Components/StorageBackedTeamList.cs b/osu.Game.Tournament/Screens/Drawings/Components/StorageBackedTeamList.cs index c230607343..74afb42c1a 100644 --- a/osu.Game.Tournament/Screens/Drawings/Components/StorageBackedTeamList.cs +++ b/osu.Game.Tournament/Screens/Drawings/Components/StorageBackedTeamList.cs @@ -45,7 +45,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components continue; // ReSharper disable once PossibleNullReferenceException - string[] split = line.Split(':'); + string[] split = line.Split(':', StringSplitOptions.TrimEntries); if (split.Length < 2) { @@ -55,9 +55,9 @@ namespace osu.Game.Tournament.Screens.Drawings.Components teams.Add(new TournamentTeam { - FullName = { Value = split[1].Trim(), }, - Acronym = { Value = split.Length >= 3 ? split[2].Trim() : null, }, - FlagName = { Value = split[0].Trim() } + FullName = { Value = split[1], }, + Acronym = { Value = split.Length >= 3 ? split[2] : null, }, + FlagName = { Value = split[0] } }); } } diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index a4e15f790a..704756e3dd 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -132,13 +132,7 @@ namespace osu.Game.Beatmaps.Formats protected KeyValuePair SplitKeyVal(string line, char separator = ':', bool shouldTrim = true) { - string[] split = line.Split(separator, 2); - - if (shouldTrim) - { - for (int i = 0; i < split.Length; i++) - split[i] = split[i].Trim(); - } + string[] split = line.Split(separator, 2, shouldTrim ? StringSplitOptions.TrimEntries : StringSplitOptions.None); return new KeyValuePair ( From b3e44f20bca94f78599500027eaaa7ce164f8e65 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 26 Dec 2022 21:53:41 +0800 Subject: [PATCH 1208/2991] Use new lazer API endpoint This is a temporary change to target the new experimental/next deploy. The main change that should result from this is having the user profile show the pp^next values from the new domain. --- osu.Game/Online/ProductionEndpointConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/ProductionEndpointConfiguration.cs b/osu.Game/Online/ProductionEndpointConfiguration.cs index 316452280d..3a74d24b58 100644 --- a/osu.Game/Online/ProductionEndpointConfiguration.cs +++ b/osu.Game/Online/ProductionEndpointConfiguration.cs @@ -9,7 +9,7 @@ namespace osu.Game.Online { public ProductionEndpointConfiguration() { - WebsiteRootUrl = APIEndpointUrl = @"https://osu.ppy.sh"; + WebsiteRootUrl = APIEndpointUrl = @"https://lazer.ppy.sh"; APIClientSecret = @"FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk"; APIClientID = "5"; SpectatorEndpointUrl = "https://spectator.ppy.sh/spectator"; From 61029b126d03f00bea9b7ecfa3862452fcf7c7e9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 27 Dec 2022 17:50:30 +0800 Subject: [PATCH 1209/2991] Add link to hard link explanation wiki page --- osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index 8b85bb49a5..0f8a78453d 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -22,6 +22,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Localisation; +using osu.Game.Online.Chat; using osu.Game.Overlays.Settings; using osu.Game.Overlays.Settings.Sections.Maintenance; using osu.Game.Screens.Edit.Setup; @@ -127,7 +128,9 @@ namespace osu.Game.Overlays.FirstRunSetup if (available) { copyInformation.Text = - "Data migration will use \"hard links\". No extra disk space will be used, and you can delete either data folder at any point without affecting the other installation."; + "Data migration will use \"hard links\". No extra disk space will be used, and you can delete either data folder at any point without affecting the other installation. "; + + copyInformation.AddLink("Learn more about how \"hard links\" work", LinkAction.OpenWiki, @"Client/Release_stream/Lazer/File_storage#via-hard-links"); } else if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows) copyInformation.Text = "Lightweight linking of files is not supported on your operating system yet, so a copy of all files will be made during import."; From 1a4489edb28c98907fda40551bd7f42f66174d2e Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 27 Dec 2022 14:55:51 +0300 Subject: [PATCH 1210/2991] Move version pinning of system packages to `osu.Game` --- osu.Game/osu.Game.csproj | 5 +++++ osu.iOS.props | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index da14ed123f..cce3e42be4 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -43,5 +43,10 @@ + + + + + diff --git a/osu.iOS.props b/osu.iOS.props index 9b9abfc37b..6201022da1 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -17,10 +17,5 @@ - - - - - From e2703bba188b606760c74023f4cf7d62fdd8792a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 27 Dec 2022 19:48:18 +0100 Subject: [PATCH 1211/2991] Fix invalid data in test scene --- .../Visual/Ranking/TestSceneOverallRanking.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs b/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs index 2edc577a95..355a572f95 100644 --- a/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs +++ b/osu.Game.Tests/Visual/Ranking/TestSceneOverallRanking.cs @@ -28,7 +28,7 @@ namespace osu.Game.Tests.Visual.Ranking new UserStatistics { GlobalRank = 12_345, - Accuracy = 0.9899, + Accuracy = 98.99, MaxCombo = 2_322, RankedScore = 23_123_543_456, TotalScore = 123_123_543_456, @@ -37,7 +37,7 @@ namespace osu.Game.Tests.Visual.Ranking new UserStatistics { GlobalRank = 1_234, - Accuracy = 0.9907, + Accuracy = 99.07, MaxCombo = 2_352, RankedScore = 23_124_231_435, TotalScore = 123_124_231_435, @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual.Ranking new UserStatistics { GlobalRank = 1_234, - Accuracy = 0.9907, + Accuracy = 99.07, MaxCombo = 2_352, RankedScore = 23_124_231_435, TotalScore = 123_124_231_435, @@ -62,7 +62,7 @@ namespace osu.Game.Tests.Visual.Ranking new UserStatistics { GlobalRank = 12_345, - Accuracy = 0.9899, + Accuracy = 98.99, MaxCombo = 2_322, RankedScore = 23_123_543_456, TotalScore = 123_123_543_456, @@ -76,7 +76,7 @@ namespace osu.Game.Tests.Visual.Ranking var statistics = new UserStatistics { GlobalRank = 12_345, - Accuracy = 0.9899, + Accuracy = 98.99, MaxCombo = 2_322, RankedScore = 23_123_543_456, TotalScore = 123_123_543_456, @@ -93,7 +93,7 @@ namespace osu.Game.Tests.Visual.Ranking var statistics = new UserStatistics { GlobalRank = null, - Accuracy = 0.9899, + Accuracy = 98.99, MaxCombo = 2_322, RankedScore = 23_123_543_456, TotalScore = 123_123_543_456, From e90619244da7ff3151c329193c4e80a4f602daa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 27 Dec 2022 19:51:51 +0100 Subject: [PATCH 1212/2991] Fix incorrect accuracy display on overall ranking view --- osu.Game/Screens/Ranking/Statistics/User/AccuracyChangeRow.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Ranking/Statistics/User/AccuracyChangeRow.cs b/osu.Game/Screens/Ranking/Statistics/User/AccuracyChangeRow.cs index 0f5dd9074a..0fd666e9d0 100644 --- a/osu.Game/Screens/Ranking/Statistics/User/AccuracyChangeRow.cs +++ b/osu.Game/Screens/Ranking/Statistics/User/AccuracyChangeRow.cs @@ -16,11 +16,11 @@ namespace osu.Game.Screens.Ranking.Statistics.User protected override LocalisableString Label => UsersStrings.ShowStatsHitAccuracy; - protected override LocalisableString FormatCurrentValue(double current) => current.FormatAccuracy(); + protected override LocalisableString FormatCurrentValue(double current) => (current / 100).FormatAccuracy(); protected override int CalculateDifference(double previous, double current, out LocalisableString formattedDifference) { - double difference = current - previous; + double difference = (current - previous) / 100; if (difference < 0) formattedDifference = difference.FormatAccuracy(); From 0d78bc224826fc70deaf961ba0c4b5a997cb8e71 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 28 Dec 2022 06:42:32 +0800 Subject: [PATCH 1213/2991] Fix `osu.ppy.sh` links no longer opening in-game Addresses https://github.com/ppy/osu/discussions/21838. --- osu.Game/Online/ProductionEndpointConfiguration.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/ProductionEndpointConfiguration.cs b/osu.Game/Online/ProductionEndpointConfiguration.cs index 3a74d24b58..003ec50afd 100644 --- a/osu.Game/Online/ProductionEndpointConfiguration.cs +++ b/osu.Game/Online/ProductionEndpointConfiguration.cs @@ -9,7 +9,8 @@ namespace osu.Game.Online { public ProductionEndpointConfiguration() { - WebsiteRootUrl = APIEndpointUrl = @"https://lazer.ppy.sh"; + WebsiteRootUrl = @"https://osu.ppy.sh"; + APIEndpointUrl = @"https://lazer.ppy.sh"; APIClientSecret = @"FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk"; APIClientID = "5"; SpectatorEndpointUrl = "https://spectator.ppy.sh/spectator"; From e9d32fca18151036b7d2ba95fc7bae8f771671d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 28 Dec 2022 07:28:18 +0100 Subject: [PATCH 1214/2991] Fix various failures in initial statistics fetch - If the local user is restricted, then attempting to fetch their data from the `/users` endpoint would result in an empty response. - Even if the user was successfully fetched, their `RulesetsStatistics` may not be populated (and instead be `null`). Curiously this was not picked up by static analysis until the first issue was fixed. Closes #21839. --- osu.Game/Online/Solo/SoloStatisticsWatcher.cs | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs index 33344044b9..b2f371fd74 100644 --- a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs +++ b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs @@ -75,15 +75,27 @@ namespace osu.Game.Online.Solo return; var userRequest = new GetUsersRequest(new[] { localUser.OnlineID }); - userRequest.Success += response => Schedule(() => - { - latestStatistics = new Dictionary(); - foreach (var rulesetStats in response.Users.Single().RulesetsStatistics) - latestStatistics.Add(rulesetStats.Key, rulesetStats.Value); - }); + userRequest.Success += initialiseUserStatistics; api.Queue(userRequest); }); + private void initialiseUserStatistics(GetUsersResponse response) => Schedule(() => + { + var user = response.Users.SingleOrDefault(); + + // possible if the user is restricted or similar. + if (user == null) + return; + + latestStatistics = new Dictionary(); + + if (user.RulesetsStatistics != null) + { + foreach (var rulesetStats in user.RulesetsStatistics) + latestStatistics.Add(rulesetStats.Key, rulesetStats.Value); + } + }); + private void userScoreProcessed(int userId, long scoreId) { if (userId != api.LocalUser.Value?.OnlineID) From a0a26b1e8c257b40dc66ad62be754afcd8a7edda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 28 Dec 2022 07:37:52 +0100 Subject: [PATCH 1215/2991] Ignore statistics update subscriptions with invalid score ID If score submission fails, the score will not receive a correct online ID from web, but will still be passed on to the solo statistics watcher on the results screen. This could lead to the watcher subscribing to changes with score ID equal to the default of -1. If this happened more than once, that would cause a crash due to duplicate keys in the `callbacks` dictionary. Closes #21837. --- osu.Game/Online/Solo/SoloStatisticsWatcher.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs index b2f371fd74..235abde068 100644 --- a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs +++ b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs @@ -51,7 +51,7 @@ namespace osu.Game.Online.Solo if (!api.IsLoggedIn) return; - if (!score.Ruleset.IsLegacyRuleset()) + if (!score.Ruleset.IsLegacyRuleset() || score.OnlineID <= 0) return; var callback = new StatisticsUpdateCallback(score, onUpdateReady); From 04f9a354c3fb6e695e4cad4bfddd31b5ac8c03e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 28 Dec 2022 07:49:09 +0100 Subject: [PATCH 1216/2991] Convert `SoloResultsScreen` to NRT --- osu.Game/Screens/Ranking/SoloResultsScreen.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Ranking/SoloResultsScreen.cs b/osu.Game/Screens/Ranking/SoloResultsScreen.cs index 110e813e04..94d333c2da 100644 --- a/osu.Game/Screens/Ranking/SoloResultsScreen.cs +++ b/osu.Game/Screens/Ranking/SoloResultsScreen.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -26,15 +24,15 @@ namespace osu.Game.Screens.Ranking /// public bool ShowUserStatistics { get; init; } - private GetScoresRequest getScoreRequest; + private GetScoresRequest? getScoreRequest; [Resolved] - private RulesetStore rulesets { get; set; } + private RulesetStore rulesets { get; set; } = null!; [Resolved] - private SoloStatisticsWatcher soloStatisticsWatcher { get; set; } + private SoloStatisticsWatcher soloStatisticsWatcher { get; set; } = null!; - private readonly Bindable statisticsUpdate = new Bindable(); + private readonly Bindable statisticsUpdate = new Bindable(); public SoloResultsScreen(ScoreInfo score, bool allowRetry) : base(score, allowRetry) @@ -62,7 +60,7 @@ namespace osu.Game.Screens.Ranking return base.CreateStatisticsPanel(); } - protected override APIRequest FetchScores(Action> scoresCallback) + protected override APIRequest? FetchScores(Action>? scoresCallback) { if (Score.BeatmapInfo.OnlineID <= 0 || Score.BeatmapInfo.Status <= BeatmapOnlineStatus.Pending) return null; From 3c0b8af8f1dbf19dbd9496c85d3555354fff7e3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 28 Dec 2022 07:50:10 +0100 Subject: [PATCH 1217/2991] Allow unsubscribing from solo statistics updates This is more of a safety item. To avoid potential duplicate key in dictionary errors (and also avoid being slightly memory-leaky), allow `SoloStatisticsWatcher` consumers to dispose of the subscriptions they take out. --- .../Online/TestSceneSoloStatisticsWatcher.cs | 24 ++++++++++++- osu.Game/Online/Solo/SoloStatisticsWatcher.cs | 36 +++++++++++-------- osu.Game/Screens/Ranking/SoloResultsScreen.cs | 4 ++- 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneSoloStatisticsWatcher.cs b/osu.Game.Tests/Visual/Online/TestSceneSoloStatisticsWatcher.cs index b1badc6282..e62e53bd02 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneSoloStatisticsWatcher.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneSoloStatisticsWatcher.cs @@ -35,6 +35,8 @@ namespace osu.Game.Tests.Visual.Online private Action? handleGetUsersRequest; private Action? handleGetUserRequest; + private IDisposable? subscription; + private readonly Dictionary<(int userId, string rulesetName), UserStatistics> serverSideStatistics = new Dictionary<(int userId, string rulesetName), UserStatistics>(); [SetUpSteps] @@ -246,6 +248,26 @@ namespace osu.Game.Tests.Visual.Online AddAssert("values after are correct", () => update!.After.TotalScore, () => Is.EqualTo(6_000_000)); } + [Test] + public void TestStatisticsUpdateNotFiredAfterSubscriptionDisposal() + { + int userId = getUserId(); + setUpUser(userId); + + long scoreId = getScoreId(); + var ruleset = new OsuRuleset().RulesetInfo; + + SoloStatisticsUpdate? update = null; + registerForUpdates(scoreId, ruleset, receivedUpdate => update = receivedUpdate); + AddStep("unsubscribe", () => subscription!.Dispose()); + + feignScoreProcessing(userId, ruleset, 5_000_000); + + AddStep("signal score processed", () => ((ISpectatorClient)spectatorClient).UserScoreProcessed(userId, scoreId)); + AddWaitStep("wait a bit", 5); + AddAssert("update not received", () => update == null); + } + private int nextUserId = 2000; private long nextScoreId = 50000; @@ -266,7 +288,7 @@ namespace osu.Game.Tests.Visual.Online } private void registerForUpdates(long scoreId, RulesetInfo rulesetInfo, Action onUpdateReady) => - AddStep("register for updates", () => watcher.RegisterForStatisticsUpdateAfter( + AddStep("register for updates", () => subscription = watcher.RegisterForStatisticsUpdateAfter( new ScoreInfo(Beatmap.Value.BeatmapInfo, new OsuRuleset().RulesetInfo, new RealmUser()) { Ruleset = rulesetInfo, diff --git a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs index 235abde068..46449fea73 100644 --- a/osu.Game/Online/Solo/SoloStatisticsWatcher.cs +++ b/osu.Game/Online/Solo/SoloStatisticsWatcher.cs @@ -46,24 +46,30 @@ namespace osu.Game.Online.Solo /// /// The score to listen for the statistics update for. /// The callback to be invoked once the statistics update has been prepared. - public void RegisterForStatisticsUpdateAfter(ScoreInfo score, Action onUpdateReady) => Schedule(() => + /// An representing the subscription. Disposing it is equivalent to unsubscribing from future notifications. + public IDisposable RegisterForStatisticsUpdateAfter(ScoreInfo score, Action onUpdateReady) { - if (!api.IsLoggedIn) - return; - - if (!score.Ruleset.IsLegacyRuleset() || score.OnlineID <= 0) - return; - - var callback = new StatisticsUpdateCallback(score, onUpdateReady); - - if (lastProcessedScoreId == score.OnlineID) + Schedule(() => { - requestStatisticsUpdate(api.LocalUser.Value.Id, callback); - return; - } + if (!api.IsLoggedIn) + return; - callbacks.Add(score.OnlineID, callback); - }); + if (!score.Ruleset.IsLegacyRuleset() || score.OnlineID <= 0) + return; + + var callback = new StatisticsUpdateCallback(score, onUpdateReady); + + if (lastProcessedScoreId == score.OnlineID) + { + requestStatisticsUpdate(api.LocalUser.Value.Id, callback); + return; + } + + callbacks.Add(score.OnlineID, callback); + }); + + return new InvokeOnDisposal(() => Schedule(() => callbacks.Remove(score.OnlineID))); + } private void onUserChanged(APIUser? localUser) => Schedule(() => { diff --git a/osu.Game/Screens/Ranking/SoloResultsScreen.cs b/osu.Game/Screens/Ranking/SoloResultsScreen.cs index 94d333c2da..c8920a734d 100644 --- a/osu.Game/Screens/Ranking/SoloResultsScreen.cs +++ b/osu.Game/Screens/Ranking/SoloResultsScreen.cs @@ -32,6 +32,7 @@ namespace osu.Game.Screens.Ranking [Resolved] private SoloStatisticsWatcher soloStatisticsWatcher { get; set; } = null!; + private IDisposable? statisticsSubscription; private readonly Bindable statisticsUpdate = new Bindable(); public SoloResultsScreen(ScoreInfo score, bool allowRetry) @@ -44,7 +45,7 @@ namespace osu.Game.Screens.Ranking base.LoadComplete(); if (ShowUserStatistics) - soloStatisticsWatcher.RegisterForStatisticsUpdateAfter(Score, update => statisticsUpdate.Value = update); + statisticsSubscription = soloStatisticsWatcher.RegisterForStatisticsUpdateAfter(Score, update => statisticsUpdate.Value = update); } protected override StatisticsPanel CreateStatisticsPanel() @@ -75,6 +76,7 @@ namespace osu.Game.Screens.Ranking base.Dispose(isDisposing); getScoreRequest?.Cancel(); + statisticsSubscription?.Dispose(); } } } From 76367444cbebff0d893ae941df3e0179d9d9c3d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 28 Dec 2022 10:36:54 +0100 Subject: [PATCH 1218/2991] Adjust Android package versioning to .NET 6 With .NET 6, the way Xamarin package versioning works has changed. - The `ApplicationVersion` MSBuild property aims to replace `android:versionCode` in the manifest. - The `ApplicationDisplayVersion` MSBuild property aims to replace `android:versionName` in the manifest. More about this can be read in Xamarin docs: https://github.com/xamarin/xamarin-android/blob/ec712da8c1ce03f71578e08cafb6a767cdb90cd5/Documentation/guides/OneDotNetSingleProject.md To this end: - Manual `version{Code,Name}` specs are removed from `AndroidManifest.xml`, as they were preventing MSBuild properties from functioning properly. - `Version` now defaults to 0.0.0, so that local builds don't appear like they were deployed (see `OsuGameBase.IsDeployedBuild`). - `ApplicationDisplayVersion` now defaults to `Version`. This addresses the Android portion of #21498. - `ApplicationVersion` can now be specified by command line, but still needs to be supplied manually for version detection to work correctly. See `OsuGameAndroid.AssemblyVersion` for more info. Putting the pieces together, the complete publish command to deploy a new build should look something like so: dotnet publish -f net6.0-android \ -r android-arm64 \ -c Release \ -p:Version=2022.1228.0 \ -p:ApplicationVersion=202212280 --- osu.Android/AndroidManifest.xml | 2 +- osu.Android/osu.Android.csproj | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Android/AndroidManifest.xml b/osu.Android/AndroidManifest.xml index be326be5eb..bc2f49b1a9 100644 --- a/osu.Android/AndroidManifest.xml +++ b/osu.Android/AndroidManifest.xml @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/osu.Android/osu.Android.csproj b/osu.Android/osu.Android.csproj index de53e5dd59..1507bfaa29 100644 --- a/osu.Android/osu.Android.csproj +++ b/osu.Android/osu.Android.csproj @@ -8,6 +8,9 @@ true false + 0.0.0 + 1 + $(Version) From b4c5e18da0347872e068086d6954d3321721ad1a Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 28 Dec 2022 13:23:46 +0300 Subject: [PATCH 1219/2991] Add keywords to ease search of "first object visibility" setting --- osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs index 69e24bc616..f6b3c12487 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs @@ -27,6 +27,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { LabelText = GameplaySettingsStrings.IncreaseFirstObjectVisibility, Current = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility), + Keywords = new[] { @"approach", @"circle", @"hidden" }, }, }; } From 9021cf7be6b4b6f271f7159c215e13878f95c3ec Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Wed, 28 Dec 2022 11:42:34 +0100 Subject: [PATCH 1220/2991] Allow aspect ratios smaller than the default in taiko --- osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs index 79c5c36e08..d42aaddf9e 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Taiko.UI float height = default_relative_height; - if (LockPlayfieldAspect.Value) + if (LockPlayfieldAspect.Value && Parent.ChildSize.X / Parent.ChildSize.Y > default_aspect) height *= Math.Clamp(Parent.ChildSize.X / Parent.ChildSize.Y, 0.4f, 4) / default_aspect; Height = height; From b2aa2e16029d984109049fce98c58466be867709 Mon Sep 17 00:00:00 2001 From: BlauFx Date: Wed, 28 Dec 2022 13:23:07 +0100 Subject: [PATCH 1221/2991] Add hardlink support for Linux --- osu.Game/Database/RealmFileStore.cs | 16 +++++++++++---- osu.Game/IO/HardLinkHelper.cs | 20 ++++++++++++++----- .../FirstRunSetup/ScreenImportFromStable.cs | 2 +- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/osu.Game/Database/RealmFileStore.cs b/osu.Game/Database/RealmFileStore.cs index 04b503b808..49102d81e5 100644 --- a/osu.Game/Database/RealmFileStore.cs +++ b/osu.Game/Database/RealmFileStore.cs @@ -63,11 +63,19 @@ namespace osu.Game.Database private void copyToStore(RealmFile file, Stream data, bool preferHardLinks) { - if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows && data is FileStream fs && preferHardLinks) + // attempt to do a fast hard link rather than copy. + if (data is FileStream fs && preferHardLinks) { - // attempt to do a fast hard link rather than copy. - if (HardLinkHelper.CreateHardLink(Storage.GetFullPath(file.GetStoragePath(), true), fs.Name, IntPtr.Zero)) - return; + if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows) + { + if (HardLinkHelper.CreateHardLink(Storage.GetFullPath(file.GetStoragePath(), true), fs.Name, IntPtr.Zero)) + return; + } + else if (RuntimeInfo.OS == RuntimeInfo.Platform.Linux) + { + if (HardLinkHelper.link(fs.Name, Storage.GetFullPath(file.GetStoragePath(), true)) == 0) + return; + } } data.Seek(0, SeekOrigin.Begin); diff --git a/osu.Game/IO/HardLinkHelper.cs b/osu.Game/IO/HardLinkHelper.cs index 1393bf26fd..8d521bab9f 100644 --- a/osu.Game/IO/HardLinkHelper.cs +++ b/osu.Game/IO/HardLinkHelper.cs @@ -14,9 +14,8 @@ namespace osu.Game.IO { public static bool CheckAvailability(string testDestinationPath, string testSourcePath) { - // We can support other operating systems quite easily in the future. - // Let's handle the most common one for now, though. - if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows) + // TODO: Add macOS support for hardlinks. + if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows || RuntimeInfo.OS != RuntimeInfo.Platform.Linux) return false; const string test_filename = "_hard_link_test"; @@ -26,12 +25,20 @@ namespace osu.Game.IO cleanupFiles(); + try { File.WriteAllText(testSourcePath, string.Empty); - // Test availability by creating an arbitrary hard link between the source and destination paths. - return CreateHardLink(testDestinationPath, testSourcePath, IntPtr.Zero); + + bool isHardLinkAvailable = false; + + if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows) + isHardLinkAvailable = CreateHardLink(testDestinationPath, testSourcePath, IntPtr.Zero); + else if (RuntimeInfo.OS == RuntimeInfo.Platform.Linux) + isHardLinkAvailable = link(testSourcePath, testDestinationPath) == 0; + + return isHardLinkAvailable; } catch { @@ -70,6 +77,9 @@ namespace osu.Game.IO return result; } + [DllImport("libc", SetLastError = true)] + public static extern int link(string oldpath, string newpath); + [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool CreateHardLink(string lpFileName, string lpExistingFileName, IntPtr lpSecurityAttributes); diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index 0f8a78453d..2603a6c6c4 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -132,7 +132,7 @@ namespace osu.Game.Overlays.FirstRunSetup copyInformation.AddLink("Learn more about how \"hard links\" work", LinkAction.OpenWiki, @"Client/Release_stream/Lazer/File_storage#via-hard-links"); } - else if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows) + else if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows || RuntimeInfo.OS != RuntimeInfo.Platform.Linux) copyInformation.Text = "Lightweight linking of files is not supported on your operating system yet, so a copy of all files will be made during import."; else { From 16165b1f67fc51ea01b906b020dc195788f99a2b Mon Sep 17 00:00:00 2001 From: BlauFx Date: Wed, 28 Dec 2022 13:58:52 +0100 Subject: [PATCH 1222/2991] Remove blank line --- osu.Game/IO/HardLinkHelper.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/IO/HardLinkHelper.cs b/osu.Game/IO/HardLinkHelper.cs index 8d521bab9f..b3eb528bbb 100644 --- a/osu.Game/IO/HardLinkHelper.cs +++ b/osu.Game/IO/HardLinkHelper.cs @@ -25,7 +25,6 @@ namespace osu.Game.IO cleanupFiles(); - try { File.WriteAllText(testSourcePath, string.Empty); From 5c5e84f931a45b5c35261d2e38aabc857730bc47 Mon Sep 17 00:00:00 2001 From: BlauFx Date: Wed, 28 Dec 2022 14:06:50 +0100 Subject: [PATCH 1223/2991] Fix formatiing --- osu.Game/IO/HardLinkHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/IO/HardLinkHelper.cs b/osu.Game/IO/HardLinkHelper.cs index b3eb528bbb..d059e8b710 100644 --- a/osu.Game/IO/HardLinkHelper.cs +++ b/osu.Game/IO/HardLinkHelper.cs @@ -76,7 +76,7 @@ namespace osu.Game.IO return result; } - [DllImport("libc", SetLastError = true)] + [DllImport("libc", SetLastError = true)] public static extern int link(string oldpath, string newpath); [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] From f32564652b3d07224c10cce449ba7dd28b7fecf4 Mon Sep 17 00:00:00 2001 From: BlauFx Date: Wed, 28 Dec 2022 14:33:38 +0100 Subject: [PATCH 1224/2991] Mention the filesystem should be NTFS on Windows --- osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index 2603a6c6c4..6e9b724774 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -136,8 +136,10 @@ namespace osu.Game.Overlays.FirstRunSetup copyInformation.Text = "Lightweight linking of files is not supported on your operating system yet, so a copy of all files will be made during import."; else { + string mentionNTFS = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? " (and the file system is NTFS)." : "."; + copyInformation.Text = - "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install (and the file system is NTFS). "; + $"A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install{mentionNTFS}"; copyInformation.AddLink(GeneralSettingsStrings.ChangeFolderLocation, () => { game?.PerformFromScreen(menu => menu.Push(new MigrationSelectScreen())); From 53bca947d13fe267260e3767c67cd6e30efd2154 Mon Sep 17 00:00:00 2001 From: BlauFx Date: Wed, 28 Dec 2022 14:34:27 +0100 Subject: [PATCH 1225/2991] Move duplicated code into its own method --- osu.Game/Database/RealmFileStore.cs | 15 ++------------- osu.Game/IO/HardLinkHelper.cs | 23 ++++++++++++++--------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/osu.Game/Database/RealmFileStore.cs b/osu.Game/Database/RealmFileStore.cs index 49102d81e5..e5ace5b346 100644 --- a/osu.Game/Database/RealmFileStore.cs +++ b/osu.Game/Database/RealmFileStore.cs @@ -64,19 +64,8 @@ namespace osu.Game.Database private void copyToStore(RealmFile file, Stream data, bool preferHardLinks) { // attempt to do a fast hard link rather than copy. - if (data is FileStream fs && preferHardLinks) - { - if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows) - { - if (HardLinkHelper.CreateHardLink(Storage.GetFullPath(file.GetStoragePath(), true), fs.Name, IntPtr.Zero)) - return; - } - else if (RuntimeInfo.OS == RuntimeInfo.Platform.Linux) - { - if (HardLinkHelper.link(fs.Name, Storage.GetFullPath(file.GetStoragePath(), true)) == 0) - return; - } - } + if (data is FileStream fs && preferHardLinks && HardLinkHelper.AttemptHardLink(Storage.GetFullPath(file.GetStoragePath(), true), fs.Name)) + return; data.Seek(0, SeekOrigin.Begin); diff --git a/osu.Game/IO/HardLinkHelper.cs b/osu.Game/IO/HardLinkHelper.cs index d059e8b710..c8fc6d9f49 100644 --- a/osu.Game/IO/HardLinkHelper.cs +++ b/osu.Game/IO/HardLinkHelper.cs @@ -28,16 +28,9 @@ namespace osu.Game.IO try { File.WriteAllText(testSourcePath, string.Empty); + // Test availability by creating an arbitrary hard link between the source and destination paths. - - bool isHardLinkAvailable = false; - - if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows) - isHardLinkAvailable = CreateHardLink(testDestinationPath, testSourcePath, IntPtr.Zero); - else if (RuntimeInfo.OS == RuntimeInfo.Platform.Linux) - isHardLinkAvailable = link(testSourcePath, testDestinationPath) == 0; - - return isHardLinkAvailable; + return AttemptHardLink(testDestinationPath, testSourcePath); } catch { @@ -61,6 +54,18 @@ namespace osu.Game.IO } } + public static bool AttemptHardLink(string testDestinationPath, string testSourcePath) + { + bool isHardLinkAvailable = false; + + if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows) + isHardLinkAvailable = CreateHardLink(testDestinationPath, testSourcePath, IntPtr.Zero); + else if (RuntimeInfo.OS == RuntimeInfo.Platform.Linux) + isHardLinkAvailable = link(testSourcePath, testDestinationPath) == 0; + + return isHardLinkAvailable; + } + // For future use (to detect if a file is a hard link with other references existing on disk). public static int GetFileLinkCount(string filePath) { From c6da7248bacc02b4879c329d68238d8865b46cd6 Mon Sep 17 00:00:00 2001 From: BlauFx Date: Wed, 28 Dec 2022 14:40:32 +0100 Subject: [PATCH 1226/2991] Remove unnecessary directive --- osu.Game/Database/RealmFileStore.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Database/RealmFileStore.cs b/osu.Game/Database/RealmFileStore.cs index e5ace5b346..df276adbaf 100644 --- a/osu.Game/Database/RealmFileStore.cs +++ b/osu.Game/Database/RealmFileStore.cs @@ -4,7 +4,6 @@ using System; using System.IO; using System.Linq; -using osu.Framework; using osu.Framework.Extensions; using osu.Framework.IO.Stores; using osu.Framework.Logging; From d63be3ff17b8eaee6e39d757db32c8f124e4e3a6 Mon Sep 17 00:00:00 2001 From: BlauFx Date: Wed, 28 Dec 2022 15:02:44 +0100 Subject: [PATCH 1227/2991] Change name of variable --- osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index 6e9b724774..74c1bf955c 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -136,10 +136,10 @@ namespace osu.Game.Overlays.FirstRunSetup copyInformation.Text = "Lightweight linking of files is not supported on your operating system yet, so a copy of all files will be made during import."; else { - string mentionNTFS = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? " (and the file system is NTFS)." : "."; + string mentionNtfs = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? " (and the file system is NTFS)." : "."; copyInformation.Text = - $"A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install{mentionNTFS}"; + $"A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install{mentionNtfs}"; copyInformation.AddLink(GeneralSettingsStrings.ChangeFolderLocation, () => { game?.PerformFromScreen(menu => menu.Push(new MigrationSelectScreen())); From 2c346eae0d827abb91a05a3c0300a3c9e02076d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 28 Dec 2022 21:19:28 +0100 Subject: [PATCH 1228/2991] Revert inlining of hard link creation into condition Just feels bad. Mixing data access with actual underlying logic. --- osu.Game/Database/RealmFileStore.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Database/RealmFileStore.cs b/osu.Game/Database/RealmFileStore.cs index df276adbaf..4f429cb20c 100644 --- a/osu.Game/Database/RealmFileStore.cs +++ b/osu.Game/Database/RealmFileStore.cs @@ -62,9 +62,12 @@ namespace osu.Game.Database private void copyToStore(RealmFile file, Stream data, bool preferHardLinks) { - // attempt to do a fast hard link rather than copy. - if (data is FileStream fs && preferHardLinks && HardLinkHelper.AttemptHardLink(Storage.GetFullPath(file.GetStoragePath(), true), fs.Name)) - return; + if (data is FileStream fs && preferHardLinks) + { + // attempt to do a fast hard link rather than copy. + if (HardLinkHelper.AttemptHardLink(Storage.GetFullPath(file.GetStoragePath(), true), fs.Name)) + return; + } data.Seek(0, SeekOrigin.Begin); From cadd487c75c0876ec15388f55577cbac97d2df2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 28 Dec 2022 21:20:49 +0100 Subject: [PATCH 1229/2991] Use switch statement in `AttemptHardLink()` --- osu.Game/IO/HardLinkHelper.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/osu.Game/IO/HardLinkHelper.cs b/osu.Game/IO/HardLinkHelper.cs index c8fc6d9f49..d6ca11a68f 100644 --- a/osu.Game/IO/HardLinkHelper.cs +++ b/osu.Game/IO/HardLinkHelper.cs @@ -56,14 +56,17 @@ namespace osu.Game.IO public static bool AttemptHardLink(string testDestinationPath, string testSourcePath) { - bool isHardLinkAvailable = false; + switch (RuntimeInfo.OS) + { + case RuntimeInfo.Platform.Windows: + return CreateHardLink(testDestinationPath, testSourcePath, IntPtr.Zero); - if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows) - isHardLinkAvailable = CreateHardLink(testDestinationPath, testSourcePath, IntPtr.Zero); - else if (RuntimeInfo.OS == RuntimeInfo.Platform.Linux) - isHardLinkAvailable = link(testSourcePath, testDestinationPath) == 0; + case RuntimeInfo.Platform.Linux: + return link(testSourcePath, testDestinationPath) == 0; - return isHardLinkAvailable; + default: + return false; + } } // For future use (to detect if a file is a hard link with other references existing on disk). From 04d4b4a6ce2a7cb5aff2bea79e8dd6378f34a833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 28 Dec 2022 21:23:06 +0100 Subject: [PATCH 1230/2991] Rename and xmldoc hard link creation method --- osu.Game/Database/RealmFileStore.cs | 2 +- osu.Game/IO/HardLinkHelper.cs | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/osu.Game/Database/RealmFileStore.cs b/osu.Game/Database/RealmFileStore.cs index 4f429cb20c..f75d3be725 100644 --- a/osu.Game/Database/RealmFileStore.cs +++ b/osu.Game/Database/RealmFileStore.cs @@ -65,7 +65,7 @@ namespace osu.Game.Database if (data is FileStream fs && preferHardLinks) { // attempt to do a fast hard link rather than copy. - if (HardLinkHelper.AttemptHardLink(Storage.GetFullPath(file.GetStoragePath(), true), fs.Name)) + if (HardLinkHelper.TryCreateHardLink(Storage.GetFullPath(file.GetStoragePath(), true), fs.Name)) return; } diff --git a/osu.Game/IO/HardLinkHelper.cs b/osu.Game/IO/HardLinkHelper.cs index d6ca11a68f..9c0a8fbba1 100644 --- a/osu.Game/IO/HardLinkHelper.cs +++ b/osu.Game/IO/HardLinkHelper.cs @@ -30,7 +30,7 @@ namespace osu.Game.IO File.WriteAllText(testSourcePath, string.Empty); // Test availability by creating an arbitrary hard link between the source and destination paths. - return AttemptHardLink(testDestinationPath, testSourcePath); + return TryCreateHardLink(testDestinationPath, testSourcePath); } catch { @@ -54,15 +54,23 @@ namespace osu.Game.IO } } - public static bool AttemptHardLink(string testDestinationPath, string testSourcePath) + /// + /// Attempts to create a hard link from to , + /// using platform-specific native methods. + /// + /// + /// Hard links are only available on Windows and Linux. + /// + /// Whether the hard link was successfully created. + public static bool TryCreateHardLink(string destinationPath, string sourcePath) { switch (RuntimeInfo.OS) { case RuntimeInfo.Platform.Windows: - return CreateHardLink(testDestinationPath, testSourcePath, IntPtr.Zero); + return CreateHardLink(destinationPath, sourcePath, IntPtr.Zero); case RuntimeInfo.Platform.Linux: - return link(testSourcePath, testDestinationPath) == 0; + return link(sourcePath, destinationPath) == 0; default: return false; From d4b3965967ea155e94975409de1a5883c3981523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 28 Dec 2022 21:25:24 +0100 Subject: [PATCH 1231/2991] Change warning message about file duplication - It was being glued in an ugly way that would have prevented sanely localising it. - Even on Linux, the filesystem (whichever one the user has chosen out of the multitude available) still needs to support hard links for them to have a chance of working. --- osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index 74c1bf955c..8b1b50ed98 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -136,10 +136,9 @@ namespace osu.Game.Overlays.FirstRunSetup copyInformation.Text = "Lightweight linking of files is not supported on your operating system yet, so a copy of all files will be made during import."; else { - string mentionNtfs = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? " (and the file system is NTFS)." : "."; - - copyInformation.Text = - $"A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install{mentionNtfs}"; + copyInformation.Text = RuntimeInfo.OS == RuntimeInfo.Platform.Windows + ? "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install (and the file system is NTFS)." + : "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install (and the file system supports hard links)."; copyInformation.AddLink(GeneralSettingsStrings.ChangeFolderLocation, () => { game?.PerformFromScreen(menu => menu.Push(new MigrationSelectScreen())); From 8d79fa93ac06a5913628a0eb2ba847a869fd7e2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 28 Dec 2022 21:58:30 +0100 Subject: [PATCH 1232/2991] Implement `GetFileLinkCount()` for Linux --- osu.Game/IO/HardLinkHelper.cs | 65 +++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 7 deletions(-) diff --git a/osu.Game/IO/HardLinkHelper.cs b/osu.Game/IO/HardLinkHelper.cs index 9c0a8fbba1..03cb043cca 100644 --- a/osu.Game/IO/HardLinkHelper.cs +++ b/osu.Game/IO/HardLinkHelper.cs @@ -81,19 +81,30 @@ namespace osu.Game.IO public static int GetFileLinkCount(string filePath) { int result = 0; - SafeFileHandle handle = CreateFile(filePath, FileAccess.Read, FileShare.Read, IntPtr.Zero, FileMode.Open, FileAttributes.Archive, IntPtr.Zero); - ByHandleFileInformation fileInfo; + switch (RuntimeInfo.OS) + { + case RuntimeInfo.Platform.Windows: + SafeFileHandle handle = CreateFile(filePath, FileAccess.Read, FileShare.Read, IntPtr.Zero, FileMode.Open, FileAttributes.Archive, IntPtr.Zero); - if (GetFileInformationByHandle(handle, out fileInfo)) - result = (int)fileInfo.NumberOfLinks; - CloseHandle(handle); + ByHandleFileInformation fileInfo; + + if (GetFileInformationByHandle(handle, out fileInfo)) + result = (int)fileInfo.NumberOfLinks; + CloseHandle(handle); + break; + + case RuntimeInfo.Platform.Linux: + if (stat(filePath, out var statbuf) == 0) + result = (int)statbuf.st_nlink; + + break; + } return result; } - [DllImport("libc", SetLastError = true)] - public static extern int link(string oldpath, string newpath); + #region Windows native methods [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] public static extern bool CreateHardLink(string lpFileName, string lpExistingFileName, IntPtr lpSecurityAttributes); @@ -129,5 +140,45 @@ namespace osu.Game.IO public readonly uint FileIndexHigh; public readonly uint FileIndexLow; } + + #endregion + + #region Linux native methods + + [DllImport("libc", SetLastError = true)] + public static extern int link(string oldpath, string newpath); + + [DllImport("libc", SetLastError = true)] + private static extern int stat(string pathname, out struct_stat statbuf); + + // ReSharper disable once InconsistentNaming + // Struct layout is likely non-portable across unices. Tread with caution. + [StructLayout(LayoutKind.Sequential)] + private struct struct_stat + { + public readonly long st_dev; + public readonly long st_ino; + public readonly long st_nlink; + public readonly int st_mode; + public readonly int st_uid; + public readonly int st_gid; + public readonly long st_rdev; + public readonly long st_size; + public readonly long st_blksize; + public readonly long st_blocks; + public readonly timespec st_atim; + public readonly timespec st_mtim; + public readonly timespec st_ctim; + } + + // ReSharper disable once InconsistentNaming + [StructLayout(LayoutKind.Sequential)] + private struct timespec + { + public readonly long tv_sec; + public readonly long tv_nsec; + } + + #endregion } } From 49b0ec9ddb43d0f507ba8155d7bec69ed7876bb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 28 Dec 2022 22:18:27 +0100 Subject: [PATCH 1233/2991] Fix broken condition --- osu.Game/IO/HardLinkHelper.cs | 2 +- osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/IO/HardLinkHelper.cs b/osu.Game/IO/HardLinkHelper.cs index 03cb043cca..fef084f5f0 100644 --- a/osu.Game/IO/HardLinkHelper.cs +++ b/osu.Game/IO/HardLinkHelper.cs @@ -15,7 +15,7 @@ namespace osu.Game.IO public static bool CheckAvailability(string testDestinationPath, string testSourcePath) { // TODO: Add macOS support for hardlinks. - if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows || RuntimeInfo.OS != RuntimeInfo.Platform.Linux) + if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows && RuntimeInfo.OS != RuntimeInfo.Platform.Linux) return false; const string test_filename = "_hard_link_test"; diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index 8b1b50ed98..0e7514a7dc 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -132,7 +132,7 @@ namespace osu.Game.Overlays.FirstRunSetup copyInformation.AddLink("Learn more about how \"hard links\" work", LinkAction.OpenWiki, @"Client/Release_stream/Lazer/File_storage#via-hard-links"); } - else if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows || RuntimeInfo.OS != RuntimeInfo.Platform.Linux) + else if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows && RuntimeInfo.OS != RuntimeInfo.Platform.Linux) copyInformation.Text = "Lightweight linking of files is not supported on your operating system yet, so a copy of all files will be made during import."; else { From 10c11e974de9c2533059bcd76b7abf248f497ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 28 Dec 2022 22:19:49 +0100 Subject: [PATCH 1234/2991] Fix broken spacing --- osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index 0e7514a7dc..2e3ab823f7 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -137,8 +137,8 @@ namespace osu.Game.Overlays.FirstRunSetup else { copyInformation.Text = RuntimeInfo.OS == RuntimeInfo.Platform.Windows - ? "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install (and the file system is NTFS)." - : "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install (and the file system supports hard links)."; + ? "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install (and the file system is NTFS). " + : "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install (and the file system supports hard links). "; copyInformation.AddLink(GeneralSettingsStrings.ChangeFolderLocation, () => { game?.PerformFromScreen(menu => menu.Push(new MigrationSelectScreen())); From 74bc5d46666403f54f9f6e5336c028e00cf1ff03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 28 Dec 2022 22:38:42 +0100 Subject: [PATCH 1235/2991] Disable naming rule inspection on struct stat definition --- osu.Game/IO/HardLinkHelper.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/IO/HardLinkHelper.cs b/osu.Game/IO/HardLinkHelper.cs index fef084f5f0..ebf2d2bd71 100644 --- a/osu.Game/IO/HardLinkHelper.cs +++ b/osu.Game/IO/HardLinkHelper.cs @@ -145,6 +145,8 @@ namespace osu.Game.IO #region Linux native methods +#pragma warning disable IDE1006 // Naming rule violation + [DllImport("libc", SetLastError = true)] public static extern int link(string oldpath, string newpath); @@ -179,6 +181,8 @@ namespace osu.Game.IO public readonly long tv_nsec; } +#pragma warning restore IDE1006 + #endregion } } From b40d114e76dd447438e105f4b91aa9c3441b1496 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Wed, 28 Dec 2022 15:00:57 -0800 Subject: [PATCH 1236/2991] Remove context menu from news card for now --- osu.Game/Overlays/News/NewsCard.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/osu.Game/Overlays/News/NewsCard.cs b/osu.Game/Overlays/News/NewsCard.cs index f18ce7ff06..e0be5cc4a9 100644 --- a/osu.Game/Overlays/News/NewsCard.cs +++ b/osu.Game/Overlays/News/NewsCard.cs @@ -12,18 +12,16 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Framework.Platform; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.News { - public partial class NewsCard : OsuHoverContainer, IHasContextMenu + public partial class NewsCard : OsuHoverContainer { protected override IEnumerable EffectTargets => new[] { background }; @@ -163,10 +161,5 @@ namespace osu.Game.Overlays.News DateTimeOffset IHasCustomTooltip.TooltipContent => date; } - - public MenuItem[] ContextMenuItems => new MenuItem[] - { - new OsuMenuItem("View news in browser", MenuItemType.Highlighted, Action), - }; } } From ffd9359f4a6c9ce223d889b87b6b936b9b8de333 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Wed, 28 Dec 2022 14:50:40 -0800 Subject: [PATCH 1237/2991] Add tests for chat text box saving / syncing --- .../Visual/Online/TestSceneChatOverlay.cs | 46 +++++++++++++++++++ .../Online/TestSceneStandAloneChatDisplay.cs | 32 +++++++++++-- 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 8cc4eabcd7..a8369dd6d9 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -530,6 +530,52 @@ namespace osu.Game.Tests.Visual.Online }); } + [Test] + public void TestTextBoxSavePerChannel() + { + var testPMChannel = new Channel(testUser); + + AddStep("show overlay", () => chatOverlay.Show()); + joinTestChannel(0); + joinChannel(testPMChannel); + + AddAssert("listing is visible", () => listingIsVisible); + AddStep("search for 'number 2'", () => chatOverlayTextBox.Text = "number 2"); + AddAssert("'number 2' saved to selector", () => channelManager.CurrentChannel.Value.TextBoxMessage.Value == "number 2"); + + AddStep("select normal channel", () => clickDrawable(getChannelListItem(testChannel1))); + AddAssert("text box cleared on normal channel", () => chatOverlayTextBox.Text == string.Empty); + AddAssert("nothing saved on normal channel", () => channelManager.CurrentChannel.Value.TextBoxMessage.Value == string.Empty); + AddStep("type '727'", () => chatOverlayTextBox.Text = "727"); + AddAssert("'727' saved to normal channel", () => channelManager.CurrentChannel.Value.TextBoxMessage.Value == "727"); + + AddStep("select PM channel", () => clickDrawable(getChannelListItem(testPMChannel))); + AddAssert("text box cleared on PM channel", () => chatOverlayTextBox.Text == string.Empty); + AddAssert("nothing saved on PM channel", () => channelManager.CurrentChannel.Value.TextBoxMessage.Value == string.Empty); + AddStep("type 'hello'", () => chatOverlayTextBox.Text = "hello"); + AddAssert("'hello' saved to PM channel", () => channelManager.CurrentChannel.Value.TextBoxMessage.Value == "hello"); + + AddStep("select normal channel", () => clickDrawable(getChannelListItem(testChannel1))); + AddAssert("text box contains '727'", () => chatOverlayTextBox.Text == "727"); + + AddStep("select PM channel", () => clickDrawable(getChannelListItem(testPMChannel))); + AddAssert("text box contains 'hello'", () => chatOverlayTextBox.Text == "hello"); + AddStep("click close button", () => + { + ChannelListItemCloseButton closeButton = getChannelListItem(testPMChannel).ChildrenOfType().Single(); + clickDrawable(closeButton); + }); + + AddAssert("listing is visible", () => listingIsVisible); + AddAssert("text box contains 'channel 2'", () => chatOverlayTextBox.Text == "number 2"); + AddUntilStep("only channel 2 visible", () => + { + IEnumerable listingItems = chatOverlay.ChildrenOfType() + .Where(item => item.IsPresent); + return listingItems.Count() == 1 && listingItems.Single().Channel == testChannel2; + }); + } + private void joinTestChannel(int i) { AddStep($"Join test channel {i}", () => channelManager.JoinChannel(testChannels[i])); diff --git a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs index ebd5e12acb..d7f79d3e30 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneStandAloneChatDisplay.cs @@ -50,6 +50,8 @@ namespace osu.Game.Tests.Visual.Online private ChannelManager channelManager; private TestStandAloneChatDisplay chatDisplay; + private TestStandAloneChatDisplay chatWithTextBox; + private TestStandAloneChatDisplay chatWithTextBox2; private int messageIdSequence; private Channel testChannel; @@ -78,7 +80,7 @@ namespace osu.Game.Tests.Visual.Online private void reinitialiseDrawableDisplay() { - Children = new[] + Children = new Drawable[] { chatDisplay = new TestStandAloneChatDisplay { @@ -88,13 +90,28 @@ namespace osu.Game.Tests.Visual.Online Size = new Vector2(400, 80), Channel = { Value = testChannel }, }, - new TestStandAloneChatDisplay(true) + new FillFlowContainer { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, Margin = new MarginPadding(20), - Size = new Vector2(400, 150), - Channel = { Value = testChannel }, + Children = new[] + { + chatWithTextBox = new TestStandAloneChatDisplay(true) + { + Margin = new MarginPadding(20), + Size = new Vector2(400, 150), + Channel = { Value = testChannel }, + }, + chatWithTextBox2 = new TestStandAloneChatDisplay(true) + { + Margin = new MarginPadding(20), + Size = new Vector2(400, 150), + Channel = { Value = testChannel }, + }, + } } }; } @@ -351,6 +368,13 @@ namespace osu.Game.Tests.Visual.Online checkScrolledToBottom(); } + [Test] + public void TestTextBoxSync() + { + AddStep("type 'hello' to text box 1", () => chatWithTextBox.ChildrenOfType().Single().Text = "hello"); + AddAssert("text box 2 contains 'hello'", () => chatWithTextBox2.ChildrenOfType().Single().Text == "hello"); + } + private void fillChat(int count = 10) { AddStep("fill chat", () => From c326745f96747453453f49f5d3e51e494f4682fd Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Wed, 28 Dec 2022 15:12:57 -0800 Subject: [PATCH 1238/2991] Save / sync chat text box messages per channel --- osu.Game/Online/Chat/Channel.cs | 5 +++++ osu.Game/Online/Chat/StandAloneChatDisplay.cs | 8 ++++++++ osu.Game/Overlays/Chat/ChatTextBar.cs | 11 ++++++++--- osu.Game/Overlays/Chat/ChatTextBox.cs | 1 - 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index 24b384b1d4..761e8aba8d 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -98,6 +98,11 @@ namespace osu.Game.Online.Chat /// public Bindable HighlightedMessage = new Bindable(); + /// + /// The current text box message while in this . + /// + public Bindable TextBoxMessage = new Bindable(string.Empty); + [JsonConstructor] public Channel() { diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs index 7fd6f99102..43da9a1d43 100644 --- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs +++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs @@ -87,6 +87,14 @@ namespace osu.Game.Online.Chat channelManager ??= manager; } + protected override void LoadComplete() + { + base.LoadComplete(); + + if (channelManager != null) + TextBox?.Current.BindTo(channelManager.CurrentChannel.Value.TextBoxMessage); + } + protected virtual StandAloneDrawableChannel CreateDrawableChannel(Channel channel) => new StandAloneDrawableChannel(channel); diff --git a/osu.Game/Overlays/Chat/ChatTextBar.cs b/osu.Game/Overlays/Chat/ChatTextBar.cs index bcf5c1a409..682c96a695 100644 --- a/osu.Game/Overlays/Chat/ChatTextBar.cs +++ b/osu.Game/Overlays/Chat/ChatTextBar.cs @@ -128,9 +128,8 @@ namespace osu.Game.Overlays.Chat chattingTextContainer.FadeTo(showSearch ? 0 : 1); searchIconContainer.FadeTo(showSearch ? 1 : 0); - // Clear search terms if any exist when switching back to chat mode - if (!showSearch) - OnSearchTermsChanged?.Invoke(string.Empty); + if (showSearch) + OnSearchTermsChanged?.Invoke(chatTextBox.Current.Value); }, true); currentChannel.BindValueChanged(change => @@ -151,6 +150,12 @@ namespace osu.Game.Overlays.Chat chattingText.Text = ChatStrings.TalkingIn(newChannel.Name); break; } + + if (change.OldValue != null) + chatTextBox.Current.UnbindFrom(change.OldValue.TextBoxMessage); + + if (newChannel != null) + chatTextBox.Current.BindTo(newChannel.TextBoxMessage); }, true); } diff --git a/osu.Game/Overlays/Chat/ChatTextBox.cs b/osu.Game/Overlays/Chat/ChatTextBox.cs index 780c85a9c1..7cd005698e 100644 --- a/osu.Game/Overlays/Chat/ChatTextBox.cs +++ b/osu.Game/Overlays/Chat/ChatTextBox.cs @@ -24,7 +24,6 @@ namespace osu.Game.Overlays.Chat bool showSearch = change.NewValue; PlaceholderText = showSearch ? HomeStrings.SearchPlaceholder : ChatStrings.InputPlaceholder; - Text = string.Empty; }, true); } From 70dbb8edac4a2f7ed7513ade3e186cddfb95adfd Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Thu, 29 Dec 2022 01:37:37 -0800 Subject: [PATCH 1239/2991] Fix stand alone chat display textbox not binding to local channel --- osu.Game/Online/Chat/StandAloneChatDisplay.cs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs index 43da9a1d43..0a5434822b 100644 --- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs +++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs @@ -87,14 +87,6 @@ namespace osu.Game.Online.Chat channelManager ??= manager; } - protected override void LoadComplete() - { - base.LoadComplete(); - - if (channelManager != null) - TextBox?.Current.BindTo(channelManager.CurrentChannel.Value.TextBoxMessage); - } - protected virtual StandAloneDrawableChannel CreateDrawableChannel(Channel channel) => new StandAloneDrawableChannel(channel); @@ -119,8 +111,13 @@ namespace osu.Game.Online.Chat { drawableChannel?.Expire(); + if (e.OldValue != null) + TextBox?.Current.UnbindFrom(e.OldValue.TextBoxMessage); + if (e.NewValue == null) return; + TextBox?.Current.BindTo(e.NewValue.TextBoxMessage); + drawableChannel = CreateDrawableChannel(e.NewValue); drawableChannel.CreateChatLineAction = CreateMessage; drawableChannel.Padding = new MarginPadding { Bottom = postingTextBox ? text_box_height : 0 }; From 680646d3a6b41a133fb6e0ab15537d2a1710dbc1 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Thu, 29 Dec 2022 12:02:08 +0100 Subject: [PATCH 1240/2991] Make offsetting of bottom bar more readable --- osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs index ea4db1f8fa..342f5d1bd7 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs @@ -119,8 +119,9 @@ namespace osu.Game.Screens.Select.FooterV2 }, new Container { - //Offset the bar to centre it with consideration for the shearing - Position = new Vector2(-0.15f * 35, -10), + // The X offset has to multiplied as such to account for the fact that we only want to offset by the distance from the CenterLeft point of the container + // not the whole shear width + Position = new Vector2(-SHEAR.X * (button_height / 2 - 10), -10), Anchor = Anchor.BottomCentre, Origin = Anchor.Centre, Size = new Vector2(120, 6), From cacc23204d2a94d79e947a495444d95506ce27f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 29 Dec 2022 13:16:13 +0100 Subject: [PATCH 1241/2991] Add failing test coverage --- osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs index 0bc42b06dd..acb68fc9cd 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs @@ -201,6 +201,22 @@ namespace osu.Game.Tests.Visual.Menus AddAssert("volume not changed", () => Audio.Volume.Value == 0.5); } + [Test] + public void TestRulesetSelectorOverflow() + { + AddStep("set toolbar width", () => + { + toolbar.RelativeSizeAxes = Axes.None; + toolbar.Width = 0; + }); + AddStep("move mouse over news toggle button", () => + { + var button = toolbar.ChildrenOfType().Single(); + InputManager.MoveMouseTo(button); + }); + AddAssert("no ruleset toggle buttons hovered", () => !toolbar.ChildrenOfType().Any(button => button.IsHovered)); + } + public partial class TestToolbar : Toolbar { public new Bindable OverlayActivationMode => base.OverlayActivationMode as Bindable; From c5f7da9a4ecb6f9d1810653d09adacbae0d877a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 29 Dec 2022 13:18:59 +0100 Subject: [PATCH 1242/2991] Fix hover propagating through toolbar buttons Closes #21920. Weirdly enough this was semeingly fixed once before in ancient times in 3891f467a34562d2d921fe996654802d0b29ab0b, but then unfixed again in 566e09083f06b87591c7745d82adf0d831a6066f. The second change is no longer needed since the toolbar became opaque in #9447. --- osu.Game/Overlays/Toolbar/ToolbarButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarButton.cs b/osu.Game/Overlays/Toolbar/ToolbarButton.cs index ea5fc5bb38..4193e52584 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarButton.cs @@ -179,7 +179,7 @@ namespace osu.Game.Overlays.Toolbar HoverBackground.FadeIn(200); tooltipContainer.FadeIn(100); - return base.OnHover(e); + return true; } protected override void OnHoverLost(HoverLostEvent e) From 0fcf10e10a0bdfd121c47b81649769a3e70a92f0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 29 Dec 2022 22:35:13 +0800 Subject: [PATCH 1243/2991] Also support hard links on macOS --- osu.Game/IO/HardLinkHelper.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/IO/HardLinkHelper.cs b/osu.Game/IO/HardLinkHelper.cs index ebf2d2bd71..619bfdad6e 100644 --- a/osu.Game/IO/HardLinkHelper.cs +++ b/osu.Game/IO/HardLinkHelper.cs @@ -14,8 +14,8 @@ namespace osu.Game.IO { public static bool CheckAvailability(string testDestinationPath, string testSourcePath) { - // TODO: Add macOS support for hardlinks. - if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows && RuntimeInfo.OS != RuntimeInfo.Platform.Linux) + // For simplicity, only support desktop operating systems for now. + if (!RuntimeInfo.IsDesktop) return false; const string test_filename = "_hard_link_test"; @@ -59,7 +59,7 @@ namespace osu.Game.IO /// using platform-specific native methods. /// /// - /// Hard links are only available on Windows and Linux. + /// Hard links are only available on desktop platforms. /// /// Whether the hard link was successfully created. public static bool TryCreateHardLink(string destinationPath, string sourcePath) @@ -70,6 +70,7 @@ namespace osu.Game.IO return CreateHardLink(destinationPath, sourcePath, IntPtr.Zero); case RuntimeInfo.Platform.Linux: + case RuntimeInfo.Platform.macOS: return link(sourcePath, destinationPath) == 0; default: @@ -95,6 +96,7 @@ namespace osu.Game.IO break; case RuntimeInfo.Platform.Linux: + case RuntimeInfo.Platform.macOS: if (stat(filePath, out var statbuf) == 0) result = (int)statbuf.st_nlink; From ccf713c885c1dd77155a22d95db00158f45ae6d8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 29 Dec 2022 23:18:12 +0800 Subject: [PATCH 1244/2991] Fix incorrect hard link validity check in stable import screen --- osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index 2e3ab823f7..0a2274575f 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -132,7 +132,7 @@ namespace osu.Game.Overlays.FirstRunSetup copyInformation.AddLink("Learn more about how \"hard links\" work", LinkAction.OpenWiki, @"Client/Release_stream/Lazer/File_storage#via-hard-links"); } - else if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows && RuntimeInfo.OS != RuntimeInfo.Platform.Linux) + else if (!RuntimeInfo.IsDesktop) copyInformation.Text = "Lightweight linking of files is not supported on your operating system yet, so a copy of all files will be made during import."; else { From f7febdac5e20ba71eb1dee4c64dd1916a558135a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 29 Dec 2022 22:48:33 +0100 Subject: [PATCH 1245/2991] Add failing assertion --- osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs index acb68fc9cd..aef6f9ade0 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs @@ -207,7 +207,7 @@ namespace osu.Game.Tests.Visual.Menus AddStep("set toolbar width", () => { toolbar.RelativeSizeAxes = Axes.None; - toolbar.Width = 0; + toolbar.Width = 400; }); AddStep("move mouse over news toggle button", () => { @@ -215,6 +215,7 @@ namespace osu.Game.Tests.Visual.Menus InputManager.MoveMouseTo(button); }); AddAssert("no ruleset toggle buttons hovered", () => !toolbar.ChildrenOfType().Any(button => button.IsHovered)); + AddUntilStep("toolbar gradient visible", () => toolbar.ChildrenOfType().Single().Children.All(d => d.Alpha > 0)); } public partial class TestToolbar : Toolbar From bf975eb48a89707d69b62ff1e2bebd434464ad2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 29 Dec 2022 23:02:45 +0100 Subject: [PATCH 1246/2991] Fix toolbar gradient not showing when mouse is hovered over buttons --- osu.Game/Overlays/Toolbar/Toolbar.cs | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index ac0f822f68..a559363bbf 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -13,6 +13,7 @@ using osuTK; using osu.Framework.Graphics.Shapes; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Input; using osu.Framework.Input.Events; using osu.Game.Rulesets; using osu.Framework.Input.Bindings; @@ -196,6 +197,9 @@ namespace osu.Game.Overlays.Toolbar public partial class ToolbarBackground : Container { + private InputManager inputManager; + private Bindable showGradient { get; } = new BindableBool(); + private readonly Box gradientBackground; public ToolbarBackground() @@ -220,15 +224,26 @@ namespace osu.Game.Overlays.Toolbar }; } - protected override bool OnHover(HoverEvent e) + protected override void LoadComplete() { - gradientBackground.FadeIn(transition_time, Easing.OutQuint); - return true; + base.LoadComplete(); + + inputManager = GetContainingInputManager(); + showGradient.BindValueChanged(_ => updateState(), true); } - protected override void OnHoverLost(HoverLostEvent e) + protected override void Update() { - gradientBackground.FadeOut(transition_time, Easing.OutQuint); + base.Update(); + showGradient.Value = Contains(inputManager.CurrentState.Mouse.Position); + } + + private void updateState() + { + if (showGradient.Value) + gradientBackground.FadeIn(transition_time, Easing.OutQuint); + else + gradientBackground.FadeOut(transition_time, Easing.OutQuint); } } From f625c5d7446144455f2366a252392467de2a1038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 29 Dec 2022 23:34:33 +0100 Subject: [PATCH 1247/2991] Fix gradient showing when toggling toolbar with mouse above window --- osu.Game/Overlays/Toolbar/Toolbar.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index a559363bbf..dbad866f74 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -235,7 +235,11 @@ namespace osu.Game.Overlays.Toolbar protected override void Update() { base.Update(); - showGradient.Value = Contains(inputManager.CurrentState.Mouse.Position); + + var currentMousePosition = inputManager.CurrentState.Mouse.Position; + // ensure that the gradient is not shown if the mouse is above the window. + // this is relevant when the background is moving due to the toolbar being toggled. + showGradient.Value = currentMousePosition.Y >= 0 && Contains(inputManager.CurrentState.Mouse.Position); } private void updateState() From 0d70f2c0fd3d070b49c6ce4225a88bed63932392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 09:07:48 +0100 Subject: [PATCH 1248/2991] Use alternative workaround --- osu.Game/Overlays/Toolbar/Toolbar.cs | 54 +++++++++++++++++++--------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index dbad866f74..f21ef0ee98 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -13,7 +13,6 @@ using osuTK; using osu.Framework.Graphics.Shapes; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Input; using osu.Framework.Input.Events; using osu.Game.Rulesets; using osu.Framework.Input.Bindings; @@ -66,9 +65,12 @@ namespace osu.Game.Overlays.Toolbar [BackgroundDependencyLoader(true)] private void load(OsuGame osuGame) { + ToolbarBackground background; + HoverInterceptor interceptor; + Children = new Drawable[] { - new ToolbarBackground(), + background = new ToolbarBackground(), new GridContainer { RelativeSizeAxes = Axes.Both, @@ -181,9 +183,15 @@ namespace osu.Game.Overlays.Toolbar }, }, } + }, + interceptor = new HoverInterceptor + { + RelativeSizeAxes = Axes.Both } }; + ((IBindable)background.ShowGradient).BindTo(interceptor.ReceivedHover); + if (osuGame != null) OverlayActivationMode.BindTo(osuGame.OverlayActivationMode); } @@ -197,8 +205,7 @@ namespace osu.Game.Overlays.Toolbar public partial class ToolbarBackground : Container { - private InputManager inputManager; - private Bindable showGradient { get; } = new BindableBool(); + public Bindable ShowGradient { get; } = new BindableBool(); private readonly Box gradientBackground; @@ -228,29 +235,42 @@ namespace osu.Game.Overlays.Toolbar { base.LoadComplete(); - inputManager = GetContainingInputManager(); - showGradient.BindValueChanged(_ => updateState(), true); - } - - protected override void Update() - { - base.Update(); - - var currentMousePosition = inputManager.CurrentState.Mouse.Position; - // ensure that the gradient is not shown if the mouse is above the window. - // this is relevant when the background is moving due to the toolbar being toggled. - showGradient.Value = currentMousePosition.Y >= 0 && Contains(inputManager.CurrentState.Mouse.Position); + ShowGradient.BindValueChanged(_ => updateState(), true); } private void updateState() { - if (showGradient.Value) + if (ShowGradient.Value) gradientBackground.FadeIn(transition_time, Easing.OutQuint); else gradientBackground.FadeOut(transition_time, Easing.OutQuint); } } + /// + /// Whenever the mouse cursor is within the bounds of the toolbar, we want the background gradient to show, for toolbar button descriptions to be legible. + /// Unfortunately we also need to ensure that the toolbar buttons handle hover, to prevent the possibility of multiple descriptions being shown + /// due to hover events passing through multiple buttons. + /// This drawable is a workaround, that when placed front-most in the toolbar, allows to see whether hover events have been propagated through it without handling them. + /// + private partial class HoverInterceptor : Drawable + { + public IBindable ReceivedHover => receivedHover; + private readonly Bindable receivedHover = new BindableBool(); + + protected override bool OnHover(HoverEvent e) + { + receivedHover.Value = true; + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + receivedHover.Value = false; + base.OnHoverLost(e); + } + } + protected override void UpdateState(ValueChangedEvent state) { bool blockShow = hiddenByUser || OverlayActivationMode.Value == OverlayActivation.Disabled; From 3c32a50c125bf4e9b28b26298277bb80cc38cb0f Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Fri, 30 Dec 2022 21:19:46 +0900 Subject: [PATCH 1249/2991] add new accuracy counter display --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 14 ++++++++ .../Play/HUD/GameplayAccuracyCounter.cs | 32 ++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 4228840461..cec2b7e6b9 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -39,6 +39,16 @@ namespace osu.Game.Rulesets.Scoring /// public readonly BindableDouble Accuracy = new BindableDouble(1) { MinValue = 0, MaxValue = 1 }; + /// + /// The accuracy which increase from 0%. + /// + public readonly BindableDouble IncreaseAccuracy = new BindableDouble(0) { MinValue = 0, MaxValue = 1 }; + + /// + /// The accuracy which Decrease from 100%. + /// + public readonly BindableDouble DecreaseAccuracy = new BindableDouble(0) { MinValue = 0, MaxValue = 1 }; + /// /// The current combo. /// @@ -264,6 +274,10 @@ namespace osu.Game.Rulesets.Scoring private void updateScore() { Accuracy.Value = currentMaximumScoringValues.BaseScore > 0 ? (double)currentScoringValues.BaseScore / currentMaximumScoringValues.BaseScore : 1; + IncreaseAccuracy.Value = maximumScoringValues.BaseScore > 0 ? (double)currentScoringValues.BaseScore / maximumScoringValues.BaseScore : 0; + DecreaseAccuracy.Value = maximumScoringValues.BaseScore > 0 + ? (double)(maximumScoringValues.BaseScore - (currentMaximumScoringValues.BaseScore - currentScoringValues.BaseScore)) / maximumScoringValues.BaseScore + : 1; TotalScore.Value = computeScore(Mode.Value, currentScoringValues, maximumScoringValues); } diff --git a/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs index 1933193515..f8848f57b9 100644 --- a/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs +++ b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs @@ -4,6 +4,8 @@ #nullable disable using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Scoring; @@ -11,10 +13,38 @@ namespace osu.Game.Screens.Play.HUD { public abstract partial class GameplayAccuracyCounter : PercentageCounter { + [SettingSource("Accuracy Display Mode")] + public Bindable AccType { get; } = new Bindable(); + [BackgroundDependencyLoader] private void load(ScoreProcessor scoreProcessor) { - Current.BindTo(scoreProcessor.Accuracy); + AccType.BindValueChanged(mod => + { + Current.UnbindBindings(); + + switch (mod.NewValue) + { + case AccuracyType.Current: + Current.BindTo(scoreProcessor.Accuracy); + break; + + case AccuracyType.Increase: + Current.BindTo(scoreProcessor.IncreaseAccuracy); + break; + + case AccuracyType.Decrease: + Current.BindTo(scoreProcessor.DecreaseAccuracy); + break; + } + }, true); + } + + public enum AccuracyType + { + Current, + Increase, + Decrease } } } From a91da2284d27e5dc84c98b724cbbfae5cc4c2fad Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Fri, 30 Dec 2022 22:58:46 +0900 Subject: [PATCH 1250/2991] safe way to pass bindable --- .../Components/Timelines/Summary/Parts/PreviewTimePart.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs index 6149900fdc..b20f971086 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs @@ -22,10 +22,13 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts private partial class PreviewTimeVisualisation : PointVisualisation { + private BindableInt previewTime = new BindableInt(); + public PreviewTimeVisualisation(BindableInt time) : base(time.Value) { - time.BindValueChanged(s => X = s.NewValue); + previewTime.BindTo(time); + previewTime.BindValueChanged(s => X = s.NewValue); } [BackgroundDependencyLoader] From 23c485c763e91b4e7352138a0a94ec698afbb09c Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Fri, 30 Dec 2022 22:59:56 +0900 Subject: [PATCH 1251/2991] readonly --- .../Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs index b20f971086..bd34662969 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs @@ -22,7 +22,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts private partial class PreviewTimeVisualisation : PointVisualisation { - private BindableInt previewTime = new BindableInt(); + private readonly BindableInt previewTime = new BindableInt(); public PreviewTimeVisualisation(BindableInt time) : base(time.Value) From 784fe7ecf2278bf112f4a101d37a290ad028b67f Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Fri, 30 Dec 2022 23:06:10 +0900 Subject: [PATCH 1252/2991] rename `AccType` to `AccuracyDisplay` --- osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs index f8848f57b9..a862e5e230 100644 --- a/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs +++ b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs @@ -14,12 +14,12 @@ namespace osu.Game.Screens.Play.HUD public abstract partial class GameplayAccuracyCounter : PercentageCounter { [SettingSource("Accuracy Display Mode")] - public Bindable AccType { get; } = new Bindable(); + public Bindable AccuracyDisplay { get; } = new Bindable(); [BackgroundDependencyLoader] private void load(ScoreProcessor scoreProcessor) { - AccType.BindValueChanged(mod => + AccuracyDisplay.BindValueChanged(mod => { Current.UnbindBindings(); From 8beb168be9775b93947af36ab8d2ca54cf22a536 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Fri, 30 Dec 2022 23:24:20 +0900 Subject: [PATCH 1253/2991] remove nullable disabled --- osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs index a862e5e230..f7916d833a 100644 --- a/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs +++ b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Game.Configuration; From d60349c7c606ba8a6b27a9b38d3448b609b89c0b Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Fri, 30 Dec 2022 23:24:41 +0900 Subject: [PATCH 1254/2991] add description --- osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs index f7916d833a..ba96260f51 100644 --- a/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs +++ b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.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.ComponentModel; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Game.Configuration; @@ -11,7 +12,7 @@ namespace osu.Game.Screens.Play.HUD { public abstract partial class GameplayAccuracyCounter : PercentageCounter { - [SettingSource("Accuracy Display Mode")] + [SettingSource("Accuracy Display Mode", "Which Accuracy will display")] public Bindable AccuracyDisplay { get; } = new Bindable(); [BackgroundDependencyLoader] @@ -23,7 +24,7 @@ namespace osu.Game.Screens.Play.HUD switch (mod.NewValue) { - case AccuracyType.Current: + case AccuracyType.Rolling: Current.BindTo(scoreProcessor.Accuracy); break; @@ -40,8 +41,13 @@ namespace osu.Game.Screens.Play.HUD public enum AccuracyType { - Current, + [Description("Rolling")] + Rolling, + + [Description("Best achievable")] Increase, + + [Description("Worst achievable")] Decrease } } From 6d42cc5a360c4907357802e1720c2b563c0ac3d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 20:30:58 +0100 Subject: [PATCH 1255/2991] Naming pass --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 8 +++--- .../Play/HUD/GameplayAccuracyCounter.cs | 28 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index cec2b7e6b9..c379691c52 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -42,12 +42,12 @@ namespace osu.Game.Rulesets.Scoring /// /// The accuracy which increase from 0%. /// - public readonly BindableDouble IncreaseAccuracy = new BindableDouble(0) { MinValue = 0, MaxValue = 1 }; + public readonly BindableDouble MinimumAccuracy = new BindableDouble(0) { MinValue = 0, MaxValue = 1 }; /// /// The accuracy which Decrease from 100%. /// - public readonly BindableDouble DecreaseAccuracy = new BindableDouble(0) { MinValue = 0, MaxValue = 1 }; + public readonly BindableDouble MaximumAccuracy = new BindableDouble(0) { MinValue = 0, MaxValue = 1 }; /// /// The current combo. @@ -274,8 +274,8 @@ namespace osu.Game.Rulesets.Scoring private void updateScore() { Accuracy.Value = currentMaximumScoringValues.BaseScore > 0 ? (double)currentScoringValues.BaseScore / currentMaximumScoringValues.BaseScore : 1; - IncreaseAccuracy.Value = maximumScoringValues.BaseScore > 0 ? (double)currentScoringValues.BaseScore / maximumScoringValues.BaseScore : 0; - DecreaseAccuracy.Value = maximumScoringValues.BaseScore > 0 + MinimumAccuracy.Value = maximumScoringValues.BaseScore > 0 ? (double)currentScoringValues.BaseScore / maximumScoringValues.BaseScore : 0; + MaximumAccuracy.Value = maximumScoringValues.BaseScore > 0 ? (double)(maximumScoringValues.BaseScore - (currentMaximumScoringValues.BaseScore - currentScoringValues.BaseScore)) / maximumScoringValues.BaseScore : 1; TotalScore.Value = computeScore(Mode.Value, currentScoringValues, maximumScoringValues); diff --git a/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs index ba96260f51..32e7827be8 100644 --- a/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs +++ b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs @@ -12,8 +12,8 @@ namespace osu.Game.Screens.Play.HUD { public abstract partial class GameplayAccuracyCounter : PercentageCounter { - [SettingSource("Accuracy Display Mode", "Which Accuracy will display")] - public Bindable AccuracyDisplay { get; } = new Bindable(); + [SettingSource("Accuracy display mode", "Which accuracy mode should be displayed.")] + public Bindable AccuracyDisplay { get; } = new Bindable(); [BackgroundDependencyLoader] private void load(ScoreProcessor scoreProcessor) @@ -24,31 +24,31 @@ namespace osu.Game.Screens.Play.HUD switch (mod.NewValue) { - case AccuracyType.Rolling: + case AccuracyDisplayMode.Standard: Current.BindTo(scoreProcessor.Accuracy); break; - case AccuracyType.Increase: - Current.BindTo(scoreProcessor.IncreaseAccuracy); + case AccuracyDisplayMode.MinimumAchievable: + Current.BindTo(scoreProcessor.MinimumAccuracy); break; - case AccuracyType.Decrease: - Current.BindTo(scoreProcessor.DecreaseAccuracy); + case AccuracyDisplayMode.MaximumAchievable: + Current.BindTo(scoreProcessor.MaximumAccuracy); break; } }, true); } - public enum AccuracyType + public enum AccuracyDisplayMode { - [Description("Rolling")] - Rolling, + [Description("Standard")] + Standard, - [Description("Best achievable")] - Increase, + [Description("Maximum achievable")] + MaximumAchievable, - [Description("Worst achievable")] - Decrease + [Description("Minimum achievable")] + MinimumAchievable } } } From bb2822a175a44604a4bd2b08b04ff63c30bad788 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 20:43:23 +0100 Subject: [PATCH 1256/2991] xmldoc pass --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index c379691c52..ab4422b2ef 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -40,12 +40,14 @@ namespace osu.Game.Rulesets.Scoring public readonly BindableDouble Accuracy = new BindableDouble(1) { MinValue = 0, MaxValue = 1 }; /// - /// The accuracy which increase from 0%. + /// The minimum achievable accuracy for the whole beatmap at this stage of gameplay. + /// Assumes that all objects that have not been judged yet will receive the minimum hit result. /// public readonly BindableDouble MinimumAccuracy = new BindableDouble(0) { MinValue = 0, MaxValue = 1 }; /// - /// The accuracy which Decrease from 100%. + /// The maximum achievable accuracy for the whole beatmap at this stage of gameplay. + /// Assumes that all objects that have not been judged yet will receive the maximum hit result. /// public readonly BindableDouble MaximumAccuracy = new BindableDouble(0) { MinValue = 0, MaxValue = 1 }; From 8ace635249edccfc3eae7ac2f1519a821d518674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 20:43:47 +0100 Subject: [PATCH 1257/2991] Adjust minimum values --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index ab4422b2ef..2fec68f0b0 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -43,13 +43,13 @@ namespace osu.Game.Rulesets.Scoring /// The minimum achievable accuracy for the whole beatmap at this stage of gameplay. /// Assumes that all objects that have not been judged yet will receive the minimum hit result. /// - public readonly BindableDouble MinimumAccuracy = new BindableDouble(0) { MinValue = 0, MaxValue = 1 }; + public readonly BindableDouble MinimumAccuracy = new BindableDouble { MinValue = 0, MaxValue = 1 }; /// /// The maximum achievable accuracy for the whole beatmap at this stage of gameplay. /// Assumes that all objects that have not been judged yet will receive the maximum hit result. /// - public readonly BindableDouble MaximumAccuracy = new BindableDouble(0) { MinValue = 0, MaxValue = 1 }; + public readonly BindableDouble MaximumAccuracy = new BindableDouble(1) { MinValue = 0, MaxValue = 1 }; /// /// The current combo. From ae026e2d2db216ee35aeeb776f677af84fad512e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 20:52:05 +0100 Subject: [PATCH 1258/2991] Add test coverage --- .../Gameplay/TestSceneScoreProcessor.cs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs b/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs index 3ce7aa72d9..90c7688443 100644 --- a/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs +++ b/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Linq; using NUnit.Framework; using osu.Framework.Testing; +using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Online.Spectator; using osu.Game.Rulesets.Judgements; @@ -139,6 +140,29 @@ namespace osu.Game.Tests.Gameplay Assert.That(score.MaximumStatistics[HitResult.LargeBonus], Is.EqualTo(1)); } + [Test] + public void TestAccuracyModes() + { + var beatmap = new Beatmap + { + HitObjects = Enumerable.Range(0, 4).Select(_ => new TestHitObject(HitResult.Great)).ToList() + }; + + var scoreProcessor = new ScoreProcessor(new OsuRuleset()); + scoreProcessor.ApplyBeatmap(beatmap); + + Assert.That(scoreProcessor.Accuracy.Value, Is.EqualTo(1)); + Assert.That(scoreProcessor.MinimumAccuracy.Value, Is.EqualTo(0)); + Assert.That(scoreProcessor.MaximumAccuracy.Value, Is.EqualTo(1)); + + scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], beatmap.HitObjects[0].CreateJudgement()) { Type = HitResult.Ok }); + scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[1], beatmap.HitObjects[1].CreateJudgement()) { Type = HitResult.Great }); + + Assert.That(scoreProcessor.Accuracy.Value, Is.EqualTo((double)(100 + 300) / (2 * 300)).Within(Precision.DOUBLE_EPSILON)); + Assert.That(scoreProcessor.MinimumAccuracy.Value, Is.EqualTo((double)(100 + 300) / (4 * 300)).Within(Precision.DOUBLE_EPSILON)); + Assert.That(scoreProcessor.MaximumAccuracy.Value, Is.EqualTo((double)(100 + 3 * 300) / (4 * 300)).Within(Precision.DOUBLE_EPSILON)); + } + private class TestJudgement : Judgement { public override HitResult MaxResult { get; } From 6ed474d4fbb1be6523bbf809273dee21748bf926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 20:56:54 +0100 Subject: [PATCH 1259/2991] Rearrange formula for maximum accuracy Feels like it's easier to understand this way. The difference of the maximum scoring values for the entire beatmap and the max values for the part of the beatmap that has already been played represents the act of filling the rest of the unjudged objects with maximum results. --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 2fec68f0b0..13276a8748 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -278,7 +278,7 @@ namespace osu.Game.Rulesets.Scoring Accuracy.Value = currentMaximumScoringValues.BaseScore > 0 ? (double)currentScoringValues.BaseScore / currentMaximumScoringValues.BaseScore : 1; MinimumAccuracy.Value = maximumScoringValues.BaseScore > 0 ? (double)currentScoringValues.BaseScore / maximumScoringValues.BaseScore : 0; MaximumAccuracy.Value = maximumScoringValues.BaseScore > 0 - ? (double)(maximumScoringValues.BaseScore - (currentMaximumScoringValues.BaseScore - currentScoringValues.BaseScore)) / maximumScoringValues.BaseScore + ? (double)(currentScoringValues.BaseScore + (maximumScoringValues.BaseScore - currentMaximumScoringValues.BaseScore)) / maximumScoringValues.BaseScore : 1; TotalScore.Value = computeScore(Mode.Value, currentScoringValues, maximumScoringValues); } From 7580ab78be796e9bf80b2b8dd8a3a96dbca2a904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 21:08:48 +0100 Subject: [PATCH 1260/2991] Move binding to `LoadComplete()` --- osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs index 32e7827be8..210f96ce46 100644 --- a/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs +++ b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs @@ -15,9 +15,13 @@ namespace osu.Game.Screens.Play.HUD [SettingSource("Accuracy display mode", "Which accuracy mode should be displayed.")] public Bindable AccuracyDisplay { get; } = new Bindable(); - [BackgroundDependencyLoader] - private void load(ScoreProcessor scoreProcessor) + [Resolved] + private ScoreProcessor scoreProcessor { get; set; } = null!; + + protected override void LoadComplete() { + base.LoadComplete(); + AccuracyDisplay.BindValueChanged(mod => { Current.UnbindBindings(); From 6509d3538c203f41049218899b1dd0471dcfa385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 21:12:29 +0100 Subject: [PATCH 1261/2991] Fix counter initially rolling down from 100% to 0% in minimum achievable mode --- osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs index 210f96ce46..ca7fef8f73 100644 --- a/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs +++ b/osu.Game/Screens/Play/HUD/GameplayAccuracyCounter.cs @@ -41,6 +41,12 @@ namespace osu.Game.Screens.Play.HUD break; } }, true); + + // if the accuracy counter is using the "minimum achievable" mode, + // then its initial value is 0%, rather than the 100% that the base PercentageCounter assumes. + // to counteract this, manually finish transforms on DisplayedCount once after the initial callback above + // to stop it from rolling down from 100% to 0%. + FinishTransforms(targetMember: nameof(DisplayedCount)); } public enum AccuracyDisplayMode From 87250ad84707e5b7b1a5041af9fc102b9da81f43 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 1 Jan 2023 14:32:28 +0800 Subject: [PATCH 1262/2991] Add search keywords for beatmap colours / hitsound overrides --- osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs index e8db5fe58a..da5fc519e6 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/BeatmapSettings.cs @@ -32,11 +32,13 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay }, new SettingsCheckbox { + Keywords = new[] { "combo", "override" }, LabelText = SkinSettingsStrings.BeatmapColours, Current = config.GetBindable(OsuSetting.BeatmapColours) }, new SettingsCheckbox { + Keywords = new[] { "samples", "override" }, LabelText = SkinSettingsStrings.BeatmapHitsounds, Current = config.GetBindable(OsuSetting.BeatmapHitsounds) }, From 9a4f0cad2c5306b6c3076b7ab5262002386f9992 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 1 Jan 2023 17:48:04 +0800 Subject: [PATCH 1263/2991] Fix incorrect domain root being used for recent activity entries on profile overlay Closes https://github.com/ppy/osu/issues/21980. --- .../Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 4a8b020e33..c3fa467e5f 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -224,7 +224,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent private void addBeatmapsetLink() => content.AddLink(activity.Beatmapset?.Title, LinkAction.OpenBeatmapSet, getLinkArgument(activity.Beatmapset?.Url), creationParameters: t => t.Font = getLinkFont()); - private string getLinkArgument(string url) => MessageFormatter.GetLinkDetails($"{api.APIEndpointUrl}{url}").Argument.ToString(); + private string getLinkArgument(string url) => MessageFormatter.GetLinkDetails($"{api.WebsiteRootUrl}{url}").Argument.ToString(); private FontUsage getLinkFont(FontWeight fontWeight = FontWeight.Regular) => OsuFont.GetFont(size: font_size, weight: fontWeight, italics: true); From a82f1a6abd19bc8f79f1b3e72a45806d4c2c23ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 1 Jan 2023 18:48:56 +0100 Subject: [PATCH 1264/2991] Adjust method naming and copy --- osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs | 2 +- osu.Game/Screens/Edit/Editor.cs | 4 ++-- osu.Game/Tests/Visual/EditorTestScene.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs b/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs index ad49f3ac0a..d5aa71095b 100644 --- a/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs +++ b/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs @@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual.Editing { AddStep("seek to 1000", () => EditorClock.Seek(1000)); AddAssert("time is 1000", () => EditorClock.CurrentTime == 1000); - AddStep("set current time as preview point", () => Editor.SetCurrentTimeAsPreview()); + AddStep("set current time as preview point", () => Editor.SetPreviewPointToCurrentTime()); AddAssert("preview time is 1000", () => EditorBeatmap.PreviewTime.Value == 1000); } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 62bb7d3133..be4e2f9628 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -327,7 +327,7 @@ namespace osu.Game.Screens.Edit { Items = new MenuItem[] { - new EditorMenuItem("Set Current Position as Preview Point", MenuItemType.Standard, SetCurrentTimeAsPreview) + new EditorMenuItem("Set preview point to current time", MenuItemType.Standard, SetPreviewPointToCurrentTime) } } } @@ -808,7 +808,7 @@ namespace osu.Game.Screens.Edit protected void Redo() => changeHandler?.RestoreState(1); - protected void SetCurrentTimeAsPreview() + protected void SetPreviewPointToCurrentTime() { editorBeatmap.PreviewTime.Value = (int)clock.CurrentTime; } diff --git a/osu.Game/Tests/Visual/EditorTestScene.cs b/osu.Game/Tests/Visual/EditorTestScene.cs index 9c8ac65add..6e2f1e99cd 100644 --- a/osu.Game/Tests/Visual/EditorTestScene.cs +++ b/osu.Game/Tests/Visual/EditorTestScene.cs @@ -102,7 +102,7 @@ namespace osu.Game.Tests.Visual public new void Redo() => base.Redo(); - public new void SetCurrentTimeAsPreview() => base.SetCurrentTimeAsPreview(); + public new void SetPreviewPointToCurrentTime() => base.SetPreviewPointToCurrentTime(); public new bool Save() => base.Save(); From 656bf12b3d43d15d38873b9993c6531fcfb2eb1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 1 Jan 2023 19:37:19 +0100 Subject: [PATCH 1265/2991] Add all possible timeline elements to test for demonstrative purposes --- .../Visual/Editing/TestSceneEditorSummaryTimeline.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorSummaryTimeline.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorSummaryTimeline.cs index ccd2feef9c..f255dd08a8 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorSummaryTimeline.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorSummaryTimeline.cs @@ -6,6 +6,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Osu; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Components.Timelines.Summary; @@ -21,7 +22,13 @@ namespace osu.Game.Tests.Visual.Editing public TestSceneEditorSummaryTimeline() { - editorBeatmap = new EditorBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)); + var beatmap = CreateBeatmap(new OsuRuleset().RulesetInfo); + + beatmap.ControlPointInfo.Add(100000, new TimingControlPoint { BeatLength = 100 }); + beatmap.ControlPointInfo.Add(50000, new DifficultyControlPoint { SliderVelocity = 2 }); + beatmap.BeatmapInfo.Bookmarks = new[] { 75000, 125000 }; + + editorBeatmap = new EditorBeatmap(beatmap); } protected override void LoadComplete() From 452ebddfd28b8740e9c268a8ee41fc48de701d2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 1 Jan 2023 19:39:21 +0100 Subject: [PATCH 1266/2991] Adjust visual appearance of preview time part - Use slightly different hue of green to distinguish from difficulty control points. The colour is still not ideal, but picking a distinctive enough hue is pretty hard. - Place the preview time part at the bottom rather at the top. Not sure why it was at the top; not only could it overlap with the control points, but it also looked quite badly misaligned there when bookmarks were displayed at the bottom. --- .../Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs | 2 +- .../Edit/Components/Timelines/Summary/SummaryTimeline.cs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs index bd34662969..9d3bbe8bff 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts } [BackgroundDependencyLoader] - private void load(OsuColour colours) => Colour = colours.Lime; + private void load(OsuColour colours) => Colour = colours.Green1; } } } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs index 41377bcb18..075d47d82e 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs @@ -44,9 +44,8 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary new PreviewTimePart { Anchor = Anchor.Centre, - Origin = Anchor.BottomCentre, + Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.Both, - Y = -10, Height = 0.35f }, new Container From efdd557f3b7b9a503b189d1aa864d6bd4f15421f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 1 Jan 2023 19:45:23 +0100 Subject: [PATCH 1267/2991] Adjust binding logic --- .../Timelines/Summary/Parts/PreviewTimePart.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs index 9d3bbe8bff..de7f611424 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs @@ -13,7 +13,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts protected override void LoadBeatmap(EditorBeatmap beatmap) { base.LoadBeatmap(beatmap); - Add(new PreviewTimeVisualisation(beatmap.PreviewTime)); + Add(new PreviewTimeVisualisation(beatmap)); beatmap.PreviewTime.BindValueChanged(s => { Alpha = s.NewValue == -1 ? 0 : 1; @@ -24,11 +24,10 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { private readonly BindableInt previewTime = new BindableInt(); - public PreviewTimeVisualisation(BindableInt time) - : base(time.Value) + public PreviewTimeVisualisation(EditorBeatmap editorBeatmap) { - previewTime.BindTo(time); - previewTime.BindValueChanged(s => X = s.NewValue); + previewTime.BindTo(editorBeatmap.PreviewTime); + previewTime.BindValueChanged(s => X = s.NewValue, true); } [BackgroundDependencyLoader] From b689ad6d80e177734a470fc0d30e6497dc9af09b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 1 Jan 2023 19:54:26 +0100 Subject: [PATCH 1268/2991] Fix changing preview point not prompting for save --- osu.Game/Screens/Edit/EditorBeatmap.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index dfd7328d11..1684dcf0cd 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -111,7 +111,12 @@ namespace osu.Game.Screens.Edit trackStartTime(obj); PreviewTime = new BindableInt(playableBeatmap.Metadata.PreviewTime); - PreviewTime.BindValueChanged(s => this.beatmapInfo.Metadata.PreviewTime = s.NewValue); + PreviewTime.BindValueChanged(s => + { + BeginChange(); + this.beatmapInfo.Metadata.PreviewTime = s.NewValue; + EndChange(); + }); } /// From 88e90d5fa098f7f19fa2986d44aa9a02336ab0b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 13:17:59 +0100 Subject: [PATCH 1269/2991] Enable NRT in user profile overlay --- .../Profile/Header/BottomHeaderContainer.cs | 14 ++++---- .../Profile/Header/CentreHeaderContainer.cs | 10 +++--- .../Header/Components/ExpandDetailsButton.cs | 8 ++--- .../Header/Components/FollowersButton.cs | 4 +-- .../Profile/Header/Components/LevelBadge.cs | 13 ++++--- .../Header/Components/LevelProgressBar.cs | 10 +++--- .../Components/MappingSubscribersButton.cs | 4 +-- .../Header/Components/MessageUserButton.cs | 24 ++++++------- .../Components/OverlinedInfoContainer.cs | 2 -- .../Components/OverlinedTotalPlayTime.cs | 8 ++--- .../Header/Components/PreviousUsernames.cs | 10 +++--- .../Header/Components/ProfileHeaderButton.cs | 2 -- .../ProfileHeaderStatisticsButton.cs | 2 -- .../Components/ProfileRulesetSelector.cs | 7 ++-- .../Components/ProfileRulesetTabItem.cs | 2 -- .../Profile/Header/Components/RankGraph.cs | 8 ++--- .../Header/Components/SupporterIcon.cs | 8 ++--- .../Profile/Header/DetailHeaderContainer.cs | 18 +++++----- .../Profile/Header/MedalHeaderContainer.cs | 12 +++---- .../Profile/Header/TopHeaderContainer.cs | 24 ++++++------- osu.Game/Overlays/Profile/ProfileHeader.cs | 8 ++--- osu.Game/Overlays/Profile/ProfileSection.cs | 4 +-- .../Overlays/Profile/Sections/AboutSection.cs | 2 -- .../Sections/BeatmapMetadataContainer.cs | 6 ++-- .../Beatmaps/PaginatedBeatmapContainer.cs | 10 +++--- .../Profile/Sections/BeatmapsSection.cs | 2 -- .../Overlays/Profile/Sections/CounterPill.cs | 4 +-- .../Historical/ChartProfileSubsection.cs | 10 +++--- .../Historical/DrawableMostPlayedBeatmap.cs | 2 -- .../PaginatedMostPlayedBeatmapContainer.cs | 8 ++--- .../Historical/PlayHistorySubsection.cs | 6 ++-- .../Sections/Historical/ProfileLineChart.cs | 6 +--- .../Sections/Historical/ReplaysSubsection.cs | 6 ++-- .../Sections/Historical/UserHistoryGraph.cs | 6 +--- .../Profile/Sections/HistoricalSection.cs | 2 -- .../Kudosu/DrawableKudosuHistoryItem.cs | 4 +-- .../Profile/Sections/Kudosu/KudosuInfo.cs | 6 ++-- .../Kudosu/PaginatedKudosuHistoryContainer.cs | 8 ++--- .../Profile/Sections/KudosuSection.cs | 2 -- .../Profile/Sections/MedalsSection.cs | 2 -- .../Sections/PaginatedProfileSubsection.cs | 35 ++++++++++--------- .../Profile/Sections/ProfileItemContainer.cs | 2 -- .../Profile/Sections/ProfileSubsection.cs | 10 ++---- .../Sections/ProfileSubsectionHeader.cs | 4 +-- .../Sections/Ranks/DrawableProfileScore.cs | 13 +++---- .../Ranks/DrawableProfileWeightedScore.cs | 2 -- .../Sections/Ranks/PaginatedScoreContainer.cs | 8 ++--- .../Overlays/Profile/Sections/RanksSection.cs | 2 -- .../Sections/Recent/DrawableRecentActivity.cs | 17 +++++---- .../Profile/Sections/Recent/MedalIcon.cs | 2 -- .../PaginatedRecentActivityContainer.cs | 8 ++--- .../Profile/Sections/RecentSection.cs | 2 -- osu.Game/Overlays/Profile/UserGraph.cs | 25 +++++++------ osu.Game/Overlays/UserProfileOverlay.cs | 15 ++++---- osu.Game/Users/UserCoverBackground.cs | 12 +++---- 55 files changed, 172 insertions(+), 279 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 5ba3963a45..f5c7a3f87a 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using Humanizer; using osu.Framework.Allocation; @@ -25,15 +23,15 @@ namespace osu.Game.Overlays.Profile.Header { public partial class BottomHeaderContainer : CompositeDrawable { - public readonly Bindable User = new Bindable(); + public readonly Bindable User = new Bindable(); - private LinkFlowContainer topLinkContainer; - private LinkFlowContainer bottomLinkContainer; + private LinkFlowContainer topLinkContainer = null!; + private LinkFlowContainer bottomLinkContainer = null!; private Color4 iconColour; [Resolved] - private IAPIProvider api { get; set; } + private IAPIProvider api { get; set; } = null!; public BottomHeaderContainer() { @@ -78,7 +76,7 @@ namespace osu.Game.Overlays.Profile.Header User.BindValueChanged(user => updateDisplay(user.NewValue)); } - private void updateDisplay(APIUser user) + private void updateDisplay(APIUser? user) { topLinkContainer.Clear(); bottomLinkContainer.Clear(); @@ -164,7 +162,7 @@ namespace osu.Game.Overlays.Profile.Header private void addSpacer(OsuTextFlowContainer textFlow) => textFlow.AddArbitraryDrawable(new Container { Width = 15 }); - private bool tryAddInfo(IconUsage icon, string content, string link = null) + private bool tryAddInfo(IconUsage icon, string content, string? link = null) { if (string.IsNullOrEmpty(content)) return false; diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 5f6af7a6e2..5e4e1184a4 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.LocalisationExtensions; @@ -20,10 +18,10 @@ namespace osu.Game.Overlays.Profile.Header public partial class CentreHeaderContainer : CompositeDrawable { public readonly BindableBool DetailsVisible = new BindableBool(true); - public readonly Bindable User = new Bindable(); + public readonly Bindable User = new Bindable(); - private OverlinedInfoContainer hiddenDetailGlobal; - private OverlinedInfoContainer hiddenDetailCountry; + private OverlinedInfoContainer hiddenDetailGlobal = null!; + private OverlinedInfoContainer hiddenDetailCountry = null!; public CentreHeaderContainer() { @@ -146,7 +144,7 @@ namespace osu.Game.Overlays.Profile.Header User.BindValueChanged(user => updateDisplay(user.NewValue)); } - private void updateDisplay(APIUser user) + private void updateDisplay(APIUser? user) { hiddenDetailGlobal.Content = user?.Statistics?.GlobalRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-"; hiddenDetailCountry.Content = user?.Statistics?.CountryRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-"; diff --git a/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs b/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs index a778ddd2b1..e7a83c95d8 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; @@ -23,9 +21,9 @@ namespace osu.Game.Overlays.Profile.Header.Components public override LocalisableString TooltipText => DetailsVisible.Value ? CommonStrings.ButtonsCollapse : CommonStrings.ButtonsExpand; - private SpriteIcon icon; - private Sample sampleOpen; - private Sample sampleClose; + private SpriteIcon icon = null!; + private Sample? sampleOpen; + private Sample? sampleClose; protected override HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverClickSounds(); diff --git a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs index c278a6c48b..c0bcec622a 100644 --- a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; @@ -14,7 +12,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class FollowersButton : ProfileHeaderStatisticsButton { - public readonly Bindable User = new Bindable(); + public readonly Bindable User = new Bindable(); public override LocalisableString TooltipText => FriendsStrings.ButtonsDisabled; diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index ef2f35e9a8..8f84e69bac 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -20,11 +18,11 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelBadge : CompositeDrawable, IHasTooltip { - public readonly Bindable User = new Bindable(); + public readonly Bindable User = new Bindable(); public LocalisableString TooltipText { get; private set; } - private OsuSpriteText levelText; + private OsuSpriteText levelText = null!; public LevelBadge() { @@ -53,10 +51,11 @@ namespace osu.Game.Overlays.Profile.Header.Components User.BindValueChanged(user => updateLevel(user.NewValue)); } - private void updateLevel(APIUser user) + private void updateLevel(APIUser? user) { - levelText.Text = user?.Statistics?.Level.Current.ToString() ?? "0"; - TooltipText = UsersStrings.ShowStatsLevel(user?.Statistics?.Level.Current.ToString()); + string level = user?.Statistics?.Level.Current.ToString() ?? "0"; + levelText.Text = level; + TooltipText = UsersStrings.ShowStatsLevel(level); } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs index 0351230fb3..ea5ca0c8bd 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.LocalisationExtensions; @@ -21,12 +19,12 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelProgressBar : CompositeDrawable, IHasTooltip { - public readonly Bindable User = new Bindable(); + public readonly Bindable User = new Bindable(); public LocalisableString TooltipText { get; } - private Bar levelProgressBar; - private OsuSpriteText levelProgressText; + private Bar levelProgressBar = null!; + private OsuSpriteText levelProgressText = null!; public LevelProgressBar() { @@ -61,7 +59,7 @@ namespace osu.Game.Overlays.Profile.Header.Components User.BindValueChanged(user => updateProgress(user.NewValue)); } - private void updateProgress(APIUser user) + private void updateProgress(APIUser? user) { levelProgressBar.Length = user?.Statistics?.Level.Progress / 100f ?? 0; levelProgressText.Text = user?.Statistics?.Level.Progress.ToLocalisableString("0'%'") ?? default; diff --git a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs index 887cf10cce..c600f7622a 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; @@ -14,7 +12,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class MappingSubscribersButton : ProfileHeaderStatisticsButton { - public readonly Bindable User = new Bindable(); + public readonly Bindable User = new Bindable(); public override LocalisableString TooltipText => FollowsStrings.MappingFollowers; diff --git a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs index 4886324a22..3266e3c308 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -18,21 +16,21 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class MessageUserButton : ProfileHeaderButton { - public readonly Bindable User = new Bindable(); + public readonly Bindable User = new Bindable(); public override LocalisableString TooltipText => UsersStrings.CardSendMessage; - [Resolved(CanBeNull = true)] - private ChannelManager channelManager { get; set; } - - [Resolved(CanBeNull = true)] - private UserProfileOverlay userOverlay { get; set; } - - [Resolved(CanBeNull = true)] - private ChatOverlay chatOverlay { get; set; } + [Resolved] + private ChannelManager? channelManager { get; set; } [Resolved] - private IAPIProvider apiProvider { get; set; } + private UserProfileOverlay? userOverlay { get; set; } + + [Resolved] + private ChatOverlay? chatOverlay { get; set; } + + [Resolved] + private IAPIProvider apiProvider { get; set; } = null!; public MessageUserButton() { @@ -56,7 +54,7 @@ namespace osu.Game.Overlays.Profile.Header.Components chatOverlay?.Show(); }; - User.ValueChanged += e => Content.Alpha = !e.NewValue.PMFriendsOnly && apiProvider.LocalUser.Value.Id != e.NewValue.Id ? 1 : 0; + User.ValueChanged += e => Content.Alpha = e.NewValue != null && !e.NewValue.PMFriendsOnly && apiProvider.LocalUser.Value.Id != e.NewValue.Id ? 1 : 0; } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs index 244f185e28..42b67865a0 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs index c040f5a787..e9e277acd3 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -16,11 +14,11 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class OverlinedTotalPlayTime : CompositeDrawable, IHasTooltip { - public readonly Bindable User = new Bindable(); + public readonly Bindable User = new Bindable(); public LocalisableString TooltipText { get; set; } - private OverlinedInfoContainer info; + private OverlinedInfoContainer info = null!; public OverlinedTotalPlayTime() { @@ -41,7 +39,7 @@ namespace osu.Game.Overlays.Profile.Header.Components User.BindValueChanged(updateTime, true); } - private void updateTime(ValueChangedEvent user) + private void updateTime(ValueChangedEvent user) { TooltipText = (user.NewValue?.Statistics?.PlayTime ?? 0) / 3600 + " hours"; info.Content = formatTime(user.NewValue?.Statistics?.PlayTime); diff --git a/osu.Game/Overlays/Profile/Header/Components/PreviousUsernames.cs b/osu.Game/Overlays/Profile/Header/Components/PreviousUsernames.cs index 0abc4de5ef..b722fe92e0 100644 --- a/osu.Game/Overlays/Profile/Header/Components/PreviousUsernames.cs +++ b/osu.Game/Overlays/Profile/Header/Components/PreviousUsernames.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using osu.Framework.Allocation; @@ -27,7 +25,7 @@ namespace osu.Game.Overlays.Profile.Header.Components private const int width = 310; private const int move_offset = 15; - public readonly Bindable User = new Bindable(); + public readonly Bindable User = new Bindable(); private readonly TextFlowContainer text; private readonly Box background; @@ -109,11 +107,11 @@ namespace osu.Game.Overlays.Profile.Header.Components User.BindValueChanged(onUserChanged, true); } - private void onUserChanged(ValueChangedEvent user) + private void onUserChanged(ValueChangedEvent user) { text.Text = string.Empty; - string[] usernames = user.NewValue?.PreviousUsernames; + string[]? usernames = user.NewValue?.PreviousUsernames; if (usernames?.Any() ?? false) { @@ -149,7 +147,7 @@ namespace osu.Game.Overlays.Profile.Header.Components private partial class HoverIconContainer : Container { - public Action ActivateHover; + public Action? ActivateHover; public HoverIconContainer() { diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs index c4a46440d2..414ca4d077 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderStatisticsButton.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderStatisticsButton.cs index 5ad726a3ea..32c5ebee2c 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderStatisticsButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderStatisticsButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index 72446bde3a..684ce9088e 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -1,9 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.UserInterface; using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets; @@ -12,12 +11,12 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class ProfileRulesetSelector : OverlayRulesetSelector { - public readonly Bindable User = new Bindable(); + public readonly Bindable User = new Bindable(); protected override void LoadComplete() { base.LoadComplete(); - User.BindValueChanged(u => SetDefaultRuleset(Rulesets.GetRuleset(u.NewValue?.PlayMode ?? "osu")), true); + User.BindValueChanged(u => SetDefaultRuleset(Rulesets.GetRuleset(u.NewValue?.PlayMode ?? "osu").AsNonNull()), true); } public void SetDefaultRuleset(RulesetInfo ruleset) diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs index 72adc96f9a..9caa7dd1bc 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Sprites; diff --git a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs index 51531977d2..fe1069eea1 100644 --- a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -21,7 +19,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { private const int ranked_days = 88; - public readonly Bindable Statistics = new Bindable(); + public readonly Bindable Statistics = new Bindable(); private readonly OsuSpriteText placeholder; @@ -42,11 +40,11 @@ namespace osu.Game.Overlays.Profile.Header.Components Statistics.BindValueChanged(statistics => updateStatistics(statistics.NewValue), true); } - private void updateStatistics(UserStatistics statistics) + private void updateStatistics(UserStatistics? statistics) { // checking both IsRanked and RankHistory is required. // see https://github.com/ppy/osu-web/blob/154ceafba0f35a1dd935df53ec98ae2ea5615f9f/resources/assets/lib/profile-page/rank-chart.tsx#L46 - int[] userRanks = statistics?.IsRanked == true ? statistics.RankHistory?.Data : null; + int[]? userRanks = statistics?.IsRanked == true ? statistics.RankHistory?.Data : null; Data = userRanks?.Select((x, index) => new KeyValuePair(index, x)).Where(x => x.Value != 0).ToArray(); } diff --git a/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs b/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs index 4028eb1389..92e2017659 100644 --- a/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs +++ b/osu.Game/Overlays/Profile/Header/Components/SupporterIcon.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -82,10 +80,10 @@ namespace osu.Game.Overlays.Profile.Header.Components } [Resolved] - private OsuColour colours { get; set; } + private OsuColour colours { get; set; } = null!; - [BackgroundDependencyLoader(true)] - private void load(OsuGame game) + [BackgroundDependencyLoader] + private void load(OsuGame? game) { background.Colour = colours.Pink; diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 44986dc178..95fead1246 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -25,14 +23,14 @@ namespace osu.Game.Overlays.Profile.Header public partial class DetailHeaderContainer : CompositeDrawable { private readonly Dictionary scoreRankInfos = new Dictionary(); - private OverlinedInfoContainer medalInfo; - private OverlinedInfoContainer ppInfo; - private OverlinedInfoContainer detailGlobalRank; - private OverlinedInfoContainer detailCountryRank; - private FillFlowContainer fillFlow; - private RankGraph rankGraph; + private OverlinedInfoContainer medalInfo = null!; + private OverlinedInfoContainer ppInfo = null!; + private OverlinedInfoContainer detailGlobalRank = null!; + private OverlinedInfoContainer detailCountryRank = null!; + private FillFlowContainer? fillFlow; + private RankGraph rankGraph = null!; - public readonly Bindable User = new Bindable(); + public readonly Bindable User = new Bindable(); private bool expanded = true; @@ -173,7 +171,7 @@ namespace osu.Game.Overlays.Profile.Header }; } - private void updateDisplay(APIUser user) + private void updateDisplay(APIUser? user) { medalInfo.Content = user?.Achievements?.Length.ToString() ?? "0"; ppInfo.Content = user?.Statistics?.PP?.ToLocalisableString("#,##0") ?? (LocalisableString)"0"; diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index ab800d006d..79f9eba57d 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Threading; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -20,9 +18,9 @@ namespace osu.Game.Overlays.Profile.Header { public partial class MedalHeaderContainer : CompositeDrawable { - private FillFlowContainer badgeFlowContainer; + private FillFlowContainer badgeFlowContainer = null!; - public readonly Bindable User = new Bindable(); + public readonly Bindable User = new Bindable(); [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -66,16 +64,16 @@ namespace osu.Game.Overlays.Profile.Header }; } - private CancellationTokenSource cancellationTokenSource; + private CancellationTokenSource? cancellationTokenSource; - private void updateDisplay(APIUser user) + private void updateDisplay(APIUser? user) { cancellationTokenSource?.Cancel(); cancellationTokenSource = new CancellationTokenSource(); badgeFlowContainer.Clear(); - var badges = user.Badges; + var badges = user?.Badges; if (badges?.Length > 0) { diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 8826dd982d..a6501f567f 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions; @@ -29,19 +27,19 @@ namespace osu.Game.Overlays.Profile.Header { private const float avatar_size = 110; - public readonly Bindable User = new Bindable(); + public readonly Bindable User = new Bindable(); [Resolved] - private IAPIProvider api { get; set; } + private IAPIProvider api { get; set; } = null!; - private SupporterIcon supporterTag; - private UpdateableAvatar avatar; - private OsuSpriteText usernameText; - private ExternalLinkButton openUserExternally; - private OsuSpriteText titleText; - private UpdateableFlag userFlag; - private OsuSpriteText userCountryText; - private FillFlowContainer userStats; + private SupporterIcon supporterTag = null!; + private UpdateableAvatar avatar = null!; + private OsuSpriteText usernameText = null!; + private ExternalLinkButton openUserExternally = null!; + private OsuSpriteText titleText = null!; + private UpdateableFlag userFlag = null!; + private OsuSpriteText userCountryText = null!; + private FillFlowContainer userStats = null!; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -176,7 +174,7 @@ namespace osu.Game.Overlays.Profile.Header User.BindValueChanged(user => updateUser(user.NewValue)); } - private void updateUser(APIUser user) + private void updateUser(APIUser? user) { avatar.User = user; usernameText.Text = user?.Username ?? string.Empty; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 8443678989..2b8d2503e0 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Diagnostics; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; @@ -20,9 +18,9 @@ namespace osu.Game.Overlays.Profile { public partial class ProfileHeader : TabControlOverlayHeader { - private UserCoverBackground coverContainer; + private UserCoverBackground coverContainer = null!; - public Bindable User = new Bindable(); + public Bindable User = new Bindable(); private CentreHeaderContainer centreHeaderContainer; private DetailHeaderContainer detailHeaderContainer; @@ -102,7 +100,7 @@ namespace osu.Game.Overlays.Profile protected override OverlayTitle CreateTitle() => new ProfileHeaderTitle(); - private void updateDisplay(APIUser user) => coverContainer.User = user; + private void updateDisplay(APIUser? user) => coverContainer.User = user; private partial class ProfileHeaderTitle : OverlayTitle { diff --git a/osu.Game/Overlays/Profile/ProfileSection.cs b/osu.Game/Overlays/Profile/ProfileSection.cs index fc99050f73..62b40545df 100644 --- a/osu.Game/Overlays/Profile/ProfileSection.cs +++ b/osu.Game/Overlays/Profile/ProfileSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; @@ -31,7 +29,7 @@ namespace osu.Game.Overlays.Profile protected override Container Content => content; - public readonly Bindable User = new Bindable(); + public readonly Bindable User = new Bindable(); protected ProfileSection() { diff --git a/osu.Game/Overlays/Profile/Sections/AboutSection.cs b/osu.Game/Overlays/Profile/Sections/AboutSection.cs index ac3dca5107..69a8b23412 100644 --- a/osu.Game/Overlays/Profile/Sections/AboutSection.cs +++ b/osu.Game/Overlays/Profile/Sections/AboutSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Localisation; using osu.Game.Resources.Localisation.Web; diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs b/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs index 5a80a4d444..499c572eac 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -25,8 +23,8 @@ namespace osu.Game.Overlays.Profile.Sections AutoSizeAxes = Axes.Both; } - [BackgroundDependencyLoader(true)] - private void load(BeatmapSetOverlay beatmapSetOverlay) + [BackgroundDependencyLoader] + private void load(BeatmapSetOverlay? beatmapSetOverlay) { Action = () => { diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index 56d9fb9ec6..e327d71d25 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -24,7 +22,7 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps protected override int InitialItemsCount => type == BeatmapSetType.Graveyard ? 2 : 6; - public PaginatedBeatmapContainer(BeatmapSetType type, Bindable user, LocalisableString headerText) + public PaginatedBeatmapContainer(BeatmapSetType type, Bindable user, LocalisableString headerText) : base(user, headerText) { this.type = type; @@ -66,10 +64,10 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps } } - protected override APIRequest> CreateRequest(PaginationParameters pagination) => - new GetUserBeatmapsRequest(User.Value.Id, type, pagination); + protected override APIRequest> CreateRequest(APIUser user, PaginationParameters pagination) => + new GetUserBeatmapsRequest(user.Id, type, pagination); - protected override Drawable CreateDrawableItem(APIBeatmapSet model) => model.OnlineID > 0 + protected override Drawable? CreateDrawableItem(APIBeatmapSet model) => model.OnlineID > 0 ? new BeatmapCardNormal(model) { Anchor = Anchor.TopCentre, diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs index cf80ebd66f..3b304a79ef 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Localisation; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Profile.Sections.Beatmaps; diff --git a/osu.Game/Overlays/Profile/Sections/CounterPill.cs b/osu.Game/Overlays/Profile/Sections/CounterPill.cs index c93cdb84f2..74cd4b218b 100644 --- a/osu.Game/Overlays/Profile/Sections/CounterPill.cs +++ b/osu.Game/Overlays/Profile/Sections/CounterPill.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; @@ -18,7 +16,7 @@ namespace osu.Game.Overlays.Profile.Sections { public readonly BindableInt Current = new BindableInt(); - private OsuSpriteText counter; + private OsuSpriteText counter = null!; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs index e0837320b2..c532c693ec 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Framework.Bindables; @@ -15,14 +13,14 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { public abstract partial class ChartProfileSubsection : ProfileSubsection { - private ProfileLineChart chart; + private ProfileLineChart chart = null!; /// /// Text describing the value being plotted on the graph, which will be displayed as a prefix to the value in the history graph tooltip. /// protected abstract LocalisableString GraphCounterName { get; } - protected ChartProfileSubsection(Bindable user, LocalisableString headerText) + protected ChartProfileSubsection(Bindable user, LocalisableString headerText) : base(user, headerText) { } @@ -46,7 +44,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical User.BindValueChanged(onUserChanged, true); } - private void onUserChanged(ValueChangedEvent e) + private void onUserChanged(ValueChangedEvent e) { var values = GetValues(e.NewValue); @@ -86,6 +84,6 @@ namespace osu.Game.Overlays.Profile.Sections.Historical return filledHistoryEntries.ToArray(); } - protected abstract APIUserHistoryCount[] GetValues(APIUser user); + protected abstract APIUserHistoryCount[]? GetValues(APIUser? user); } } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs b/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs index a31ee88f3b..53447a971b 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs index 222969bdfd..515c1fd146 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -18,7 +16,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { public partial class PaginatedMostPlayedBeatmapContainer : PaginatedProfileSubsection { - public PaginatedMostPlayedBeatmapContainer(Bindable user) + public PaginatedMostPlayedBeatmapContainer(Bindable user) : base(user, UsersStrings.ShowExtraHistoricalMostPlayedTitle) { } @@ -31,8 +29,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical protected override int GetCount(APIUser user) => user.BeatmapPlayCountsCount; - protected override APIRequest> CreateRequest(PaginationParameters pagination) => - new GetUserMostPlayedBeatmapsRequest(User.Value.Id, pagination); + protected override APIRequest> CreateRequest(APIUser user, PaginationParameters pagination) => + new GetUserMostPlayedBeatmapsRequest(user.Id, pagination); protected override Drawable CreateDrawableItem(APIUserMostPlayedBeatmap mostPlayed) => new DrawableMostPlayedBeatmap(mostPlayed); diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs index 186bf73898..c8a6b1da31 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osu.Framework.Localisation; using osu.Game.Online.API.Requests.Responses; @@ -14,11 +12,11 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalMonthlyPlaycountsCountLabel; - public PlayHistorySubsection(Bindable user) + public PlayHistorySubsection(Bindable user) : base(user, UsersStrings.ShowExtraHistoricalMonthlyPlaycountsTitle) { } - protected override APIUserHistoryCount[] GetValues(APIUser user) => user?.MonthlyPlayCounts; + protected override APIUserHistoryCount[]? GetValues(APIUser? user) => user?.MonthlyPlayCounts; } } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ProfileLineChart.cs b/osu.Game/Overlays/Profile/Sections/Historical/ProfileLineChart.cs index da86d870fc..5711bfc046 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ProfileLineChart.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ProfileLineChart.cs @@ -1,11 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; -using JetBrains.Annotations; using System; using System.Linq; using osu.Game.Graphics.Sprites; @@ -22,9 +19,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { public partial class ProfileLineChart : CompositeDrawable { - private APIUserHistoryCount[] values; + private APIUserHistoryCount[] values = Array.Empty(); - [NotNull] public APIUserHistoryCount[] Values { get => values; diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs index d1d1e76e14..ac7c616a64 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osu.Framework.Localisation; using osu.Game.Online.API.Requests.Responses; @@ -14,11 +12,11 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalReplaysWatchedCountsCountLabel; - public ReplaysSubsection(Bindable user) + public ReplaysSubsection(Bindable user) : base(user, UsersStrings.ShowExtraHistoricalReplaysWatchedCountsTitle) { } - protected override APIUserHistoryCount[] GetValues(APIUser user) => user?.ReplaysWatchedCounts; + protected override APIUserHistoryCount[]? GetValues(APIUser? user) => user?.ReplaysWatchedCounts; } } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/UserHistoryGraph.cs b/osu.Game/Overlays/Profile/Sections/Historical/UserHistoryGraph.cs index 3f68ffdd0e..310607e757 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/UserHistoryGraph.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/UserHistoryGraph.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Localisation; using osu.Game.Online.API.Requests.Responses; @@ -17,8 +14,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { private readonly LocalisableString tooltipCounterName; - [CanBeNull] - public APIUserHistoryCount[] Values + public APIUserHistoryCount[]? Values { set => Data = value?.Select(v => new KeyValuePair(v.Date, v.Count)).ToArray(); } diff --git a/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs b/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs index 13e0aefc65..19f7a32d4d 100644 --- a/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs +++ b/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Online.API.Requests; diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index 122b20cbfc..e7991acb89 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -20,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu private const int height = 25; [Resolved] - private OsuColour colours { get; set; } + private OsuColour colours { get; set; } = null!; private readonly APIKudosuHistory historyItem; private readonly LinkFlowContainer linkFlowContainer; diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs index 2b4d58b845..acf4827dfd 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osuTK; using osu.Framework.Graphics; @@ -22,9 +20,9 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class KudosuInfo : Container { - private readonly Bindable user = new Bindable(); + private readonly Bindable user = new Bindable(); - public KudosuInfo(Bindable user) + public KudosuInfo(Bindable user) { this.user.BindTo(user); CountSection total; diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs index c082c634a7..c5de810f22 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Online.API.Requests; using osu.Framework.Bindables; @@ -16,13 +14,13 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class PaginatedKudosuHistoryContainer : PaginatedProfileSubsection { - public PaginatedKudosuHistoryContainer(Bindable user) + public PaginatedKudosuHistoryContainer(Bindable user) : base(user, missingText: UsersStrings.ShowExtraKudosuEntryEmpty) { } - protected override APIRequest> CreateRequest(PaginationParameters pagination) - => new GetUserKudosuHistoryRequest(User.Value.Id, pagination); + protected override APIRequest> CreateRequest(APIUser user, PaginationParameters pagination) + => new GetUserKudosuHistoryRequest(user.Id, pagination); protected override Drawable CreateDrawableItem(APIKudosuHistory item) => new DrawableKudosuHistoryItem(item); } diff --git a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs b/osu.Game/Overlays/Profile/Sections/KudosuSection.cs index 26cf78c537..482a853c44 100644 --- a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs +++ b/osu.Game/Overlays/Profile/Sections/KudosuSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Overlays.Profile.Sections.Kudosu; using osu.Framework.Localisation; diff --git a/osu.Game/Overlays/Profile/Sections/MedalsSection.cs b/osu.Game/Overlays/Profile/Sections/MedalsSection.cs index a511dc95a0..42f241d662 100644 --- a/osu.Game/Overlays/Profile/Sections/MedalsSection.cs +++ b/osu.Game/Overlays/Profile/Sections/MedalsSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Localisation; using osu.Game.Resources.Localisation.Web; diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs index 530391466a..f32221747c 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using System.Threading; @@ -35,20 +33,20 @@ namespace osu.Game.Overlays.Profile.Sections protected virtual int InitialItemsCount => 5; [Resolved] - private IAPIProvider api { get; set; } + private IAPIProvider api { get; set; } = null!; protected PaginationParameters? CurrentPage { get; private set; } - protected ReverseChildIDFillFlowContainer ItemsContainer { get; private set; } + protected ReverseChildIDFillFlowContainer ItemsContainer { get; private set; } = null!; - private APIRequest> retrievalRequest; - private CancellationTokenSource loadCancellation; + private APIRequest>? retrievalRequest; + private CancellationTokenSource? loadCancellation; - private ShowMoreButton moreButton; - private OsuSpriteText missing; + private ShowMoreButton moreButton = null!; + private OsuSpriteText missing = null!; private readonly LocalisableString? missingText; - protected PaginatedProfileSubsection(Bindable user, LocalisableString? headerText = null, LocalisableString? missingText = null) + protected PaginatedProfileSubsection(Bindable user, LocalisableString? headerText = null, LocalisableString? missingText = null) : base(user, headerText, CounterVisibilityState.AlwaysVisible) { this.missingText = missingText; @@ -94,7 +92,7 @@ namespace osu.Game.Overlays.Profile.Sections User.BindValueChanged(onUserChanged, true); } - private void onUserChanged(ValueChangedEvent e) + private void onUserChanged(ValueChangedEvent e) { loadCancellation?.Cancel(); retrievalRequest?.Cancel(); @@ -111,17 +109,20 @@ namespace osu.Game.Overlays.Profile.Sections private void showMore() { + if (User.Value == null) + return; + loadCancellation = new CancellationTokenSource(); CurrentPage = CurrentPage?.TakeNext(ItemsPerPage) ?? new PaginationParameters(InitialItemsCount); - retrievalRequest = CreateRequest(CurrentPage.Value); - retrievalRequest.Success += UpdateItems; + retrievalRequest = CreateRequest(User.Value, CurrentPage.Value); + retrievalRequest.Success += items => UpdateItems(items, loadCancellation); api.Queue(retrievalRequest); } - protected virtual void UpdateItems(List items) => Schedule(() => + protected virtual void UpdateItems(List items, CancellationTokenSource cancellationTokenSource) => Schedule(() => { OnItemsReceived(items); @@ -136,7 +137,7 @@ namespace osu.Game.Overlays.Profile.Sections return; } - LoadComponentsAsync(items.Select(CreateDrawableItem).Where(d => d != null), drawables => + LoadComponentsAsync(items.Select(CreateDrawableItem).Where(d => d != null).Cast(), drawables => { missing.Hide(); @@ -144,7 +145,7 @@ namespace osu.Game.Overlays.Profile.Sections moreButton.IsLoading = false; ItemsContainer.AddRange(drawables); - }, loadCancellation.Token); + }, cancellationTokenSource.Token); }); protected virtual int GetCount(APIUser user) => 0; @@ -153,9 +154,9 @@ namespace osu.Game.Overlays.Profile.Sections { } - protected abstract APIRequest> CreateRequest(PaginationParameters pagination); + protected abstract APIRequest> CreateRequest(APIUser user, PaginationParameters pagination); - protected abstract Drawable CreateDrawableItem(TModel model); + protected abstract Drawable? CreateDrawableItem(TModel model); protected override void Dispose(bool isDisposing) { diff --git a/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs index c81a08fa20..b30faee380 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs index 9d88645c9a..0a0e1a9298 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs @@ -1,13 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using JetBrains.Annotations; using osu.Framework.Localisation; using osu.Game.Online.API.Requests.Responses; @@ -15,14 +12,14 @@ namespace osu.Game.Overlays.Profile.Sections { public abstract partial class ProfileSubsection : FillFlowContainer { - protected readonly Bindable User = new Bindable(); + protected readonly Bindable User = new Bindable(); private readonly LocalisableString headerText; private readonly CounterVisibilityState counterVisibilityState; - private ProfileSubsectionHeader header; + private ProfileSubsectionHeader header = null!; - protected ProfileSubsection(Bindable user, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) + protected ProfileSubsection(Bindable user, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) { this.headerText = headerText ?? string.Empty; this.counterVisibilityState = counterVisibilityState; @@ -46,7 +43,6 @@ namespace osu.Game.Overlays.Profile.Sections }; } - [NotNull] protected abstract Drawable CreateContent(); protected void SetCount(int value) => header.Current.Value = value; diff --git a/osu.Game/Overlays/Profile/Sections/ProfileSubsectionHeader.cs b/osu.Game/Overlays/Profile/Sections/ProfileSubsectionHeader.cs index 598ac19059..fa21535d02 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileSubsectionHeader.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileSubsectionHeader.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; @@ -30,7 +28,7 @@ namespace osu.Game.Overlays.Profile.Sections private readonly LocalisableString text; private readonly CounterVisibilityState counterState; - private CounterPill counterPill; + private CounterPill counterPill = null!; public ProfileSubsectionHeader(LocalisableString text, CounterVisibilityState counterState) { diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 67df4825cc..0f3e0bc6b2 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -1,12 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -34,10 +32,10 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks protected readonly SoloScoreInfo Score; [Resolved] - private OsuColour colours { get; set; } + private OsuColour colours { get; set; } = null!; [Resolved] - private OverlayColourProvider colourProvider { get; set; } + private OverlayColourProvider colourProvider { get; set; } = null!; public DrawableProfileScore(SoloScoreInfo score) { @@ -84,7 +82,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Spacing = new Vector2(0, 2), Children = new Drawable[] { - new ScoreBeatmapMetadataContainer(Score.Beatmap), + new ScoreBeatmapMetadataContainer(Score.Beatmap.AsNonNull()), new FillFlowContainer { AutoSizeAxes = Axes.Both, @@ -94,7 +92,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { new OsuSpriteText { - Text = $"{Score.Beatmap?.DifficultyName}", + Text = $"{Score.Beatmap.AsNonNull().DifficultyName}", Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular), Colour = colours.Yellow }, @@ -199,7 +197,6 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks }); } - [NotNull] protected virtual Drawable CreateRightContent() => CreateDrawableAccuracy(); protected Drawable CreateDrawableAccuracy() => new Container diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs index f04d7d9733..6cfe34ec6f 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index 38fac075fb..3ef0275f50 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics.Containers; using osu.Game.Online.API.Requests; using System; @@ -21,7 +19,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { private readonly ScoreType type; - public PaginatedScoreContainer(ScoreType type, Bindable user, LocalisableString headerText) + public PaginatedScoreContainer(ScoreType type, Bindable user, LocalisableString headerText) : base(user, headerText) { this.type = type; @@ -62,8 +60,8 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks base.OnItemsReceived(items); } - protected override APIRequest> CreateRequest(PaginationParameters pagination) => - new GetUserScoresRequest(User.Value.Id, type, pagination); + protected override APIRequest> CreateRequest(APIUser user, PaginationParameters pagination) => + new GetUserScoresRequest(user.Id, type, pagination); private int drawableItemIndex; diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index ca41bff2f9..ce831b30a8 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Online.API.Requests; using osu.Framework.Localisation; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index c3fa467e5f..0479ab7c16 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -1,10 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; @@ -24,14 +23,14 @@ namespace osu.Game.Overlays.Profile.Sections.Recent private const int font_size = 14; [Resolved] - private IAPIProvider api { get; set; } + private IAPIProvider api { get; set; } = null!; [Resolved] - private IRulesetStore rulesets { get; set; } + private IRulesetStore rulesets { get; set; } = null!; private readonly APIRecentActivity activity; - private LinkFlowContainer content; + private LinkFlowContainer content = null!; public DrawableRecentActivity(APIRecentActivity activity) { @@ -216,15 +215,15 @@ namespace osu.Game.Overlays.Profile.Sections.Recent rulesets.AvailableRulesets.FirstOrDefault(r => r.ShortName == activity.Mode)?.Name ?? activity.Mode; private void addUserLink() - => content.AddLink(activity.User?.Username, LinkAction.OpenUserProfile, getLinkArgument(activity.User?.Url), creationParameters: t => t.Font = getLinkFont(FontWeight.Bold)); + => content.AddLink(activity.User.AsNonNull().Username, LinkAction.OpenUserProfile, getLinkArgument(activity.User.AsNonNull().Url), creationParameters: t => t.Font = getLinkFont(FontWeight.Bold)); private void addBeatmapLink() - => content.AddLink(activity.Beatmap?.Title, LinkAction.OpenBeatmap, getLinkArgument(activity.Beatmap?.Url), creationParameters: t => t.Font = getLinkFont()); + => content.AddLink(activity.Beatmap.AsNonNull().Title, LinkAction.OpenBeatmap, getLinkArgument(activity.Beatmap.AsNonNull().Url), creationParameters: t => t.Font = getLinkFont()); private void addBeatmapsetLink() - => content.AddLink(activity.Beatmapset?.Title, LinkAction.OpenBeatmapSet, getLinkArgument(activity.Beatmapset?.Url), creationParameters: t => t.Font = getLinkFont()); + => content.AddLink(activity.Beatmapset.AsNonNull().Title, LinkAction.OpenBeatmapSet, getLinkArgument(activity.Beatmapset.AsNonNull().Url), creationParameters: t => t.Font = getLinkFont()); - private string getLinkArgument(string url) => MessageFormatter.GetLinkDetails($"{api.WebsiteRootUrl}{url}").Argument.ToString(); + private string getLinkArgument(string url) => MessageFormatter.GetLinkDetails($"{api.WebsiteRootUrl}{url}").Argument.ToString().AsNonNull(); private FontUsage getLinkFont(FontWeight fontWeight = FontWeight.Regular) => OsuFont.GetFont(size: font_size, weight: fontWeight, italics: true); diff --git a/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs b/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs index 5eeed24469..6cb439ab33 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index b07dfc154f..4e5b11d79f 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Online.API.Requests; using osu.Framework.Bindables; @@ -18,7 +16,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { public partial class PaginatedRecentActivityContainer : PaginatedProfileSubsection { - public PaginatedRecentActivityContainer(Bindable user) + public PaginatedRecentActivityContainer(Bindable user) : base(user, missingText: EventsStrings.Empty) { } @@ -29,8 +27,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent ItemsContainer.Spacing = new Vector2(0, 8); } - protected override APIRequest> CreateRequest(PaginationParameters pagination) => - new GetUserRecentActivitiesRequest(User.Value.Id, pagination); + protected override APIRequest> CreateRequest(APIUser user, PaginationParameters pagination) => + new GetUserRecentActivitiesRequest(user.Id, pagination); protected override Drawable CreateDrawableItem(APIRecentActivity model) => new DrawableRecentActivity(model); } diff --git a/osu.Game/Overlays/Profile/Sections/RecentSection.cs b/osu.Game/Overlays/Profile/Sections/RecentSection.cs index f2ebf81504..e29dc7f635 100644 --- a/osu.Game/Overlays/Profile/Sections/RecentSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RecentSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Localisation; using osu.Game.Overlays.Profile.Sections.Recent; using osu.Game.Resources.Localisation.Web; diff --git a/osu.Game/Overlays/Profile/UserGraph.cs b/osu.Game/Overlays/Profile/UserGraph.cs index fa9cbe0449..63cdbea5a4 100644 --- a/osu.Game/Overlays/Profile/UserGraph.cs +++ b/osu.Game/Overlays/Profile/UserGraph.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -26,12 +23,12 @@ namespace osu.Game.Overlays.Profile /// /// Type of data to be used for X-axis of the graph. /// Type of data to be used for Y-axis of the graph. - public abstract partial class UserGraph : Container, IHasCustomTooltip + public abstract partial class UserGraph : Container, IHasCustomTooltip { protected const float FADE_DURATION = 150; private readonly UserLineGraph graph; - private KeyValuePair[] data; + private KeyValuePair[]? data; private int hoveredIndex = -1; protected UserGraph() @@ -83,8 +80,7 @@ namespace osu.Game.Overlays.Profile /// /// Set of values which will be used to create a graph. /// - [CanBeNull] - protected KeyValuePair[] Data + protected KeyValuePair[]? Data { set { @@ -120,9 +116,9 @@ namespace osu.Game.Overlays.Profile protected virtual void ShowGraph() => graph.FadeIn(FADE_DURATION, Easing.Out); protected virtual void HideGraph() => graph.FadeOut(FADE_DURATION, Easing.Out); - public ITooltip GetCustomTooltip() => new UserGraphTooltip(); + public ITooltip GetCustomTooltip() => new UserGraphTooltip(); - public UserGraphTooltipContent TooltipContent + public UserGraphTooltipContent? TooltipContent { get { @@ -143,7 +139,7 @@ namespace osu.Game.Overlays.Profile private readonly Box ballBg; private readonly Box line; - public Action OnBallMove; + public Action? OnBallMove; public UserLineGraph() { @@ -191,7 +187,7 @@ namespace osu.Game.Overlays.Profile Vector2 position = calculateBallPosition(index); movingBall.MoveToY(position.Y, duration, Easing.OutQuint); bar.MoveToX(position.X, duration, Easing.OutQuint); - OnBallMove.Invoke(index); + OnBallMove?.Invoke(index); } public void ShowBar() => bar.FadeIn(FADE_DURATION); @@ -207,7 +203,7 @@ namespace osu.Game.Overlays.Profile } } - private partial class UserGraphTooltip : VisibilityContainer, ITooltip + private partial class UserGraphTooltip : VisibilityContainer, ITooltip { protected readonly OsuSpriteText Label, Counter, BottomText; private readonly Box background; @@ -267,8 +263,11 @@ namespace osu.Game.Overlays.Profile background.Colour = colours.Gray1; } - public void SetContent(UserGraphTooltipContent content) + public void SetContent(UserGraphTooltipContent? content) { + if (content == null) + return; + Label.Text = content.Name; Counter.Text = content.Count; BottomText.Text = content.Time; diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 386f95cf0a..1a7c4173ab 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -1,9 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; +using System.Diagnostics; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -24,11 +23,11 @@ namespace osu.Game.Overlays { public partial class UserProfileOverlay : FullscreenOverlay { - private ProfileSection lastSection; - private ProfileSection[] sections; - private GetUserRequest userReq; - private ProfileSectionsContainer sectionsContainer; - private ProfileSectionTabControl tabs; + private ProfileSection? lastSection; + private ProfileSection[]? sections; + private GetUserRequest? userReq; + private ProfileSectionsContainer? sectionsContainer; + private ProfileSectionTabControl? tabs; public const float CONTENT_X_MARGIN = 70; @@ -133,6 +132,8 @@ namespace osu.Game.Overlays private void userLoadComplete(APIUser user) { + Debug.Assert(sections != null && sectionsContainer != null && tabs != null); + Header.User.Value = user; if (user.ProfileOrder != null) diff --git a/osu.Game/Users/UserCoverBackground.cs b/osu.Game/Users/UserCoverBackground.cs index 69a5fba876..de6a306b2a 100644 --- a/osu.Game/Users/UserCoverBackground.cs +++ b/osu.Game/Users/UserCoverBackground.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; @@ -17,15 +15,15 @@ using osuTK.Graphics; namespace osu.Game.Users { - public partial class UserCoverBackground : ModelBackedDrawable + public partial class UserCoverBackground : ModelBackedDrawable { - public APIUser User + public APIUser? User { get => Model; set => Model = value; } - protected override Drawable CreateDrawable(APIUser user) => new Cover(user); + protected override Drawable CreateDrawable(APIUser? user) => new Cover(user); protected override double LoadDelay => 300; @@ -40,9 +38,9 @@ namespace osu.Game.Users [LongRunningLoad] private partial class Cover : CompositeDrawable { - private readonly APIUser user; + private readonly APIUser? user; - public Cover(APIUser user) + public Cover(APIUser? user) { this.user = user; From 73f14bd14fb76791d44365d33d782d519a897177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 15:05:04 +0100 Subject: [PATCH 1270/2991] Enable NRT in user profile overlay test scenes --- osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs | 2 -- osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs | 2 -- .../Visual/Online/TestSceneProfileRulesetSelector.cs | 4 +--- osu.Game.Tests/Visual/Online/TestSceneUserHistoryGraph.cs | 2 -- osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs | 4 +--- osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs | 2 -- .../Visual/Online/TestSceneUserProfilePreviousUsernames.cs | 6 ++---- .../Visual/Online/TestSceneUserProfileRecentSection.cs | 2 -- osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs | 2 -- osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs | 2 -- .../UserInterface/TestSceneProfileSubsectionHeader.cs | 4 +--- 11 files changed, 5 insertions(+), 27 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs index d884c0cf14..28f0e6ff9c 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; diff --git a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs index e753632474..84497245db 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Overlays.Profile.Sections.Kudosu; using System.Collections.Generic; using System; diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs index e81b7a2ac8..a4d8238fa3 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Rulesets.Catch; @@ -24,7 +22,7 @@ namespace osu.Game.Tests.Visual.Online public TestSceneProfileRulesetSelector() { ProfileRulesetSelector selector; - var user = new Bindable(); + var user = new Bindable(); Child = selector = new ProfileRulesetSelector { diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserHistoryGraph.cs b/osu.Game.Tests/Visual/Online/TestSceneUserHistoryGraph.cs index d93bf059dd..454242270d 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserHistoryGraph.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserHistoryGraph.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Graphics; diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index 75743d788a..bfd6372e6f 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using NUnit.Framework; @@ -20,7 +18,7 @@ namespace osu.Game.Tests.Visual.Online [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); - private ProfileHeader header; + private ProfileHeader header = null!; [SetUpSteps] public void SetUpSteps() diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs index 02d01b4a46..35c7e7bf28 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using NUnit.Framework; diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.cs index fcefb31716..921738d331 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using NUnit.Framework; using osu.Framework.Graphics; @@ -14,7 +12,7 @@ namespace osu.Game.Tests.Visual.Online [TestFixture] public partial class TestSceneUserProfilePreviousUsernames : OsuTestScene { - private PreviousUsernames container; + private PreviousUsernames container = null!; [SetUp] public void SetUp() => Schedule(() => @@ -50,7 +48,7 @@ namespace osu.Game.Tests.Visual.Online AddUntilStep("Is hidden", () => container.Alpha == 0); } - private static readonly APIUser[] users = + private static readonly APIUser?[] users = { new APIUser { Id = 1, PreviousUsernames = new[] { "username1" } }, new APIUser { Id = 2, PreviousUsernames = new[] { "longusername", "longerusername" } }, diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs index f8432118d4..9d0ea80533 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using NUnit.Framework; diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs index 6f0ef10911..5249e8694d 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Graphics; diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs index ef3a677efc..fdbd8a4325 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneProfileSubsectionHeader.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneProfileSubsectionHeader.cs index b4b45da133..c51095f360 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneProfileSubsectionHeader.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneProfileSubsectionHeader.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using NUnit.Framework; using osu.Game.Overlays.Profile.Sections; using osu.Framework.Testing; @@ -18,7 +16,7 @@ namespace osu.Game.Tests.Visual.UserInterface [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink); - private ProfileSubsectionHeader header; + private ProfileSubsectionHeader header = null!; [Test] public void TestHiddenCounter() From 83b8d8ad8cb8cb00cf58ba148fb427b0bde86e94 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 1 Jan 2023 16:48:47 -0800 Subject: [PATCH 1271/2991] Add failing replay player mouse middle pause test --- .../Visual/Gameplay/TestSceneReplayPlayer.cs | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs index e0a6a60ff2..601fe445f0 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs @@ -4,6 +4,7 @@ #nullable disable using NUnit.Framework; +using osu.Framework.Screens; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; using osuTK.Input; @@ -23,14 +24,29 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("player loaded", () => Player.IsLoaded); } - [Test] - public void TestPause() + [TestCase("space")] + [TestCase("mouse middle")] + public void TestPause(string action) { double? lastTime = null; AddUntilStep("wait for first hit", () => Player.ScoreProcessor.TotalScore.Value > 0); - AddStep("Pause playback", () => InputManager.Key(Key.Space)); + AddStep("Pause playback", () => + { + switch (action) + { + case "space": + InputManager.Key(Key.Space); + break; + + case "mouse middle": + InputManager.Click(MouseButton.Middle); + break; + } + }); + + AddAssert("player not exited", () => Player.IsCurrentScreen()); AddUntilStep("Time stopped progressing", () => { From d79ee29f29c64a1922bf32c2f1de34be6b5e8e68 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 1 Jan 2023 18:00:39 -0800 Subject: [PATCH 1272/2991] Make replays pause with middle mouse button instead of exiting --- .../Screens/Play/HUD/HoldForMenuButton.cs | 19 ++++++++++++++++++- osu.Game/Screens/Play/Player.cs | 3 ++- osu.Game/Screens/Play/ReplayPlayer.cs | 1 + 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs b/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs index f902e0903d..0921a9f18a 100644 --- a/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs +++ b/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs @@ -31,6 +31,8 @@ namespace osu.Game.Screens.Play.HUD public readonly Bindable IsPaused = new Bindable(); + public readonly Bindable ReplayLoaded = new Bindable(); + private HoldButton button; public Action Action { get; set; } @@ -60,6 +62,7 @@ namespace osu.Game.Screens.Play.HUD HoverGained = () => text.FadeIn(500, Easing.OutQuint), HoverLost = () => text.FadeOut(500, Easing.OutQuint), IsPaused = { BindTarget = IsPaused }, + ReplayLoaded = { BindTarget = ReplayLoaded }, Action = () => Action(), } }; @@ -110,6 +113,8 @@ namespace osu.Game.Screens.Play.HUD public readonly Bindable IsPaused = new Bindable(); + public readonly Bindable ReplayLoaded = new Bindable(); + protected override bool AllowMultipleFires => true; public Action HoverGained; @@ -251,7 +256,14 @@ namespace osu.Game.Screens.Play.HUD switch (e.Action) { case GlobalAction.Back: - case GlobalAction.PauseGameplay: // in the future this behaviour will differ for replays etc. + if (!pendingAnimation) + BeginConfirm(); + return true; + + case GlobalAction.PauseGameplay: + // handled by replay player + if (ReplayLoaded.Value) return false; + if (!pendingAnimation) BeginConfirm(); return true; @@ -265,7 +277,12 @@ namespace osu.Game.Screens.Play.HUD switch (e.Action) { case GlobalAction.Back: + AbortConfirm(); + break; + case GlobalAction.PauseGameplay: + if (ReplayLoaded.Value) return; + AbortConfirm(); break; } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 05133fba35..7fe81987c8 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -433,7 +433,8 @@ namespace osu.Game.Screens.Play HoldToQuit = { Action = () => PerformExit(true), - IsPaused = { BindTarget = GameplayClockContainer.IsPaused } + IsPaused = { BindTarget = GameplayClockContainer.IsPaused }, + ReplayLoaded = { BindTarget = DrawableRuleset.HasReplayLoaded }, }, KeyCounter = { diff --git a/osu.Game/Screens/Play/ReplayPlayer.cs b/osu.Game/Screens/Play/ReplayPlayer.cs index c5ef6b1585..77ee7bc113 100644 --- a/osu.Game/Screens/Play/ReplayPlayer.cs +++ b/osu.Game/Screens/Play/ReplayPlayer.cs @@ -81,6 +81,7 @@ namespace osu.Game.Screens.Play return true; case GlobalAction.TogglePauseReplay: + case GlobalAction.PauseGameplay: if (GameplayClockContainer.IsPaused.Value) GameplayClockContainer.Start(); else From 608d8ee7d40bc52370bd116401b23741715d505e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 12:13:44 +0100 Subject: [PATCH 1273/2991] Add `UserProfile` model to be used in user profile overlay As `APIUser` implements `IEquatable`, attempting to replace an `APIUser` with another `APIUser` with the same online ID has no effect on the user profile overlay. This is a significant hurdle in implementing support for viewing the profile for different rulesets, as in that case the profile is basically reloaded for the same user, but slightly different data. To facilitate this, wrap `APIUser` in a new `UserProfile` class. This will mean that the equality rules can be changed locally to the user profile overlay without impacting other components that depend on the `APIUser` equality rules. The ruleset that the user profile is being displayed with will eventually be added to `UserProfile`, too. --- osu.Game/Overlays/Profile/UserProfile.cs | 25 ++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 osu.Game/Overlays/Profile/UserProfile.cs diff --git a/osu.Game/Overlays/Profile/UserProfile.cs b/osu.Game/Overlays/Profile/UserProfile.cs new file mode 100644 index 0000000000..12a469ddf9 --- /dev/null +++ b/osu.Game/Overlays/Profile/UserProfile.cs @@ -0,0 +1,25 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Overlays.Profile +{ + /// + /// Contains data about a profile presented on the . + /// + public class UserProfile + { + /// + /// The user whose profile is being presented. + /// + public APIUser User { get; } + + // TODO: add ruleset + + public UserProfile(APIUser user) + { + User = user; + } + } +} From d7294ac3e63e101831af267c45098e75202d6f06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 14:56:19 +0100 Subject: [PATCH 1274/2991] Substitute `APIUser` for `UserProfile` in overlay --- .../Online/TestSceneHistoricalSection.cs | 5 +++-- .../Online/TestScenePlayHistorySubsection.cs | 21 +++++++++---------- .../Online/TestSceneUserProfileHeader.cs | 18 ++++++++-------- .../Visual/Online/TestSceneUserRanks.cs | 3 ++- .../Profile/Header/BottomHeaderContainer.cs | 4 ++-- .../Profile/Header/CentreHeaderContainer.cs | 14 ++++++------- .../Header/Components/FollowersButton.cs | 5 ++--- .../Profile/Header/Components/LevelBadge.cs | 4 ++-- .../Header/Components/LevelProgressBar.cs | 4 ++-- .../Components/MappingSubscribersButton.cs | 5 ++--- .../Header/Components/MessageUserButton.cs | 11 ++++++---- .../Components/OverlinedTotalPlayTime.cs | 12 +++++------ .../Profile/Header/DetailHeaderContainer.cs | 11 +++++----- .../Profile/Header/MedalHeaderContainer.cs | 4 ++-- .../Profile/Header/TopHeaderContainer.cs | 9 ++++---- osu.Game/Overlays/Profile/ProfileHeader.cs | 17 +++++++-------- osu.Game/Overlays/Profile/ProfileSection.cs | 3 +-- .../Beatmaps/PaginatedBeatmapContainer.cs | 2 +- .../Profile/Sections/BeatmapsSection.cs | 14 ++++++------- .../Historical/ChartProfileSubsection.cs | 10 ++++----- .../PaginatedMostPlayedBeatmapContainer.cs | 4 ++-- .../Historical/PlayHistorySubsection.cs | 4 ++-- .../Sections/Historical/ReplaysSubsection.cs | 4 ++-- .../Profile/Sections/HistoricalSection.cs | 8 +++---- .../Profile/Sections/Kudosu/KudosuInfo.cs | 9 ++++---- .../Kudosu/PaginatedKudosuHistoryContainer.cs | 4 ++-- .../Profile/Sections/KudosuSection.cs | 4 ++-- .../Sections/PaginatedProfileSubsection.cs | 16 +++++++------- .../Profile/Sections/ProfileSubsection.cs | 7 +++---- .../Sections/Ranks/PaginatedScoreContainer.cs | 4 ++-- .../Overlays/Profile/Sections/RanksSection.cs | 6 +++--- .../PaginatedRecentActivityContainer.cs | 4 ++-- .../Profile/Sections/RecentSection.cs | 2 +- osu.Game/Overlays/UserProfileOverlay.cs | 7 ++++--- 34 files changed, 130 insertions(+), 129 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs index 28f0e6ff9c..92bb41b7d5 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs @@ -9,6 +9,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; +using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile.Sections; namespace osu.Game.Tests.Visual.Online @@ -37,8 +38,8 @@ namespace osu.Game.Tests.Visual.Online Child = section = new HistoricalSection(), }); - AddStep("Show peppy", () => section.User.Value = new APIUser { Id = 2 }); - AddStep("Show WubWoofWolf", () => section.User.Value = new APIUser { Id = 39828 }); + AddStep("Show peppy", () => section.UserProfile.Value = new UserProfile(new APIUser { Id = 2 })); + AddStep("Show WubWoofWolf", () => section.UserProfile.Value = new UserProfile(new APIUser { Id = 39828 })); } } } diff --git a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs index 15e411b9d8..a486d77f97 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Overlays.Profile.Sections.Historical; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -14,6 +12,7 @@ using System.Linq; using osu.Framework.Testing; using osu.Framework.Graphics.Shapes; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays.Profile; namespace osu.Game.Tests.Visual.Online { @@ -22,7 +21,7 @@ namespace osu.Game.Tests.Visual.Online [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Red); - private readonly Bindable user = new Bindable(); + private readonly Bindable user = new Bindable(); private readonly PlayHistorySubsection section; public TestScenePlayHistorySubsection() @@ -45,49 +44,49 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestNullValues() { - AddStep("Load user", () => user.Value = user_with_null_values); + AddStep("Load user", () => user.Value = new UserProfile(user_with_null_values)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestEmptyValues() { - AddStep("Load user", () => user.Value = user_with_empty_values); + AddStep("Load user", () => user.Value = new UserProfile(user_with_empty_values)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestOneValue() { - AddStep("Load user", () => user.Value = user_with_one_value); + AddStep("Load user", () => user.Value = new UserProfile(user_with_one_value)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestTwoValues() { - AddStep("Load user", () => user.Value = user_with_two_values); + AddStep("Load user", () => user.Value = new UserProfile(user_with_two_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantValues() { - AddStep("Load user", () => user.Value = user_with_constant_values); + AddStep("Load user", () => user.Value = new UserProfile(user_with_constant_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantZeroValues() { - AddStep("Load user", () => user.Value = user_with_zero_values); + AddStep("Load user", () => user.Value = new UserProfile(user_with_zero_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestFilledValues() { - AddStep("Load user", () => user.Value = user_with_filled_values); + AddStep("Load user", () => user.Value = new UserProfile(user_with_filled_values)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is the same", () => user_with_filled_values.MonthlyPlayCounts.Length == getChartValuesLength()); } @@ -95,7 +94,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestMissingValues() { - AddStep("Load user", () => user.Value = user_with_missing_values); + AddStep("Load user", () => user.Value = new UserProfile(user_with_missing_values)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is 7", () => getChartValuesLength() == 7); } diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index bfd6372e6f..4caab98f63 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -29,33 +29,33 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestBasic() { - AddStep("Show example user", () => header.User.Value = TestSceneUserProfileOverlay.TEST_USER); + AddStep("Show example user", () => header.UserProfile.Value = new UserProfile(TestSceneUserProfileOverlay.TEST_USER)); } [Test] public void TestOnlineState() { - AddStep("Show online user", () => header.User.Value = new APIUser + AddStep("Show online user", () => header.UserProfile.Value = new UserProfile(new APIUser { Id = 1001, Username = "IAmOnline", LastVisit = DateTimeOffset.Now, IsOnline = true, - }); + })); - AddStep("Show offline user", () => header.User.Value = new APIUser + AddStep("Show offline user", () => header.UserProfile.Value = new UserProfile(new APIUser { Id = 1002, Username = "IAmOffline", LastVisit = DateTimeOffset.Now.AddDays(-10), IsOnline = false, - }); + })); } [Test] public void TestRankedState() { - AddStep("Show ranked user", () => header.User.Value = new APIUser + AddStep("Show ranked user", () => header.UserProfile.Value = new UserProfile(new APIUser { Id = 2001, Username = "RankedUser", @@ -70,9 +70,9 @@ namespace osu.Game.Tests.Visual.Online Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray() }, } - }); + })); - AddStep("Show unranked user", () => header.User.Value = new APIUser + AddStep("Show unranked user", () => header.UserProfile.Value = new UserProfile(new APIUser { Id = 2002, Username = "UnrankedUser", @@ -86,7 +86,7 @@ namespace osu.Game.Tests.Visual.Online Data = Enumerable.Range(2345, 85).ToArray() }, } - }); + })); } } } diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs index fdbd8a4325..184b969279 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs @@ -10,6 +10,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; +using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile.Sections; namespace osu.Game.Tests.Visual.Online @@ -44,7 +45,7 @@ namespace osu.Game.Tests.Visual.Online } }); - AddStep("Show cookiezi", () => ranks.User.Value = new APIUser { Id = 124493 }); + AddStep("Show cookiezi", () => ranks.UserProfile.Value = new UserProfile(new APIUser { Id = 124493 })); } } } diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index f5c7a3f87a..64a333dff7 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.Profile.Header { public partial class BottomHeaderContainer : CompositeDrawable { - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); private LinkFlowContainer topLinkContainer = null!; private LinkFlowContainer bottomLinkContainer = null!; @@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Profile.Header } }; - User.BindValueChanged(user => updateDisplay(user.NewValue)); + UserProfile.BindValueChanged(user => updateDisplay(user.NewValue?.User)); } private void updateDisplay(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 5e4e1184a4..701c4a1464 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Header public partial class CentreHeaderContainer : CompositeDrawable { public readonly BindableBool DetailsVisible = new BindableBool(true); - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); private OverlinedInfoContainer hiddenDetailGlobal = null!; private OverlinedInfoContainer hiddenDetailCountry = null!; @@ -53,15 +53,15 @@ namespace osu.Game.Overlays.Profile.Header { new FollowersButton { - User = { BindTarget = User } + UserProfile = { BindTarget = UserProfile } }, new MappingSubscribersButton { - User = { BindTarget = User } + UserProfile = { BindTarget = UserProfile } }, new MessageUserButton { - User = { BindTarget = User } + UserProfile = { BindTarget = UserProfile } }, } }, @@ -92,7 +92,7 @@ namespace osu.Game.Overlays.Profile.Header Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Size = new Vector2(40), - User = { BindTarget = User } + UserProfile = { BindTarget = UserProfile } }, expandedDetailContainer = new Container { @@ -104,7 +104,7 @@ namespace osu.Game.Overlays.Profile.Header Child = new LevelProgressBar { RelativeSizeAxes = Axes.Both, - User = { BindTarget = User } + UserProfile = { BindTarget = UserProfile } } }, hiddenDetailContainer = new FillFlowContainer @@ -141,7 +141,7 @@ namespace osu.Game.Overlays.Profile.Header expandedDetailContainer.FadeTo(visible.NewValue ? 1 : 0, 200, Easing.OutQuint); }); - User.BindValueChanged(user => updateDisplay(user.NewValue)); + UserProfile.BindValueChanged(userProfile => updateDisplay(userProfile.NewValue?.User)); } private void updateDisplay(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs index c0bcec622a..48e9718a7c 100644 --- a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs @@ -5,14 +5,13 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Header.Components { public partial class FollowersButton : ProfileHeaderStatisticsButton { - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public override LocalisableString TooltipText => FriendsStrings.ButtonsDisabled; @@ -22,7 +21,7 @@ namespace osu.Game.Overlays.Profile.Header.Components private void load() { // todo: when friending/unfriending is implemented, the APIAccess.Friends list should be updated accordingly. - User.BindValueChanged(user => SetValue(user.NewValue?.FollowerCount ?? 0), true); + UserProfile.BindValueChanged(user => SetValue(user.NewValue?.User.FollowerCount ?? 0), true); } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index 8f84e69bac..f68c9838a0 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelBadge : CompositeDrawable, IHasTooltip { - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public LocalisableString TooltipText { get; private set; } @@ -48,7 +48,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; - User.BindValueChanged(user => updateLevel(user.NewValue)); + UserProfile.BindValueChanged(user => updateLevel(user.NewValue?.User)); } private void updateLevel(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs index ea5ca0c8bd..e3100c5af5 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelProgressBar : CompositeDrawable, IHasTooltip { - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public LocalisableString TooltipText { get; } @@ -56,7 +56,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; - User.BindValueChanged(user => updateProgress(user.NewValue)); + UserProfile.BindValueChanged(user => updateProgress(user.NewValue?.User)); } private void updateProgress(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs index c600f7622a..29b42cb223 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs @@ -5,14 +5,13 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Header.Components { public partial class MappingSubscribersButton : ProfileHeaderStatisticsButton { - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public override LocalisableString TooltipText => FollowsStrings.MappingFollowers; @@ -21,7 +20,7 @@ namespace osu.Game.Overlays.Profile.Header.Components [BackgroundDependencyLoader] private void load() { - User.BindValueChanged(user => SetValue(user.NewValue?.MappingFollowerCount ?? 0), true); + UserProfile.BindValueChanged(user => SetValue(user.NewValue?.User.MappingFollowerCount ?? 0), true); } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs index 3266e3c308..f57b43c3a4 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Game.Online.API; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; using osu.Game.Resources.Localisation.Web; using osuTK; @@ -16,7 +15,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class MessageUserButton : ProfileHeaderButton { - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public override LocalisableString TooltipText => UsersStrings.CardSendMessage; @@ -49,12 +48,16 @@ namespace osu.Game.Overlays.Profile.Header.Components { if (!Content.IsPresent) return; - channelManager?.OpenPrivateChannel(User.Value); + channelManager?.OpenPrivateChannel(UserProfile.Value?.User); userOverlay?.Hide(); chatOverlay?.Show(); }; - User.ValueChanged += e => Content.Alpha = e.NewValue != null && !e.NewValue.PMFriendsOnly && apiProvider.LocalUser.Value.Id != e.NewValue.Id ? 1 : 0; + UserProfile.ValueChanged += e => + { + var user = e.NewValue?.User; + Content.Alpha = user != null && !user.PMFriendsOnly && apiProvider.LocalUser.Value.Id != user.Id ? 1 : 0; + }; } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs index e9e277acd3..1de13ba7c7 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs @@ -7,14 +7,13 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Localisation; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Header.Components { public partial class OverlinedTotalPlayTime : CompositeDrawable, IHasTooltip { - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public LocalisableString TooltipText { get; set; } @@ -36,13 +35,14 @@ namespace osu.Game.Overlays.Profile.Header.Components LineColour = colourProvider.Highlight1, }; - User.BindValueChanged(updateTime, true); + UserProfile.BindValueChanged(updateTime, true); } - private void updateTime(ValueChangedEvent user) + private void updateTime(ValueChangedEvent userProfile) { - TooltipText = (user.NewValue?.Statistics?.PlayTime ?? 0) / 3600 + " hours"; - info.Content = formatTime(user.NewValue?.Statistics?.PlayTime); + int? playTime = userProfile.NewValue?.User.Statistics?.PlayTime; + TooltipText = (playTime ?? 0) / 3600 + " hours"; + info.Content = formatTime(playTime); } private string formatTime(int? secondsNull) diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 95fead1246..8b9a90c9a3 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Leaderboards; using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Resources.Localisation.Web; @@ -30,7 +29,7 @@ namespace osu.Game.Overlays.Profile.Header private FillFlowContainer? fillFlow; private RankGraph rankGraph = null!; - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); private bool expanded = true; @@ -61,7 +60,7 @@ namespace osu.Game.Overlays.Profile.Header { AutoSizeAxes = Axes.Y; - User.ValueChanged += e => updateDisplay(e.NewValue); + UserProfile.ValueChanged += e => updateDisplay(e.NewValue); InternalChildren = new Drawable[] { @@ -99,7 +98,7 @@ namespace osu.Game.Overlays.Profile.Header { new OverlinedTotalPlayTime { - User = { BindTarget = User } + UserProfile = { BindTarget = UserProfile } }, medalInfo = new OverlinedInfoContainer { @@ -171,8 +170,10 @@ namespace osu.Game.Overlays.Profile.Header }; } - private void updateDisplay(APIUser? user) + private void updateDisplay(UserProfile? userProfile) { + var user = userProfile?.User; + medalInfo.Content = user?.Achievements?.Length.ToString() ?? "0"; ppInfo.Content = user?.Statistics?.PP?.ToLocalisableString("#,##0") ?? (LocalisableString)"0"; diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index 79f9eba57d..b41c60ed4e 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -20,14 +20,14 @@ namespace osu.Game.Overlays.Profile.Header { private FillFlowContainer badgeFlowContainer = null!; - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { Alpha = 0; AutoSizeAxes = Axes.Y; - User.ValueChanged += e => updateDisplay(e.NewValue); + UserProfile.ValueChanged += e => updateDisplay(e.NewValue?.User); InternalChildren = new Drawable[] { diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index a6501f567f..69258c914f 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -15,7 +15,6 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Cursor; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Resources.Localisation.Web; using osu.Game.Users.Drawables; @@ -27,7 +26,7 @@ namespace osu.Game.Overlays.Profile.Header { private const float avatar_size = 110; - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); [Resolved] private IAPIProvider api { get; set; } = null!; @@ -171,11 +170,13 @@ namespace osu.Game.Overlays.Profile.Header } }; - User.BindValueChanged(user => updateUser(user.NewValue)); + UserProfile.BindValueChanged(user => updateUser(user.NewValue)); } - private void updateUser(APIUser? user) + private void updateUser(UserProfile? userProfile) { + var user = userProfile?.User; + avatar.User = user; usernameText.Text = user?.Username ?? string.Empty; openUserExternally.Link = $@"{api.WebsiteRootUrl}/users/{user?.Id ?? 0}"; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 2b8d2503e0..447e9148e8 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile.Header; using osu.Game.Resources.Localisation.Web; using osu.Game.Users; @@ -20,7 +19,7 @@ namespace osu.Game.Overlays.Profile { private UserCoverBackground coverContainer = null!; - public Bindable User = new Bindable(); + public Bindable UserProfile = new Bindable(); private CentreHeaderContainer centreHeaderContainer; private DetailHeaderContainer detailHeaderContainer; @@ -29,7 +28,7 @@ namespace osu.Game.Overlays.Profile { ContentSidePadding = UserProfileOverlay.CONTENT_X_MARGIN; - User.ValueChanged += e => updateDisplay(e.NewValue); + UserProfile.ValueChanged += e => updateDisplay(e.NewValue); TabControl.AddItem(LayoutStrings.HeaderUsersShow); @@ -73,34 +72,34 @@ namespace osu.Game.Overlays.Profile new TopHeaderContainer { RelativeSizeAxes = Axes.X, - User = { BindTarget = User }, + UserProfile = { BindTarget = UserProfile }, }, centreHeaderContainer = new CentreHeaderContainer { RelativeSizeAxes = Axes.X, - User = { BindTarget = User }, + UserProfile = { BindTarget = UserProfile }, }, detailHeaderContainer = new DetailHeaderContainer { RelativeSizeAxes = Axes.X, - User = { BindTarget = User }, + UserProfile = { BindTarget = UserProfile }, }, new MedalHeaderContainer { RelativeSizeAxes = Axes.X, - User = { BindTarget = User }, + UserProfile = { BindTarget = UserProfile }, }, new BottomHeaderContainer { RelativeSizeAxes = Axes.X, - User = { BindTarget = User }, + UserProfile = { BindTarget = UserProfile }, }, } }; protected override OverlayTitle CreateTitle() => new ProfileHeaderTitle(); - private void updateDisplay(APIUser? user) => coverContainer.User = user; + private void updateDisplay(UserProfile? userProfile) => coverContainer.User = userProfile?.User; private partial class ProfileHeaderTitle : OverlayTitle { diff --git a/osu.Game/Overlays/Profile/ProfileSection.cs b/osu.Game/Overlays/Profile/ProfileSection.cs index 62b40545df..97b8f2b13f 100644 --- a/osu.Game/Overlays/Profile/ProfileSection.cs +++ b/osu.Game/Overlays/Profile/ProfileSection.cs @@ -13,7 +13,6 @@ using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Profile { @@ -29,7 +28,7 @@ namespace osu.Game.Overlays.Profile protected override Container Content => content; - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); protected ProfileSection() { diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index e327d71d25..3b1f26ee7d 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps protected override int InitialItemsCount => type == BeatmapSetType.Graveyard ? 2 : 6; - public PaginatedBeatmapContainer(BeatmapSetType type, Bindable user, LocalisableString headerText) + public PaginatedBeatmapContainer(BeatmapSetType type, Bindable user, LocalisableString headerText) : base(user, headerText) { this.type = type; diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs index 3b304a79ef..19d0da2cef 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs @@ -18,13 +18,13 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedBeatmapContainer(BeatmapSetType.Favourite, User, UsersStrings.ShowExtraBeatmapsFavouriteTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Ranked, User, UsersStrings.ShowExtraBeatmapsRankedTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Loved, User, UsersStrings.ShowExtraBeatmapsLovedTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Guest, User, UsersStrings.ShowExtraBeatmapsGuestTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Pending, User, UsersStrings.ShowExtraBeatmapsPendingTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, User, UsersStrings.ShowExtraBeatmapsGraveyardTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Nominated, User, UsersStrings.ShowExtraBeatmapsNominatedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Favourite, UserProfile, UsersStrings.ShowExtraBeatmapsFavouriteTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Ranked, UserProfile, UsersStrings.ShowExtraBeatmapsRankedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Loved, UserProfile, UsersStrings.ShowExtraBeatmapsLovedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Guest, UserProfile, UsersStrings.ShowExtraBeatmapsGuestTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Pending, UserProfile, UsersStrings.ShowExtraBeatmapsPendingTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, UserProfile, UsersStrings.ShowExtraBeatmapsGraveyardTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Nominated, UserProfile, UsersStrings.ShowExtraBeatmapsNominatedTitle), }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs index c532c693ec..724733c7a9 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs @@ -20,8 +20,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical /// protected abstract LocalisableString GraphCounterName { get; } - protected ChartProfileSubsection(Bindable user, LocalisableString headerText) - : base(user, headerText) + protected ChartProfileSubsection(Bindable userProfile, LocalisableString headerText) + : base(userProfile, headerText) { } @@ -41,12 +41,12 @@ namespace osu.Game.Overlays.Profile.Sections.Historical protected override void LoadComplete() { base.LoadComplete(); - User.BindValueChanged(onUserChanged, true); + UserProfile.BindValueChanged(onUserChanged, true); } - private void onUserChanged(ValueChangedEvent e) + private void onUserChanged(ValueChangedEvent e) { - var values = GetValues(e.NewValue); + var values = GetValues(e.NewValue?.User); if (values == null || values.Length <= 1) { diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs index 515c1fd146..5851262229 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs @@ -16,8 +16,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { public partial class PaginatedMostPlayedBeatmapContainer : PaginatedProfileSubsection { - public PaginatedMostPlayedBeatmapContainer(Bindable user) - : base(user, UsersStrings.ShowExtraHistoricalMostPlayedTitle) + public PaginatedMostPlayedBeatmapContainer(Bindable userProfile) + : base(userProfile, UsersStrings.ShowExtraHistoricalMostPlayedTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs index c8a6b1da31..5fa58dbdab 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs @@ -12,8 +12,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalMonthlyPlaycountsCountLabel; - public PlayHistorySubsection(Bindable user) - : base(user, UsersStrings.ShowExtraHistoricalMonthlyPlaycountsTitle) + public PlayHistorySubsection(Bindable userProfile) + : base(userProfile, UsersStrings.ShowExtraHistoricalMonthlyPlaycountsTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs index ac7c616a64..04e70afa36 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs @@ -12,8 +12,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalReplaysWatchedCountsCountLabel; - public ReplaysSubsection(Bindable user) - : base(user, UsersStrings.ShowExtraHistoricalReplaysWatchedCountsTitle) + public ReplaysSubsection(Bindable userProfile) + : base(userProfile, UsersStrings.ShowExtraHistoricalReplaysWatchedCountsTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs b/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs index 19f7a32d4d..eecdffad19 100644 --- a/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs +++ b/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs @@ -20,10 +20,10 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new Drawable[] { - new PlayHistorySubsection(User), - new PaginatedMostPlayedBeatmapContainer(User), - new PaginatedScoreContainer(ScoreType.Recent, User, UsersStrings.ShowExtraHistoricalRecentPlaysTitle), - new ReplaysSubsection(User) + new PlayHistorySubsection(UserProfile), + new PaginatedMostPlayedBeatmapContainer(UserProfile), + new PaginatedScoreContainer(ScoreType.Recent, UserProfile, UsersStrings.ShowExtraHistoricalRecentPlaysTitle), + new ReplaysSubsection(UserProfile) }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs index acf4827dfd..7fd0759fac 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs @@ -14,17 +14,16 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.LocalisationExtensions; using osu.Game.Resources.Localisation.Web; using osu.Framework.Localisation; -using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class KudosuInfo : Container { - private readonly Bindable user = new Bindable(); + private readonly Bindable userProfile = new Bindable(); - public KudosuInfo(Bindable user) + public KudosuInfo(Bindable userProfile) { - this.user.BindTo(user); + this.userProfile.BindTo(userProfile); CountSection total; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -32,7 +31,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu CornerRadius = 3; Child = total = new CountTotal(); - this.user.ValueChanged += u => total.Count = u.NewValue?.Kudosu.Total ?? 0; + this.userProfile.ValueChanged += u => total.Count = u.NewValue?.User.Kudosu.Total ?? 0; } protected override bool OnClick(ClickEvent e) => true; diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs index c5de810f22..6addd86894 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs @@ -14,8 +14,8 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class PaginatedKudosuHistoryContainer : PaginatedProfileSubsection { - public PaginatedKudosuHistoryContainer(Bindable user) - : base(user, missingText: UsersStrings.ShowExtraKudosuEntryEmpty) + public PaginatedKudosuHistoryContainer(Bindable userProfile) + : base(userProfile, missingText: UsersStrings.ShowExtraKudosuEntryEmpty) { } diff --git a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs b/osu.Game/Overlays/Profile/Sections/KudosuSection.cs index 482a853c44..b884f8854a 100644 --- a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs +++ b/osu.Game/Overlays/Profile/Sections/KudosuSection.cs @@ -18,8 +18,8 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new Drawable[] { - new KudosuInfo(User), - new PaginatedKudosuHistoryContainer(User), + new KudosuInfo(UserProfile), + new PaginatedKudosuHistoryContainer(UserProfile), }; } } diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs index f32221747c..d77844fd56 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs @@ -46,8 +46,8 @@ namespace osu.Game.Overlays.Profile.Sections private OsuSpriteText missing = null!; private readonly LocalisableString? missingText; - protected PaginatedProfileSubsection(Bindable user, LocalisableString? headerText = null, LocalisableString? missingText = null) - : base(user, headerText, CounterVisibilityState.AlwaysVisible) + protected PaginatedProfileSubsection(Bindable userProfile, LocalisableString? headerText = null, LocalisableString? missingText = null) + : base(userProfile, headerText, CounterVisibilityState.AlwaysVisible) { this.missingText = missingText; } @@ -89,10 +89,10 @@ namespace osu.Game.Overlays.Profile.Sections protected override void LoadComplete() { base.LoadComplete(); - User.BindValueChanged(onUserChanged, true); + UserProfile.BindValueChanged(onUserChanged, true); } - private void onUserChanged(ValueChangedEvent e) + private void onUserChanged(ValueChangedEvent e) { loadCancellation?.Cancel(); retrievalRequest?.Cancel(); @@ -100,23 +100,23 @@ namespace osu.Game.Overlays.Profile.Sections CurrentPage = null; ItemsContainer.Clear(); - if (e.NewValue != null) + if (e.NewValue?.User != null) { showMore(); - SetCount(GetCount(e.NewValue)); + SetCount(GetCount(e.NewValue.User)); } } private void showMore() { - if (User.Value == null) + if (UserProfile.Value?.User == null) return; loadCancellation = new CancellationTokenSource(); CurrentPage = CurrentPage?.TakeNext(ItemsPerPage) ?? new PaginationParameters(InitialItemsCount); - retrievalRequest = CreateRequest(User.Value, CurrentPage.Value); + retrievalRequest = CreateRequest(UserProfile.Value.User, CurrentPage.Value); retrievalRequest.Success += items => UpdateItems(items, loadCancellation); api.Queue(retrievalRequest); diff --git a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs index 0a0e1a9298..5df8688659 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs @@ -6,24 +6,23 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Localisation; -using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Profile.Sections { public abstract partial class ProfileSubsection : FillFlowContainer { - protected readonly Bindable User = new Bindable(); + protected readonly Bindable UserProfile = new Bindable(); private readonly LocalisableString headerText; private readonly CounterVisibilityState counterVisibilityState; private ProfileSubsectionHeader header = null!; - protected ProfileSubsection(Bindable user, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) + protected ProfileSubsection(Bindable userProfile, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) { this.headerText = headerText ?? string.Empty; this.counterVisibilityState = counterVisibilityState; - User.BindTo(user); + UserProfile.BindTo(userProfile); } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index 3ef0275f50..cdd1738c8e 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -19,8 +19,8 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { private readonly ScoreType type; - public PaginatedScoreContainer(ScoreType type, Bindable user, LocalisableString headerText) - : base(user, headerText) + public PaginatedScoreContainer(ScoreType type, Bindable userProfile, LocalisableString headerText) + : base(userProfile, headerText) { this.type = type; } diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index ce831b30a8..f8d1d82300 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -18,9 +18,9 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedScoreContainer(ScoreType.Pinned, User, UsersStrings.ShowExtraTopRanksPinnedTitle), - new PaginatedScoreContainer(ScoreType.Best, User, UsersStrings.ShowExtraTopRanksBestTitle), - new PaginatedScoreContainer(ScoreType.Firsts, User, UsersStrings.ShowExtraTopRanksFirstTitle) + new PaginatedScoreContainer(ScoreType.Pinned, UserProfile, UsersStrings.ShowExtraTopRanksPinnedTitle), + new PaginatedScoreContainer(ScoreType.Best, UserProfile, UsersStrings.ShowExtraTopRanksBestTitle), + new PaginatedScoreContainer(ScoreType.Firsts, UserProfile, UsersStrings.ShowExtraTopRanksFirstTitle) }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 4e5b11d79f..c08ea58b5a 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -16,8 +16,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { public partial class PaginatedRecentActivityContainer : PaginatedProfileSubsection { - public PaginatedRecentActivityContainer(Bindable user) - : base(user, missingText: EventsStrings.Empty) + public PaginatedRecentActivityContainer(Bindable userProfile) + : base(userProfile, missingText: EventsStrings.Empty) { } diff --git a/osu.Game/Overlays/Profile/Sections/RecentSection.cs b/osu.Game/Overlays/Profile/Sections/RecentSection.cs index e29dc7f635..6a90b7d1e3 100644 --- a/osu.Game/Overlays/Profile/Sections/RecentSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RecentSection.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedRecentActivityContainer(User), + new PaginatedRecentActivityContainer(UserProfile), }; } } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 1a7c4173ab..4fcfc7dc3c 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -47,7 +47,7 @@ namespace osu.Game.Overlays Show(); - if (user.OnlineID == Header?.User.Value?.Id) + if (user.OnlineID == Header?.UserProfile.Value?.User.Id) return; if (sectionsContainer != null) @@ -134,7 +134,8 @@ namespace osu.Game.Overlays { Debug.Assert(sections != null && sectionsContainer != null && tabs != null); - Header.User.Value = user; + var userProfile = new UserProfile(user); + Header.UserProfile.Value = userProfile; if (user.ProfileOrder != null) { @@ -144,7 +145,7 @@ namespace osu.Game.Overlays if (sec != null) { - sec.User.Value = user; + sec.UserProfile.Value = userProfile; sectionsContainer.Add(sec); tabs.AddItem(sec); From ae3a211da727babd94791cfce7a021fe1bacdb44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 16:11:56 +0100 Subject: [PATCH 1275/2991] Rewrite user profile overlay test to not depend on online API --- .../Online/TestSceneUserProfileOverlay.cs | 96 ++++++++----------- 1 file changed, 38 insertions(+), 58 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs index 35c7e7bf28..446e13a8a3 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs @@ -4,9 +4,12 @@ using System; using System.Linq; using NUnit.Framework; +using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; -using osu.Game.Overlays.Profile; using osu.Game.Users; namespace osu.Game.Tests.Visual.Online @@ -14,9 +17,41 @@ namespace osu.Game.Tests.Visual.Online [TestFixture] public partial class TestSceneUserProfileOverlay : OsuTestScene { - protected override bool UseOnlineAPI => true; + private DummyAPIAccess dummyAPI => (DummyAPIAccess)API; - private readonly TestUserProfileOverlay profile; + private UserProfileOverlay profile = null!; + + [SetUpSteps] + public void SetUp() + { + AddStep("create profile overlay", () => Child = profile = new UserProfileOverlay()); + } + + [Test] + public void TestBlank() + { + AddStep("show overlay", () => profile.Show()); + } + + [Test] + public void TestActualUser() + { + AddStep("set up request handling", () => + { + dummyAPI.HandleRequest = req => + { + if (req is GetUserRequest getUserRequest) + { + getUserRequest.TriggerSuccess(TEST_USER); + return true; + } + + return false; + }; + }); + AddStep("show user", () => profile.ShowUser(new APIUser { Id = 1 })); + AddToggleStep("toggle visibility", visible => profile.State.Value = visible ? Visibility.Visible : Visibility.Hidden); + } public static readonly APIUser TEST_USER = new APIUser { @@ -64,60 +99,5 @@ namespace osu.Game.Tests.Visual.Online Colour = "ff0000", Achievements = Array.Empty(), }; - - public TestSceneUserProfileOverlay() - { - Add(profile = new TestUserProfileOverlay()); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - AddStep("Show offline dummy", () => profile.ShowUser(TEST_USER)); - - AddStep("Show null dummy", () => profile.ShowUser(new APIUser - { - Username = @"Null", - Id = 1, - })); - - AddStep("Show ppy", () => profile.ShowUser(new APIUser - { - Username = @"peppy", - Id = 2, - IsSupporter = true, - CountryCode = CountryCode.AU, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg" - })); - - AddStep("Show flyte", () => profile.ShowUser(new APIUser - { - Username = @"flyte", - Id = 3103765, - CountryCode = CountryCode.JP, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg" - })); - - AddStep("Show bancho", () => profile.ShowUser(new APIUser - { - Username = @"BanchoBot", - Id = 3, - IsBot = true, - CountryCode = CountryCode.SH, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c4.jpg" - })); - - AddStep("Show ppy from username", () => profile.ShowUser(new APIUser { Username = @"peppy" })); - AddStep("Show flyte from username", () => profile.ShowUser(new APIUser { Username = @"flyte" })); - - AddStep("Hide", profile.Hide); - AddStep("Show without reload", profile.Show); - } - - private partial class TestUserProfileOverlay : UserProfileOverlay - { - public new ProfileHeader Header => base.Header; - } } } From 4dd7727f71a420ea7058ad5a0f0d133371faaf49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 16:12:39 +0100 Subject: [PATCH 1276/2991] Remove test-specific workaround in overlay --- osu.Game/Overlays/UserProfileOverlay.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 4fcfc7dc3c..5ec92efdbb 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -116,15 +116,6 @@ namespace osu.Game.Overlays sectionsContainer.ScrollToTop(); - // Check arbitrarily whether this user has already been populated. - // This is only generally used by tests, but should be quite safe unless we want to force a refresh on loading a previous user in the future. - if (user is APIUser apiUser && apiUser.JoinDate != default) - { - userReq = null; - userLoadComplete(apiUser); - return; - } - userReq = user.OnlineID > 1 ? new GetUserRequest(user.OnlineID) : new GetUserRequest(user.Username); userReq.Success += userLoadComplete; API.Queue(userReq); From 1722f3a125255174ddf9db18db6126b7023f3823 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 17:53:50 +0100 Subject: [PATCH 1277/2991] Add ruleset to `UserProfile` --- .../Visual/Online/TestSceneHistoricalSection.cs | 5 +++-- .../Online/TestScenePlayHistorySubsection.cs | 17 +++++++++-------- .../Visual/Online/TestSceneUserProfileHeader.cs | 11 ++++++----- .../Visual/Online/TestSceneUserRanks.cs | 3 ++- osu.Game/Overlays/Profile/UserProfile.cs | 9 +++++++-- osu.Game/Overlays/UserProfileOverlay.cs | 15 +++++++++++---- 6 files changed, 38 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs index 92bb41b7d5..438e191650 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs @@ -11,6 +11,7 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile.Sections; +using osu.Game.Rulesets.Osu; namespace osu.Game.Tests.Visual.Online { @@ -38,8 +39,8 @@ namespace osu.Game.Tests.Visual.Online Child = section = new HistoricalSection(), }); - AddStep("Show peppy", () => section.UserProfile.Value = new UserProfile(new APIUser { Id = 2 })); - AddStep("Show WubWoofWolf", () => section.UserProfile.Value = new UserProfile(new APIUser { Id = 39828 })); + AddStep("Show peppy", () => section.UserProfile.Value = new UserProfile(new APIUser { Id = 2 }, new OsuRuleset().RulesetInfo)); + AddStep("Show WubWoofWolf", () => section.UserProfile.Value = new UserProfile(new APIUser { Id = 39828 }, new OsuRuleset().RulesetInfo)); } } } diff --git a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs index a486d77f97..5c6ffdcd80 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs @@ -13,6 +13,7 @@ using osu.Framework.Testing; using osu.Framework.Graphics.Shapes; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile; +using osu.Game.Rulesets.Osu; namespace osu.Game.Tests.Visual.Online { @@ -44,49 +45,49 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestNullValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_null_values)); + AddStep("Load user", () => user.Value = new UserProfile(user_with_null_values, new OsuRuleset().RulesetInfo)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestEmptyValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_empty_values)); + AddStep("Load user", () => user.Value = new UserProfile(user_with_empty_values, new OsuRuleset().RulesetInfo)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestOneValue() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_one_value)); + AddStep("Load user", () => user.Value = new UserProfile(user_with_one_value, new OsuRuleset().RulesetInfo)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestTwoValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_two_values)); + AddStep("Load user", () => user.Value = new UserProfile(user_with_two_values, new OsuRuleset().RulesetInfo)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_constant_values)); + AddStep("Load user", () => user.Value = new UserProfile(user_with_constant_values, new OsuRuleset().RulesetInfo)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantZeroValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_zero_values)); + AddStep("Load user", () => user.Value = new UserProfile(user_with_zero_values, new OsuRuleset().RulesetInfo)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestFilledValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_filled_values)); + AddStep("Load user", () => user.Value = new UserProfile(user_with_filled_values, new OsuRuleset().RulesetInfo)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is the same", () => user_with_filled_values.MonthlyPlayCounts.Length == getChartValuesLength()); } @@ -94,7 +95,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestMissingValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_missing_values)); + AddStep("Load user", () => user.Value = new UserProfile(user_with_missing_values, new OsuRuleset().RulesetInfo)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is 7", () => getChartValuesLength() == 7); } diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index 4caab98f63..6458f54183 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -9,6 +9,7 @@ using osu.Framework.Testing; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; using osu.Game.Overlays.Profile; +using osu.Game.Rulesets.Osu; using osu.Game.Users; namespace osu.Game.Tests.Visual.Online @@ -29,7 +30,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestBasic() { - AddStep("Show example user", () => header.UserProfile.Value = new UserProfile(TestSceneUserProfileOverlay.TEST_USER)); + AddStep("Show example user", () => header.UserProfile.Value = new UserProfile(TestSceneUserProfileOverlay.TEST_USER, new OsuRuleset().RulesetInfo)); } [Test] @@ -41,7 +42,7 @@ namespace osu.Game.Tests.Visual.Online Username = "IAmOnline", LastVisit = DateTimeOffset.Now, IsOnline = true, - })); + }, new OsuRuleset().RulesetInfo)); AddStep("Show offline user", () => header.UserProfile.Value = new UserProfile(new APIUser { @@ -49,7 +50,7 @@ namespace osu.Game.Tests.Visual.Online Username = "IAmOffline", LastVisit = DateTimeOffset.Now.AddDays(-10), IsOnline = false, - })); + }, new OsuRuleset().RulesetInfo)); } [Test] @@ -70,7 +71,7 @@ namespace osu.Game.Tests.Visual.Online Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray() }, } - })); + }, new OsuRuleset().RulesetInfo)); AddStep("Show unranked user", () => header.UserProfile.Value = new UserProfile(new APIUser { @@ -86,7 +87,7 @@ namespace osu.Game.Tests.Visual.Online Data = Enumerable.Range(2345, 85).ToArray() }, } - })); + }, new OsuRuleset().RulesetInfo)); } } } diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs index 184b969279..ab53551ea1 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs @@ -12,6 +12,7 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile.Sections; +using osu.Game.Rulesets.Osu; namespace osu.Game.Tests.Visual.Online { @@ -45,7 +46,7 @@ namespace osu.Game.Tests.Visual.Online } }); - AddStep("Show cookiezi", () => ranks.UserProfile.Value = new UserProfile(new APIUser { Id = 124493 })); + AddStep("Show cookiezi", () => ranks.UserProfile.Value = new UserProfile(new APIUser { Id = 124493 }, new OsuRuleset().RulesetInfo)); } } } diff --git a/osu.Game/Overlays/Profile/UserProfile.cs b/osu.Game/Overlays/Profile/UserProfile.cs index 12a469ddf9..60fc5a0492 100644 --- a/osu.Game/Overlays/Profile/UserProfile.cs +++ b/osu.Game/Overlays/Profile/UserProfile.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Online.API.Requests.Responses; +using osu.Game.Rulesets; namespace osu.Game.Overlays.Profile { @@ -15,11 +16,15 @@ namespace osu.Game.Overlays.Profile /// public APIUser User { get; } - // TODO: add ruleset + /// + /// The ruleset that the user profile is being shown with. + /// + public RulesetInfo Ruleset { get; } - public UserProfile(APIUser user) + public UserProfile(APIUser user, RulesetInfo ruleset) { User = user; + Ruleset = ruleset; } } } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 5ec92efdbb..2625d85636 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -5,6 +5,7 @@ using System; using System.Diagnostics; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -15,6 +16,7 @@ using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile.Sections; +using osu.Game.Rulesets; using osu.Game.Users; using osuTK; using osuTK.Graphics; @@ -29,6 +31,9 @@ namespace osu.Game.Overlays private ProfileSectionsContainer? sectionsContainer; private ProfileSectionTabControl? tabs; + [Resolved] + private RulesetStore rulesets { get; set; } = null!; + public const float CONTENT_X_MARGIN = 70; public UserProfileOverlay() @@ -40,7 +45,7 @@ namespace osu.Game.Overlays protected override Color4 BackgroundColour => ColourProvider.Background6; - public void ShowUser(IUser user) + public void ShowUser(IUser user, IRulesetInfo? ruleset = null) { if (user.OnlineID == APIUser.SYSTEM_USER_ID) return; @@ -117,15 +122,17 @@ namespace osu.Game.Overlays sectionsContainer.ScrollToTop(); userReq = user.OnlineID > 1 ? new GetUserRequest(user.OnlineID) : new GetUserRequest(user.Username); - userReq.Success += userLoadComplete; + userReq.Success += u => userLoadComplete(u, ruleset); API.Queue(userReq); } - private void userLoadComplete(APIUser user) + private void userLoadComplete(APIUser user, IRulesetInfo? ruleset) { Debug.Assert(sections != null && sectionsContainer != null && tabs != null); - var userProfile = new UserProfile(user); + var actualRuleset = rulesets.GetRuleset(ruleset?.ShortName ?? user.PlayMode).AsNonNull(); + + var userProfile = new UserProfile(user, actualRuleset); Header.UserProfile.Value = userProfile; if (user.ProfileOrder != null) From 7683ab68b034796e1dad3f3a5d63eef71bca450c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 18:03:44 +0100 Subject: [PATCH 1278/2991] Use `UserProfile` in profile ruleset selector --- .../Online/TestSceneProfileRulesetSelector.cs | 26 +++++++++---------- .../Components/ProfileRulesetSelector.cs | 12 ++++++--- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs index a4d8238fa3..a176557d92 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs @@ -11,6 +11,7 @@ using osu.Framework.Bindables; using osu.Game.Overlays; using osu.Framework.Allocation; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays.Profile; namespace osu.Game.Tests.Visual.Online { @@ -21,26 +22,25 @@ namespace osu.Game.Tests.Visual.Online public TestSceneProfileRulesetSelector() { - ProfileRulesetSelector selector; - var user = new Bindable(); + var userProfile = new Bindable(); - Child = selector = new ProfileRulesetSelector + Child = new ProfileRulesetSelector { Anchor = Anchor.Centre, Origin = Anchor.Centre, - User = { BindTarget = user } + UserProfile = { BindTarget = userProfile } }; + AddStep("User on osu ruleset", () => userProfile.Value = new UserProfile(new APIUser { Id = 0, PlayMode = "osu" }, new OsuRuleset().RulesetInfo)); + AddStep("User on taiko ruleset", () => userProfile.Value = new UserProfile(new APIUser { Id = 1, PlayMode = "osu" }, new TaikoRuleset().RulesetInfo)); + AddStep("User on catch ruleset", () => userProfile.Value = new UserProfile(new APIUser { Id = 2, PlayMode = "osu" }, new CatchRuleset().RulesetInfo)); + AddStep("User on mania ruleset", () => userProfile.Value = new UserProfile(new APIUser { Id = 3, PlayMode = "osu" }, new ManiaRuleset().RulesetInfo)); - AddStep("set osu! as default", () => selector.SetDefaultRuleset(new OsuRuleset().RulesetInfo)); - AddStep("set taiko as default", () => selector.SetDefaultRuleset(new TaikoRuleset().RulesetInfo)); - AddStep("set catch as default", () => selector.SetDefaultRuleset(new CatchRuleset().RulesetInfo)); - AddStep("set mania as default", () => selector.SetDefaultRuleset(new ManiaRuleset().RulesetInfo)); + AddStep("User with osu as default", () => userProfile.Value = new UserProfile(new APIUser { Id = 0, PlayMode = "osu" }, new OsuRuleset().RulesetInfo)); + AddStep("User with taiko as default", () => userProfile.Value = new UserProfile(new APIUser { Id = 1, PlayMode = "taiko" }, new OsuRuleset().RulesetInfo)); + AddStep("User with catch as default", () => userProfile.Value = new UserProfile(new APIUser { Id = 2, PlayMode = "fruits" }, new OsuRuleset().RulesetInfo)); + AddStep("User with mania as default", () => userProfile.Value = new UserProfile(new APIUser { Id = 3, PlayMode = "mania" }, new OsuRuleset().RulesetInfo)); - AddStep("User with osu as default", () => user.Value = new APIUser { Id = 0, PlayMode = "osu" }); - AddStep("User with taiko as default", () => user.Value = new APIUser { Id = 1, PlayMode = "taiko" }); - AddStep("User with catch as default", () => user.Value = new APIUser { Id = 2, PlayMode = "fruits" }); - AddStep("User with mania as default", () => user.Value = new APIUser { Id = 3, PlayMode = "mania" }); - AddStep("null user", () => user.Value = null); + AddStep("null user", () => userProfile.Value = null); } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index 684ce9088e..fff6ead528 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -4,19 +4,25 @@ using osu.Framework.Bindables; using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.UserInterface; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets; namespace osu.Game.Overlays.Profile.Header.Components { public partial class ProfileRulesetSelector : OverlayRulesetSelector { - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); protected override void LoadComplete() { base.LoadComplete(); - User.BindValueChanged(u => SetDefaultRuleset(Rulesets.GetRuleset(u.NewValue?.PlayMode ?? "osu").AsNonNull()), true); + + UserProfile.BindValueChanged(userProfile => updateState(userProfile.NewValue), true); + } + + private void updateState(UserProfile? userProfile) + { + Current.Value = userProfile?.Ruleset; + SetDefaultRuleset(Rulesets.GetRuleset(userProfile?.User.PlayMode ?? @"osu").AsNonNull()); } public void SetDefaultRuleset(RulesetInfo ruleset) From a2e726502f8c549361f4fcbfba5cebe9a2e5db4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 18:44:03 +0100 Subject: [PATCH 1279/2991] Add ruleset selector to profile overlay --- .../Visual/Online/TestSceneUserProfileOverlay.cs | 1 + .../Profile/Header/Components/ProfileRulesetSelector.cs | 4 +++- osu.Game/Overlays/Profile/ProfileHeader.cs | 8 ++++++++ osu.Game/Overlays/TabControlOverlayHeader.cs | 8 ++++---- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs index 446e13a8a3..393fcd6d70 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs @@ -98,6 +98,7 @@ namespace osu.Game.Tests.Visual.Online Title = "osu!volunteer", Colour = "ff0000", Achievements = Array.Empty(), + PlayMode = "osu" }; } } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index fff6ead528..cdd0ed0b0a 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -1,9 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; using osu.Framework.Bindables; using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.UserInterface; +using osu.Game.Extensions; using osu.Game.Rulesets; namespace osu.Game.Overlays.Profile.Header.Components @@ -21,7 +23,7 @@ namespace osu.Game.Overlays.Profile.Header.Components private void updateState(UserProfile? userProfile) { - Current.Value = userProfile?.Ruleset; + Current.Value = Items.SingleOrDefault(ruleset => userProfile?.Ruleset.MatchesOnlineID(ruleset) == true); SetDefaultRuleset(Rulesets.GetRuleset(userProfile?.User.PlayMode ?? @"osu").AsNonNull()); } diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 447e9148e8..059469230c 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; using osu.Game.Overlays.Profile.Header; +using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Resources.Localisation.Web; using osu.Game.Users; @@ -35,6 +36,13 @@ namespace osu.Game.Overlays.Profile // todo: pending implementation. // TabControl.AddItem(LayoutStrings.HeaderUsersModding); + TabControlContainer.Add(new ProfileRulesetSelector + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + UserProfile = { BindTarget = UserProfile } + }); + // Haphazardly guaranteed by OverlayHeader constructor (see CreateBackground / CreateContent). Debug.Assert(centreHeaderContainer != null); Debug.Assert(detailHeaderContainer != null); diff --git a/osu.Game/Overlays/TabControlOverlayHeader.cs b/osu.Game/Overlays/TabControlOverlayHeader.cs index cad94eba71..8613bac40c 100644 --- a/osu.Game/Overlays/TabControlOverlayHeader.cs +++ b/osu.Game/Overlays/TabControlOverlayHeader.cs @@ -23,10 +23,10 @@ namespace osu.Game.Overlays /// The type of item to be represented by tabs. public abstract partial class TabControlOverlayHeader : OverlayHeader, IHasCurrentValue { - protected OsuTabControl TabControl; + protected OsuTabControl TabControl { get; } + protected Container TabControlContainer { get; } private readonly Box controlBackground; - private readonly Container tabControlContainer; private readonly BindableWithCurrent current = new BindableWithCurrent(); public Bindable Current @@ -41,7 +41,7 @@ namespace osu.Game.Overlays set { base.ContentSidePadding = value; - tabControlContainer.Padding = new MarginPadding { Horizontal = value }; + TabControlContainer.Padding = new MarginPadding { Horizontal = value }; } } @@ -57,7 +57,7 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.Both, }, - tabControlContainer = new Container + TabControlContainer = new Container { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, From c759b743dc2c27bea5686ace7a9ebb34e045073f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 19:12:50 +0100 Subject: [PATCH 1280/2991] Add support for switching rulesets on profile overlay --- .../Profile/Header/Components/ProfileRulesetSelector.cs | 9 +++++++++ .../Sections/Beatmaps/PaginatedBeatmapContainer.cs | 4 ++-- .../Historical/PaginatedMostPlayedBeatmapContainer.cs | 4 ++-- .../Sections/Kudosu/PaginatedKudosuHistoryContainer.cs | 5 ++--- .../Profile/Sections/PaginatedProfileSubsection.cs | 6 +++--- .../Profile/Sections/Ranks/PaginatedScoreContainer.cs | 4 ++-- .../Sections/Recent/PaginatedRecentActivityContainer.cs | 5 ++--- osu.Game/Overlays/UserProfileOverlay.cs | 5 +++-- 8 files changed, 25 insertions(+), 17 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index cdd0ed0b0a..2214112577 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.UserInterface; @@ -12,6 +13,9 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class ProfileRulesetSelector : OverlayRulesetSelector { + [Resolved] + private UserProfileOverlay? profileOverlay { get; set; } + public readonly Bindable UserProfile = new Bindable(); protected override void LoadComplete() @@ -19,6 +23,11 @@ namespace osu.Game.Overlays.Profile.Header.Components base.LoadComplete(); UserProfile.BindValueChanged(userProfile => updateState(userProfile.NewValue), true); + Current.BindValueChanged(ruleset => + { + if (UserProfile.Value != null && !ruleset.NewValue.Equals(UserProfile.Value.Ruleset)) + profileOverlay?.ShowUser(UserProfile.Value.User, ruleset.NewValue); + }); } private void updateState(UserProfile? userProfile) diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index 3b1f26ee7d..be7a3039f1 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -64,8 +64,8 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps } } - protected override APIRequest> CreateRequest(APIUser user, PaginationParameters pagination) => - new GetUserBeatmapsRequest(user.Id, type, pagination); + protected override APIRequest> CreateRequest(UserProfile userProfile, PaginationParameters pagination) => + new GetUserBeatmapsRequest(userProfile.User.Id, type, pagination); protected override Drawable? CreateDrawableItem(APIBeatmapSet model) => model.OnlineID > 0 ? new BeatmapCardNormal(model) diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs index 5851262229..3d1458ddf5 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs @@ -29,8 +29,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical protected override int GetCount(APIUser user) => user.BeatmapPlayCountsCount; - protected override APIRequest> CreateRequest(APIUser user, PaginationParameters pagination) => - new GetUserMostPlayedBeatmapsRequest(user.Id, pagination); + protected override APIRequest> CreateRequest(UserProfile userProfile, PaginationParameters pagination) => + new GetUserMostPlayedBeatmapsRequest(userProfile.User.Id, pagination); protected override Drawable CreateDrawableItem(APIUserMostPlayedBeatmap mostPlayed) => new DrawableMostPlayedBeatmap(mostPlayed); diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs index 6addd86894..f65b334a9d 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs @@ -8,7 +8,6 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API; using System.Collections.Generic; using osu.Game.Resources.Localisation.Web; -using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Overlays.Profile.Sections.Kudosu { @@ -19,8 +18,8 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { } - protected override APIRequest> CreateRequest(APIUser user, PaginationParameters pagination) - => new GetUserKudosuHistoryRequest(user.Id, pagination); + protected override APIRequest> CreateRequest(UserProfile userProfile, PaginationParameters pagination) + => new GetUserKudosuHistoryRequest(userProfile.User.Id, pagination); protected override Drawable CreateDrawableItem(APIKudosuHistory item) => new DrawableKudosuHistoryItem(item); } diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs index d77844fd56..654cc9ff7b 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs @@ -109,14 +109,14 @@ namespace osu.Game.Overlays.Profile.Sections private void showMore() { - if (UserProfile.Value?.User == null) + if (UserProfile.Value == null) return; loadCancellation = new CancellationTokenSource(); CurrentPage = CurrentPage?.TakeNext(ItemsPerPage) ?? new PaginationParameters(InitialItemsCount); - retrievalRequest = CreateRequest(UserProfile.Value.User, CurrentPage.Value); + retrievalRequest = CreateRequest(UserProfile.Value, CurrentPage.Value); retrievalRequest.Success += items => UpdateItems(items, loadCancellation); api.Queue(retrievalRequest); @@ -154,7 +154,7 @@ namespace osu.Game.Overlays.Profile.Sections { } - protected abstract APIRequest> CreateRequest(APIUser user, PaginationParameters pagination); + protected abstract APIRequest> CreateRequest(UserProfile userProfile, PaginationParameters pagination); protected abstract Drawable? CreateDrawableItem(TModel model); diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index cdd1738c8e..aba63cc25d 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -60,8 +60,8 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks base.OnItemsReceived(items); } - protected override APIRequest> CreateRequest(APIUser user, PaginationParameters pagination) => - new GetUserScoresRequest(user.Id, type, pagination); + protected override APIRequest> CreateRequest(UserProfile userProfile, PaginationParameters pagination) => + new GetUserScoresRequest(userProfile.User.Id, type, pagination, userProfile.Ruleset); private int drawableItemIndex; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index c08ea58b5a..74247572ed 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -10,7 +10,6 @@ using System.Collections.Generic; using osuTK; using osu.Framework.Allocation; using osu.Game.Resources.Localisation.Web; -using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Overlays.Profile.Sections.Recent { @@ -27,8 +26,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent ItemsContainer.Spacing = new Vector2(0, 8); } - protected override APIRequest> CreateRequest(APIUser user, PaginationParameters pagination) => - new GetUserRecentActivitiesRequest(user.Id, pagination); + protected override APIRequest> CreateRequest(UserProfile userProfile, PaginationParameters pagination) => + new GetUserRecentActivitiesRequest(userProfile.User.Id, pagination); protected override Drawable CreateDrawableItem(APIRecentActivity model) => new DrawableRecentActivity(model); } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 2625d85636..185119c631 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; +using osu.Game.Extensions; using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; @@ -52,7 +53,7 @@ namespace osu.Game.Overlays Show(); - if (user.OnlineID == Header?.UserProfile.Value?.User.Id) + if (user.OnlineID == Header.UserProfile.Value?.User.Id && ruleset?.MatchesOnlineID(Header.UserProfile.Value?.Ruleset) == true) return; if (sectionsContainer != null) @@ -121,7 +122,7 @@ namespace osu.Game.Overlays sectionsContainer.ScrollToTop(); - userReq = user.OnlineID > 1 ? new GetUserRequest(user.OnlineID) : new GetUserRequest(user.Username); + userReq = user.OnlineID > 1 ? new GetUserRequest(user.OnlineID, ruleset) : new GetUserRequest(user.Username, ruleset); userReq.Success += u => userLoadComplete(u, ruleset); API.Queue(userReq); } From a124c967dfd96a671640b24734f9e9c10d574f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 20:13:23 +0100 Subject: [PATCH 1281/2991] Add proper offline & loading state handling to user profile overlay --- .../Online/TestSceneUserProfileOverlay.cs | 25 +++++++++++++++++++ osu.Game/Overlays/UserProfileOverlay.cs | 18 +++++++++++++ 2 files changed, 43 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs index 393fcd6d70..d3d9dcb990 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs @@ -51,6 +51,31 @@ namespace osu.Game.Tests.Visual.Online }); AddStep("show user", () => profile.ShowUser(new APIUser { Id = 1 })); AddToggleStep("toggle visibility", visible => profile.State.Value = visible ? Visibility.Visible : Visibility.Hidden); + AddStep("log out", () => dummyAPI.Logout()); + AddStep("log back in", () => dummyAPI.Login("username", "password")); + } + + [Test] + public void TestLoading() + { + GetUserRequest pendingRequest = null!; + + AddStep("set up request handling", () => + { + dummyAPI.HandleRequest = req => + { + if (req is GetUserRequest getUserRequest) + { + pendingRequest = getUserRequest; + return true; + } + + return false; + }; + }); + AddStep("show user", () => profile.ShowUser(new APIUser { Id = 1 })); + AddWaitStep("wait some", 3); + AddStep("complete request", () => pendingRequest.TriggerSuccess(TEST_USER)); } public static readonly APIUser TEST_USER = new APIUser diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 185119c631..155833e0c6 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -13,6 +13,8 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Extensions; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile; @@ -26,6 +28,11 @@ namespace osu.Game.Overlays { public partial class UserProfileOverlay : FullscreenOverlay { + protected override Container Content => onlineViewContainer; + + private readonly OnlineViewContainer onlineViewContainer; + private readonly LoadingLayer loadingLayer; + private ProfileSection? lastSection; private ProfileSection[]? sections; private GetUserRequest? userReq; @@ -40,6 +47,14 @@ namespace osu.Game.Overlays public UserProfileOverlay() : base(OverlayColourScheme.Pink) { + base.Content.AddRange(new Drawable[] + { + onlineViewContainer = new OnlineViewContainer($"Sign in to view the {Header.Title.Title}") + { + RelativeSizeAxes = Axes.Both + }, + loadingLayer = new LoadingLayer(true) + }); } protected override ProfileHeader CreateHeader() => new ProfileHeader(); @@ -125,6 +140,7 @@ namespace osu.Game.Overlays userReq = user.OnlineID > 1 ? new GetUserRequest(user.OnlineID, ruleset) : new GetUserRequest(user.Username, ruleset); userReq.Success += u => userLoadComplete(u, ruleset); API.Queue(userReq); + loadingLayer.Show(); } private void userLoadComplete(APIUser user, IRulesetInfo? ruleset) @@ -151,6 +167,8 @@ namespace osu.Game.Overlays } } } + + loadingLayer.Hide(); } private partial class ProfileSectionTabControl : OverlayTabControl From 8f7ae0395a082eda458009ccdaf3504675dca9fa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Jan 2023 00:55:05 +0800 Subject: [PATCH 1282/2991] Fix song select leaderboard potentially showing wrong scores on quick beatmap changes Closes #22002. --- .../Select/Leaderboards/BeatmapLeaderboard.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index b8a2eec526..9e8247059d 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -154,10 +154,17 @@ namespace osu.Game.Screens.Select.Leaderboards scoreRetrievalRequest = new GetScoresRequest(fetchBeatmapInfo, fetchRuleset, Scope, requestMods); - scoreRetrievalRequest.Success += response => SetScores( - scoreManager.OrderByTotalScore(response.Scores.Select(s => s.ToScoreInfo(rulesets, fetchBeatmapInfo))), - response.UserScore?.CreateScoreInfo(rulesets, fetchBeatmapInfo) - ); + scoreRetrievalRequest.Success += response => Schedule(() => + { + // Beatmap may have changed since fetch request. Can't rely on request cancellation due to Schedule inside SetScores. + if (!fetchBeatmapInfo.Equals(BeatmapInfo)) + return; + + SetScores( + scoreManager.OrderByTotalScore(response.Scores.Select(s => s.ToScoreInfo(rulesets, fetchBeatmapInfo))), + response.UserScore?.CreateScoreInfo(rulesets, fetchBeatmapInfo) + ); + }); return scoreRetrievalRequest; } From ac85433178f9f61992e6a2239a3e783fca9f76ef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Jan 2023 09:44:34 +0800 Subject: [PATCH 1283/2991] Fix default volume control keys not working when chat textbox is focused Closes #22004. --- osu.Game/Graphics/UserInterface/HistoryTextBox.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs index d74a4f2cdb..b6dc1fcc9b 100644 --- a/osu.Game/Graphics/UserInterface/HistoryTextBox.cs +++ b/osu.Game/Graphics/UserInterface/HistoryTextBox.cs @@ -45,6 +45,9 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnKeyDown(KeyDownEvent e) { + if (e.ControlPressed || e.AltPressed || e.SuperPressed || e.ShiftPressed) + return false; + switch (e.Key) { case Key.Up: From 4491a5ba9f7c38010600bcc4db4c358cdc6c7c9e Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 3 Jan 2023 13:41:08 +0300 Subject: [PATCH 1284/2991] Fix editor exporting beatmap combo colours in wrong order --- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 03c63ff4f2..7e058d755e 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -300,7 +300,7 @@ namespace osu.Game.Beatmaps.Formats { var comboColour = colours[i]; - writer.Write(FormattableString.Invariant($"Combo{i}: ")); + writer.Write(FormattableString.Invariant($"Combo{1 + i}: ")); writer.Write(FormattableString.Invariant($"{(byte)(comboColour.R * byte.MaxValue)},")); writer.Write(FormattableString.Invariant($"{(byte)(comboColour.G * byte.MaxValue)},")); writer.Write(FormattableString.Invariant($"{(byte)(comboColour.B * byte.MaxValue)},")); From efbd9ba4b90946909faa4a07024484e38cd15001 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 3 Jan 2023 15:28:05 +0300 Subject: [PATCH 1285/2991] Fix catcher not moving when fully hidden in "No Scope" mod --- osu.Game.Rulesets.Catch/Mods/CatchModNoScope.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModNoScope.cs b/osu.Game.Rulesets.Catch/Mods/CatchModNoScope.cs index 19b4a39f97..ddeea51ecb 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModNoScope.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModNoScope.cs @@ -26,6 +26,9 @@ namespace osu.Game.Rulesets.Catch.Mods var catchPlayfield = (CatchPlayfield)playfield; bool shouldAlwaysShowCatcher = IsBreakTime.Value; float targetAlpha = shouldAlwaysShowCatcher ? 1 : ComboBasedAlpha; + + // AlwaysPresent required for catcher to still act on input when fully hidden. + catchPlayfield.CatcherArea.AlwaysPresent = true; catchPlayfield.CatcherArea.Alpha = (float)Interpolation.Lerp(catchPlayfield.CatcherArea.Alpha, targetAlpha, Math.Clamp(catchPlayfield.Time.Elapsed / TRANSITION_DURATION, 0, 1)); } } From 71125afcb45365a09424a7348ef20d51dc2a2392 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 3 Jan 2023 15:43:36 +0300 Subject: [PATCH 1286/2991] Add test coverage --- .../Mods/TestSceneCatchModNoScope.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModNoScope.cs b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModNoScope.cs index 50b928d509..c48bf7adc9 100644 --- a/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModNoScope.cs +++ b/osu.Game.Rulesets.Catch.Tests/Mods/TestSceneCatchModNoScope.cs @@ -18,6 +18,36 @@ namespace osu.Game.Rulesets.Catch.Tests.Mods { protected override Ruleset CreatePlayerRuleset() => new CatchRuleset(); + [Test] + public void TestAlwaysHidden() + { + CreateModTest(new ModTestData + { + Mod = new CatchModNoScope + { + HiddenComboCount = { Value = 0 }, + }, + Autoplay = true, + PassCondition = () => Player.ScoreProcessor.Combo.Value == 2, + Beatmap = new Beatmap + { + HitObjects = new List + { + new Fruit + { + X = CatchPlayfield.CENTER_X * 0.5f, + StartTime = 1000, + }, + new Fruit + { + X = CatchPlayfield.CENTER_X * 1.5f, + StartTime = 2000, + } + } + } + }); + } + [Test] public void TestVisibleDuringBreak() { From 96e81e7f41e825e2ed631a97ab212f13ec30b259 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Jan 2023 01:41:21 +0800 Subject: [PATCH 1287/2991] Switch on NRT and add `IEquatable` to `GetScoresRequest` --- .../Online/API/Requests/GetScoresRequest.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index 7d1d26b75d..f2a2daccb5 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Game.Beatmaps; using osu.Game.Rulesets; @@ -11,10 +9,11 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets.Mods; using System.Text; using System.Collections.Generic; +using System.Linq; namespace osu.Game.Online.API.Requests { - public class GetScoresRequest : APIRequest + public class GetScoresRequest : APIRequest, IEquatable { public const int MAX_SCORES_PER_REQUEST = 50; @@ -23,7 +22,7 @@ namespace osu.Game.Online.API.Requests private readonly IRulesetInfo ruleset; private readonly IEnumerable mods; - public GetScoresRequest(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset, BeatmapLeaderboardScope scope = BeatmapLeaderboardScope.Global, IEnumerable mods = null) + public GetScoresRequest(IBeatmapInfo beatmapInfo, IRulesetInfo ruleset, BeatmapLeaderboardScope scope = BeatmapLeaderboardScope.Global, IEnumerable? mods = null) { if (beatmapInfo.OnlineID <= 0) throw new InvalidOperationException($"Cannot lookup a beatmap's scores without having a populated {nameof(IBeatmapInfo.OnlineID)}."); @@ -51,5 +50,16 @@ namespace osu.Game.Online.API.Requests return query.ToString(); } + + public bool Equals(GetScoresRequest? other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + + return beatmapInfo.Equals(other.beatmapInfo) + && scope == other.scope + && ruleset.Equals(other.ruleset) + && mods.SequenceEqual(other.mods); + } } } From beb3b96aca7366fa812d436103ffbdfa5b682eee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Jan 2023 01:44:00 +0800 Subject: [PATCH 1288/2991] Harden request equality checks --- .../Select/Leaderboards/BeatmapLeaderboard.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs index 9e8247059d..c419501add 100644 --- a/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/BeatmapLeaderboard.cs @@ -152,12 +152,14 @@ namespace osu.Game.Screens.Select.Leaderboards else if (filterMods) requestMods = mods.Value; - scoreRetrievalRequest = new GetScoresRequest(fetchBeatmapInfo, fetchRuleset, Scope, requestMods); + scoreRetrievalRequest?.Cancel(); - scoreRetrievalRequest.Success += response => Schedule(() => + var newRequest = new GetScoresRequest(fetchBeatmapInfo, fetchRuleset, Scope, requestMods); + newRequest.Success += response => Schedule(() => { - // Beatmap may have changed since fetch request. Can't rely on request cancellation due to Schedule inside SetScores. - if (!fetchBeatmapInfo.Equals(BeatmapInfo)) + // Request may have changed since fetch request. + // Can't rely on request cancellation due to Schedule inside SetScores so let's play it safe. + if (!newRequest.Equals(scoreRetrievalRequest)) return; SetScores( @@ -166,7 +168,7 @@ namespace osu.Game.Screens.Select.Leaderboards ); }); - return scoreRetrievalRequest; + return scoreRetrievalRequest = newRequest; } protected override LeaderboardScore CreateDrawableScore(ScoreInfo model, int index) => new LeaderboardScore(model, index, IsOnlineScope) From 49b098407983ec0e39a2b8e19c2df469fe0ba703 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 2 Jan 2023 21:53:58 -0800 Subject: [PATCH 1289/2991] Add failing playlist no selection after deleted test --- .../TestScenePlaylistsRoomSettingsPlaylist.cs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsRoomSettingsPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsRoomSettingsPlaylist.cs index 91e9ce5ea2..ae27db0dd1 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsRoomSettingsPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestScenePlaylistsRoomSettingsPlaylist.cs @@ -3,6 +3,7 @@ #nullable disable +using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -46,10 +47,14 @@ namespace osu.Game.Tests.Visual.Multiplayer AddAssert("item removed", () => !playlist.Items.Contains(selectedItem)); } - [Test] - public void TestNextItemSelectedAfterDeletion() + [TestCase(true)] + [TestCase(false)] + public void TestNextItemSelectedAfterDeletion(bool allowSelection) { - createPlaylist(); + createPlaylist(p => + { + p.AllowSelection = allowSelection; + }); moveToItem(0); AddStep("click", () => InputManager.Click(MouseButton.Left)); @@ -57,7 +62,7 @@ namespace osu.Game.Tests.Visual.Multiplayer moveToDeleteButton(0); AddStep("click delete button", () => InputManager.Click(MouseButton.Left)); - AddAssert("item 0 is selected", () => playlist.SelectedItem.Value == playlist.Items[0]); + AddAssert("item 0 is " + (allowSelection ? "selected" : "not selected"), () => playlist.SelectedItem.Value == (allowSelection ? playlist.Items[0] : null)); } [Test] @@ -117,7 +122,7 @@ namespace osu.Game.Tests.Visual.Multiplayer InputManager.MoveMouseTo(item.ChildrenOfType().ElementAt(0), offset); }); - private void createPlaylist() + private void createPlaylist(Action setupPlaylist = null) { AddStep("create playlist", () => { @@ -154,6 +159,8 @@ namespace osu.Game.Tests.Visual.Multiplayer } }); } + + setupPlaylist?.Invoke(playlist); }); AddUntilStep("wait for items to load", () => playlist.ItemMap.Values.All(i => i.IsLoaded)); From 5dfd4180c84c09bce3ef25803d66ab0168377842 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 2 Jan 2023 21:22:24 -0800 Subject: [PATCH 1290/2991] Fix playlist selecting random item when not allowed after deleting --- .../OnlinePlay/Playlists/PlaylistsRoomSettingsPlaylist.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsPlaylist.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsPlaylist.cs index df502ae09c..736f09584b 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsPlaylist.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsPlaylist.cs @@ -24,7 +24,8 @@ namespace osu.Game.Screens.OnlinePlay.Playlists Items.Remove(item); - SelectedItem.Value = nextItem ?? Items.LastOrDefault(); + if (AllowSelection && SelectedItem.Value == item) + SelectedItem.Value = nextItem ?? Items.LastOrDefault(); }; } } From 5fb6f220e69437c87224e4ae13c4da6205c1f87d Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 2 Jan 2023 21:21:27 -0800 Subject: [PATCH 1291/2991] Fix playlist items not animating when rearranging --- osu.Game/Screens/OnlinePlay/DrawableRoomPlaylist.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylist.cs b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylist.cs index f5477837b0..8abdec9ade 100644 --- a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylist.cs +++ b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylist.cs @@ -156,6 +156,8 @@ namespace osu.Game.Screens.OnlinePlay protected override FillFlowContainer> CreateListFillFlowContainer() => new FillFlowContainer> { + LayoutDuration = 200, + LayoutEasing = Easing.OutQuint, Spacing = new Vector2(0, 2) }; From d70df08f45bb4573bb28ba866036a3cf9527589a Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 4 Jan 2023 16:18:33 +0300 Subject: [PATCH 1292/2991] Tint "argon" slider ball with combo colour --- .../Skinning/Argon/ArgonSliderBall.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderBall.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderBall.cs index 48b43f359d..d6ce793c7e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderBall.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderBall.cs @@ -2,6 +2,8 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; @@ -21,6 +23,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon private readonly Vector2 defaultIconScale = new Vector2(0.6f, 0.8f); + private readonly IBindable accentColour = new Bindable(); + [Resolved(canBeNull: true)] private DrawableHitObject? parentObject { get; set; } @@ -37,7 +41,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon { fill = new Box { - Colour = ColourInfo.GradientVertical(Colour4.FromHex("FC618F"), Colour4.FromHex("BB1A41")), RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -53,10 +56,22 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon }; } + [BackgroundDependencyLoader] + private void load() + { + if (parentObject != null) + accentColour.BindTo(parentObject.AccentColour); + } + protected override void LoadComplete() { base.LoadComplete(); + accentColour.BindValueChanged(colour => + { + fill.Colour = ColourInfo.GradientVertical(colour.NewValue, colour.NewValue.Darken(0.5f)); + }, true); + if (parentObject != null) { parentObject.ApplyCustomUpdateState += updateStateTransforms; From 760b2d98df1908064a89b54cffcec2befecff943 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 4 Jan 2023 16:19:30 +0300 Subject: [PATCH 1293/2991] Tint "argon" slider follow circle with combo colour --- .../Skinning/Argon/ArgonFollowCircle.cs | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonFollowCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonFollowCircle.cs index 95c75164aa..fca3e70236 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonFollowCircle.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonFollowCircle.cs @@ -1,35 +1,64 @@ // 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Utils; +using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables; +using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Argon { public partial class ArgonFollowCircle : FollowCircle { + private readonly CircularContainer circleContainer; + private readonly Box circleFill; + + private readonly IBindable accentColour = new Bindable(); + + [Resolved(canBeNull: true)] + private DrawableHitObject? parentObject { get; set; } + public ArgonFollowCircle() { - InternalChild = new CircularContainer + InternalChild = circleContainer = new CircularContainer { RelativeSizeAxes = Axes.Both, Masking = true, BorderThickness = 4, - BorderColour = ColourInfo.GradientVertical(Colour4.FromHex("FC618F"), Colour4.FromHex("BB1A41")), Blending = BlendingParameters.Additive, - Child = new Box + Child = circleFill = new Box { - Colour = ColourInfo.GradientVertical(Colour4.FromHex("FC618F"), Colour4.FromHex("BB1A41")), RelativeSizeAxes = Axes.Both, Alpha = 0.3f, } }; } + [BackgroundDependencyLoader] + private void load() + { + if (parentObject != null) + accentColour.BindTo(parentObject.AccentColour); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + accentColour.BindValueChanged(colour => + { + circleContainer.BorderColour = ColourInfo.GradientVertical(colour.NewValue, colour.NewValue.Darken(0.5f)); + circleFill.Colour = ColourInfo.GradientVertical(colour.NewValue, colour.NewValue.Darken(0.5f)); + }, true); + } + protected override void OnSliderPress() { const float duration = 300f; From 39221a52dacdc4232f071ab03cac9c70aea8ada6 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 5 Jan 2023 12:49:45 +0300 Subject: [PATCH 1294/2991] Fix advanced statistics display using decoupled ruleset bindable for difficulty calculation --- osu.Game/OsuGameBase.cs | 5 ++++- .../Screens/Select/Details/AdvancedStats.cs | 20 +++++++++++++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 36e248c1f2..83a32dd557 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -160,9 +160,12 @@ namespace osu.Game protected Bindable Beatmap { get; private set; } // cached via load() method + /// + /// The current ruleset selection for the local user. + /// [Cached] [Cached(typeof(IBindable))] - protected readonly Bindable Ruleset = new Bindable(); + protected internal readonly Bindable Ruleset = new Bindable(); /// /// The current mod selection for the local user. diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index 5d0588e67b..3d45679604 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -30,14 +30,16 @@ namespace osu.Game.Screens.Select.Details { public partial class AdvancedStats : Container { + [Resolved] + private BeatmapDifficultyCache difficultyCache { get; set; } + [Resolved] private IBindable> mods { get; set; } [Resolved] - private IBindable ruleset { get; set; } + private OsuGameBase game { get; set; } - [Resolved] - private BeatmapDifficultyCache difficultyCache { get; set; } + private IBindable gameRuleset; protected readonly StatisticRow FirstValue, HpDrain, Accuracy, ApproachRate; private readonly StatisticRow starDifficulty; @@ -84,7 +86,13 @@ namespace osu.Game.Screens.Select.Details { base.LoadComplete(); - ruleset.BindValueChanged(_ => updateStatistics()); + // the cached ruleset bindable might be a decoupled bindable provided by SongSelect, + // which we can't rely on in combination with the game-wide selected mods list, + // since mods could be updated to the new ruleset instances while the decoupled bindable is held behind, + // therefore resulting in performing difficulty calculation with invalid states. + gameRuleset = game.Ruleset.GetBoundCopy(); + gameRuleset.BindValueChanged(_ => updateStatistics()); + mods.BindValueChanged(modsChanged, true); } @@ -151,8 +159,8 @@ namespace osu.Game.Screens.Select.Details starDifficultyCancellationSource = new CancellationTokenSource(); - var normalStarDifficultyTask = difficultyCache.GetDifficultyAsync(BeatmapInfo, ruleset.Value, null, starDifficultyCancellationSource.Token); - var moddedStarDifficultyTask = difficultyCache.GetDifficultyAsync(BeatmapInfo, ruleset.Value, mods.Value, starDifficultyCancellationSource.Token); + var normalStarDifficultyTask = difficultyCache.GetDifficultyAsync(BeatmapInfo, gameRuleset.Value, null, starDifficultyCancellationSource.Token); + var moddedStarDifficultyTask = difficultyCache.GetDifficultyAsync(BeatmapInfo, gameRuleset.Value, mods.Value, starDifficultyCancellationSource.Token); Task.WhenAll(normalStarDifficultyTask, moddedStarDifficultyTask).ContinueWith(_ => Schedule(() => { From 8f37e69dc4e8c7804098a7415deb838a33f4933e Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 5 Jan 2023 12:50:38 +0300 Subject: [PATCH 1295/2991] Schedule difficulty calculation to avoid performing with incomplete state updates --- osu.Game/Screens/Select/Details/AdvancedStats.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index 3d45679604..a383298faa 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -150,7 +150,14 @@ namespace osu.Game.Screens.Select.Details private CancellationTokenSource starDifficultyCancellationSource; - private void updateStarDifficulty() + /// + /// Updates the displayed star difficulty statistics with the values provided by the currently-selected beatmap, ruleset, and selected mods. + /// + /// + /// This is scheduled to avoid scenarios wherein a ruleset changes first before selected mods do, + /// potentially resulting in failure during difficulty calculation due to incomplete bindable state updates. + /// + private void updateStarDifficulty() => Scheduler.AddOnce(() => { starDifficultyCancellationSource?.Cancel(); @@ -172,7 +179,7 @@ namespace osu.Game.Screens.Select.Details starDifficulty.Value = ((float)normalDifficulty.Value.Stars, (float)moddedDifficulty.Value.Stars); }), starDifficultyCancellationSource.Token, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Current); - } + }); protected override void Dispose(bool isDisposing) { From 8da7667b0b84392004fe23ada51191b69d6ebb7a Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 5 Jan 2023 14:06:24 +0300 Subject: [PATCH 1296/2991] Decrease transition duration of extended difficulty list during hide --- .../Drawables/Cards/BeatmapCardContent.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs index d4cbe6ddd0..7deb5f768c 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardContent.cs @@ -138,9 +138,18 @@ namespace osu.Game.Beatmaps.Drawables.Cards // This avoids depth issues where a hovered (scaled) card to the right of another card would be beneath the card to the left. this.ScaleTo(Expanded.Value ? 1.03f : 1, 500, Easing.OutQuint); - background.FadeTo(Expanded.Value ? 1 : 0, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); - dropdownContent.FadeTo(Expanded.Value ? 1 : 0, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); - borderContainer.FadeTo(Expanded.Value ? 1 : 0, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); + if (Expanded.Value) + { + background.FadeIn(BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); + dropdownContent.FadeIn(BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); + borderContainer.FadeIn(BeatmapCard.TRANSITION_DURATION, Easing.OutQuint); + } + else + { + background.FadeOut(BeatmapCard.TRANSITION_DURATION / 3f, Easing.OutQuint); + dropdownContent.FadeOut(BeatmapCard.TRANSITION_DURATION / 3f, Easing.OutQuint); + borderContainer.FadeOut(BeatmapCard.TRANSITION_DURATION / 3f, Easing.OutQuint); + } content.TweenEdgeEffectTo(new EdgeEffectParameters { From 7d8aff8f7e75b6f5517eeb91a97cf09a401a8587 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 5 Jan 2023 14:35:57 +0300 Subject: [PATCH 1297/2991] Fix settings toolbox group not animating on expansion --- osu.Game/Overlays/SettingsToolboxGroup.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/SettingsToolboxGroup.cs b/osu.Game/Overlays/SettingsToolboxGroup.cs index 56c890e9e2..86964e7ed4 100644 --- a/osu.Game/Overlays/SettingsToolboxGroup.cs +++ b/osu.Game/Overlays/SettingsToolboxGroup.cs @@ -126,7 +126,8 @@ namespace osu.Game.Overlays { base.LoadComplete(); - Expanded.BindValueChanged(updateExpandedState, true); + Expanded.BindValueChanged(_ => updateExpandedState(true)); + updateExpandedState(false); this.Delay(600).Schedule(updateFadeState); } @@ -161,21 +162,25 @@ namespace osu.Game.Overlays return base.OnInvalidate(invalidation, source); } - private void updateExpandedState(ValueChangedEvent expanded) + private void updateExpandedState(bool animate) { // clearing transforms is necessary to avoid a previous height transform // potentially continuing to get processed while content has changed to autosize. content.ClearTransforms(); - if (expanded.NewValue) + if (Expanded.Value) + { content.AutoSizeAxes = Axes.Y; + content.AutoSizeDuration = animate ? transition_duration : 0; + content.AutoSizeEasing = Easing.OutQuint; + } else { content.AutoSizeAxes = Axes.None; - content.ResizeHeightTo(0, transition_duration, Easing.OutQuint); + content.ResizeHeightTo(0, animate ? transition_duration : 0, Easing.OutQuint); } - headerContent.FadeColour(expanded.NewValue ? Color4.White : OsuColour.Gray(0.5f), 200, Easing.OutQuint); + headerContent.FadeColour(Expanded.Value ? Color4.White : OsuColour.Gray(0.5f), 200, Easing.OutQuint); } private void updateFadeState() From 86b1164e28b5f33fd0f0f11a03bf6b854ac1235f Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 5 Jan 2023 14:41:26 +0300 Subject: [PATCH 1298/2991] Add visual test case --- .../UserInterface/TestSceneSettingsToolboxGroup.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsToolboxGroup.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsToolboxGroup.cs index 71b98ed9af..f96d2feba8 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsToolboxGroup.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSettingsToolboxGroup.cs @@ -55,6 +55,16 @@ namespace osu.Game.Tests.Visual.UserInterface }; }); + [Test] + public void TestDisplay() + { + AddRepeatStep("toggle expanded state", () => + { + InputManager.MoveMouseTo(group.ChildrenOfType().Single()); + InputManager.Click(MouseButton.Left); + }, 5); + } + [Test] public void TestClickExpandButtonMultipleTimes() { From c6e2104ec298647d6a0bb48b86846bbdf6ea7707 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 6 Jan 2023 03:46:49 +0300 Subject: [PATCH 1299/2991] Refresh waveforms instead of recreating the whole component --- .../Screens/Edit/Timing/TapTimingControl.cs | 19 ++----------------- .../Edit/Timing/WaveformComparisonDisplay.cs | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs index 0d29b69d96..bb7a3b8be3 100644 --- a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs +++ b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs @@ -3,7 +3,6 @@ using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -30,15 +29,12 @@ namespace osu.Game.Screens.Edit.Timing [Resolved] private Bindable selectedGroup { get; set; } = null!; - private readonly IBindable track = new Bindable(); - private readonly BindableBool isHandlingTapping = new BindableBool(); private MetronomeDisplay metronome = null!; - private Container waveformContainer = null!; [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider, OsuColour colours, EditorClock clock) + private void load(OverlayColourProvider colourProvider, OsuColour colours) { const float padding = 10; @@ -92,11 +88,7 @@ namespace osu.Game.Screens.Edit.Timing Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, }, - waveformContainer = new Container - { - RelativeSizeAxes = Axes.Both, - Child = new WaveformComparisonDisplay(), - } + new WaveformComparisonDisplay() } }, } @@ -187,13 +179,6 @@ namespace osu.Game.Screens.Edit.Timing if (handling.NewValue) start(); }, true); - - track.BindTo(clock.Track); - } - - protected override void LoadComplete() - { - track.ValueChanged += _ => waveformContainer.Child = new WaveformComparisonDisplay(); } private void start() diff --git a/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs b/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs index 6c17aeed54..b5a1ab29d2 100644 --- a/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs +++ b/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs @@ -4,6 +4,7 @@ using System; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Audio; @@ -294,13 +295,18 @@ namespace osu.Game.Screens.Edit.Timing [Resolved] private OverlayColourProvider colourProvider { get; set; } = null!; + [Resolved] + private IBindable beatmap { get; set; } = null!; + + private readonly IBindable track = new Bindable(); + public WaveformRow(bool isMainRow) { this.isMainRow = isMainRow; } [BackgroundDependencyLoader] - private void load(IBindable beatmap) + private void load(EditorClock clock) { InternalChildren = new Drawable[] { @@ -330,6 +336,13 @@ namespace osu.Game.Screens.Edit.Timing Colour = colourProvider.Content2 } }; + + track.BindTo(clock.Track); + } + + protected override void LoadComplete() + { + track.ValueChanged += _ => waveformGraph.Waveform = beatmap.Value.Waveform; } public int BeatIndex { set => beatIndexText.Text = value.ToString(); } From 408356d05e0d2f7a1178c99dc34b66e2b944324d Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 6 Jan 2023 11:58:38 +0300 Subject: [PATCH 1300/2991] Fix gameplay leaderboard showing "-" on non-tracked scores --- osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs | 4 ++-- osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs index f6f289db55..d990af32e7 100644 --- a/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/GameplayLeaderboard.cs @@ -171,13 +171,13 @@ namespace osu.Game.Screens.Play.HUD for (int i = 0; i < Flow.Count; i++) { Flow.SetLayoutPosition(orderedByScore[i], i); - orderedByScore[i].ScorePosition = CheckValidScorePosition(i + 1) ? i + 1 : null; + orderedByScore[i].ScorePosition = CheckValidScorePosition(orderedByScore[i], i + 1) ? i + 1 : null; } sorting.Validate(); } - protected virtual bool CheckValidScorePosition(int i) => true; + protected virtual bool CheckValidScorePosition(GameplayLeaderboardScore score, int position) => true; private partial class InputDisabledScrollContainer : OsuScrollContainer { diff --git a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs index 0f3e54ecdd..9f92880919 100644 --- a/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs +++ b/osu.Game/Screens/Play/HUD/SoloGameplayLeaderboard.cs @@ -100,16 +100,16 @@ namespace osu.Game.Screens.Play.HUD local.DisplayOrder.Value = long.MaxValue; } - protected override bool CheckValidScorePosition(int i) + protected override bool CheckValidScorePosition(GameplayLeaderboardScore score, int position) { // change displayed position to '-' when there are 50 already submitted scores and tracked score is last - if (scoreSource.Value != PlayBeatmapDetailArea.TabType.Local) + if (score.Tracked && scoreSource.Value != PlayBeatmapDetailArea.TabType.Local) { - if (i == Flow.Count && Flow.Count > GetScoresRequest.MAX_SCORES_PER_REQUEST) + if (position == Flow.Count && Flow.Count > GetScoresRequest.MAX_SCORES_PER_REQUEST) return false; } - return base.CheckValidScorePosition(i); + return base.CheckValidScorePosition(score, position); } private void updateVisibility() => From 458fe382ed51b110fc476013c7db32fe8b69926b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Jan 2023 20:06:41 +0900 Subject: [PATCH 1301/2991] Make selected tab items more bold --- osu.Game/Overlays/BeatmapListing/FilterTabItem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs b/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs index 7b95ae8ea8..042efb18fb 100644 --- a/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs +++ b/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs @@ -81,7 +81,7 @@ namespace osu.Game.Overlays.BeatmapListing private void updateState() { text.FadeColour(IsHovered ? colourProvider.Light1 : GetStateColour(), 200, Easing.OutQuint); - text.Font = text.Font.With(weight: Active.Value ? FontWeight.SemiBold : FontWeight.Regular); + text.Font = text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Regular); } protected virtual Color4 GetStateColour() => Active.Value ? colourProvider.Content1 : colourProvider.Light2; From 3c74d27deb556d93c52f7b10f33f7d38c7b5848f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Jan 2023 20:35:58 +0900 Subject: [PATCH 1302/2991] Also add an underline to better accent current filters --- ...BeatmapSearchMultipleSelectionFilterRow.cs | 23 +++++++++++++++++++ .../Overlays/BeatmapListing/FilterTabItem.cs | 12 +++++----- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs index 5d1ccbd58b..c6cd6591a9 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs @@ -12,6 +12,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Framework.Localisation; using osuTK; @@ -100,9 +101,31 @@ namespace osu.Game.Overlays.BeatmapListing protected partial class MultipleSelectionFilterTabItem : FilterTabItem { + private readonly Box selectedUnderline; + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } + public MultipleSelectionFilterTabItem(T value) : base(value) { + // This doesn't match any actual design, but should make it easier for the user to understand + // that filters are applied until we settle on a final design. + AddInternal(selectedUnderline = new Box + { + Depth = float.MaxValue, + RelativeSizeAxes = Axes.X, + Height = 1.5f, + Anchor = Anchor.BottomLeft, + Origin = Anchor.CentreLeft, + }); + } + + protected override void UpdateState() + { + base.UpdateState(); + selectedUnderline.FadeTo(Active.Value ? 1 : 0, 200, Easing.OutQuint); + selectedUnderline.FadeColour(IsHovered ? colourProvider.Light1 : GetStateColour(), 200, Easing.OutQuint); } protected override bool OnClick(ClickEvent e) diff --git a/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs b/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs index 7b95ae8ea8..34ade0596d 100644 --- a/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs +++ b/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs @@ -52,33 +52,33 @@ namespace osu.Game.Overlays.BeatmapListing { base.LoadComplete(); - updateState(); + UpdateState(); FinishTransforms(true); } protected override bool OnHover(HoverEvent e) { base.OnHover(e); - updateState(); + UpdateState(); return true; } protected override void OnHoverLost(HoverLostEvent e) { base.OnHoverLost(e); - updateState(); + UpdateState(); } - protected override void OnActivated() => updateState(); + protected override void OnActivated() => UpdateState(); - protected override void OnDeactivated() => updateState(); + protected override void OnDeactivated() => UpdateState(); /// /// Returns the label text to be used for the supplied . /// protected virtual LocalisableString LabelFor(T value) => (value as Enum)?.GetLocalisableDescription() ?? value.ToString(); - private void updateState() + protected virtual void UpdateState() { text.FadeColour(IsHovered ? colourProvider.Light1 : GetStateColour(), 200, Easing.OutQuint); text.Font = text.Font.With(weight: Active.Value ? FontWeight.SemiBold : FontWeight.Regular); From 4319937bc79a1eabc6ffbba40566087938c14323 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 6 Jan 2023 20:35:58 +0900 Subject: [PATCH 1303/2991] Also add an underline to better accent current filters --- ...BeatmapSearchMultipleSelectionFilterRow.cs | 23 +++++++++++++++++++ .../Overlays/BeatmapListing/FilterTabItem.cs | 12 +++++----- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs index 5d1ccbd58b..c6cd6591a9 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs @@ -12,6 +12,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Framework.Localisation; using osuTK; @@ -100,9 +101,31 @@ namespace osu.Game.Overlays.BeatmapListing protected partial class MultipleSelectionFilterTabItem : FilterTabItem { + private readonly Box selectedUnderline; + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } + public MultipleSelectionFilterTabItem(T value) : base(value) { + // This doesn't match any actual design, but should make it easier for the user to understand + // that filters are applied until we settle on a final design. + AddInternal(selectedUnderline = new Box + { + Depth = float.MaxValue, + RelativeSizeAxes = Axes.X, + Height = 1.5f, + Anchor = Anchor.BottomLeft, + Origin = Anchor.CentreLeft, + }); + } + + protected override void UpdateState() + { + base.UpdateState(); + selectedUnderline.FadeTo(Active.Value ? 1 : 0, 200, Easing.OutQuint); + selectedUnderline.FadeColour(IsHovered ? colourProvider.Light1 : GetStateColour(), 200, Easing.OutQuint); } protected override bool OnClick(ClickEvent e) diff --git a/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs b/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs index 042efb18fb..9a697890f3 100644 --- a/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs +++ b/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs @@ -52,33 +52,33 @@ namespace osu.Game.Overlays.BeatmapListing { base.LoadComplete(); - updateState(); + UpdateState(); FinishTransforms(true); } protected override bool OnHover(HoverEvent e) { base.OnHover(e); - updateState(); + UpdateState(); return true; } protected override void OnHoverLost(HoverLostEvent e) { base.OnHoverLost(e); - updateState(); + UpdateState(); } - protected override void OnActivated() => updateState(); + protected override void OnActivated() => UpdateState(); - protected override void OnDeactivated() => updateState(); + protected override void OnDeactivated() => UpdateState(); /// /// Returns the label text to be used for the supplied . /// protected virtual LocalisableString LabelFor(T value) => (value as Enum)?.GetLocalisableDescription() ?? value.ToString(); - private void updateState() + protected virtual void UpdateState() { text.FadeColour(IsHovered ? colourProvider.Light1 : GetStateColour(), 200, Easing.OutQuint); text.Font = text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Regular); From 0ade4d92d1f70a4943c49e06643996c70bc0c010 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 6 Jan 2023 15:13:31 +0300 Subject: [PATCH 1304/2991] Fix multiple highlighting issues with beatmap listing tab items --- .../BeatmapSearchMultipleSelectionFilterRow.cs | 5 ++--- osu.Game/Overlays/BeatmapListing/FilterTabItem.cs | 10 +++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs index c6cd6591a9..abd2643a41 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchMultipleSelectionFilterRow.cs @@ -103,8 +103,7 @@ namespace osu.Game.Overlays.BeatmapListing { private readonly Box selectedUnderline; - [Resolved] - private OverlayColourProvider colourProvider { get; set; } + protected override bool HighlightOnHoverWhenActive => true; public MultipleSelectionFilterTabItem(T value) : base(value) @@ -125,7 +124,7 @@ namespace osu.Game.Overlays.BeatmapListing { base.UpdateState(); selectedUnderline.FadeTo(Active.Value ? 1 : 0, 200, Easing.OutQuint); - selectedUnderline.FadeColour(IsHovered ? colourProvider.Light1 : GetStateColour(), 200, Easing.OutQuint); + selectedUnderline.FadeColour(IsHovered ? ColourProvider.Content2 : GetStateColour(), 200, Easing.OutQuint); } protected override bool OnClick(ClickEvent e) diff --git a/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs b/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs index 34ade0596d..a97b2e16c3 100644 --- a/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs +++ b/osu.Game/Overlays/BeatmapListing/FilterTabItem.cs @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.BeatmapListing public partial class FilterTabItem : TabItem { [Resolved] - private OverlayColourProvider colourProvider { get; set; } + protected OverlayColourProvider ColourProvider { get; private set; } private OsuSpriteText text; @@ -78,12 +78,16 @@ namespace osu.Game.Overlays.BeatmapListing /// protected virtual LocalisableString LabelFor(T value) => (value as Enum)?.GetLocalisableDescription() ?? value.ToString(); + protected virtual bool HighlightOnHoverWhenActive => false; + protected virtual void UpdateState() { - text.FadeColour(IsHovered ? colourProvider.Light1 : GetStateColour(), 200, Easing.OutQuint); + bool highlightHover = IsHovered && (!Active.Value || HighlightOnHoverWhenActive); + + text.FadeColour(highlightHover ? ColourProvider.Content2 : GetStateColour(), 200, Easing.OutQuint); text.Font = text.Font.With(weight: Active.Value ? FontWeight.SemiBold : FontWeight.Regular); } - protected virtual Color4 GetStateColour() => Active.Value ? colourProvider.Content1 : colourProvider.Light2; + protected virtual Color4 GetStateColour() => Active.Value ? ColourProvider.Content1 : ColourProvider.Light2; } } From e90c698e62974d630865fe8962f4926e321ca345 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 6 Jan 2023 16:35:39 +0300 Subject: [PATCH 1305/2991] Fix WCD does not take into account start time of control points --- osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs b/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs index b5a1ab29d2..3b3acea935 100644 --- a/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs +++ b/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs @@ -151,7 +151,7 @@ namespace osu.Game.Screens.Edit.Timing if (!displayLocked.Value) { float trackLength = (float)beatmap.Value.Track.Length; - int totalBeatsAvailable = (int)(trackLength / timingPoint.BeatLength); + int totalBeatsAvailable = (int)((trackLength - timingPoint.Time) / timingPoint.BeatLength); Scheduler.AddOnce(showFromBeat, (int)(e.MousePosition.X / DrawWidth * totalBeatsAvailable)); } From 9364c7775d57e18e1abea1b7d5fe0d1416c45f03 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 6 Jan 2023 19:26:30 +0300 Subject: [PATCH 1306/2991] Refresh background on file change in editor --- .../Screens/Backgrounds/BackgroundScreenBeatmap.cs | 12 ++++++++++++ osu.Game/Screens/Edit/Setup/ResourcesSection.cs | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs index 42a81ad3fa..312fd496a1 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs @@ -99,6 +99,18 @@ namespace osu.Game.Screens.Backgrounds } } + /// + /// Reloads beatmap's background. + /// + public void RefreshBackground() + { + Schedule(() => + { + cancellationSource?.Cancel(); + LoadComponentAsync(new BeatmapBackground(beatmap), switchBackground, (cancellationSource = new CancellationTokenSource()).Token); + }); + } + private void switchBackground(BeatmapBackground b) { float newDepth = 0; diff --git a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs index ca0f50cd34..c79d9d6632 100644 --- a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs +++ b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs @@ -33,6 +33,9 @@ namespace osu.Game.Screens.Edit.Setup [Resolved] private EditorBeatmap editorBeatmap { get; set; } + [Resolved] + private Editor editor { get; set; } + [Resolved] private SetupScreenHeader header { get; set; } @@ -93,6 +96,8 @@ namespace osu.Game.Screens.Edit.Setup working.Value.Metadata.BackgroundFile = destination.Name; header.Background.UpdateBackground(); + editor.ApplyToBackground(bg => bg.RefreshBackground()); + return true; } From b8fbd68e325018606a5b2de181c0d64a7f0a9c16 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Fri, 6 Jan 2023 11:39:41 -0500 Subject: [PATCH 1307/2991] reduce mania hidden mod precision --- osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs index 76a102bda3..2eb9e6d1eb 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Mods [SettingSource("Coverage", "The proportion of playfield height that notes will be hidden for.")] public BindableNumber CoverageAmount { get; } = new BindableFloat(0.5f) { - Precision = 0.01f, + Precision = 0.1f, MinValue = 0.2f, MaxValue = 0.8f, Default = 0.5f, From 53d7dcefe5c4d4da6c0a642bf9556e419a3cb2ce Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Thu, 5 Jan 2023 14:40:18 -0800 Subject: [PATCH 1308/2991] Fix osu! logo not being draggable on player loader --- osu.Game/Screens/Menu/OsuLogo.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 2d6a0736e9..7a5a26226b 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -282,7 +282,7 @@ namespace osu.Game.Screens.Menu if (beatIndex < 0) return; - if (IsHovered) + if (Action != null && IsHovered) { this.Delay(early_activation).Schedule(() => { @@ -361,11 +361,11 @@ namespace osu.Game.Screens.Menu } } - public override bool HandlePositionalInput => base.HandlePositionalInput && Action != null && Alpha > 0.2f; + public override bool HandlePositionalInput => base.HandlePositionalInput && Alpha > 0.2f; protected override bool OnMouseDown(MouseDownEvent e) { - if (e.Button != MouseButton.Left) return false; + if (Action == null || e.Button != MouseButton.Left) return false; logoBounceContainer.ScaleTo(0.9f, 1000, Easing.Out); return true; @@ -380,7 +380,9 @@ namespace osu.Game.Screens.Menu protected override bool OnClick(ClickEvent e) { - if (Action?.Invoke() ?? true) + if (Action == null) return false; + + if (Action.Invoke()) sampleClick.Play(); flashLayer.ClearTransforms(); @@ -391,6 +393,8 @@ namespace osu.Game.Screens.Menu protected override bool OnHover(HoverEvent e) { + if (Action == null) return false; + logoHoverContainer.ScaleTo(1.1f, 500, Easing.OutElastic); return true; } From 7f970f3cd846068bb775586f398e8fce73329089 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Thu, 29 Dec 2022 21:17:24 -0800 Subject: [PATCH 1309/2991] Display nominators on beatmap set overlay --- .../API/Requests/Responses/APIBeatmapSet.cs | 6 ++ .../Responses/BeatmapSetOnlineNominations.cs | 22 +++++++ osu.Game/Overlays/BeatmapSet/Info.cs | 4 ++ .../BeatmapSet/MetadataSectionNominators.cs | 62 +++++++++++++++++++ osu.Game/Overlays/BeatmapSet/MetadataType.cs | 5 +- 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Online/API/Requests/Responses/BeatmapSetOnlineNominations.cs create mode 100644 osu.Game/Overlays/BeatmapSet/MetadataSectionNominators.cs diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index 717a1de6b5..eb39b7489d 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -111,6 +111,12 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"language")] public BeatmapSetOnlineLanguage Language { get; set; } + [JsonProperty(@"current_nominations")] + public BeatmapSetOnlineNominations[] CurrentNominations { get; set; } = Array.Empty(); + + [JsonProperty(@"related_users")] + public APIUser[] RelatedUsers { get; set; } = Array.Empty(); + public string Source { get; set; } = string.Empty; [JsonProperty(@"tags")] diff --git a/osu.Game/Online/API/Requests/Responses/BeatmapSetOnlineNominations.cs b/osu.Game/Online/API/Requests/Responses/BeatmapSetOnlineNominations.cs new file mode 100644 index 0000000000..5d0a3ea38b --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/BeatmapSetOnlineNominations.cs @@ -0,0 +1,22 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Newtonsoft.Json; + +namespace osu.Game.Online.API.Requests.Responses +{ + public struct BeatmapSetOnlineNominations + { + [JsonProperty(@"beatmapset_id")] + public int BeatmapsetId { get; set; } + + [JsonProperty(@"reset")] + public bool Reset { get; set; } + + [JsonProperty(@"rulesets")] + public string[]? Rulesets { get; set; } + + [JsonProperty(@"user_id")] + public int UserId { get; set; } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index d184f0d0fd..dbeea74f6f 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -3,6 +3,7 @@ #nullable disable +using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -36,6 +37,7 @@ namespace osu.Game.Overlays.BeatmapSet public Info() { + MetadataSectionNominators nominators; MetadataSection source, tags; MetadataSectionGenre genre; MetadataSectionLanguage language; @@ -82,6 +84,7 @@ namespace osu.Game.Overlays.BeatmapSet Direction = FillDirection.Full, Children = new Drawable[] { + nominators = new MetadataSectionNominators(), source = new MetadataSectionSource(), genre = new MetadataSectionGenre { Width = 0.5f }, language = new MetadataSectionLanguage { Width = 0.5f }, @@ -122,6 +125,7 @@ namespace osu.Game.Overlays.BeatmapSet BeatmapSet.ValueChanged += b => { + nominators.Metadata = (b.NewValue?.CurrentNominations ?? Array.Empty(), b.NewValue?.RelatedUsers ?? Array.Empty()); source.Metadata = b.NewValue?.Source ?? string.Empty; tags.Metadata = b.NewValue?.Tags ?? string.Empty; genre.Metadata = b.NewValue?.Genre ?? new BeatmapSetOnlineGenre { Id = (int)SearchGenre.Unspecified }; diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSectionNominators.cs b/osu.Game/Overlays/BeatmapSet/MetadataSectionNominators.cs new file mode 100644 index 0000000000..78a3fe7cd5 --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/MetadataSectionNominators.cs @@ -0,0 +1,62 @@ +// 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.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Resources.Localisation.Web; + +namespace osu.Game.Overlays.BeatmapSet +{ + public partial class MetadataSectionNominators : MetadataSection<(BeatmapSetOnlineNominations[] CurrentNominations, APIUser[] RelatedUsers)> + { + public override (BeatmapSetOnlineNominations[] CurrentNominations, APIUser[] RelatedUsers) Metadata + { + set + { + if (value.CurrentNominations.Length == 0) + { + this.FadeOut(TRANSITION_DURATION); + return; + } + + base.Metadata = value; + } + } + + public MetadataSectionNominators(Action<(BeatmapSetOnlineNominations[] CurrentNominations, APIUser[] RelatedUsers)>? searchAction = null) + : base(MetadataType.Nominators, searchAction) + { + } + + protected override void AddMetadata((BeatmapSetOnlineNominations[] CurrentNominations, APIUser[] RelatedUsers) metadata, LinkFlowContainer loaded) + { + int[] nominatorIds = metadata.CurrentNominations.Select(n => n.UserId).ToArray(); + + int nominatorsFound = 0; + + foreach (int nominatorId in nominatorIds) + { + foreach (var user in metadata.RelatedUsers) + { + if (nominatorId != user.OnlineID) continue; + + nominatorsFound++; + + loaded.AddUserLink(new APIUser + { + Username = user.Username, + Id = nominatorId, + }); + + if (nominatorsFound < nominatorIds.Length) + loaded.AddText(CommonStrings.ArrayAndWordsConnector); + + break; + } + } + } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/MetadataType.cs b/osu.Game/Overlays/BeatmapSet/MetadataType.cs index 924e020641..dc96ce99e9 100644 --- a/osu.Game/Overlays/BeatmapSet/MetadataType.cs +++ b/osu.Game/Overlays/BeatmapSet/MetadataType.cs @@ -23,6 +23,9 @@ namespace osu.Game.Overlays.BeatmapSet Genre, [LocalisableDescription(typeof(BeatmapsetsStrings), nameof(BeatmapsetsStrings.ShowInfoLanguage))] - Language + Language, + + [LocalisableDescription(typeof(BeatmapsetsStrings), nameof(BeatmapsetsStrings.ShowInfoNominators))] + Nominators, } } From e449d8dda067cc671b648330e6089d3e5f53cf9c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 6 Jan 2023 22:39:46 +0300 Subject: [PATCH 1310/2991] Fix friends list duplicating on connection failure --- osu.Game/Online/API/APIAccess.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index f2b9b6e968..757f6598e7 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -259,7 +259,11 @@ namespace osu.Game.Online.API var friendsReq = new GetFriendsRequest(); friendsReq.Failure += _ => state.Value = APIState.Failing; - friendsReq.Success += res => friends.AddRange(res); + friendsReq.Success += res => + { + friends.Clear(); + friends.AddRange(res); + }; if (!handleRequest(friendsReq)) { From 387326db0d2b0c307e642649b065771ee7e7c682 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 6 Jan 2023 22:51:57 +0300 Subject: [PATCH 1311/2991] Make commit action abstract --- .../Visual/UserInterface/TestSceneCommentEditor.cs | 12 ++++++------ osu.Game/Overlays/Comments/CommentEditor.cs | 13 ++++--------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index a0a1c2481f..aeaca5ac21 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -118,12 +118,7 @@ namespace osu.Game.Tests.Visual.UserInterface public bool ButtonLoading => CommitButton.ChildrenOfType().Single().IsPresent && !CommitButton.ChildrenOfType().Single().IsPresent; - public TestCommentEditor() - { - OnCommit = onCommit; - } - - private void onCommit(string value) + protected override void OnCommit(string value) { CommitButton.IsLoadingSpinnerShown = true; CommittedText = value; @@ -138,6 +133,7 @@ namespace osu.Game.Tests.Visual.UserInterface private partial class TestCancellableCommentEditor : CancellableCommentEditor { public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; + protected override LocalisableString FooterText => @"Wow, another one. Sicc"; public bool Cancelled { get; private set; } @@ -147,6 +143,10 @@ namespace osu.Game.Tests.Visual.UserInterface OnCancel = () => Cancelled = true; } + protected override void OnCommit(string text) + { + } + protected override LocalisableString CommitButtonText => @"Save"; protected override LocalisableString TextBoxPlaceholder => @"Multiline textboxes soon"; } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 092a92f935..c7c66874d1 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.Sprites; using osuTK.Graphics; using osu.Game.Graphics.UserInterface; -using System; using osuTK; using osu.Framework.Bindables; using osu.Framework.Localisation; @@ -23,8 +22,6 @@ namespace osu.Game.Overlays.Comments { private const int side_padding = 8; - public Action? OnCommit; - protected abstract LocalisableString FooterText { get; } protected abstract LocalisableString CommitButtonText { get; } @@ -98,11 +95,7 @@ namespace osu.Game.Overlays.Comments Text = CommitButtonText, Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - Action = () => - { - OnCommit?.Invoke(Current.Value); - Current.Value = string.Empty; - } + Action = () => OnCommit(Current.Value) } } } @@ -121,6 +114,8 @@ namespace osu.Game.Overlays.Comments Current.BindValueChanged(text => CommitButton.IsBlocked.Value = string.IsNullOrEmpty(text.NewValue), true); } + protected abstract void OnCommit(string text); + private partial class EditorTextBox : BasicTextBox { protected override float LeftRightPadding => side_padding; @@ -151,7 +146,7 @@ namespace osu.Game.Overlays.Comments protected override Drawable GetDrawableCharacter(char c) => new FallingDownContainer { AutoSizeAxes = Axes.Both, - Child = new OsuSpriteText { Text = c.ToString(), Font = OsuFont.GetFont(size: CalculatedTextSize) }, + Child = new OsuSpriteText { Text = c.ToString(), Font = OsuFont.GetFont(size: CalculatedTextSize) } }; } From 768a33bb64a5fef23201c5224bd53336eb80e133 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 6 Jan 2023 23:31:19 +0300 Subject: [PATCH 1312/2991] Add request class --- .../Online/API/Requests/CommentPostRequest.cs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 osu.Game/Online/API/Requests/CommentPostRequest.cs diff --git a/osu.Game/Online/API/Requests/CommentPostRequest.cs b/osu.Game/Online/API/Requests/CommentPostRequest.cs new file mode 100644 index 0000000000..bd69c04bed --- /dev/null +++ b/osu.Game/Online/API/Requests/CommentPostRequest.cs @@ -0,0 +1,41 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Net.Http; +using osu.Framework.IO.Network; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Online.API.Requests +{ + public class CommentPostRequest : APIRequest + { + public readonly CommentableType Commentable; + public readonly long CommentableId; + public readonly string Message; + public readonly long? ReplyTo; + + public CommentPostRequest(CommentableType commentable, long commentableId, string message, long? replyTo = null) + { + Commentable = commentable; + CommentableId = commentableId; + Message = message; + ReplyTo = replyTo; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + req.Method = HttpMethod.Post; + + req.AddParameter(@"comment[commentable_type]", Commentable.ToString()); + req.AddParameter(@"comment[commentable_id]", $"{CommentableId}"); + req.AddParameter(@"comment[message]", Message); + if (ReplyTo.HasValue) + req.AddParameter(@"comment[parent_id]", $"{ReplyTo}"); + + return req; + } + + protected override string Target => "comments"; + } +} From 32e90829e3d0b2df4241ecf9f419446a4d42d587 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 7 Jan 2023 02:59:24 +0300 Subject: [PATCH 1313/2991] Integrate comment editor into container --- .../Overlays/Comments/CommentsContainer.cs | 68 ++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 7bd2d6a5e6..c8a2ab39ae 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -17,15 +17,23 @@ using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Threading; using System.Collections.Generic; using JetBrains.Annotations; +using osu.Framework.Localisation; using osu.Game.Graphics.Sprites; using osu.Game.Resources.Localisation.Web; -using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; +using osu.Game.Users.Drawables; +using osuTK; namespace osu.Game.Overlays.Comments { + [Cached] public partial class CommentsContainer : CompositeDrawable { + private const string cid = "commentableId"; + + [Cached] private readonly Bindable type = new Bindable(); + + [Cached(name: cid)] private readonly BindableLong id = new BindableLong(); public readonly Bindable Sort = new Bindable(); @@ -46,12 +54,14 @@ namespace osu.Game.Overlays.Comments private DeletedCommentsCounter deletedCommentsCounter; private CommentsShowMoreButton moreButton; private TotalCommentsCounter commentCounter; + private UpdateableAvatar avatar; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; + AddRangeInternal(new Drawable[] { new Box @@ -86,6 +96,29 @@ namespace osu.Game.Overlays.Comments }, }, }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = 50, Vertical = 20 }, + Children = new Drawable[] + { + avatar = new UpdateableAvatar(api.LocalUser.Value) + { + Size = new Vector2(50), + CornerExponent = 2, + CornerRadius = 25, + Masking = true, + }, + new Container + { + Padding = new MarginPadding { Left = 60 }, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = new NewCommentEditor() + } + } + }, new CommentsHeader { Sort = { BindTarget = Sort }, @@ -146,6 +179,7 @@ namespace osu.Game.Overlays.Comments }); User.BindTo(api.LocalUser); + User.BindValueChanged(e => avatar.User = e.NewValue); } protected override void LoadComplete() @@ -336,5 +370,37 @@ namespace osu.Game.Overlays.Comments }); } } + + private partial class NewCommentEditor : CommentEditor + { + [Resolved] + public Bindable CommentableType { get; set; } + + [Resolved(name: cid)] + public BindableLong CommentableId { get; set; } + + protected override LocalisableString FooterText => default; + protected override LocalisableString CommitButtonText => CommonStrings.ButtonsPost; + protected override LocalisableString TextBoxPlaceholder => CommentsStrings.PlaceholderNew; + + [Resolved] + private IAPIProvider api { get; set; } + + protected override void OnCommit(string text) + { + CommitButton.IsLoadingSpinnerShown = true; + CommentPostRequest req = new CommentPostRequest(CommentableType.Value, CommentableId.Value, text); + req.Failure += _ => Schedule(() => + { + CommitButton.IsLoadingSpinnerShown = false; + }); + req.Success += cb => Schedule(() => + { + CommitButton.IsLoadingSpinnerShown = false; + Current.Value = string.Empty; + }); + api.Queue(req); + } + } } } From 58bf7349eea9cd4a3600f7c71ca6968feb85e776 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 7 Jan 2023 02:59:32 +0300 Subject: [PATCH 1314/2991] Fix request --- osu.Game/Online/API/Requests/CommentPostRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/CommentPostRequest.cs b/osu.Game/Online/API/Requests/CommentPostRequest.cs index bd69c04bed..7012d479bd 100644 --- a/osu.Game/Online/API/Requests/CommentPostRequest.cs +++ b/osu.Game/Online/API/Requests/CommentPostRequest.cs @@ -27,7 +27,7 @@ namespace osu.Game.Online.API.Requests var req = base.CreateWebRequest(); req.Method = HttpMethod.Post; - req.AddParameter(@"comment[commentable_type]", Commentable.ToString()); + req.AddParameter(@"comment[commentable_type]", Commentable.ToString().ToLowerInvariant()); req.AddParameter(@"comment[commentable_id]", $"{CommentableId}"); req.AddParameter(@"comment[message]", Message); if (ReplyTo.HasValue) From 167ac8b5dda3b0b4d3bf42512fd1234547c525ef Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 7 Jan 2023 03:03:52 +0300 Subject: [PATCH 1315/2991] Fix editor object being requered --- osu.Game/Screens/Edit/Setup/ResourcesSection.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs index c79d9d6632..8565843170 100644 --- a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs +++ b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.IO; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -34,7 +32,7 @@ namespace osu.Game.Screens.Edit.Setup private EditorBeatmap editorBeatmap { get; set; } [Resolved] - private Editor editor { get; set; } + private Editor? editor { get; set; } [Resolved] private SetupScreenHeader header { get; set; } @@ -96,7 +94,7 @@ namespace osu.Game.Screens.Edit.Setup working.Value.Metadata.BackgroundFile = destination.Name; header.Background.UpdateBackground(); - editor.ApplyToBackground(bg => bg.RefreshBackground()); + editor?.ApplyToBackground(bg => bg.RefreshBackground()); return true; } From b47cef838c689f551abbd5bcf1dc1f9b132c6173 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 7 Jan 2023 03:08:02 +0300 Subject: [PATCH 1316/2991] Nullability --- .../Screens/Edit/Setup/ResourcesSection.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs index 8565843170..901101dcec 100644 --- a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs +++ b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs @@ -14,28 +14,28 @@ namespace osu.Game.Screens.Edit.Setup { internal partial class ResourcesSection : SetupSection { - private LabelledFileChooser audioTrackChooser; - private LabelledFileChooser backgroundChooser; + private LabelledFileChooser audioTrackChooser = null!; + private LabelledFileChooser backgroundChooser = null!; public override LocalisableString Title => EditorSetupStrings.ResourcesHeader; [Resolved] - private MusicController music { get; set; } + private MusicController music { get; set; } = null!; [Resolved] - private BeatmapManager beatmaps { get; set; } + private BeatmapManager beatmaps { get; set; } = null!; [Resolved] - private IBindable working { get; set; } + private IBindable working { get; set; } = null!; [Resolved] - private EditorBeatmap editorBeatmap { get; set; } + private EditorBeatmap editorBeatmap { get; set; } = null!; [Resolved] private Editor? editor { get; set; } [Resolved] - private SetupScreenHeader header { get; set; } + private SetupScreenHeader header { get; set; } = null!; [BackgroundDependencyLoader] private void load() @@ -128,17 +128,17 @@ namespace osu.Game.Screens.Edit.Setup return true; } - private void backgroundChanged(ValueChangedEvent file) + private void backgroundChanged(ValueChangedEvent file) { - if (!ChangeBackgroundImage(file.NewValue)) + if (!ChangeBackgroundImage(file.NewValue!)) backgroundChooser.Current.Value = file.OldValue; updatePlaceholderText(); } - private void audioTrackChanged(ValueChangedEvent file) + private void audioTrackChanged(ValueChangedEvent file) { - if (!ChangeAudioTrack(file.NewValue)) + if (!ChangeAudioTrack(file.NewValue!)) audioTrackChooser.Current.Value = file.OldValue; updatePlaceholderText(); From 927773d56584c1b288642a3b143ef118d6ce4d65 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 7 Jan 2023 04:15:43 +0300 Subject: [PATCH 1317/2991] Display submitted comments locally --- .../Overlays/Comments/CommentsContainer.cs | 46 ++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index c8a2ab39ae..98c186b273 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -3,6 +3,7 @@ #nullable disable +using System; using osu.Framework.Allocation; using osu.Framework.Graphics.Containers; using osu.Game.Online.API; @@ -115,7 +116,10 @@ namespace osu.Game.Overlays.Comments Padding = new MarginPadding { Left = 60 }, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Child = new NewCommentEditor() + Child = new NewCommentEditor + { + OnPost = prependPostedComments + } } } }, @@ -279,7 +283,6 @@ namespace osu.Game.Overlays.Comments { pinnedContent.AddRange(loaded.Where(d => d.Comment.Pinned)); content.AddRange(loaded.Where(d => !d.Comment.Pinned)); - deletedCommentsCounter.Count.Value += topLevelComments.Select(d => d.Comment).Count(c => c.IsDeleted && c.IsTopLevel); if (bundle.HasMore) @@ -322,6 +325,42 @@ namespace osu.Game.Overlays.Comments } } + private void prependPostedComments(CommentBundle bundle) + { + var topLevelComments = new List(); + + foreach (var comment in bundle.Comments) + { + // Exclude possible duplicated comments. + if (CommentDictionary.ContainsKey(comment.Id)) + continue; + + topLevelComments.Add(getDrawableComment(comment)); + } + + if (topLevelComments.Any()) + { + LoadComponentsAsync(topLevelComments, loaded => + { + if (content[0] is NoCommentsPlaceholder placeholder) + content.Remove(placeholder, true); + + foreach (var comment in loaded) + { + int pos = -1; + + if (content.Count > 0) + { + var first = content.FlowingChildren.First(); + pos = (int)(content.GetLayoutPosition(first) - 1); + } + + content.Insert(pos, comment); + } + }, (loadCancellation = new CancellationTokenSource()).Token); + } + } + private DrawableComment getDrawableComment(Comment comment) { if (CommentDictionary.TryGetValue(comment.Id, out var existing)) @@ -386,6 +425,8 @@ namespace osu.Game.Overlays.Comments [Resolved] private IAPIProvider api { get; set; } + public Action OnPost; + protected override void OnCommit(string text) { CommitButton.IsLoadingSpinnerShown = true; @@ -398,6 +439,7 @@ namespace osu.Game.Overlays.Comments { CommitButton.IsLoadingSpinnerShown = false; Current.Value = string.Empty; + OnPost?.Invoke(cb); }); api.Queue(req); } From 49ce50878d2c761fcc0a43132cf1669f9966d687 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 7 Jan 2023 04:15:53 +0300 Subject: [PATCH 1318/2991] Add simple test --- .../Online/TestSceneCommentsContainer.cs | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 291ccd634d..86a574cf77 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -11,7 +11,11 @@ using osu.Game.Overlays; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Testing; +using osu.Framework.Utils; +using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; @@ -126,6 +130,24 @@ namespace osu.Game.Tests.Visual.Online commentsContainer.ChildrenOfType().Count(d => d.Comment.Pinned == withPinned) == 1); } + [TestCase] + public void TestPost() + { + setUpCommentsResponse(getExampleComments()); + AddStep("show comments", () => commentsContainer.ShowComments(CommentableType.Beatmapset, 123)); + setUpPostResponse(); + AddStep("Enter text", () => this.ChildrenOfType().Single().ChildrenOfType().Single().Current.Value = "comm"); + AddStep("Submit", () => this.ChildrenOfType().Single().ChildrenOfType().First().TriggerClick()); + AddUntilStep("Comment sent", () => + { + var text = this.ChildrenOfType().Single().ChildrenOfType().Single().Current.Value; + return this.ChildrenOfType().Any(x => + { + return x.ChildrenOfType().Any(y => y.Text == text); + }); + }); + } + private void setUpCommentsResponse(CommentBundle commentBundle) => AddStep("set up response", () => { @@ -139,6 +161,32 @@ namespace osu.Game.Tests.Visual.Online }; }); + private void setUpPostResponse() + => AddStep("set up response", () => + { + dummyAPI.HandleRequest = request => + { + if (!(request is CommentPostRequest req)) + return false; + + req.TriggerSuccess(new CommentBundle + { + Comments = new List + { + new Comment + { + Id = 98, + Message = req.Message, + LegacyName = "FirstUser", + CreatedAt = DateTimeOffset.Now, + VotesCount = 98, + } + } + }); + return true; + }; + }); + private CommentBundle getExampleComments(bool withPinned = false) { var bundle = new CommentBundle From 4baa2670953b4c201f5d70b64149fd6cb064d86d Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 7 Jan 2023 04:26:52 +0300 Subject: [PATCH 1319/2991] warnings --- osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 86a574cf77..e58423241b 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -14,7 +14,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Testing; -using osu.Framework.Utils; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Online.API; using osu.Game.Online.API.Requests; @@ -140,7 +139,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("Submit", () => this.ChildrenOfType().Single().ChildrenOfType().First().TriggerClick()); AddUntilStep("Comment sent", () => { - var text = this.ChildrenOfType().Single().ChildrenOfType().Single().Current.Value; + string text = this.ChildrenOfType().Single().ChildrenOfType().Single().Current.Value; return this.ChildrenOfType().Any(x => { return x.ChildrenOfType().Any(y => y.Text == text); @@ -187,7 +186,7 @@ namespace osu.Game.Tests.Visual.Online }; }); - private CommentBundle getExampleComments(bool withPinned = false) + private static CommentBundle getExampleComments(bool withPinned = false) { var bundle = new CommentBundle { From 904c76e437114a214ec5fcc649066ad4daadf30f Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 7 Jan 2023 14:23:31 +0300 Subject: [PATCH 1320/2991] Use sane `BeatmapInfo` for preview time mutation `EditorBeatmap.BeatmapInfo` is usually the correct instance for mutating properties that should persist in the database. --- osu.Game/Screens/Edit/EditorBeatmap.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 1684dcf0cd..dc1fda13f4 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -110,11 +110,11 @@ namespace osu.Game.Screens.Edit foreach (var obj in HitObjects) trackStartTime(obj); - PreviewTime = new BindableInt(playableBeatmap.Metadata.PreviewTime); + PreviewTime = new BindableInt(BeatmapInfo.Metadata.PreviewTime); PreviewTime.BindValueChanged(s => { BeginChange(); - this.beatmapInfo.Metadata.PreviewTime = s.NewValue; + BeatmapInfo.Metadata.PreviewTime = s.NewValue; EndChange(); }); } From abca13eb6cb934dc81f3791f8352ee4ac1ef0a95 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 7 Jan 2023 14:30:01 +0300 Subject: [PATCH 1321/2991] Rewrite visualisation piece to bind once and without potential event leak --- .../Visual/Editing/TestScenePreviewTime.cs | 4 ++-- .../Summary/Parts/PreviewTimePart.cs | 20 +++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs b/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs index d5aa71095b..3319788c8a 100644 --- a/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs +++ b/osu.Game.Tests/Visual/Editing/TestScenePreviewTime.cs @@ -27,9 +27,9 @@ namespace osu.Game.Tests.Visual.Editing public void TestScenePreviewTimeline() { AddStep("set preview time to -1", () => EditorBeatmap.PreviewTime.Value = -1); - AddAssert("preview time line should not show", () => Editor.ChildrenOfType().Single().Alpha == 0); + AddAssert("preview time line should not show", () => !Editor.ChildrenOfType().Single().Children.Any()); AddStep("set preview time to 1000", () => EditorBeatmap.PreviewTime.Value = 1000); - AddAssert("preview time line should show", () => Editor.ChildrenOfType().Single().Alpha == 1); + AddAssert("preview time line should show", () => Editor.ChildrenOfType().Single().Children.Single().Alpha == 1); } } } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs index de7f611424..c63bb7ac24 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/PreviewTimePart.cs @@ -10,24 +10,28 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts { public partial class PreviewTimePart : TimelinePart { + private readonly BindableInt previewTime = new BindableInt(); + protected override void LoadBeatmap(EditorBeatmap beatmap) { base.LoadBeatmap(beatmap); - Add(new PreviewTimeVisualisation(beatmap)); - beatmap.PreviewTime.BindValueChanged(s => + + previewTime.UnbindAll(); + previewTime.BindTo(beatmap.PreviewTime); + previewTime.BindValueChanged(t => { - Alpha = s.NewValue == -1 ? 0 : 1; + Clear(); + + if (t.NewValue >= 0) + Add(new PreviewTimeVisualisation(t.NewValue)); }, true); } private partial class PreviewTimeVisualisation : PointVisualisation { - private readonly BindableInt previewTime = new BindableInt(); - - public PreviewTimeVisualisation(EditorBeatmap editorBeatmap) + public PreviewTimeVisualisation(double time) + : base(time) { - previewTime.BindTo(editorBeatmap.PreviewTime); - previewTime.BindValueChanged(s => X = s.NewValue, true); } [BackgroundDependencyLoader] From aaeb43fbb2f48ce1f364c9ffd267abddcdcb3898 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 7 Jan 2023 18:15:57 +0300 Subject: [PATCH 1322/2991] Return older file if new one is null --- osu.Game/Screens/Edit/Setup/ResourcesSection.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs index 901101dcec..8c84ad90ba 100644 --- a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs +++ b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs @@ -130,7 +130,7 @@ namespace osu.Game.Screens.Edit.Setup private void backgroundChanged(ValueChangedEvent file) { - if (!ChangeBackgroundImage(file.NewValue!)) + if (file.NewValue == null || !ChangeBackgroundImage(file.NewValue)) backgroundChooser.Current.Value = file.OldValue; updatePlaceholderText(); @@ -138,7 +138,7 @@ namespace osu.Game.Screens.Edit.Setup private void audioTrackChanged(ValueChangedEvent file) { - if (!ChangeAudioTrack(file.NewValue!)) + if (file.NewValue == null || !ChangeAudioTrack(file.NewValue)) audioTrackChooser.Current.Value = file.OldValue; updatePlaceholderText(); From 0f6735564eeefca5ea9ef14dd85771da117b3366 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 7 Jan 2023 10:54:48 -0800 Subject: [PATCH 1323/2991] Move and rename nomination response model to singular --- .../BeatmapSetOnlineNomination.cs} | 4 ++-- osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs | 2 +- osu.Game/Overlays/BeatmapSet/Info.cs | 2 +- .../Overlays/BeatmapSet/MetadataSectionNominators.cs | 9 +++++---- 4 files changed, 9 insertions(+), 8 deletions(-) rename osu.Game/{Online/API/Requests/Responses/BeatmapSetOnlineNominations.cs => Beatmaps/BeatmapSetOnlineNomination.cs} (84%) diff --git a/osu.Game/Online/API/Requests/Responses/BeatmapSetOnlineNominations.cs b/osu.Game/Beatmaps/BeatmapSetOnlineNomination.cs similarity index 84% rename from osu.Game/Online/API/Requests/Responses/BeatmapSetOnlineNominations.cs rename to osu.Game/Beatmaps/BeatmapSetOnlineNomination.cs index 5d0a3ea38b..f6de414628 100644 --- a/osu.Game/Online/API/Requests/Responses/BeatmapSetOnlineNominations.cs +++ b/osu.Game/Beatmaps/BeatmapSetOnlineNomination.cs @@ -3,9 +3,9 @@ using Newtonsoft.Json; -namespace osu.Game.Online.API.Requests.Responses +namespace osu.Game.Beatmaps { - public struct BeatmapSetOnlineNominations + public struct BeatmapSetOnlineNomination { [JsonProperty(@"beatmapset_id")] public int BeatmapsetId { get; set; } diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index eb39b7489d..fc740f1eec 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -112,7 +112,7 @@ namespace osu.Game.Online.API.Requests.Responses public BeatmapSetOnlineLanguage Language { get; set; } [JsonProperty(@"current_nominations")] - public BeatmapSetOnlineNominations[] CurrentNominations { get; set; } = Array.Empty(); + public BeatmapSetOnlineNomination[] CurrentNominations { get; set; } = Array.Empty(); [JsonProperty(@"related_users")] public APIUser[] RelatedUsers { get; set; } = Array.Empty(); diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index dbeea74f6f..58739eb471 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -125,7 +125,7 @@ namespace osu.Game.Overlays.BeatmapSet BeatmapSet.ValueChanged += b => { - nominators.Metadata = (b.NewValue?.CurrentNominations ?? Array.Empty(), b.NewValue?.RelatedUsers ?? Array.Empty()); + nominators.Metadata = (b.NewValue?.CurrentNominations ?? Array.Empty(), b.NewValue?.RelatedUsers ?? Array.Empty()); source.Metadata = b.NewValue?.Source ?? string.Empty; tags.Metadata = b.NewValue?.Tags ?? string.Empty; genre.Metadata = b.NewValue?.Genre ?? new BeatmapSetOnlineGenre { Id = (int)SearchGenre.Unspecified }; diff --git a/osu.Game/Overlays/BeatmapSet/MetadataSectionNominators.cs b/osu.Game/Overlays/BeatmapSet/MetadataSectionNominators.cs index 78a3fe7cd5..76dbda3d5e 100644 --- a/osu.Game/Overlays/BeatmapSet/MetadataSectionNominators.cs +++ b/osu.Game/Overlays/BeatmapSet/MetadataSectionNominators.cs @@ -4,15 +4,16 @@ using System; using System.Linq; using osu.Framework.Graphics; +using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests.Responses; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.BeatmapSet { - public partial class MetadataSectionNominators : MetadataSection<(BeatmapSetOnlineNominations[] CurrentNominations, APIUser[] RelatedUsers)> + public partial class MetadataSectionNominators : MetadataSection<(BeatmapSetOnlineNomination[] CurrentNominations, APIUser[] RelatedUsers)> { - public override (BeatmapSetOnlineNominations[] CurrentNominations, APIUser[] RelatedUsers) Metadata + public override (BeatmapSetOnlineNomination[] CurrentNominations, APIUser[] RelatedUsers) Metadata { set { @@ -26,12 +27,12 @@ namespace osu.Game.Overlays.BeatmapSet } } - public MetadataSectionNominators(Action<(BeatmapSetOnlineNominations[] CurrentNominations, APIUser[] RelatedUsers)>? searchAction = null) + public MetadataSectionNominators(Action<(BeatmapSetOnlineNomination[] CurrentNominations, APIUser[] RelatedUsers)>? searchAction = null) : base(MetadataType.Nominators, searchAction) { } - protected override void AddMetadata((BeatmapSetOnlineNominations[] CurrentNominations, APIUser[] RelatedUsers) metadata, LinkFlowContainer loaded) + protected override void AddMetadata((BeatmapSetOnlineNomination[] CurrentNominations, APIUser[] RelatedUsers) metadata, LinkFlowContainer loaded) { int[] nominatorIds = metadata.CurrentNominations.Select(n => n.UserId).ToArray(); From 9d32fde5928f1c77804090c3c1802397b58fa036 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 7 Jan 2023 11:04:42 -0800 Subject: [PATCH 1324/2991] Mark current nominations and related users as nullable --- osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index fc740f1eec..aeae3edde2 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -112,10 +112,10 @@ namespace osu.Game.Online.API.Requests.Responses public BeatmapSetOnlineLanguage Language { get; set; } [JsonProperty(@"current_nominations")] - public BeatmapSetOnlineNomination[] CurrentNominations { get; set; } = Array.Empty(); + public BeatmapSetOnlineNomination[]? CurrentNominations { get; set; } [JsonProperty(@"related_users")] - public APIUser[] RelatedUsers { get; set; } = Array.Empty(); + public APIUser[]? RelatedUsers { get; set; } public string Source { get; set; } = string.Empty; From bae3a6851bf256040aad4f4ab07af15437aec0ca Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 7 Jan 2023 11:15:51 -0800 Subject: [PATCH 1325/2991] Block hover events behind logo even if action is null --- osu.Game/Screens/Menu/OsuLogo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 7a5a26226b..e95d0384ba 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -393,7 +393,7 @@ namespace osu.Game.Screens.Menu protected override bool OnHover(HoverEvent e) { - if (Action == null) return false; + if (Action == null) return true; logoHoverContainer.ScaleTo(1.1f, 500, Easing.OutElastic); return true; From 93a57b6871a98d94f898cfa6afbf5504ab9932c9 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 7 Jan 2023 11:28:09 -0800 Subject: [PATCH 1326/2991] Separate pausing test instead of using test cases --- .../Visual/Gameplay/TestSceneReplayPlayer.cs | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs index 601fe445f0..334d01f915 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs @@ -24,28 +24,40 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("player loaded", () => Player.IsLoaded); } - [TestCase("space")] - [TestCase("mouse middle")] - public void TestPause(string action) + [Test] + public void TestPauseViaSpace() { double? lastTime = null; AddUntilStep("wait for first hit", () => Player.ScoreProcessor.TotalScore.Value > 0); - AddStep("Pause playback", () => - { - switch (action) - { - case "space": - InputManager.Key(Key.Space); - break; + AddStep("Pause playback with space", () => InputManager.Key(Key.Space)); - case "mouse middle": - InputManager.Click(MouseButton.Middle); - break; - } + AddAssert("player not exited", () => Player.IsCurrentScreen()); + + AddUntilStep("Time stopped progressing", () => + { + double current = Player.GameplayClockContainer.CurrentTime; + bool changed = lastTime != current; + lastTime = current; + + return !changed; }); + AddWaitStep("wait some", 10); + + AddAssert("Time still stopped", () => lastTime == Player.GameplayClockContainer.CurrentTime); + } + + [Test] + public void TestPauseViaMiddleMouse() + { + double? lastTime = null; + + AddUntilStep("wait for first hit", () => Player.ScoreProcessor.TotalScore.Value > 0); + + AddStep("Pause playback with middle mouse", () => InputManager.Click(MouseButton.Middle)); + AddAssert("player not exited", () => Player.IsCurrentScreen()); AddUntilStep("Time stopped progressing", () => From 45bae5d42470b12cb4900ccb24f1cf79ad05204f Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Thu, 5 Jan 2023 13:05:20 -0800 Subject: [PATCH 1327/2991] Add middle mouse to toggle pause replay instead of using pause gameplay keybinds --- osu.Game/Input/Bindings/GlobalActionContainer.cs | 1 + osu.Game/Screens/Play/ReplayPlayer.cs | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 07cef50dec..3826139716 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -113,6 +113,7 @@ namespace osu.Game.Input.Bindings new KeyBinding(new[] { InputKey.Shift, InputKey.Tab }, GlobalAction.ToggleInGameInterface), new KeyBinding(InputKey.MouseMiddle, GlobalAction.PauseGameplay), new KeyBinding(InputKey.Space, GlobalAction.TogglePauseReplay), + new KeyBinding(InputKey.MouseMiddle, GlobalAction.TogglePauseReplay), new KeyBinding(InputKey.Left, GlobalAction.SeekReplayBackward), new KeyBinding(InputKey.Right, GlobalAction.SeekReplayForward), new KeyBinding(InputKey.Control, GlobalAction.HoldForHUD), diff --git a/osu.Game/Screens/Play/ReplayPlayer.cs b/osu.Game/Screens/Play/ReplayPlayer.cs index 77ee7bc113..c5ef6b1585 100644 --- a/osu.Game/Screens/Play/ReplayPlayer.cs +++ b/osu.Game/Screens/Play/ReplayPlayer.cs @@ -81,7 +81,6 @@ namespace osu.Game.Screens.Play return true; case GlobalAction.TogglePauseReplay: - case GlobalAction.PauseGameplay: if (GameplayClockContainer.IsPaused.Value) GameplayClockContainer.Start(); else From 750b55d9b7101e22473249688c7ff41d4971abb0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 8 Jan 2023 22:28:19 +0900 Subject: [PATCH 1328/2991] Update other events to have matching return types (and animate more) --- osu.Game/Screens/Menu/OsuLogo.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index e95d0384ba..9430a1cda8 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -365,7 +365,7 @@ namespace osu.Game.Screens.Menu protected override bool OnMouseDown(MouseDownEvent e) { - if (Action == null || e.Button != MouseButton.Left) return false; + if (e.Button != MouseButton.Left) return true; logoBounceContainer.ScaleTo(0.9f, 1000, Easing.Out); return true; @@ -380,22 +380,21 @@ namespace osu.Game.Screens.Menu protected override bool OnClick(ClickEvent e) { - if (Action == null) return false; - - if (Action.Invoke()) - sampleClick.Play(); - flashLayer.ClearTransforms(); flashLayer.Alpha = 0.4f; flashLayer.FadeOut(1500, Easing.OutExpo); + + if (Action?.Invoke() == true) + sampleClick.Play(); + return true; } protected override bool OnHover(HoverEvent e) { - if (Action == null) return true; + if (Action != null) + logoHoverContainer.ScaleTo(1.1f, 500, Easing.OutElastic); - logoHoverContainer.ScaleTo(1.1f, 500, Easing.OutElastic); return true; } From 47fb467012d77ce75da83ca2c884529d4644154d Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 8 Jan 2023 19:02:48 +0100 Subject: [PATCH 1329/2991] Remove nullable disabling in carousel --- .../SongSelect/TestScenePlaySongSelect.cs | 6 +-- osu.Game/Screens/Select/BeatmapCarousel.cs | 8 ++-- .../Select/Carousel/CarouselBeatmap.cs | 2 - .../Select/Carousel/CarouselBeatmapSet.cs | 10 ++--- .../Screens/Select/Carousel/CarouselGroup.cs | 2 +- .../Carousel/CarouselGroupEagerSelect.cs | 10 ++--- .../Screens/Select/Carousel/CarouselHeader.cs | 6 +-- .../Screens/Select/Carousel/CarouselItem.cs | 4 +- .../Carousel/DrawableCarouselBeatmap.cs | 44 +++++++++--------- .../Carousel/DrawableCarouselBeatmapSet.cs | 45 +++++++++---------- .../Select/Carousel/DrawableCarouselItem.cs | 14 +++--- .../Carousel/FilterableDifficultyIcon.cs | 2 - .../Select/Carousel/GroupedDifficultyIcon.cs | 2 - .../Select/Carousel/SetPanelBackground.cs | 2 - .../Select/Carousel/SetPanelContent.cs | 2 - 15 files changed, 65 insertions(+), 94 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 01c5ad8358..cfee02dfb8 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -208,7 +208,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep("select next and enter", () => { InputManager.MoveMouseTo(songSelect!.Carousel.ChildrenOfType() - .First(b => !((CarouselBeatmap)b.Item).BeatmapInfo.Equals(songSelect!.Carousel.SelectedBeatmapInfo))); + .First(b => !((CarouselBeatmap)b.Item!).BeatmapInfo.Equals(songSelect!.Carousel.SelectedBeatmapInfo))); InputManager.Click(MouseButton.Left); @@ -235,7 +235,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep("select next and enter", () => { InputManager.MoveMouseTo(songSelect!.Carousel.ChildrenOfType() - .First(b => !((CarouselBeatmap)b.Item).BeatmapInfo.Equals(songSelect!.Carousel.SelectedBeatmapInfo))); + .First(b => !((CarouselBeatmap)b.Item!).BeatmapInfo.Equals(songSelect!.Carousel.SelectedBeatmapInfo))); InputManager.PressButton(MouseButton.Left); @@ -614,7 +614,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("selected only shows expected ruleset (plus converts)", () => { - var selectedPanel = songSelect!.Carousel.ChildrenOfType().First(s => s.Item.State.Value == CarouselItemState.Selected); + var selectedPanel = songSelect!.Carousel.ChildrenOfType().First(s => s.Item!.State.Value == CarouselItemState.Selected); // special case for converts checked here. return selectedPanel.ChildrenOfType().All(i => diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 6955b8ef56..4a6ff7417e 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -64,7 +64,7 @@ namespace osu.Game.Screens.Select /// /// A function to optionally decide on a recommended difficulty from a beatmap set. /// - public Func, BeatmapInfo>? GetRecommendedBeatmap; + public Func, BeatmapInfo?>? GetRecommendedBeatmap; private CarouselBeatmapSet? selectedBeatmapSet; @@ -119,7 +119,7 @@ namespace osu.Game.Screens.Select { CarouselRoot newRoot = new CarouselRoot(this); - newRoot.AddItems(beatmapSets.Select(s => createCarouselSet(s.Detach())).Where(g => g != null)); + newRoot.AddItems(beatmapSets.Select(s => createCarouselSet(s.Detach())).Where(g => g != null)!); root = newRoot; @@ -739,7 +739,7 @@ namespace osu.Game.Screens.Select foreach (var panel in Scroll.Children) { - if (toDisplay.Remove(panel.Item)) + if (toDisplay.Remove(panel.Item!)) { // panel already displayed. continue; @@ -770,7 +770,7 @@ namespace osu.Game.Screens.Select { updateItem(item); - if (item.Item.Visible) + if (item.Item!.Visible) { bool isSelected = item.Item.State.Value == CarouselItemState.Selected; diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs index 03490ff37b..837939716b 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using osu.Game.Beatmaps; diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index 9a4319c6b2..a360ddabc7 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -33,7 +31,7 @@ namespace osu.Game.Screens.Select.Carousel public BeatmapSetInfo BeatmapSet; - public Func, BeatmapInfo> GetRecommendedBeatmap; + public Func, BeatmapInfo?>? GetRecommendedBeatmap; public CarouselBeatmapSet(BeatmapSetInfo beatmapSet) { @@ -47,7 +45,7 @@ namespace osu.Game.Screens.Select.Carousel .ForEach(AddItem); } - protected override CarouselItem GetNextToSelect() + protected override CarouselItem? GetNextToSelect() { if (LastSelected == null || LastSelected.Filtered.Value) { @@ -132,8 +130,8 @@ namespace osu.Game.Screens.Select.Carousel bool filtered = Items.All(i => i.Filtered.Value); - filtered |= criteria.Sort == SortMode.DateRanked && BeatmapSet?.DateRanked == null; - filtered |= criteria.Sort == SortMode.DateSubmitted && BeatmapSet?.DateSubmitted == null; + filtered |= criteria.Sort == SortMode.DateRanked && BeatmapSet.DateRanked == null; + filtered |= criteria.Sort == SortMode.DateSubmitted && BeatmapSet.DateSubmitted == null; Filtered.Value = filtered; } diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroup.cs b/osu.Game/Screens/Select/Carousel/CarouselGroup.cs index 9302578038..8667dce226 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroup.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroup.cs @@ -10,7 +10,7 @@ namespace osu.Game.Screens.Select.Carousel /// public class CarouselGroup : CarouselItem { - public override DrawableCarouselItem? CreateDrawableRepresentation() => null; + public override DrawableCarouselItem CreateDrawableRepresentation() => null!; public IReadOnlyList Items => items; diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs index 6366fc8050..7f90e05744 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -26,7 +24,7 @@ namespace osu.Game.Screens.Select.Carousel /// /// The last selected item. /// - protected CarouselItem LastSelected { get; private set; } + protected CarouselItem? LastSelected { get; private set; } /// /// We need to keep track of the index for cases where the selection is removed but we want to select a new item based on its old location. @@ -112,7 +110,7 @@ namespace osu.Game.Screens.Select.Carousel /// Finds the item this group would select next if it attempted selection /// /// An unfiltered item nearest to the last selected one or null if all items are filtered - protected virtual CarouselItem GetNextToSelect() + protected virtual CarouselItem? GetNextToSelect() { if (Items.Count == 0) return null; @@ -141,7 +139,7 @@ namespace osu.Game.Screens.Select.Carousel protected virtual void PerformSelection() { - CarouselItem nextToSelect = GetNextToSelect(); + CarouselItem? nextToSelect = GetNextToSelect(); if (nextToSelect != null) nextToSelect.State.Value = CarouselItemState.Selected; @@ -149,7 +147,7 @@ namespace osu.Game.Screens.Select.Carousel updateSelected(null); } - private void updateSelected(CarouselItem newSelection) + private void updateSelected(CarouselItem? newSelection) { if (newSelection != null) LastSelected = newSelection; diff --git a/osu.Game/Screens/Select/Carousel/CarouselHeader.cs b/osu.Game/Screens/Select/Carousel/CarouselHeader.cs index 1ae69bc951..e46f0da45d 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselHeader.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselHeader.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; @@ -95,9 +93,9 @@ namespace osu.Game.Screens.Select.Carousel public partial class HoverLayer : HoverSampleDebounceComponent { - private Sample sampleHover; + private Sample? sampleHover; - private Box box; + private Box box = null!; public HoverLayer() { diff --git a/osu.Game/Screens/Select/Carousel/CarouselItem.cs b/osu.Game/Screens/Select/Carousel/CarouselItem.cs index cbf079eb4b..5de9f2b995 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselItem.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Bindables; @@ -51,7 +49,7 @@ namespace osu.Game.Screens.Select.Carousel public virtual int CompareTo(FilterCriteria criteria, CarouselItem other) => ItemID.CompareTo(other.ItemID); - public int CompareTo(CarouselItem other) => CarouselYPosition.CompareTo(other.CarouselYPosition); + public int CompareTo(CarouselItem? other) => CarouselYPosition.CompareTo(other!.CarouselYPosition); } public enum CarouselItemState diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index 4e10961e55..88a55198b2 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -47,31 +45,31 @@ namespace osu.Game.Screens.Select.Carousel private readonly BeatmapInfo beatmapInfo; - private Sprite background; + private Sprite background = null!; - private Action startRequested; - private Action editRequested; - private Action hideRequested; + private Action? startRequested; + private Action? editRequested; + private Action? hideRequested; - private Triangles triangles; + private Triangles triangles = null!; - private StarCounter starCounter; - private DifficultyIcon difficultyIcon; - - [Resolved(CanBeNull = true)] - private BeatmapSetOverlay beatmapOverlay { get; set; } + private StarCounter starCounter = null!; + private DifficultyIcon difficultyIcon = null!; [Resolved] - private BeatmapDifficultyCache difficultyCache { get; set; } - - [Resolved(CanBeNull = true)] - private ManageCollectionsDialog manageCollectionsDialog { get; set; } + private BeatmapSetOverlay? beatmapOverlay { get; set; } [Resolved] - private RealmAccess realm { get; set; } + private BeatmapDifficultyCache difficultyCache { get; set; } = null!; - private IBindable starDifficultyBindable; - private CancellationTokenSource starDifficultyCancellationSource; + [Resolved] + private ManageCollectionsDialog? manageCollectionsDialog { get; set; } + + [Resolved] + private RealmAccess realm { get; set; } = null!; + + private IBindable starDifficultyBindable = null!; + private CancellationTokenSource? starDifficultyCancellationSource; public DrawableCarouselBeatmap(CarouselBeatmap panel) { @@ -79,8 +77,8 @@ namespace osu.Game.Screens.Select.Carousel Item = panel; } - [BackgroundDependencyLoader(true)] - private void load(BeatmapManager manager, SongSelect songSelect) + [BackgroundDependencyLoader] + private void load(BeatmapManager? manager, SongSelect? songSelect) { Header.Height = height; @@ -194,7 +192,7 @@ namespace osu.Game.Screens.Select.Carousel protected override bool OnClick(ClickEvent e) { - if (Item.State.Value == CarouselItemState.Selected) + if (Item!.State.Value == CarouselItemState.Selected) startRequested?.Invoke(beatmapInfo); return base.OnClick(e); @@ -202,7 +200,7 @@ namespace osu.Game.Screens.Select.Carousel protected override void ApplyState() { - if (Item.State.Value != CarouselItemState.Collapsed && Alpha == 0) + if (Item!.State.Value != CarouselItemState.Collapsed && Alpha == 0) starCounter.ReplayAnimation(); starDifficultyCancellationSource?.Cancel(); diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index a7fb25bc1b..f0bb8b15c2 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -1,14 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -27,30 +24,28 @@ namespace osu.Game.Screens.Select.Carousel { public const float HEIGHT = MAX_HEIGHT; - private Action restoreHiddenRequested; - private Action viewDetails; - - [Resolved(CanBeNull = true)] - private IDialogOverlay dialogOverlay { get; set; } - - [Resolved(CanBeNull = true)] - private ManageCollectionsDialog manageCollectionsDialog { get; set; } + private Action restoreHiddenRequested = null!; + private Action? viewDetails; [Resolved] - private RealmAccess realm { get; set; } + private IDialogOverlay? dialogOverlay { get; set; } + + [Resolved] + private ManageCollectionsDialog? manageCollectionsDialog { get; set; } + + [Resolved] + private RealmAccess realm { get; set; } = null!; public IEnumerable DrawableBeatmaps => beatmapContainer?.IsLoaded != true ? Enumerable.Empty() : beatmapContainer.AliveChildren; - [CanBeNull] - private Container beatmapContainer; + private Container? beatmapContainer; - private BeatmapSetInfo beatmapSet; + private BeatmapSetInfo beatmapSet = null!; - [CanBeNull] - private Task beatmapsLoadTask; + private Task? beatmapsLoadTask; [Resolved] - private BeatmapManager manager { get; set; } + private BeatmapManager manager { get; set; } = null!; protected override void FreeAfterUse() { @@ -61,8 +56,8 @@ namespace osu.Game.Screens.Select.Carousel ClearTransforms(); } - [BackgroundDependencyLoader(true)] - private void load(BeatmapSetOverlay beatmapOverlay) + [BackgroundDependencyLoader] + private void load(BeatmapSetOverlay? beatmapOverlay) { restoreHiddenRequested = s => { @@ -80,7 +75,7 @@ namespace osu.Game.Screens.Select.Carousel // position updates should not occur if the item is filtered away. // this avoids panels flying across the screen only to be eventually off-screen or faded out. - if (!Item.Visible) + if (!Item!.Visible) return; float targetY = Item.CarouselYPosition; @@ -151,7 +146,7 @@ namespace osu.Game.Screens.Select.Carousel private void updateBeatmapDifficulties() { - var carouselBeatmapSet = (CarouselBeatmapSet)Item; + var carouselBeatmapSet = (CarouselBeatmapSet)Item!; var visibleBeatmaps = carouselBeatmapSet.Items.Where(c => c.Visible).ToArray(); @@ -196,14 +191,14 @@ namespace osu.Game.Screens.Select.Carousel float yPos = DrawableCarouselBeatmap.CAROUSEL_BEATMAP_SPACING; - bool isSelected = Item.State.Value == CarouselItemState.Selected; + bool isSelected = Item!.State.Value == CarouselItemState.Selected; foreach (var panel in beatmapContainer.Children) { if (isSelected) { panel.MoveToY(yPos, 800, Easing.OutQuint); - yPos += panel.Item.TotalHeight; + yPos += panel.Item!.TotalHeight; } else panel.MoveToY(0, 800, Easing.OutQuint); @@ -218,7 +213,7 @@ namespace osu.Game.Screens.Select.Carousel List items = new List(); - if (Item.State.Value == CarouselItemState.NotSelected) + if (Item!.State.Value == CarouselItemState.NotSelected) items.Add(new OsuMenuItem("Expand", MenuItemType.Highlighted, () => Item.State.Value = CarouselItemState.Selected)); if (beatmapSet.OnlineID > 0 && viewDetails != null) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs index 26a32c23dd..580dcb3471 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Diagnostics; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -34,9 +32,9 @@ namespace osu.Game.Screens.Select.Carousel public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Header.ReceivePositionalInputAt(screenSpacePos); - private CarouselItem item; + private CarouselItem? item; - public CarouselItem Item + public CarouselItem? Item { get => item; set @@ -105,7 +103,7 @@ namespace osu.Game.Screens.Select.Carousel protected virtual void UpdateItem() { - if (item == null) + if (item == null || Item == null) return; Scheduler.AddOnce(ApplyState); @@ -130,9 +128,7 @@ namespace osu.Game.Screens.Select.Carousel { // Use the fact that we know the precise height of the item from the model to avoid the need for AutoSize overhead. // Additionally, AutoSize doesn't work well due to content starting off-screen and being masked away. - Height = Item.TotalHeight; - - Debug.Assert(Item != null); + Height = Item!.TotalHeight; switch (Item.State.Value) { @@ -162,7 +158,7 @@ namespace osu.Game.Screens.Select.Carousel protected override bool OnClick(ClickEvent e) { - Item.State.Value = CarouselItemState.Selected; + Item!.State.Value = CarouselItemState.Selected; return true; } } diff --git a/osu.Game/Screens/Select/Carousel/FilterableDifficultyIcon.cs b/osu.Game/Screens/Select/Carousel/FilterableDifficultyIcon.cs index 911b8fd4da..cd8e20ad39 100644 --- a/osu.Game/Screens/Select/Carousel/FilterableDifficultyIcon.cs +++ b/osu.Game/Screens/Select/Carousel/FilterableDifficultyIcon.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Input.Events; diff --git a/osu.Game/Screens/Select/Carousel/GroupedDifficultyIcon.cs b/osu.Game/Screens/Select/Carousel/GroupedDifficultyIcon.cs index 6e01c82a08..3de44fa032 100644 --- a/osu.Game/Screens/Select/Carousel/GroupedDifficultyIcon.cs +++ b/osu.Game/Screens/Select/Carousel/GroupedDifficultyIcon.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics; diff --git a/osu.Game/Screens/Select/Carousel/SetPanelBackground.cs b/osu.Game/Screens/Select/Carousel/SetPanelBackground.cs index a9dc59cc39..6f13a34bfc 100644 --- a/osu.Game/Screens/Select/Carousel/SetPanelBackground.cs +++ b/osu.Game/Screens/Select/Carousel/SetPanelBackground.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; diff --git a/osu.Game/Screens/Select/Carousel/SetPanelContent.cs b/osu.Game/Screens/Select/Carousel/SetPanelContent.cs index 0de507edce..7ca0e92ac8 100644 --- a/osu.Game/Screens/Select/Carousel/SetPanelContent.cs +++ b/osu.Game/Screens/Select/Carousel/SetPanelContent.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; From a32c4a64e74bae35fa294e4d00b1e7d150aa88fe Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 8 Jan 2023 19:18:28 +0100 Subject: [PATCH 1330/2991] Fix errors in test --- .../Visual/SongSelect/TestSceneBeatmapCarousel.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 2d1c5ef120..3cff853f92 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -72,7 +72,7 @@ namespace osu.Game.Tests.Visual.SongSelect var visibleBeatmapPanels = carousel.Items.OfType().Where(p => p.IsPresent).ToArray(); return visibleBeatmapPanels.Length == 1 - && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item).BeatmapInfo.Ruleset.OnlineID == 0) == 1; + && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item)!.BeatmapInfo.Ruleset.OnlineID == 0) == 1; }); AddStep("filter to ruleset 1", () => carousel.Filter(new FilterCriteria @@ -86,8 +86,8 @@ namespace osu.Game.Tests.Visual.SongSelect var visibleBeatmapPanels = carousel.Items.OfType().Where(p => p.IsPresent).ToArray(); return visibleBeatmapPanels.Length == 2 - && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item).BeatmapInfo.Ruleset.OnlineID == 0) == 1 - && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item).BeatmapInfo.Ruleset.OnlineID == 1) == 1; + && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item)!.BeatmapInfo.Ruleset.OnlineID == 0) == 1 + && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item)!.BeatmapInfo.Ruleset.OnlineID == 1) == 1; }); AddStep("filter to ruleset 2", () => carousel.Filter(new FilterCriteria @@ -101,8 +101,8 @@ namespace osu.Game.Tests.Visual.SongSelect var visibleBeatmapPanels = carousel.Items.OfType().Where(p => p.IsPresent).ToArray(); return visibleBeatmapPanels.Length == 2 - && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item).BeatmapInfo.Ruleset.OnlineID == 0) == 1 - && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item).BeatmapInfo.Ruleset.OnlineID == 2) == 1; + && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item!).BeatmapInfo.Ruleset.OnlineID == 0) == 1 + && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item!).BeatmapInfo.Ruleset.OnlineID == 2) == 1; }); } @@ -1069,7 +1069,7 @@ namespace osu.Game.Tests.Visual.SongSelect return Precision.AlmostEquals( carousel.ScreenSpaceDrawQuad.Centre, carousel.Items - .First(i => i.Item.State.Value == CarouselItemState.Selected) + .First(i => i.Item!.State.Value == CarouselItemState.Selected) .ScreenSpaceDrawQuad.Centre, 100); }); } @@ -1103,7 +1103,7 @@ namespace osu.Game.Tests.Visual.SongSelect if (currentlySelected == null) return true; - return currentlySelected.Item.Visible; + return currentlySelected.Item!.Visible; } private void checkInvisibleDifficultiesUnselectable() From f6b1dfc7b0f0f390e9fa9733aa528847a7fa648d Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 28 May 2022 21:41:23 -0700 Subject: [PATCH 1331/2991] Fix channel listing items overflowing at high ui scaling --- .../Chat/Listing/ChannelListingItem.cs | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs b/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs index 22a3bdc06f..9c85c73ee4 100644 --- a/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs +++ b/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs @@ -38,7 +38,7 @@ namespace osu.Game.Overlays.Chat.Listing private Box hoverBox = null!; private SpriteIcon checkbox = null!; private OsuSpriteText channelText = null!; - private OsuSpriteText topicText = null!; + private OsuTextFlowContainer topicText = null!; private IBindable channelJoined = null!; [Resolved] @@ -65,8 +65,8 @@ namespace osu.Game.Overlays.Chat.Listing Masking = true; CornerRadius = 5; - RelativeSizeAxes = Axes.X; - Height = 20 + (vertical_margin * 2); + RelativeSizeAxes = Content.RelativeSizeAxes = Axes.X; + AutoSizeAxes = Content.AutoSizeAxes = Axes.Y; Children = new Drawable[] { @@ -79,14 +79,19 @@ namespace osu.Game.Overlays.Chat.Listing }, new GridContainer { - RelativeSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, ColumnDimensions = new[] { new Dimension(GridSizeMode.Absolute, 40), new Dimension(GridSizeMode.Absolute, 200), - new Dimension(GridSizeMode.Absolute, 400), + new Dimension(maxSize: 400), new Dimension(GridSizeMode.AutoSize), - new Dimension(), + new Dimension(GridSizeMode.Absolute, 50), // enough for any 5 digit user count + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize, minSize: 20 + (vertical_margin * 2)), }, Content = new[] { @@ -108,12 +113,13 @@ namespace osu.Game.Overlays.Chat.Listing Font = OsuFont.Torus.With(size: text_size, weight: FontWeight.SemiBold), Margin = new MarginPadding { Bottom = 2 }, }, - topicText = new OsuSpriteText + topicText = new OsuTextFlowContainer(t => t.Font = OsuFont.Torus.With(size: text_size)) { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Text = Channel.Topic, - Font = OsuFont.Torus.With(size: text_size), Margin = new MarginPadding { Bottom = 2 }, }, new SpriteIcon From c2dd822e4a141f787d65200697ba1ea118493909 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 8 Jan 2023 14:08:36 -0800 Subject: [PATCH 1332/2991] Make pause overlay close with pause gameplay action --- osu.Game/Screens/Play/GameplayMenuOverlay.cs | 2 +- osu.Game/Screens/Play/PauseOverlay.cs | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/GameplayMenuOverlay.cs b/osu.Game/Screens/Play/GameplayMenuOverlay.cs index c681ef8f96..13f32d3b6a 100644 --- a/osu.Game/Screens/Play/GameplayMenuOverlay.cs +++ b/osu.Game/Screens/Play/GameplayMenuOverlay.cs @@ -189,7 +189,7 @@ namespace osu.Game.Screens.Play InternalButtons.Add(button); } - public bool OnPressed(KeyBindingPressEvent e) + public virtual bool OnPressed(KeyBindingPressEvent e) { switch (e.Action) { diff --git a/osu.Game/Screens/Play/PauseOverlay.cs b/osu.Game/Screens/Play/PauseOverlay.cs index 28044653e6..db2b87dae6 100644 --- a/osu.Game/Screens/Play/PauseOverlay.cs +++ b/osu.Game/Screens/Play/PauseOverlay.cs @@ -8,8 +8,10 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Graphics; +using osu.Framework.Input.Events; using osu.Game.Audio; using osu.Game.Graphics; +using osu.Game.Input.Bindings; using osu.Game.Skinning; using osuTK.Graphics; @@ -56,5 +58,17 @@ namespace osu.Game.Screens.Play pauseLoop.VolumeTo(0, TRANSITION_DURATION, Easing.OutQuad).Finally(_ => pauseLoop.Stop()); } + + public override bool OnPressed(KeyBindingPressEvent e) + { + switch (e.Action) + { + case GlobalAction.PauseGameplay: + BackAction.Invoke(); + return true; + } + + return base.OnPressed(e); + } } } From 13b00928c81f9e212c9618108660cfa205c55361 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jan 2023 15:52:08 +0900 Subject: [PATCH 1333/2991] Rename loading spinner bool to reflect that it has a setter --- .../UserInterface/TestSceneCommentEditor.cs | 4 ++-- osu.Game/Overlays/Comments/CommentEditor.cs | 24 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index aeaca5ac21..799f5c52bd 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -120,9 +120,9 @@ namespace osu.Game.Tests.Visual.UserInterface protected override void OnCommit(string value) { - CommitButton.IsLoadingSpinnerShown = true; + CommitButton.ShowLoadingSpinner = true; CommittedText = value; - Scheduler.AddDelayed(() => CommitButton.IsLoadingSpinnerShown = false, 1000); + Scheduler.AddDelayed(() => CommitButton.ShowLoadingSpinner = false, 1000); } protected override LocalisableString FooterText => @"Footer text. And it is pretty long. Cool."; diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index c7c66874d1..da71d0f364 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -2,19 +2,19 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics.Containers; +using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Framework.Graphics.UserInterface; -using osu.Framework.Graphics.Sprites; -using osuTK.Graphics; using osu.Game.Graphics.UserInterface; -using osuTK; -using osu.Framework.Bindables; -using osu.Framework.Localisation; using osu.Game.Graphics.UserInterfaceV2; +using osuTK; +using osuTK.Graphics; namespace osu.Game.Overlays.Comments { @@ -159,17 +159,17 @@ namespace osu.Game.Overlays.Comments public readonly BindableBool IsBlocked = new BindableBool(); - private bool isLoadingSpinnerShown; + private bool showLoadingSpinner; /// /// Whether loading spinner shown. /// - public bool IsLoadingSpinnerShown + public bool ShowLoadingSpinner { - get => isLoadingSpinnerShown; + get => showLoadingSpinner; set { - isLoadingSpinnerShown = value; + showLoadingSpinner = value; Enabled.Value = !value && !IsBlocked.Value; spinner.FadeTo(value ? 1f : 0f, duration, Easing.OutQuint); text.FadeTo(value ? 0f : 1f, duration, Easing.OutQuint); @@ -194,7 +194,7 @@ namespace osu.Game.Overlays.Comments base.LoadComplete(); IsBlocked.BindValueChanged(e => { - Enabled.Value = !IsLoadingSpinnerShown && !e.NewValue; + Enabled.Value = !ShowLoadingSpinner && !e.NewValue; }, true); } From 13c3d2c25444aae1e3c1de607fc566659781a01f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jan 2023 16:15:30 +0900 Subject: [PATCH 1334/2991] Fix retry loop for channel initialisation resulting in request pile-up Closes #22060. --- osu.Game/Online/Chat/ChannelManager.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 5d55374373..9741341efc 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -335,6 +335,11 @@ namespace osu.Game.Online.Chat private void initializeChannels() { + // This request is self-retrying until it succeeds. + // To avoid requests piling up when not logged in (ie. API is unavailable) exit early. + if (api.IsLoggedIn) + return; + var req = new ListChannelsRequest(); bool joinDefaults = JoinedChannels.Count == 0; @@ -350,10 +355,11 @@ namespace osu.Game.Online.Chat joinChannel(ch); } }; + req.Failure += error => { Logger.Error(error, "Fetching channel list failed"); - initializeChannels(); + Scheduler.AddDelayed(initializeChannels, 60000); }; api.Queue(req); From 4a77105e78f15b1a72d1b10a61b6dc5e8346ddc1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jan 2023 16:28:08 +0900 Subject: [PATCH 1335/2991] Rename `LockPlayfieldAspect` and add comment explaining the change --- osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs | 2 +- osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs | 4 ++-- .../UI/TaikoPlayfieldAdjustmentContainer.cs | 9 +++++++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs index f7fdd447d6..3b3b3e606c 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Taiko.Mods public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { drawableTaikoRuleset = (DrawableTaikoRuleset)drawableRuleset; - drawableTaikoRuleset.LockPlayfieldAspect.Value = false; + drawableTaikoRuleset.LockPlayfieldMaxAspect.Value = false; var playfield = (TaikoPlayfield)drawableRuleset.Playfield; playfield.ClassicHitTargetPosition.Value = true; diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs index 32a83d87b8..146daa8c27 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Taiko.UI { public new BindableDouble TimeRange => base.TimeRange; - public readonly BindableBool LockPlayfieldAspect = new BindableBool(true); + public readonly BindableBool LockPlayfieldMaxAspect = new BindableBool(true); protected override ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Overlapping; @@ -78,7 +78,7 @@ namespace osu.Game.Rulesets.Taiko.UI public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new TaikoPlayfieldAdjustmentContainer { - LockPlayfieldAspect = { BindTarget = LockPlayfieldAspect } + LockPlayfieldMaxAspect = { BindTarget = LockPlayfieldMaxAspect } }; protected override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo); diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs index d42aaddf9e..42732d90e4 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Taiko.UI private const float default_relative_height = TaikoPlayfield.DEFAULT_HEIGHT / 768; private const float default_aspect = 16f / 9f; - public readonly IBindable LockPlayfieldAspect = new BindableBool(true); + public readonly IBindable LockPlayfieldMaxAspect = new BindableBool(true); protected override void Update() { @@ -21,7 +21,12 @@ namespace osu.Game.Rulesets.Taiko.UI float height = default_relative_height; - if (LockPlayfieldAspect.Value && Parent.ChildSize.X / Parent.ChildSize.Y > default_aspect) + // Players coming from stable expect to be able to change the aspect ratio regardless of the window size. + // We originally wanted to limit this more, but there was considerable pushback from the community. + // + // As a middle-ground, the aspect ratio can still be adjusted in the downwards direction but has a maximum limit. + // This is still a bit weird, because readability changes with window size, but it is what it is. + if (LockPlayfieldMaxAspect.Value && Parent.ChildSize.X / Parent.ChildSize.Y > default_aspect) height *= Math.Clamp(Parent.ChildSize.X / Parent.ChildSize.Y, 0.4f, 4) / default_aspect; Height = height; From 22d0b34623536c46634982a02e102907b45e22a2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jan 2023 16:38:37 +0900 Subject: [PATCH 1336/2991] Remove flag causing intiialisation to only run once ever --- osu.Game/Online/Chat/ChannelManager.cs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 9741341efc..26ab9e87ba 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -71,7 +71,6 @@ namespace osu.Game.Online.Chat private UserLookupCache users { get; set; } private readonly IBindable apiState = new Bindable(); - private bool channelsInitialised; private ScheduledDelegate scheduledAck; private long? lastSilenceMessageId; @@ -95,15 +94,7 @@ namespace osu.Game.Online.Chat connector.NewMessages += msgs => Schedule(() => addMessages(msgs)); - connector.PresenceReceived += () => Schedule(() => - { - if (!channelsInitialised) - { - channelsInitialised = true; - // we want this to run after the first presence so we can see if the user is in any channels already. - initializeChannels(); - } - }); + connector.PresenceReceived += () => Schedule(initializeChannels); connector.Start(); From efded323e4818172add38612a149c8e8e91c4382 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jan 2023 16:49:36 +0900 Subject: [PATCH 1337/2991] Rename variables and avoid the need for a property --- .../Mods/TestSceneManiaModHidden.cs | 2 +- osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs | 5 +++++ osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs | 4 +--- osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs | 5 +++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs index 44d206d9e1..204f26f151 100644 --- a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs +++ b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModHidden.cs @@ -14,6 +14,6 @@ namespace osu.Game.Rulesets.Mania.Tests.Mods [TestCase(0.5f)] [TestCase(0.2f)] [TestCase(0.8f)] - public void TestCoverage(float coverage) => CreateModTest(new ModTestData { Mod = new ManiaModHidden { CoverageAmount = { Value = coverage } }, PassCondition = () => true }); + public void TestCoverage(float coverage) => CreateModTest(new ModTestData { Mod = new ManiaModHidden { Coverage = { Value = coverage } }, PassCondition = () => true }); } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs index c6e9c339f4..800973ede5 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs @@ -3,6 +3,7 @@ using System; using System.Linq; +using osu.Framework.Bindables; using osu.Framework.Localisation; using osu.Game.Rulesets.Mania.UI; @@ -18,5 +19,9 @@ namespace osu.Game.Rulesets.Mania.Mods public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ManiaModHidden)).ToArray(); protected override CoverExpandDirection ExpandDirection => CoverExpandDirection.AlongScroll; + + // This could be customisable like ManiaModHidden in the future if there's any demand. + // At that point, the bindable could be moved to `ManiaModPlayfieldCover`. + public override BindableNumber Coverage { get; } = new BindableFloat(0.5f); } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs index 2eb9e6d1eb..50d40249c1 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Mania.Mods public override double ScoreMultiplier => 1; [SettingSource("Coverage", "The proportion of playfield height that notes will be hidden for.")] - public BindableNumber CoverageAmount { get; } = new BindableFloat(0.5f) + public override BindableNumber Coverage { get; } = new BindableFloat(0.5f) { Precision = 0.1f, MinValue = 0.2f, @@ -24,8 +24,6 @@ namespace osu.Game.Rulesets.Mania.Mods Default = 0.5f, }; - protected override float Coverage => CoverageAmount.Value; - public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ManiaModFadeIn)).ToArray(); protected override CoverExpandDirection ExpandDirection => CoverExpandDirection.AgainstScroll; diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs index bfb70938b9..45d0184d1d 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs @@ -3,6 +3,7 @@ using System; using System.Linq; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Mania.Objects; @@ -22,7 +23,7 @@ namespace osu.Game.Rulesets.Mania.Mods /// protected abstract CoverExpandDirection ExpandDirection { get; } - protected virtual float Coverage => 0.5f; + public abstract BindableNumber Coverage { get; } public virtual void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { @@ -38,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Mods { c.RelativeSizeAxes = Axes.Both; c.Direction = ExpandDirection; - c.Coverage = Coverage; + c.Coverage = Coverage.Value; })); } } From 15eebd1f50d6aa4e2b666bc80c810b564330f972 Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Mon, 9 Jan 2023 11:47:13 +0200 Subject: [PATCH 1338/2991] Only show message about Songs folder --- osu.Game/Database/LegacyImportManager.cs | 4 ++-- .../Overlays/FirstRunSetup/ScreenImportFromStable.cs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Database/LegacyImportManager.cs b/osu.Game/Database/LegacyImportManager.cs index f9136fa8b6..20738f859e 100644 --- a/osu.Game/Database/LegacyImportManager.cs +++ b/osu.Game/Database/LegacyImportManager.cs @@ -54,14 +54,14 @@ namespace osu.Game.Database public void UpdateStorage(string stablePath) => cachedStorage = new StableStorage(stablePath, gameHost as DesktopGameHost); - public bool CheckHardLinkAvailability() + public bool CheckSongsFolderHardLinkAvailability() { var stableStorage = GetCurrentStableStorage(); if (stableStorage == null || gameHost is not DesktopGameHost desktopGameHost) return false; - string testExistingPath = stableStorage.GetFullPath(string.Empty); + string testExistingPath = stableStorage.GetSongStorage().GetFullPath(string.Empty); string testDestinationPath = desktopGameHost.Storage.GetFullPath(string.Empty); return HardLinkHelper.CheckAvailability(testDestinationPath, testExistingPath); diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index 0a2274575f..ca6e736637 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -122,13 +122,13 @@ namespace osu.Game.Overlays.FirstRunSetup stableLocatorTextBox.Current.Value = storage.GetFullPath(string.Empty); importButton.Enabled.Value = true; - bool available = legacyImportManager.CheckHardLinkAvailability(); - Logger.Log($"Hard link support is {available}"); + bool available = legacyImportManager.CheckSongsFolderHardLinkAvailability(); + Logger.Log($"Hard link support for beatmaps is {available}"); if (available) { copyInformation.Text = - "Data migration will use \"hard links\". No extra disk space will be used, and you can delete either data folder at any point without affecting the other installation. "; + "Beatmap migration will use \"hard links\". No extra disk space will be used, and you can delete beatmaps from either installation at any point without affecting the other. "; copyInformation.AddLink("Learn more about how \"hard links\" work", LinkAction.OpenWiki, @"Client/Release_stream/Lazer/File_storage#via-hard-links"); } @@ -137,8 +137,8 @@ namespace osu.Game.Overlays.FirstRunSetup else { copyInformation.Text = RuntimeInfo.OS == RuntimeInfo.Platform.Windows - ? "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install (and the file system is NTFS). " - : "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install (and the file system supports hard links). "; + ? "A second copy of beatmaps will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous Songs folder (and the file system is NTFS). " + : "A second copy of beatmaps will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous Songs folder (and the file system supports hard links). "; copyInformation.AddLink(GeneralSettingsStrings.ChangeFolderLocation, () => { game?.PerformFromScreen(menu => menu.Push(new MigrationSelectScreen())); From 62ffb4fe78c30da147b82757a5c0d3acfb08a3b3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jan 2023 18:54:11 +0900 Subject: [PATCH 1339/2991] Pause imports during active gameplay --- osu.Game/Beatmaps/BeatmapManager.cs | 4 +++- osu.Game/Database/ModelManager.cs | 6 +++++ .../Database/RealmArchiveModelImporter.cs | 24 ++++++++++++++++++- osu.Game/OsuGame.cs | 4 ++++ osu.Game/Scoring/ScoreManager.cs | 2 ++ osu.Game/Skinning/SkinManager.cs | 2 ++ 6 files changed, 40 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index f0533f27be..623a657cd0 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -62,6 +62,7 @@ namespace osu.Game.Beatmaps BeatmapTrackStore = audioManager.GetTrackStore(userResources); beatmapImporter = CreateBeatmapImporter(storage, realm); + beatmapImporter.PauseImports.BindTo(PauseImports); beatmapImporter.ProcessBeatmap = args => ProcessBeatmap?.Invoke(args); beatmapImporter.PostNotification = obj => PostNotification?.Invoke(obj); @@ -458,7 +459,8 @@ namespace osu.Game.Beatmaps public Task Import(ImportTask[] tasks, ImportParameters parameters = default) => beatmapImporter.Import(tasks, parameters); - public Task>> Import(ProgressNotification notification, ImportTask[] tasks, ImportParameters parameters = default) => beatmapImporter.Import(notification, tasks, parameters); + public Task>> Import(ProgressNotification notification, ImportTask[] tasks, ImportParameters parameters = default) => + beatmapImporter.Import(notification, tasks, parameters); public Task?> Import(ImportTask task, ImportParameters parameters = default, CancellationToken cancellationToken = default) => beatmapImporter.Import(task, parameters, cancellationToken); diff --git a/osu.Game/Database/ModelManager.cs b/osu.Game/Database/ModelManager.cs index 5c106aa493..9a88bd5646 100644 --- a/osu.Game/Database/ModelManager.cs +++ b/osu.Game/Database/ModelManager.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using osu.Framework.Bindables; using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Extensions; @@ -18,6 +19,11 @@ namespace osu.Game.Database public class ModelManager : IModelManager, IModelFileManager where TModel : RealmObject, IHasRealmFiles, IHasGuidPrimaryKey, ISoftDelete { + /// + /// Temporarily pause imports to avoid performance overheads affecting gameplay scenarios. + /// + public readonly BindableBool PauseImports = new BindableBool(); + protected RealmAccess Realm { get; } private readonly RealmFileStore realmFileStore; diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index 4e8b27e0b4..cd86a5a94c 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using Humanizer; +using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Logging; @@ -56,6 +57,11 @@ namespace osu.Game.Database /// private static readonly ThreadedTaskScheduler import_scheduler_batch = new ThreadedTaskScheduler(import_queue_request_concurrency, nameof(RealmArchiveModelImporter)); + /// + /// Temporarily pause imports to avoid performance overheads affecting gameplay scenarios. + /// + public readonly BindableBool PauseImports = new BindableBool(); + public abstract IEnumerable HandledExtensions { get; } protected readonly RealmFileStore Files; @@ -253,7 +259,7 @@ namespace osu.Game.Database /// An optional cancellation token. public virtual Live? ImportModel(TModel item, ArchiveReader? archive = null, ImportParameters parameters = default, CancellationToken cancellationToken = default) => Realm.Run(realm => { - cancellationToken.ThrowIfCancellationRequested(); + pauseIfNecessary(cancellationToken); TModel? existing; @@ -551,6 +557,22 @@ namespace osu.Game.Database /// Whether to perform deletion. protected virtual bool ShouldDeleteArchive(string path) => false; + private void pauseIfNecessary(CancellationToken cancellationToken) + { + if (!PauseImports.Value) + return; + + Logger.Log(@"Import is being paused."); + + while (PauseImports.Value) + { + cancellationToken.ThrowIfCancellationRequested(); + Thread.Sleep(500); + } + + Logger.Log(@"Import is being resumed."); + } + private IEnumerable getIDs(IEnumerable files) { foreach (var f in files.OrderBy(f => f.Filename)) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 6efa3c4172..27152743f8 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -307,6 +307,10 @@ namespace osu.Game // Transfer any runtime changes back to configuration file. SkinManager.CurrentSkinInfo.ValueChanged += skin => configSkin.Value = skin.NewValue.ID.ToString(); + BeatmapManager.PauseImports.BindTo(LocalUserPlaying); + SkinManager.PauseImports.BindTo(LocalUserPlaying); + ScoreManager.PauseImports.BindTo(LocalUserPlaying); + IsActive.BindValueChanged(active => updateActiveState(active.NewValue), true); Audio.AddAdjustment(AdjustableProperty.Volume, inactiveVolumeFade); diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index 5ec96a951b..0852ab43f4 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -38,6 +38,8 @@ namespace osu.Game.Scoring { PostNotification = obj => PostNotification?.Invoke(obj) }; + + scoreImporter.PauseImports.BindTo(PauseImports); } public Score GetScore(ScoreInfo score) => scoreImporter.GetScore(score); diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index f750bfad8a..a0e7037d6d 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -79,6 +79,8 @@ namespace osu.Game.Skinning PostNotification = obj => PostNotification?.Invoke(obj), }; + skinImporter.PauseImports.BindTo(PauseImports); + var defaultSkins = new[] { DefaultClassicSkin = new DefaultLegacySkin(this), From f5c8ba420c4b9693c33f801b9cb5b0757917bc8d Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Mon, 9 Jan 2023 14:53:16 +0200 Subject: [PATCH 1340/2991] Revert message change --- osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index ca6e736637..23f3b3e1af 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -128,7 +128,7 @@ namespace osu.Game.Overlays.FirstRunSetup if (available) { copyInformation.Text = - "Beatmap migration will use \"hard links\". No extra disk space will be used, and you can delete beatmaps from either installation at any point without affecting the other. "; + "Data migration will use \"hard links\". No extra disk space will be used, and you can delete either data folder at any point without affecting the other installation. "; copyInformation.AddLink("Learn more about how \"hard links\" work", LinkAction.OpenWiki, @"Client/Release_stream/Lazer/File_storage#via-hard-links"); } @@ -137,8 +137,8 @@ namespace osu.Game.Overlays.FirstRunSetup else { copyInformation.Text = RuntimeInfo.OS == RuntimeInfo.Platform.Windows - ? "A second copy of beatmaps will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous Songs folder (and the file system is NTFS). " - : "A second copy of beatmaps will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous Songs folder (and the file system supports hard links). "; + ? "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install (and the file system is NTFS). " + : "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install (and the file system supports hard links). "; copyInformation.AddLink(GeneralSettingsStrings.ChangeFolderLocation, () => { game?.PerformFromScreen(menu => menu.Push(new MigrationSelectScreen())); From 811a5626084e86a5fb47d002c2dc89f1f1b98012 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 01:10:20 +0900 Subject: [PATCH 1341/2991] Don't use bindables to avoid potential cross-usage contamination --- osu.Game/Beatmaps/BeatmapManager.cs | 11 ++++++++++- osu.Game/Database/ModelManager.cs | 3 +-- osu.Game/Database/RealmArchiveModelImporter.cs | 7 +++---- osu.Game/OsuGame.cs | 9 ++++++--- osu.Game/Scoring/ScoreManager.cs | 12 ++++++++++-- osu.Game/Skinning/SkinManager.cs | 12 ++++++++++-- 6 files changed, 40 insertions(+), 14 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 623a657cd0..eafd1e96e8 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -44,6 +44,16 @@ namespace osu.Game.Beatmaps public Action<(BeatmapSetInfo beatmapSet, bool isBatch)>? ProcessBeatmap { private get; set; } + public override bool PauseImports + { + get => base.PauseImports; + set + { + base.PauseImports = value; + beatmapImporter.PauseImports = value; + } + } + public BeatmapManager(Storage storage, RealmAccess realm, IAPIProvider? api, AudioManager audioManager, IResourceStore gameResources, GameHost? host = null, WorkingBeatmap? defaultBeatmap = null, BeatmapDifficultyCache? difficultyCache = null, bool performOnlineLookups = false) : base(storage, realm) @@ -62,7 +72,6 @@ namespace osu.Game.Beatmaps BeatmapTrackStore = audioManager.GetTrackStore(userResources); beatmapImporter = CreateBeatmapImporter(storage, realm); - beatmapImporter.PauseImports.BindTo(PauseImports); beatmapImporter.ProcessBeatmap = args => ProcessBeatmap?.Invoke(args); beatmapImporter.PostNotification = obj => PostNotification?.Invoke(obj); diff --git a/osu.Game/Database/ModelManager.cs b/osu.Game/Database/ModelManager.cs index 9a88bd5646..7d1dc5239a 100644 --- a/osu.Game/Database/ModelManager.cs +++ b/osu.Game/Database/ModelManager.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; -using osu.Framework.Bindables; using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Extensions; @@ -22,7 +21,7 @@ namespace osu.Game.Database /// /// Temporarily pause imports to avoid performance overheads affecting gameplay scenarios. /// - public readonly BindableBool PauseImports = new BindableBool(); + public virtual bool PauseImports { get; set; } protected RealmAccess Realm { get; } diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index cd86a5a94c..1fe1569d36 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -8,7 +8,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using Humanizer; -using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Logging; @@ -60,7 +59,7 @@ namespace osu.Game.Database /// /// Temporarily pause imports to avoid performance overheads affecting gameplay scenarios. /// - public readonly BindableBool PauseImports = new BindableBool(); + public bool PauseImports { get; set; } public abstract IEnumerable HandledExtensions { get; } @@ -559,12 +558,12 @@ namespace osu.Game.Database private void pauseIfNecessary(CancellationToken cancellationToken) { - if (!PauseImports.Value) + if (!PauseImports) return; Logger.Log(@"Import is being paused."); - while (PauseImports.Value) + while (PauseImports) { cancellationToken.ThrowIfCancellationRequested(); Thread.Sleep(500); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 27152743f8..dc4d56de11 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -307,9 +307,12 @@ namespace osu.Game // Transfer any runtime changes back to configuration file. SkinManager.CurrentSkinInfo.ValueChanged += skin => configSkin.Value = skin.NewValue.ID.ToString(); - BeatmapManager.PauseImports.BindTo(LocalUserPlaying); - SkinManager.PauseImports.BindTo(LocalUserPlaying); - ScoreManager.PauseImports.BindTo(LocalUserPlaying); + LocalUserPlaying.BindValueChanged(p => + { + BeatmapManager.PauseImports = p.NewValue; + SkinManager.PauseImports = p.NewValue; + ScoreManager.PauseImports = p.NewValue; + }, true); IsActive.BindValueChanged(active => updateActiveState(active.NewValue), true); diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index 0852ab43f4..3217c79768 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -28,6 +28,16 @@ namespace osu.Game.Scoring private readonly OsuConfigManager configManager; private readonly ScoreImporter scoreImporter; + public override bool PauseImports + { + get => base.PauseImports; + set + { + base.PauseImports = value; + scoreImporter.PauseImports = value; + } + } + public ScoreManager(RulesetStore rulesets, Func beatmaps, Storage storage, RealmAccess realm, IAPIProvider api, OsuConfigManager configManager = null) : base(storage, realm) @@ -38,8 +48,6 @@ namespace osu.Game.Scoring { PostNotification = obj => PostNotification?.Invoke(obj) }; - - scoreImporter.PauseImports.BindTo(PauseImports); } public Score GetScore(ScoreInfo score) => scoreImporter.GetScore(score); diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index a0e7037d6d..a4cf83b32e 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -64,6 +64,16 @@ namespace osu.Game.Skinning private Skin trianglesSkin { get; } + public override bool PauseImports + { + get => base.PauseImports; + set + { + base.PauseImports = value; + skinImporter.PauseImports = value; + } + } + public SkinManager(Storage storage, RealmAccess realm, GameHost host, IResourceStore resources, AudioManager audio, Scheduler scheduler) : base(storage, realm) { @@ -79,8 +89,6 @@ namespace osu.Game.Skinning PostNotification = obj => PostNotification?.Invoke(obj), }; - skinImporter.PauseImports.BindTo(PauseImports); - var defaultSkins = new[] { DefaultClassicSkin = new DefaultLegacySkin(this), From e35f63c001704e6914e1925955b4ddae4b0731c3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 01:37:16 +0900 Subject: [PATCH 1342/2991] Ensure screenshot filenames are unique by locking over file creation --- osu.Game/Graphics/ScreenshotManager.cs | 40 +++++++++++++++----------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/osu.Game/Graphics/ScreenshotManager.cs b/osu.Game/Graphics/ScreenshotManager.cs index 29e9b0276c..d799e82bc9 100644 --- a/osu.Game/Graphics/ScreenshotManager.cs +++ b/osu.Game/Graphics/ScreenshotManager.cs @@ -4,6 +4,7 @@ #nullable disable using System; +using System.IO; using System.Threading; using System.Threading.Tasks; using osu.Framework.Allocation; @@ -117,11 +118,11 @@ namespace osu.Game.Graphics host.GetClipboard()?.SetImage(image); - string filename = getFilename(); + (string filename, var stream) = getWritableStream(); if (filename == null) return; - using (var stream = storage.CreateFileSafely(filename)) + using (stream) { switch (screenshotFormat.Value) { @@ -142,7 +143,7 @@ namespace osu.Game.Graphics notificationOverlay.Post(new SimpleNotification { - Text = $"{filename} saved!", + Text = $"Screenshot {filename} saved!", Activated = () => { storage.PresentFileExternally(filename); @@ -152,23 +153,28 @@ namespace osu.Game.Graphics } }); - private string getFilename() + private static readonly object filename_reservation_lock = new object(); + + private (string filename, Stream stream) getWritableStream() { - var dt = DateTime.Now; - string fileExt = screenshotFormat.ToString().ToLowerInvariant(); - - string withoutIndex = $"osu_{dt:yyyy-MM-dd_HH-mm-ss}.{fileExt}"; - if (!storage.Exists(withoutIndex)) - return withoutIndex; - - for (ulong i = 1; i < ulong.MaxValue; i++) + lock (filename_reservation_lock) { - string indexedName = $"osu_{dt:yyyy-MM-dd_HH-mm-ss}-{i}.{fileExt}"; - if (!storage.Exists(indexedName)) - return indexedName; - } + var dt = DateTime.Now; + string fileExt = screenshotFormat.ToString().ToLowerInvariant(); - return null; + string withoutIndex = $"osu_{dt:yyyy-MM-dd_HH-mm-ss}.{fileExt}"; + if (!storage.Exists(withoutIndex)) + return (withoutIndex, storage.GetStream(withoutIndex, FileAccess.Write, FileMode.Create)); + + for (ulong i = 1; i < ulong.MaxValue; i++) + { + string indexedName = $"osu_{dt:yyyy-MM-dd_HH-mm-ss}-{i}.{fileExt}"; + if (!storage.Exists(indexedName)) + return (indexedName, storage.GetStream(indexedName, FileAccess.Write, FileMode.Create)); + } + + return (null, null); + } } } } From fdf0d4bd620208fdbcbee3fb35c7ed051b2015fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 9 Jan 2023 17:37:28 +0100 Subject: [PATCH 1343/2991] Rename `UserProfile{ -> Data}` --- .../Online/TestSceneHistoricalSection.cs | 4 ++-- .../Online/TestScenePlayHistorySubsection.cs | 18 +++++++++--------- .../Online/TestSceneUserProfileHeader.cs | 10 +++++----- .../Visual/Online/TestSceneUserRanks.cs | 2 +- .../Profile/Header/BottomHeaderContainer.cs | 2 +- .../Profile/Header/CentreHeaderContainer.cs | 2 +- .../Header/Components/FollowersButton.cs | 2 +- .../Profile/Header/Components/LevelBadge.cs | 2 +- .../Header/Components/LevelProgressBar.cs | 2 +- .../Components/MappingSubscribersButton.cs | 2 +- .../Header/Components/MessageUserButton.cs | 2 +- .../Components/OverlinedTotalPlayTime.cs | 4 ++-- .../Profile/Header/DetailHeaderContainer.cs | 4 ++-- .../Profile/Header/MedalHeaderContainer.cs | 2 +- .../Profile/Header/TopHeaderContainer.cs | 4 ++-- osu.Game/Overlays/Profile/ProfileHeader.cs | 4 ++-- osu.Game/Overlays/Profile/ProfileSection.cs | 2 +- .../Beatmaps/PaginatedBeatmapContainer.cs | 2 +- .../Historical/ChartProfileSubsection.cs | 4 ++-- .../PaginatedMostPlayedBeatmapContainer.cs | 2 +- .../Historical/PlayHistorySubsection.cs | 2 +- .../Sections/Historical/ReplaysSubsection.cs | 2 +- .../Profile/Sections/Kudosu/KudosuInfo.cs | 4 ++-- .../Kudosu/PaginatedKudosuHistoryContainer.cs | 2 +- .../Sections/PaginatedProfileSubsection.cs | 4 ++-- .../Profile/Sections/ProfileSubsection.cs | 4 ++-- .../Sections/Ranks/PaginatedScoreContainer.cs | 2 +- .../Recent/PaginatedRecentActivityContainer.cs | 2 +- .../{UserProfile.cs => UserProfileData.cs} | 4 ++-- osu.Game/Overlays/UserProfileOverlay.cs | 2 +- 30 files changed, 52 insertions(+), 52 deletions(-) rename osu.Game/Overlays/Profile/{UserProfile.cs => UserProfileData.cs} (88%) diff --git a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs index 92bb41b7d5..0603fa3250 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs @@ -38,8 +38,8 @@ namespace osu.Game.Tests.Visual.Online Child = section = new HistoricalSection(), }); - AddStep("Show peppy", () => section.UserProfile.Value = new UserProfile(new APIUser { Id = 2 })); - AddStep("Show WubWoofWolf", () => section.UserProfile.Value = new UserProfile(new APIUser { Id = 39828 })); + AddStep("Show peppy", () => section.UserProfile.Value = new UserProfileData(new APIUser { Id = 2 })); + AddStep("Show WubWoofWolf", () => section.UserProfile.Value = new UserProfileData(new APIUser { Id = 39828 })); } } } diff --git a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs index a486d77f97..8bd4e398e4 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Online [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Red); - private readonly Bindable user = new Bindable(); + private readonly Bindable user = new Bindable(); private readonly PlayHistorySubsection section; public TestScenePlayHistorySubsection() @@ -44,49 +44,49 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestNullValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_null_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_null_values)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestEmptyValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_empty_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_empty_values)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestOneValue() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_one_value)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_one_value)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestTwoValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_two_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_two_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_constant_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_constant_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantZeroValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_zero_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_zero_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestFilledValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_filled_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_filled_values)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is the same", () => user_with_filled_values.MonthlyPlayCounts.Length == getChartValuesLength()); } @@ -94,7 +94,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestMissingValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_missing_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_missing_values)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is 7", () => getChartValuesLength() == 7); } diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index 4caab98f63..75de033497 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -29,13 +29,13 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestBasic() { - AddStep("Show example user", () => header.UserProfile.Value = new UserProfile(TestSceneUserProfileOverlay.TEST_USER)); + AddStep("Show example user", () => header.UserProfile.Value = new UserProfileData(TestSceneUserProfileOverlay.TEST_USER)); } [Test] public void TestOnlineState() { - AddStep("Show online user", () => header.UserProfile.Value = new UserProfile(new APIUser + AddStep("Show online user", () => header.UserProfile.Value = new UserProfileData(new APIUser { Id = 1001, Username = "IAmOnline", @@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual.Online IsOnline = true, })); - AddStep("Show offline user", () => header.UserProfile.Value = new UserProfile(new APIUser + AddStep("Show offline user", () => header.UserProfile.Value = new UserProfileData(new APIUser { Id = 1002, Username = "IAmOffline", @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestRankedState() { - AddStep("Show ranked user", () => header.UserProfile.Value = new UserProfile(new APIUser + AddStep("Show ranked user", () => header.UserProfile.Value = new UserProfileData(new APIUser { Id = 2001, Username = "RankedUser", @@ -72,7 +72,7 @@ namespace osu.Game.Tests.Visual.Online } })); - AddStep("Show unranked user", () => header.UserProfile.Value = new UserProfile(new APIUser + AddStep("Show unranked user", () => header.UserProfile.Value = new UserProfileData(new APIUser { Id = 2002, Username = "UnrankedUser", diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs index 184b969279..503719add4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Online } }); - AddStep("Show cookiezi", () => ranks.UserProfile.Value = new UserProfile(new APIUser { Id = 124493 })); + AddStep("Show cookiezi", () => ranks.UserProfile.Value = new UserProfileData(new APIUser { Id = 124493 })); } } } diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 64a333dff7..a13f3585a5 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.Profile.Header { public partial class BottomHeaderContainer : CompositeDrawable { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); private LinkFlowContainer topLinkContainer = null!; private LinkFlowContainer bottomLinkContainer = null!; diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 701c4a1464..6675b5f52a 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Header public partial class CentreHeaderContainer : CompositeDrawable { public readonly BindableBool DetailsVisible = new BindableBool(true); - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); private OverlinedInfoContainer hiddenDetailGlobal = null!; private OverlinedInfoContainer hiddenDetailCountry = null!; diff --git a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs index 48e9718a7c..959212413f 100644 --- a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class FollowersButton : ProfileHeaderStatisticsButton { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public override LocalisableString TooltipText => FriendsStrings.ButtonsDisabled; diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index f68c9838a0..3e5582a1c8 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelBadge : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public LocalisableString TooltipText { get; private set; } diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs index e3100c5af5..69be4c7b7a 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelProgressBar : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public LocalisableString TooltipText { get; } diff --git a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs index 29b42cb223..cae407ef91 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class MappingSubscribersButton : ProfileHeaderStatisticsButton { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public override LocalisableString TooltipText => FollowsStrings.MappingFollowers; diff --git a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs index f57b43c3a4..45e20957c8 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs @@ -15,7 +15,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class MessageUserButton : ProfileHeaderButton { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public override LocalisableString TooltipText => UsersStrings.CardSendMessage; diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs index 1de13ba7c7..687382ed90 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class OverlinedTotalPlayTime : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public LocalisableString TooltipText { get; set; } @@ -38,7 +38,7 @@ namespace osu.Game.Overlays.Profile.Header.Components UserProfile.BindValueChanged(updateTime, true); } - private void updateTime(ValueChangedEvent userProfile) + private void updateTime(ValueChangedEvent userProfile) { int? playTime = userProfile.NewValue?.User.Statistics?.PlayTime; TooltipText = (playTime ?? 0) / 3600 + " hours"; diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 8b9a90c9a3..b7b9fd52c7 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Profile.Header private FillFlowContainer? fillFlow; private RankGraph rankGraph = null!; - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); private bool expanded = true; @@ -170,7 +170,7 @@ namespace osu.Game.Overlays.Profile.Header }; } - private void updateDisplay(UserProfile? userProfile) + private void updateDisplay(UserProfileData? userProfile) { var user = userProfile?.User; diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index b41c60ed4e..df51a82cc9 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Profile.Header { private FillFlowContainer badgeFlowContainer = null!; - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 69258c914f..0889c36b16 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Profile.Header { private const float avatar_size = 110; - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); [Resolved] private IAPIProvider api { get; set; } = null!; @@ -173,7 +173,7 @@ namespace osu.Game.Overlays.Profile.Header UserProfile.BindValueChanged(user => updateUser(user.NewValue)); } - private void updateUser(UserProfile? userProfile) + private void updateUser(UserProfileData? userProfile) { var user = userProfile?.User; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 447e9148e8..f87ee707ff 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile { private UserCoverBackground coverContainer = null!; - public Bindable UserProfile = new Bindable(); + public Bindable UserProfile = new Bindable(); private CentreHeaderContainer centreHeaderContainer; private DetailHeaderContainer detailHeaderContainer; @@ -99,7 +99,7 @@ namespace osu.Game.Overlays.Profile protected override OverlayTitle CreateTitle() => new ProfileHeaderTitle(); - private void updateDisplay(UserProfile? userProfile) => coverContainer.User = userProfile?.User; + private void updateDisplay(UserProfileData? userProfile) => coverContainer.User = userProfile?.User; private partial class ProfileHeaderTitle : OverlayTitle { diff --git a/osu.Game/Overlays/Profile/ProfileSection.cs b/osu.Game/Overlays/Profile/ProfileSection.cs index 97b8f2b13f..1e85411bc6 100644 --- a/osu.Game/Overlays/Profile/ProfileSection.cs +++ b/osu.Game/Overlays/Profile/ProfileSection.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Profile protected override Container Content => content; - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); protected ProfileSection() { diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index 3b1f26ee7d..0e74aba369 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps protected override int InitialItemsCount => type == BeatmapSetType.Graveyard ? 2 : 6; - public PaginatedBeatmapContainer(BeatmapSetType type, Bindable user, LocalisableString headerText) + public PaginatedBeatmapContainer(BeatmapSetType type, Bindable user, LocalisableString headerText) : base(user, headerText) { this.type = type; diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs index 724733c7a9..0ba93200d9 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical /// protected abstract LocalisableString GraphCounterName { get; } - protected ChartProfileSubsection(Bindable userProfile, LocalisableString headerText) + protected ChartProfileSubsection(Bindable userProfile, LocalisableString headerText) : base(userProfile, headerText) { } @@ -44,7 +44,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical UserProfile.BindValueChanged(onUserChanged, true); } - private void onUserChanged(ValueChangedEvent e) + private void onUserChanged(ValueChangedEvent e) { var values = GetValues(e.NewValue?.User); diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs index 5851262229..6b08b68962 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs @@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { public partial class PaginatedMostPlayedBeatmapContainer : PaginatedProfileSubsection { - public PaginatedMostPlayedBeatmapContainer(Bindable userProfile) + public PaginatedMostPlayedBeatmapContainer(Bindable userProfile) : base(userProfile, UsersStrings.ShowExtraHistoricalMostPlayedTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs index 5fa58dbdab..5d83610f84 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs @@ -12,7 +12,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalMonthlyPlaycountsCountLabel; - public PlayHistorySubsection(Bindable userProfile) + public PlayHistorySubsection(Bindable userProfile) : base(userProfile, UsersStrings.ShowExtraHistoricalMonthlyPlaycountsTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs index 04e70afa36..0a82f79310 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs @@ -12,7 +12,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalReplaysWatchedCountsCountLabel; - public ReplaysSubsection(Bindable userProfile) + public ReplaysSubsection(Bindable userProfile) : base(userProfile, UsersStrings.ShowExtraHistoricalReplaysWatchedCountsTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs index 7fd0759fac..c2de0efb69 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs @@ -19,9 +19,9 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class KudosuInfo : Container { - private readonly Bindable userProfile = new Bindable(); + private readonly Bindable userProfile = new Bindable(); - public KudosuInfo(Bindable userProfile) + public KudosuInfo(Bindable userProfile) { this.userProfile.BindTo(userProfile); CountSection total; diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs index 6addd86894..0173e7ce74 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs @@ -14,7 +14,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class PaginatedKudosuHistoryContainer : PaginatedProfileSubsection { - public PaginatedKudosuHistoryContainer(Bindable userProfile) + public PaginatedKudosuHistoryContainer(Bindable userProfile) : base(userProfile, missingText: UsersStrings.ShowExtraKudosuEntryEmpty) { } diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs index d77844fd56..df881ad2a7 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs @@ -46,7 +46,7 @@ namespace osu.Game.Overlays.Profile.Sections private OsuSpriteText missing = null!; private readonly LocalisableString? missingText; - protected PaginatedProfileSubsection(Bindable userProfile, LocalisableString? headerText = null, LocalisableString? missingText = null) + protected PaginatedProfileSubsection(Bindable userProfile, LocalisableString? headerText = null, LocalisableString? missingText = null) : base(userProfile, headerText, CounterVisibilityState.AlwaysVisible) { this.missingText = missingText; @@ -92,7 +92,7 @@ namespace osu.Game.Overlays.Profile.Sections UserProfile.BindValueChanged(onUserChanged, true); } - private void onUserChanged(ValueChangedEvent e) + private void onUserChanged(ValueChangedEvent e) { loadCancellation?.Cancel(); retrievalRequest?.Cancel(); diff --git a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs index 5df8688659..e85d5f22ef 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs @@ -11,14 +11,14 @@ namespace osu.Game.Overlays.Profile.Sections { public abstract partial class ProfileSubsection : FillFlowContainer { - protected readonly Bindable UserProfile = new Bindable(); + protected readonly Bindable UserProfile = new Bindable(); private readonly LocalisableString headerText; private readonly CounterVisibilityState counterVisibilityState; private ProfileSubsectionHeader header = null!; - protected ProfileSubsection(Bindable userProfile, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) + protected ProfileSubsection(Bindable userProfile, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) { this.headerText = headerText ?? string.Empty; this.counterVisibilityState = counterVisibilityState; diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index cdd1738c8e..968deecad4 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { private readonly ScoreType type; - public PaginatedScoreContainer(ScoreType type, Bindable userProfile, LocalisableString headerText) + public PaginatedScoreContainer(ScoreType type, Bindable userProfile, LocalisableString headerText) : base(userProfile, headerText) { this.type = type; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index c08ea58b5a..ad7242c339 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { public partial class PaginatedRecentActivityContainer : PaginatedProfileSubsection { - public PaginatedRecentActivityContainer(Bindable userProfile) + public PaginatedRecentActivityContainer(Bindable userProfile) : base(userProfile, missingText: EventsStrings.Empty) { } diff --git a/osu.Game/Overlays/Profile/UserProfile.cs b/osu.Game/Overlays/Profile/UserProfileData.cs similarity index 88% rename from osu.Game/Overlays/Profile/UserProfile.cs rename to osu.Game/Overlays/Profile/UserProfileData.cs index 12a469ddf9..1a1cb8f7d4 100644 --- a/osu.Game/Overlays/Profile/UserProfile.cs +++ b/osu.Game/Overlays/Profile/UserProfileData.cs @@ -8,7 +8,7 @@ namespace osu.Game.Overlays.Profile /// /// Contains data about a profile presented on the . /// - public class UserProfile + public class UserProfileData { /// /// The user whose profile is being presented. @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Profile // TODO: add ruleset - public UserProfile(APIUser user) + public UserProfileData(APIUser user) { User = user; } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 5ec92efdbb..40933d9179 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -125,7 +125,7 @@ namespace osu.Game.Overlays { Debug.Assert(sections != null && sectionsContainer != null && tabs != null); - var userProfile = new UserProfile(user); + var userProfile = new UserProfileData(user); Header.UserProfile.Value = userProfile; if (user.ProfileOrder != null) From 4dec3cae5709309f35f7aad2337cf2fdbf4fef8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 9 Jan 2023 17:46:08 +0100 Subject: [PATCH 1344/2991] Rename `UserProfileData`-related symbols --- .../Online/TestSceneHistoricalSection.cs | 4 ++-- .../Online/TestScenePlayHistorySubsection.cs | 20 +++++++++---------- .../Online/TestSceneUserProfileHeader.cs | 10 +++++----- .../Visual/Online/TestSceneUserRanks.cs | 2 +- .../Profile/Header/BottomHeaderContainer.cs | 4 ++-- .../Profile/Header/CentreHeaderContainer.cs | 14 ++++++------- .../Header/Components/FollowersButton.cs | 4 ++-- .../Profile/Header/Components/LevelBadge.cs | 4 ++-- .../Header/Components/LevelProgressBar.cs | 4 ++-- .../Components/MappingSubscribersButton.cs | 4 ++-- .../Header/Components/MessageUserButton.cs | 6 +++--- .../Components/OverlinedTotalPlayTime.cs | 8 ++++---- .../Profile/Header/DetailHeaderContainer.cs | 10 +++++----- .../Profile/Header/MedalHeaderContainer.cs | 4 ++-- .../Profile/Header/TopHeaderContainer.cs | 8 ++++---- osu.Game/Overlays/Profile/ProfileHeader.cs | 16 +++++++-------- osu.Game/Overlays/Profile/ProfileSection.cs | 2 +- .../Beatmaps/PaginatedBeatmapContainer.cs | 4 ++-- .../Profile/Sections/BeatmapsSection.cs | 14 ++++++------- .../Historical/ChartProfileSubsection.cs | 4 ++-- .../PaginatedMostPlayedBeatmapContainer.cs | 4 ++-- .../Historical/PlayHistorySubsection.cs | 4 ++-- .../Sections/Historical/ReplaysSubsection.cs | 4 ++-- .../Profile/Sections/HistoricalSection.cs | 8 ++++---- .../Profile/Sections/Kudosu/KudosuInfo.cs | 8 ++++---- .../Kudosu/PaginatedKudosuHistoryContainer.cs | 4 ++-- .../Profile/Sections/KudosuSection.cs | 4 ++-- .../Sections/PaginatedProfileSubsection.cs | 4 ++-- .../Profile/Sections/ProfileSubsection.cs | 4 ++-- .../Sections/Ranks/PaginatedScoreContainer.cs | 4 ++-- .../Overlays/Profile/Sections/RanksSection.cs | 6 +++--- .../PaginatedRecentActivityContainer.cs | 4 ++-- .../Profile/Sections/RecentSection.cs | 2 +- osu.Game/Overlays/UserProfileOverlay.cs | 6 +++--- 34 files changed, 106 insertions(+), 106 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs index 0603fa3250..78e0c6fce4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs @@ -38,8 +38,8 @@ namespace osu.Game.Tests.Visual.Online Child = section = new HistoricalSection(), }); - AddStep("Show peppy", () => section.UserProfile.Value = new UserProfileData(new APIUser { Id = 2 })); - AddStep("Show WubWoofWolf", () => section.UserProfile.Value = new UserProfileData(new APIUser { Id = 39828 })); + AddStep("Show peppy", () => section.UserProfileData.Value = new UserProfileData(new APIUser { Id = 2 })); + AddStep("Show WubWoofWolf", () => section.UserProfileData.Value = new UserProfileData(new APIUser { Id = 39828 })); } } } diff --git a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs index 8bd4e398e4..634b9df212 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Online [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Red); - private readonly Bindable user = new Bindable(); + private readonly Bindable userProfileData = new Bindable(); private readonly PlayHistorySubsection section; public TestScenePlayHistorySubsection() @@ -33,7 +33,7 @@ namespace osu.Game.Tests.Visual.Online RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background4 }, - section = new PlayHistorySubsection(user) + section = new PlayHistorySubsection(userProfileData) { Anchor = Anchor.Centre, Origin = Anchor.Centre @@ -44,49 +44,49 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestNullValues() { - AddStep("Load user", () => user.Value = new UserProfileData(user_with_null_values)); + AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_null_values)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestEmptyValues() { - AddStep("Load user", () => user.Value = new UserProfileData(user_with_empty_values)); + AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_empty_values)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestOneValue() { - AddStep("Load user", () => user.Value = new UserProfileData(user_with_one_value)); + AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_one_value)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestTwoValues() { - AddStep("Load user", () => user.Value = new UserProfileData(user_with_two_values)); + AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_two_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantValues() { - AddStep("Load user", () => user.Value = new UserProfileData(user_with_constant_values)); + AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_constant_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantZeroValues() { - AddStep("Load user", () => user.Value = new UserProfileData(user_with_zero_values)); + AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_zero_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestFilledValues() { - AddStep("Load user", () => user.Value = new UserProfileData(user_with_filled_values)); + AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_filled_values)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is the same", () => user_with_filled_values.MonthlyPlayCounts.Length == getChartValuesLength()); } @@ -94,7 +94,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestMissingValues() { - AddStep("Load user", () => user.Value = new UserProfileData(user_with_missing_values)); + AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_missing_values)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is 7", () => getChartValuesLength() == 7); } diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index 75de033497..9b565c1276 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -29,13 +29,13 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestBasic() { - AddStep("Show example user", () => header.UserProfile.Value = new UserProfileData(TestSceneUserProfileOverlay.TEST_USER)); + AddStep("Show example user", () => header.UserProfileData.Value = new UserProfileData(TestSceneUserProfileOverlay.TEST_USER)); } [Test] public void TestOnlineState() { - AddStep("Show online user", () => header.UserProfile.Value = new UserProfileData(new APIUser + AddStep("Show online user", () => header.UserProfileData.Value = new UserProfileData(new APIUser { Id = 1001, Username = "IAmOnline", @@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual.Online IsOnline = true, })); - AddStep("Show offline user", () => header.UserProfile.Value = new UserProfileData(new APIUser + AddStep("Show offline user", () => header.UserProfileData.Value = new UserProfileData(new APIUser { Id = 1002, Username = "IAmOffline", @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestRankedState() { - AddStep("Show ranked user", () => header.UserProfile.Value = new UserProfileData(new APIUser + AddStep("Show ranked user", () => header.UserProfileData.Value = new UserProfileData(new APIUser { Id = 2001, Username = "RankedUser", @@ -72,7 +72,7 @@ namespace osu.Game.Tests.Visual.Online } })); - AddStep("Show unranked user", () => header.UserProfile.Value = new UserProfileData(new APIUser + AddStep("Show unranked user", () => header.UserProfileData.Value = new UserProfileData(new APIUser { Id = 2002, Username = "UnrankedUser", diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs index 503719add4..6ec7ea008b 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Online } }); - AddStep("Show cookiezi", () => ranks.UserProfile.Value = new UserProfileData(new APIUser { Id = 124493 })); + AddStep("Show cookiezi", () => ranks.UserProfileData.Value = new UserProfileData(new APIUser { Id = 124493 })); } } } diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index a13f3585a5..091d04ad35 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.Profile.Header { public partial class BottomHeaderContainer : CompositeDrawable { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); private LinkFlowContainer topLinkContainer = null!; private LinkFlowContainer bottomLinkContainer = null!; @@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Profile.Header } }; - UserProfile.BindValueChanged(user => updateDisplay(user.NewValue?.User)); + UserProfileData.BindValueChanged(data => updateDisplay(data.NewValue?.User)); } private void updateDisplay(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 6675b5f52a..8910d3dc3b 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Header public partial class CentreHeaderContainer : CompositeDrawable { public readonly BindableBool DetailsVisible = new BindableBool(true); - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); private OverlinedInfoContainer hiddenDetailGlobal = null!; private OverlinedInfoContainer hiddenDetailCountry = null!; @@ -53,15 +53,15 @@ namespace osu.Game.Overlays.Profile.Header { new FollowersButton { - UserProfile = { BindTarget = UserProfile } + UserProfileData = { BindTarget = UserProfileData } }, new MappingSubscribersButton { - UserProfile = { BindTarget = UserProfile } + UserProfileData = { BindTarget = UserProfileData } }, new MessageUserButton { - UserProfile = { BindTarget = UserProfile } + UserProfileData = { BindTarget = UserProfileData } }, } }, @@ -92,7 +92,7 @@ namespace osu.Game.Overlays.Profile.Header Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Size = new Vector2(40), - UserProfile = { BindTarget = UserProfile } + UserProfileData = { BindTarget = UserProfileData } }, expandedDetailContainer = new Container { @@ -104,7 +104,7 @@ namespace osu.Game.Overlays.Profile.Header Child = new LevelProgressBar { RelativeSizeAxes = Axes.Both, - UserProfile = { BindTarget = UserProfile } + UserProfileData = { BindTarget = UserProfileData } } }, hiddenDetailContainer = new FillFlowContainer @@ -141,7 +141,7 @@ namespace osu.Game.Overlays.Profile.Header expandedDetailContainer.FadeTo(visible.NewValue ? 1 : 0, 200, Easing.OutQuint); }); - UserProfile.BindValueChanged(userProfile => updateDisplay(userProfile.NewValue?.User)); + UserProfileData.BindValueChanged(data => updateDisplay(data.NewValue?.User)); } private void updateDisplay(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs index 959212413f..a73b3444f6 100644 --- a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class FollowersButton : ProfileHeaderStatisticsButton { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); public override LocalisableString TooltipText => FriendsStrings.ButtonsDisabled; @@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Profile.Header.Components private void load() { // todo: when friending/unfriending is implemented, the APIAccess.Friends list should be updated accordingly. - UserProfile.BindValueChanged(user => SetValue(user.NewValue?.User.FollowerCount ?? 0), true); + UserProfileData.BindValueChanged(data => SetValue(data.NewValue?.User.FollowerCount ?? 0), true); } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index 3e5582a1c8..501c7bd41b 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelBadge : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); public LocalisableString TooltipText { get; private set; } @@ -48,7 +48,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; - UserProfile.BindValueChanged(user => updateLevel(user.NewValue?.User)); + UserProfileData.BindValueChanged(data => updateLevel(data.NewValue?.User)); } private void updateLevel(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs index 69be4c7b7a..6a5827a867 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelProgressBar : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); public LocalisableString TooltipText { get; } @@ -56,7 +56,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; - UserProfile.BindValueChanged(user => updateProgress(user.NewValue?.User)); + UserProfileData.BindValueChanged(data => updateProgress(data.NewValue?.User)); } private void updateProgress(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs index cae407ef91..7265302a88 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class MappingSubscribersButton : ProfileHeaderStatisticsButton { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); public override LocalisableString TooltipText => FollowsStrings.MappingFollowers; @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Profile.Header.Components [BackgroundDependencyLoader] private void load() { - UserProfile.BindValueChanged(user => SetValue(user.NewValue?.User.MappingFollowerCount ?? 0), true); + UserProfileData.BindValueChanged(data => SetValue(data.NewValue?.User.MappingFollowerCount ?? 0), true); } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs index 45e20957c8..0b9fa437c2 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs @@ -15,7 +15,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class MessageUserButton : ProfileHeaderButton { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); public override LocalisableString TooltipText => UsersStrings.CardSendMessage; @@ -48,12 +48,12 @@ namespace osu.Game.Overlays.Profile.Header.Components { if (!Content.IsPresent) return; - channelManager?.OpenPrivateChannel(UserProfile.Value?.User); + channelManager?.OpenPrivateChannel(UserProfileData.Value?.User); userOverlay?.Hide(); chatOverlay?.Show(); }; - UserProfile.ValueChanged += e => + UserProfileData.ValueChanged += e => { var user = e.NewValue?.User; Content.Alpha = user != null && !user.PMFriendsOnly && apiProvider.LocalUser.Value.Id != user.Id ? 1 : 0; diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs index 687382ed90..c2db9d8273 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class OverlinedTotalPlayTime : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); public LocalisableString TooltipText { get; set; } @@ -35,12 +35,12 @@ namespace osu.Game.Overlays.Profile.Header.Components LineColour = colourProvider.Highlight1, }; - UserProfile.BindValueChanged(updateTime, true); + UserProfileData.BindValueChanged(updateTime, true); } - private void updateTime(ValueChangedEvent userProfile) + private void updateTime(ValueChangedEvent data) { - int? playTime = userProfile.NewValue?.User.Statistics?.PlayTime; + int? playTime = data.NewValue?.User.Statistics?.PlayTime; TooltipText = (playTime ?? 0) / 3600 + " hours"; info.Content = formatTime(playTime); } diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index b7b9fd52c7..d2986c343d 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Profile.Header private FillFlowContainer? fillFlow; private RankGraph rankGraph = null!; - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); private bool expanded = true; @@ -60,7 +60,7 @@ namespace osu.Game.Overlays.Profile.Header { AutoSizeAxes = Axes.Y; - UserProfile.ValueChanged += e => updateDisplay(e.NewValue); + UserProfileData.ValueChanged += e => updateDisplay(e.NewValue); InternalChildren = new Drawable[] { @@ -98,7 +98,7 @@ namespace osu.Game.Overlays.Profile.Header { new OverlinedTotalPlayTime { - UserProfile = { BindTarget = UserProfile } + UserProfileData = { BindTarget = UserProfileData } }, medalInfo = new OverlinedInfoContainer { @@ -170,9 +170,9 @@ namespace osu.Game.Overlays.Profile.Header }; } - private void updateDisplay(UserProfileData? userProfile) + private void updateDisplay(UserProfileData? data) { - var user = userProfile?.User; + var user = data?.User; medalInfo.Content = user?.Achievements?.Length.ToString() ?? "0"; ppInfo.Content = user?.Statistics?.PP?.ToLocalisableString("#,##0") ?? (LocalisableString)"0"; diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index df51a82cc9..2c2e2b3197 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -20,14 +20,14 @@ namespace osu.Game.Overlays.Profile.Header { private FillFlowContainer badgeFlowContainer = null!; - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { Alpha = 0; AutoSizeAxes = Axes.Y; - UserProfile.ValueChanged += e => updateDisplay(e.NewValue?.User); + UserProfileData.ValueChanged += e => updateDisplay(e.NewValue?.User); InternalChildren = new Drawable[] { diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 0889c36b16..c8a797e478 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Profile.Header { private const float avatar_size = 110; - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); [Resolved] private IAPIProvider api { get; set; } = null!; @@ -170,12 +170,12 @@ namespace osu.Game.Overlays.Profile.Header } }; - UserProfile.BindValueChanged(user => updateUser(user.NewValue)); + UserProfileData.BindValueChanged(data => updateUser(data.NewValue)); } - private void updateUser(UserProfileData? userProfile) + private void updateUser(UserProfileData? data) { - var user = userProfile?.User; + var user = data?.User; avatar.User = user; usernameText.Text = user?.Username ?? string.Empty; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index f87ee707ff..5f58960b15 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile { private UserCoverBackground coverContainer = null!; - public Bindable UserProfile = new Bindable(); + public Bindable UserProfileData = new Bindable(); private CentreHeaderContainer centreHeaderContainer; private DetailHeaderContainer detailHeaderContainer; @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Profile { ContentSidePadding = UserProfileOverlay.CONTENT_X_MARGIN; - UserProfile.ValueChanged += e => updateDisplay(e.NewValue); + UserProfileData.ValueChanged += e => updateDisplay(e.NewValue); TabControl.AddItem(LayoutStrings.HeaderUsersShow); @@ -72,34 +72,34 @@ namespace osu.Game.Overlays.Profile new TopHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfile = { BindTarget = UserProfile }, + UserProfileData = { BindTarget = UserProfileData }, }, centreHeaderContainer = new CentreHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfile = { BindTarget = UserProfile }, + UserProfileData = { BindTarget = UserProfileData }, }, detailHeaderContainer = new DetailHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfile = { BindTarget = UserProfile }, + UserProfileData = { BindTarget = UserProfileData }, }, new MedalHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfile = { BindTarget = UserProfile }, + UserProfileData = { BindTarget = UserProfileData }, }, new BottomHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfile = { BindTarget = UserProfile }, + UserProfileData = { BindTarget = UserProfileData }, }, } }; protected override OverlayTitle CreateTitle() => new ProfileHeaderTitle(); - private void updateDisplay(UserProfileData? userProfile) => coverContainer.User = userProfile?.User; + private void updateDisplay(UserProfileData? data) => coverContainer.User = data?.User; private partial class ProfileHeaderTitle : OverlayTitle { diff --git a/osu.Game/Overlays/Profile/ProfileSection.cs b/osu.Game/Overlays/Profile/ProfileSection.cs index 1e85411bc6..009e0d1dac 100644 --- a/osu.Game/Overlays/Profile/ProfileSection.cs +++ b/osu.Game/Overlays/Profile/ProfileSection.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Profile protected override Container Content => content; - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); protected ProfileSection() { diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index 0e74aba369..9c692cbeac 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -22,8 +22,8 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps protected override int InitialItemsCount => type == BeatmapSetType.Graveyard ? 2 : 6; - public PaginatedBeatmapContainer(BeatmapSetType type, Bindable user, LocalisableString headerText) - : base(user, headerText) + public PaginatedBeatmapContainer(BeatmapSetType type, Bindable userProfileData, LocalisableString headerText) + : base(userProfileData, headerText) { this.type = type; } diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs index 19d0da2cef..8818cae735 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs @@ -18,13 +18,13 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedBeatmapContainer(BeatmapSetType.Favourite, UserProfile, UsersStrings.ShowExtraBeatmapsFavouriteTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Ranked, UserProfile, UsersStrings.ShowExtraBeatmapsRankedTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Loved, UserProfile, UsersStrings.ShowExtraBeatmapsLovedTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Guest, UserProfile, UsersStrings.ShowExtraBeatmapsGuestTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Pending, UserProfile, UsersStrings.ShowExtraBeatmapsPendingTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, UserProfile, UsersStrings.ShowExtraBeatmapsGraveyardTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Nominated, UserProfile, UsersStrings.ShowExtraBeatmapsNominatedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Favourite, UserProfileData, UsersStrings.ShowExtraBeatmapsFavouriteTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Ranked, UserProfileData, UsersStrings.ShowExtraBeatmapsRankedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Loved, UserProfileData, UsersStrings.ShowExtraBeatmapsLovedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Guest, UserProfileData, UsersStrings.ShowExtraBeatmapsGuestTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Pending, UserProfileData, UsersStrings.ShowExtraBeatmapsPendingTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, UserProfileData, UsersStrings.ShowExtraBeatmapsGraveyardTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Nominated, UserProfileData, UsersStrings.ShowExtraBeatmapsNominatedTitle), }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs index 0ba93200d9..77e967376c 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs @@ -20,8 +20,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical /// protected abstract LocalisableString GraphCounterName { get; } - protected ChartProfileSubsection(Bindable userProfile, LocalisableString headerText) - : base(userProfile, headerText) + protected ChartProfileSubsection(Bindable userProfileData, LocalisableString headerText) + : base(userProfileData, headerText) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs index 6b08b68962..7afb21e8ca 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs @@ -16,8 +16,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { public partial class PaginatedMostPlayedBeatmapContainer : PaginatedProfileSubsection { - public PaginatedMostPlayedBeatmapContainer(Bindable userProfile) - : base(userProfile, UsersStrings.ShowExtraHistoricalMostPlayedTitle) + public PaginatedMostPlayedBeatmapContainer(Bindable userProfileData) + : base(userProfileData, UsersStrings.ShowExtraHistoricalMostPlayedTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs index 5d83610f84..cf8708d7b2 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs @@ -12,8 +12,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalMonthlyPlaycountsCountLabel; - public PlayHistorySubsection(Bindable userProfile) - : base(userProfile, UsersStrings.ShowExtraHistoricalMonthlyPlaycountsTitle) + public PlayHistorySubsection(Bindable userProfileData) + : base(userProfileData, UsersStrings.ShowExtraHistoricalMonthlyPlaycountsTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs index 0a82f79310..ab35680fd8 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs @@ -12,8 +12,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalReplaysWatchedCountsCountLabel; - public ReplaysSubsection(Bindable userProfile) - : base(userProfile, UsersStrings.ShowExtraHistoricalReplaysWatchedCountsTitle) + public ReplaysSubsection(Bindable userProfileData) + : base(userProfileData, UsersStrings.ShowExtraHistoricalReplaysWatchedCountsTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs b/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs index eecdffad19..5590db6502 100644 --- a/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs +++ b/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs @@ -20,10 +20,10 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new Drawable[] { - new PlayHistorySubsection(UserProfile), - new PaginatedMostPlayedBeatmapContainer(UserProfile), - new PaginatedScoreContainer(ScoreType.Recent, UserProfile, UsersStrings.ShowExtraHistoricalRecentPlaysTitle), - new ReplaysSubsection(UserProfile) + new PlayHistorySubsection(UserProfileData), + new PaginatedMostPlayedBeatmapContainer(UserProfileData), + new PaginatedScoreContainer(ScoreType.Recent, UserProfileData, UsersStrings.ShowExtraHistoricalRecentPlaysTitle), + new ReplaysSubsection(UserProfileData) }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs index c2de0efb69..d5a945b3da 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs @@ -19,11 +19,11 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class KudosuInfo : Container { - private readonly Bindable userProfile = new Bindable(); + private readonly Bindable userProfileData = new Bindable(); - public KudosuInfo(Bindable userProfile) + public KudosuInfo(Bindable userProfileData) { - this.userProfile.BindTo(userProfile); + this.userProfileData.BindTo(userProfileData); CountSection total; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu CornerRadius = 3; Child = total = new CountTotal(); - this.userProfile.ValueChanged += u => total.Count = u.NewValue?.User.Kudosu.Total ?? 0; + this.userProfileData.ValueChanged += u => total.Count = u.NewValue?.User.Kudosu.Total ?? 0; } protected override bool OnClick(ClickEvent e) => true; diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs index 0173e7ce74..a2ab104239 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs @@ -14,8 +14,8 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class PaginatedKudosuHistoryContainer : PaginatedProfileSubsection { - public PaginatedKudosuHistoryContainer(Bindable userProfile) - : base(userProfile, missingText: UsersStrings.ShowExtraKudosuEntryEmpty) + public PaginatedKudosuHistoryContainer(Bindable userProfileData) + : base(userProfileData, missingText: UsersStrings.ShowExtraKudosuEntryEmpty) { } diff --git a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs b/osu.Game/Overlays/Profile/Sections/KudosuSection.cs index b884f8854a..8fbaa1214f 100644 --- a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs +++ b/osu.Game/Overlays/Profile/Sections/KudosuSection.cs @@ -18,8 +18,8 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new Drawable[] { - new KudosuInfo(UserProfile), - new PaginatedKudosuHistoryContainer(UserProfile), + new KudosuInfo(UserProfileData), + new PaginatedKudosuHistoryContainer(UserProfileData), }; } } diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs index df881ad2a7..3556e9d809 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs @@ -46,8 +46,8 @@ namespace osu.Game.Overlays.Profile.Sections private OsuSpriteText missing = null!; private readonly LocalisableString? missingText; - protected PaginatedProfileSubsection(Bindable userProfile, LocalisableString? headerText = null, LocalisableString? missingText = null) - : base(userProfile, headerText, CounterVisibilityState.AlwaysVisible) + protected PaginatedProfileSubsection(Bindable userProfileData, LocalisableString? headerText = null, LocalisableString? missingText = null) + : base(userProfileData, headerText, CounterVisibilityState.AlwaysVisible) { this.missingText = missingText; } diff --git a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs index e85d5f22ef..20452a1274 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs @@ -18,11 +18,11 @@ namespace osu.Game.Overlays.Profile.Sections private ProfileSubsectionHeader header = null!; - protected ProfileSubsection(Bindable userProfile, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) + protected ProfileSubsection(Bindable userProfileData, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) { this.headerText = headerText ?? string.Empty; this.counterVisibilityState = counterVisibilityState; - UserProfile.BindTo(userProfile); + UserProfile.BindTo(userProfileData); } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index 968deecad4..14d57bfadc 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -19,8 +19,8 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { private readonly ScoreType type; - public PaginatedScoreContainer(ScoreType type, Bindable userProfile, LocalisableString headerText) - : base(userProfile, headerText) + public PaginatedScoreContainer(ScoreType type, Bindable userProfileData, LocalisableString headerText) + : base(userProfileData, headerText) { this.type = type; } diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index f8d1d82300..6b705a40d5 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -18,9 +18,9 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedScoreContainer(ScoreType.Pinned, UserProfile, UsersStrings.ShowExtraTopRanksPinnedTitle), - new PaginatedScoreContainer(ScoreType.Best, UserProfile, UsersStrings.ShowExtraTopRanksBestTitle), - new PaginatedScoreContainer(ScoreType.Firsts, UserProfile, UsersStrings.ShowExtraTopRanksFirstTitle) + new PaginatedScoreContainer(ScoreType.Pinned, UserProfileData, UsersStrings.ShowExtraTopRanksPinnedTitle), + new PaginatedScoreContainer(ScoreType.Best, UserProfileData, UsersStrings.ShowExtraTopRanksBestTitle), + new PaginatedScoreContainer(ScoreType.Firsts, UserProfileData, UsersStrings.ShowExtraTopRanksFirstTitle) }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index ad7242c339..6f346b457a 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -16,8 +16,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { public partial class PaginatedRecentActivityContainer : PaginatedProfileSubsection { - public PaginatedRecentActivityContainer(Bindable userProfile) - : base(userProfile, missingText: EventsStrings.Empty) + public PaginatedRecentActivityContainer(Bindable userProfileData) + : base(userProfileData, missingText: EventsStrings.Empty) { } diff --git a/osu.Game/Overlays/Profile/Sections/RecentSection.cs b/osu.Game/Overlays/Profile/Sections/RecentSection.cs index 6a90b7d1e3..95dbe7373c 100644 --- a/osu.Game/Overlays/Profile/Sections/RecentSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RecentSection.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedRecentActivityContainer(UserProfile), + new PaginatedRecentActivityContainer(UserProfileData), }; } } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 40933d9179..add90a0eed 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -47,7 +47,7 @@ namespace osu.Game.Overlays Show(); - if (user.OnlineID == Header?.UserProfile.Value?.User.Id) + if (user.OnlineID == Header?.UserProfileData.Value?.User.Id) return; if (sectionsContainer != null) @@ -126,7 +126,7 @@ namespace osu.Game.Overlays Debug.Assert(sections != null && sectionsContainer != null && tabs != null); var userProfile = new UserProfileData(user); - Header.UserProfile.Value = userProfile; + Header.UserProfileData.Value = userProfile; if (user.ProfileOrder != null) { @@ -136,7 +136,7 @@ namespace osu.Game.Overlays if (sec != null) { - sec.UserProfile.Value = userProfile; + sec.UserProfileData.Value = userProfile; sectionsContainer.Add(sec); tabs.AddItem(sec); From a1fbfe4b8b6da1f3f7ff8415e71306ae897b13f7 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 19:53:41 +0300 Subject: [PATCH 1345/2991] Specifiy importer name during pause/resume in logs --- osu.Game/Database/RealmArchiveModelImporter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index 1fe1569d36..1ea97ba718 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -561,7 +561,7 @@ namespace osu.Game.Database if (!PauseImports) return; - Logger.Log(@"Import is being paused."); + Logger.Log($@"{GetType().Name} is being paused."); while (PauseImports) { @@ -569,7 +569,7 @@ namespace osu.Game.Database Thread.Sleep(500); } - Logger.Log(@"Import is being resumed."); + Logger.Log($@"{GetType().Name} is being resumed."); } private IEnumerable getIDs(IEnumerable files) From 8a052235916ff3b532b515b12c04f62457eab686 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 20:07:46 +0300 Subject: [PATCH 1346/2991] Check cancellation token if importer was resumed while sleeping --- osu.Game/Database/RealmArchiveModelImporter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index 1ea97ba718..d107a6a605 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -569,6 +569,7 @@ namespace osu.Game.Database Thread.Sleep(500); } + cancellationToken.ThrowIfCancellationRequested(); Logger.Log($@"{GetType().Name} is being resumed."); } From 6027e7cc4e60012eae835b453f3310078f3e1b97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 9 Jan 2023 18:22:49 +0100 Subject: [PATCH 1347/2991] Fix one more missed related symbol --- .../Profile/Sections/Historical/ChartProfileSubsection.cs | 2 +- .../Overlays/Profile/Sections/PaginatedProfileSubsection.cs | 6 +++--- osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs index 77e967376c..2162adc2b7 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs @@ -41,7 +41,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical protected override void LoadComplete() { base.LoadComplete(); - UserProfile.BindValueChanged(onUserChanged, true); + UserProfileData.BindValueChanged(onUserChanged, true); } private void onUserChanged(ValueChangedEvent e) diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs index 3556e9d809..6ed347e929 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs @@ -89,7 +89,7 @@ namespace osu.Game.Overlays.Profile.Sections protected override void LoadComplete() { base.LoadComplete(); - UserProfile.BindValueChanged(onUserChanged, true); + UserProfileData.BindValueChanged(onUserChanged, true); } private void onUserChanged(ValueChangedEvent e) @@ -109,14 +109,14 @@ namespace osu.Game.Overlays.Profile.Sections private void showMore() { - if (UserProfile.Value?.User == null) + if (UserProfileData.Value?.User == null) return; loadCancellation = new CancellationTokenSource(); CurrentPage = CurrentPage?.TakeNext(ItemsPerPage) ?? new PaginationParameters(InitialItemsCount); - retrievalRequest = CreateRequest(UserProfile.Value.User, CurrentPage.Value); + retrievalRequest = CreateRequest(UserProfileData.Value.User, CurrentPage.Value); retrievalRequest.Success += items => UpdateItems(items, loadCancellation); api.Queue(retrievalRequest); diff --git a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs index 20452a1274..78e23da33a 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Profile.Sections { public abstract partial class ProfileSubsection : FillFlowContainer { - protected readonly Bindable UserProfile = new Bindable(); + protected readonly Bindable UserProfileData = new Bindable(); private readonly LocalisableString headerText; private readonly CounterVisibilityState counterVisibilityState; @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Profile.Sections { this.headerText = headerText ?? string.Empty; this.counterVisibilityState = counterVisibilityState; - UserProfile.BindTo(userProfileData); + UserProfileData.BindTo(userProfileData); } [BackgroundDependencyLoader] From 69260ca3c358c77c83e87ee4b9ddaf57fc39fa0a Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 9 Jan 2023 18:36:55 +0100 Subject: [PATCH 1348/2991] remove unnecessary usages of nullable forgiveness, add asserts for debugging --- .../Visual/SongSelect/TestSceneBeatmapCarousel.cs | 2 +- osu.Game/Screens/Select/BeatmapCarousel.cs | 4 +++- osu.Game/Screens/Select/Carousel/CarouselGroup.cs | 2 +- osu.Game/Screens/Select/Carousel/CarouselItem.cs | 10 ++++++++-- .../Select/Carousel/DrawableCarouselBeatmap.cs | 6 +++--- .../Select/Carousel/DrawableCarouselBeatmapSet.cs | 14 ++++++++------ .../Select/Carousel/DrawableCarouselItem.cs | 10 +++++++--- 7 files changed, 31 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 3cff853f92..1a466dea58 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -1069,7 +1069,7 @@ namespace osu.Game.Tests.Visual.SongSelect return Precision.AlmostEquals( carousel.ScreenSpaceDrawQuad.Centre, carousel.Items - .First(i => i.Item!.State.Value == CarouselItemState.Selected) + .First(i => i.Item?.State.Value == CarouselItemState.Selected) .ScreenSpaceDrawQuad.Centre, 100); }); } diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 4a6ff7417e..12dcdbd3dc 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -770,7 +770,9 @@ namespace osu.Game.Screens.Select { updateItem(item); - if (item.Item!.Visible) + Debug.Assert(item.Item != null); + + if (item.Item.Visible) { bool isSelected = item.Item.State.Value == CarouselItemState.Selected; diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroup.cs b/osu.Game/Screens/Select/Carousel/CarouselGroup.cs index 8667dce226..9302578038 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroup.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroup.cs @@ -10,7 +10,7 @@ namespace osu.Game.Screens.Select.Carousel /// public class CarouselGroup : CarouselItem { - public override DrawableCarouselItem CreateDrawableRepresentation() => null!; + public override DrawableCarouselItem? CreateDrawableRepresentation() => null; public IReadOnlyList Items => items; diff --git a/osu.Game/Screens/Select/Carousel/CarouselItem.cs b/osu.Game/Screens/Select/Carousel/CarouselItem.cs index 5de9f2b995..38a1d7117f 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselItem.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Diagnostics; using osu.Framework.Bindables; namespace osu.Game.Screens.Select.Carousel @@ -41,7 +42,7 @@ namespace osu.Game.Screens.Select.Carousel /// /// Create a fresh drawable version of this item. /// - public abstract DrawableCarouselItem CreateDrawableRepresentation(); + public abstract DrawableCarouselItem? CreateDrawableRepresentation(); public virtual void Filter(FilterCriteria criteria) { @@ -49,7 +50,12 @@ namespace osu.Game.Screens.Select.Carousel public virtual int CompareTo(FilterCriteria criteria, CarouselItem other) => ItemID.CompareTo(other.ItemID); - public int CompareTo(CarouselItem? other) => CarouselYPosition.CompareTo(other!.CarouselYPosition); + public int CompareTo(CarouselItem? other) + { + Debug.Assert(other != null); + + return CarouselYPosition.CompareTo(other.CarouselYPosition); + } } public enum CarouselItemState diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index 88a55198b2..e05d950369 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -192,7 +192,7 @@ namespace osu.Game.Screens.Select.Carousel protected override bool OnClick(ClickEvent e) { - if (Item!.State.Value == CarouselItemState.Selected) + if (Item?.State.Value == CarouselItemState.Selected) startRequested?.Invoke(beatmapInfo); return base.OnClick(e); @@ -200,13 +200,13 @@ namespace osu.Game.Screens.Select.Carousel protected override void ApplyState() { - if (Item!.State.Value != CarouselItemState.Collapsed && Alpha == 0) + if (Item?.State.Value != CarouselItemState.Collapsed && Alpha == 0) starCounter.ReplayAnimation(); starDifficultyCancellationSource?.Cancel(); // Only compute difficulty when the item is visible. - if (Item.State.Value != CarouselItemState.Collapsed) + if (Item?.State.Value != CarouselItemState.Collapsed) { // We've potentially cancelled the computation above so a new bindable is required. starDifficultyBindable = difficultyCache.GetBindableDifficulty(beatmapInfo, (starDifficultyCancellationSource = new CancellationTokenSource()).Token); diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index f0bb8b15c2..8974b173fb 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -73,10 +73,10 @@ namespace osu.Game.Screens.Select.Carousel { base.Update(); + Debug.Assert(Item != null); // position updates should not occur if the item is filtered away. // this avoids panels flying across the screen only to be eventually off-screen or faded out. - if (!Item!.Visible) - return; + if (!Item.Visible) return; float targetY = Item.CarouselYPosition; @@ -146,7 +146,9 @@ namespace osu.Game.Screens.Select.Carousel private void updateBeatmapDifficulties() { - var carouselBeatmapSet = (CarouselBeatmapSet)Item!; + if (Item == null) return; + + var carouselBeatmapSet = (CarouselBeatmapSet)Item; var visibleBeatmaps = carouselBeatmapSet.Items.Where(c => c.Visible).ToArray(); @@ -166,7 +168,7 @@ namespace osu.Game.Screens.Select.Carousel { X = 100, RelativeSizeAxes = Axes.Both, - ChildrenEnumerable = visibleBeatmaps.Select(c => c.CreateDrawableRepresentation()) + ChildrenEnumerable = visibleBeatmaps.Select(c => c.CreateDrawableRepresentation()!) }; beatmapsLoadTask = LoadComponentAsync(beatmapContainer, loaded => @@ -191,7 +193,7 @@ namespace osu.Game.Screens.Select.Carousel float yPos = DrawableCarouselBeatmap.CAROUSEL_BEATMAP_SPACING; - bool isSelected = Item!.State.Value == CarouselItemState.Selected; + bool isSelected = Item?.State.Value == CarouselItemState.Selected; foreach (var panel in beatmapContainer.Children) { @@ -213,7 +215,7 @@ namespace osu.Game.Screens.Select.Carousel List items = new List(); - if (Item!.State.Value == CarouselItemState.NotSelected) + if (Item?.State.Value == CarouselItemState.NotSelected) items.Add(new OsuMenuItem("Expand", MenuItemType.Highlighted, () => Item.State.Value = CarouselItemState.Selected)); if (beatmapSet.OnlineID > 0 && viewDetails != null) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs index 580dcb3471..c283cca3c8 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs @@ -103,7 +103,7 @@ namespace osu.Game.Screens.Select.Carousel protected virtual void UpdateItem() { - if (item == null || Item == null) + if (Item == null) return; Scheduler.AddOnce(ApplyState); @@ -126,9 +126,11 @@ namespace osu.Game.Screens.Select.Carousel protected virtual void ApplyState() { + if (Item == null) return; + // Use the fact that we know the precise height of the item from the model to avoid the need for AutoSize overhead. // Additionally, AutoSize doesn't work well due to content starting off-screen and being masked away. - Height = Item!.TotalHeight; + Height = Item.TotalHeight; switch (Item.State.Value) { @@ -158,7 +160,9 @@ namespace osu.Game.Screens.Select.Carousel protected override bool OnClick(ClickEvent e) { - Item!.State.Value = CarouselItemState.Selected; + Debug.Assert(Item != null); + + Item.State.Value = CarouselItemState.Selected; return true; } } From d6f60db234d0d4e632f911d2ef2a220d798cf70f Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 9 Jan 2023 18:51:51 +0100 Subject: [PATCH 1349/2991] Add the ability to toggle the visibility of the main bar in BarHitErrorMeter.cs --- .../Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index eeca2be7cd..d1b79afe35 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -42,6 +42,9 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters [SettingSource("Label style", "How to show early/late extremities")] public Bindable LabelStyle { get; } = new Bindable(LabelStyles.Icons); + [SettingSource("Bar visibility")] + public Bindable BarVisibility { get; } = new Bindable(true); + private const int judgement_line_width = 14; private const int max_concurrent_judgements = 50; @@ -178,6 +181,11 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters CentreMarkerStyle.BindValueChanged(style => recreateCentreMarker(style.NewValue), true); LabelStyle.BindValueChanged(style => recreateLabels(style.NewValue), true); + BarVisibility.BindValueChanged(visible => + { + colourBarsEarly.FadeTo(visible.NewValue ? 1 : 0, 500, Easing.OutQuint); + colourBarsLate.FadeTo(visible.NewValue ? 1 : 0, 500, Easing.OutQuint); + }, true); // delay the appearance animations for only the initial appearance. using (arrowContainer.BeginDelayedSequence(450)) From dbc19777e02120b1362886deec24adf3b7c8fe9c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 21:17:40 +0300 Subject: [PATCH 1350/2991] Move stable import buttons under "debug" section --- .../MaintenanceSettingsStrings.cs | 20 ------ .../Settings/Sections/DebugSection.cs | 12 ++-- .../DebugSettings/BatchImportSettings.cs | 66 +++++++++++++++++++ .../Sections/Maintenance/BeatmapSettings.cs | 17 +---- .../Maintenance/CollectionsSettings.cs | 17 +---- .../Sections/Maintenance/ScoreSettings.cs | 17 +---- .../Sections/Maintenance/SkinSettings.cs | 17 +---- 7 files changed, 77 insertions(+), 89 deletions(-) create mode 100644 osu.Game/Overlays/Settings/Sections/DebugSettings/BatchImportSettings.cs diff --git a/osu.Game/Localisation/MaintenanceSettingsStrings.cs b/osu.Game/Localisation/MaintenanceSettingsStrings.cs index 8aa0adf7a0..469f565f1e 100644 --- a/osu.Game/Localisation/MaintenanceSettingsStrings.cs +++ b/osu.Game/Localisation/MaintenanceSettingsStrings.cs @@ -54,11 +54,6 @@ namespace osu.Game.Localisation /// public static LocalisableString RestartAndReOpenRequiredForCompletion => new TranslatableString(getKey(@"restart_and_re_open_required_for_completion"), @"To complete this operation, osu! will close. Please open it again to use the new data location."); - /// - /// "Import beatmaps from stable" - /// - public static LocalisableString ImportBeatmapsFromStable => new TranslatableString(getKey(@"import_beatmaps_from_stable"), @"Import beatmaps from stable"); - /// /// "Delete ALL beatmaps" /// @@ -69,31 +64,16 @@ namespace osu.Game.Localisation /// public static LocalisableString DeleteAllBeatmapVideos => new TranslatableString(getKey(@"delete_all_beatmap_videos"), @"Delete ALL beatmap videos"); - /// - /// "Import scores from stable" - /// - public static LocalisableString ImportScoresFromStable => new TranslatableString(getKey(@"import_scores_from_stable"), @"Import scores from stable"); - /// /// "Delete ALL scores" /// public static LocalisableString DeleteAllScores => new TranslatableString(getKey(@"delete_all_scores"), @"Delete ALL scores"); - /// - /// "Import skins from stable" - /// - public static LocalisableString ImportSkinsFromStable => new TranslatableString(getKey(@"import_skins_from_stable"), @"Import skins from stable"); - /// /// "Delete ALL skins" /// public static LocalisableString DeleteAllSkins => new TranslatableString(getKey(@"delete_all_skins"), @"Delete ALL skins"); - /// - /// "Import collections from stable" - /// - public static LocalisableString ImportCollectionsFromStable => new TranslatableString(getKey(@"import_collections_from_stable"), @"Import collections from stable"); - /// /// "Delete ALL collections" /// diff --git a/osu.Game/Overlays/Settings/Sections/DebugSection.cs b/osu.Game/Overlays/Settings/Sections/DebugSection.cs index 2594962314..509410fbb1 100644 --- a/osu.Game/Overlays/Settings/Sections/DebugSection.cs +++ b/osu.Game/Overlays/Settings/Sections/DebugSection.cs @@ -3,6 +3,7 @@ #nullable disable +using osu.Framework.Development; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; @@ -22,11 +23,12 @@ namespace osu.Game.Overlays.Settings.Sections public DebugSection() { - Children = new Drawable[] - { - new GeneralSettings(), - new MemorySettings(), - }; + Add(new GeneralSettings()); + + if (DebugUtils.IsDebugBuild) + Add(new BatchImportSettings()); + + Add(new MemorySettings()); } } } diff --git a/osu.Game/Overlays/Settings/Sections/DebugSettings/BatchImportSettings.cs b/osu.Game/Overlays/Settings/Sections/DebugSettings/BatchImportSettings.cs new file mode 100644 index 0000000000..1c17356313 --- /dev/null +++ b/osu.Game/Overlays/Settings/Sections/DebugSettings/BatchImportSettings.cs @@ -0,0 +1,66 @@ +// 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.Allocation; +using osu.Framework.Localisation; +using osu.Game.Database; + +namespace osu.Game.Overlays.Settings.Sections.DebugSettings +{ + public partial class BatchImportSettings : SettingsSubsection + { + protected override LocalisableString Header => @"Batch Import"; + + private SettingsButton importBeatmapsButton = null!; + private SettingsButton importCollectionsButton = null!; + private SettingsButton importScoresButton = null!; + private SettingsButton importSkinsButton = null!; + + [BackgroundDependencyLoader] + private void load(LegacyImportManager? legacyImportManager) + { + if (legacyImportManager?.SupportsImportFromStable != true) + return; + + AddRange(new[] + { + importBeatmapsButton = new SettingsButton + { + Text = @"Import beatmaps from stable", + Action = () => + { + importBeatmapsButton.Enabled.Value = false; + legacyImportManager.ImportFromStableAsync(StableContent.Beatmaps).ContinueWith(_ => Schedule(() => importBeatmapsButton.Enabled.Value = true)); + } + }, + importSkinsButton = new SettingsButton + { + Text = @"Import skins from stable", + Action = () => + { + importSkinsButton.Enabled.Value = false; + legacyImportManager.ImportFromStableAsync(StableContent.Skins).ContinueWith(_ => Schedule(() => importSkinsButton.Enabled.Value = true)); + } + }, + importCollectionsButton = new SettingsButton + { + Text = @"Import collections from stable", + Action = () => + { + importCollectionsButton.Enabled.Value = false; + legacyImportManager.ImportFromStableAsync(StableContent.Collections).ContinueWith(_ => Schedule(() => importCollectionsButton.Enabled.Value = true)); + } + }, + importScoresButton = new SettingsButton + { + Text = @"Import scores from stable", + Action = () => + { + importScoresButton.Enabled.Value = false; + legacyImportManager.ImportFromStableAsync(StableContent.Scores).ContinueWith(_ => Schedule(() => importScoresButton.Enabled.Value = true)); + } + }, + }); + } + } +} diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs index 9c0b86c862..4b1836ed86 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs @@ -6,7 +6,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Beatmaps; -using osu.Game.Database; using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Maintenance @@ -15,28 +14,14 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { protected override LocalisableString Header => CommonStrings.Beatmaps; - private SettingsButton importBeatmapsButton = null!; private SettingsButton deleteBeatmapsButton = null!; private SettingsButton deleteBeatmapVideosButton = null!; private SettingsButton restoreButton = null!; private SettingsButton undeleteButton = null!; [BackgroundDependencyLoader] - private void load(BeatmapManager beatmaps, LegacyImportManager? legacyImportManager, IDialogOverlay? dialogOverlay) + private void load(BeatmapManager beatmaps, IDialogOverlay? dialogOverlay) { - if (legacyImportManager?.SupportsImportFromStable == true) - { - Add(importBeatmapsButton = new SettingsButton - { - Text = MaintenanceSettingsStrings.ImportBeatmapsFromStable, - Action = () => - { - importBeatmapsButton.Enabled.Value = false; - legacyImportManager.ImportFromStableAsync(StableContent.Beatmaps).ContinueWith(_ => Schedule(() => importBeatmapsButton.Enabled.Value = true)); - } - }); - } - Add(deleteBeatmapsButton = new DangerousSettingsButton { Text = MaintenanceSettingsStrings.DeleteAllBeatmaps, diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/CollectionsSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/CollectionsSettings.cs index 4da5aaf492..09acc22c25 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/CollectionsSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/CollectionsSettings.cs @@ -14,8 +14,6 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { protected override LocalisableString Header => CommonStrings.Collections; - private SettingsButton importCollectionsButton = null!; - [Resolved] private RealmAccess realm { get; set; } = null!; @@ -23,21 +21,8 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance private INotificationOverlay? notificationOverlay { get; set; } [BackgroundDependencyLoader] - private void load(LegacyImportManager? legacyImportManager, IDialogOverlay? dialogOverlay) + private void load(IDialogOverlay? dialogOverlay) { - if (legacyImportManager?.SupportsImportFromStable == true) - { - Add(importCollectionsButton = new SettingsButton - { - Text = MaintenanceSettingsStrings.ImportCollectionsFromStable, - Action = () => - { - importCollectionsButton.Enabled.Value = false; - legacyImportManager.ImportFromStableAsync(StableContent.Collections).ContinueWith(_ => Schedule(() => importCollectionsButton.Enabled.Value = true)); - } - }); - } - Add(new DangerousSettingsButton { Text = MaintenanceSettingsStrings.DeleteAllCollections, diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/ScoreSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/ScoreSettings.cs index 1f09854843..c6f4f1e1a5 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/ScoreSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/ScoreSettings.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Localisation; -using osu.Game.Database; using osu.Game.Localisation; using osu.Game.Scoring; @@ -14,25 +13,11 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { protected override LocalisableString Header => CommonStrings.Scores; - private SettingsButton importScoresButton = null!; private SettingsButton deleteScoresButton = null!; [BackgroundDependencyLoader] - private void load(ScoreManager scores, LegacyImportManager? legacyImportManager, IDialogOverlay? dialogOverlay) + private void load(ScoreManager scores, IDialogOverlay? dialogOverlay) { - if (legacyImportManager?.SupportsImportFromStable == true) - { - Add(importScoresButton = new SettingsButton - { - Text = MaintenanceSettingsStrings.ImportScoresFromStable, - Action = () => - { - importScoresButton.Enabled.Value = false; - legacyImportManager.ImportFromStableAsync(StableContent.Scores).ContinueWith(_ => Schedule(() => importScoresButton.Enabled.Value = true)); - } - }); - } - Add(deleteScoresButton = new DangerousSettingsButton { Text = MaintenanceSettingsStrings.DeleteAllScores, diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/SkinSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/SkinSettings.cs index e4185fe6c2..c3ac49af6d 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/SkinSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/SkinSettings.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Localisation; -using osu.Game.Database; using osu.Game.Localisation; using osu.Game.Skinning; @@ -14,25 +13,11 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { protected override LocalisableString Header => CommonStrings.Skins; - private SettingsButton importSkinsButton = null!; private SettingsButton deleteSkinsButton = null!; [BackgroundDependencyLoader] - private void load(SkinManager skins, LegacyImportManager? legacyImportManager, IDialogOverlay? dialogOverlay) + private void load(SkinManager skins, IDialogOverlay? dialogOverlay) { - if (legacyImportManager?.SupportsImportFromStable == true) - { - Add(importSkinsButton = new SettingsButton - { - Text = MaintenanceSettingsStrings.ImportSkinsFromStable, - Action = () => - { - importSkinsButton.Enabled.Value = false; - legacyImportManager.ImportFromStableAsync(StableContent.Skins).ContinueWith(_ => Schedule(() => importSkinsButton.Enabled.Value = true)); - } - }); - } - Add(deleteSkinsButton = new DangerousSettingsButton { Text = MaintenanceSettingsStrings.DeleteAllSkins, From 98390ea2a86b8eedadac75605a43f6ac316b4088 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 21:33:04 +0300 Subject: [PATCH 1351/2991] Fix condition flipped --- osu.Game/Online/Chat/ChannelManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 26ab9e87ba..1e3921bac0 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -328,7 +328,7 @@ namespace osu.Game.Online.Chat { // This request is self-retrying until it succeeds. // To avoid requests piling up when not logged in (ie. API is unavailable) exit early. - if (api.IsLoggedIn) + if (!api.IsLoggedIn) return; var req = new ListChannelsRequest(); From 85396ba9d4016552504babdef678a8b7fbd65a2e Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Mon, 9 Jan 2023 19:26:43 +0000 Subject: [PATCH 1352/2991] Added ruleset config stuff for Taiko; Added ruleset settings entry for Taiko touch control scheme --- .../TaikoRulesetConfigManager.cs | 28 +++++++++++++++ .../Configuration/TaikoTouchControlScheme.cs | 14 ++++++++ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 8 +++++ .../TaikoSettingsSubsection.cs | 36 +++++++++++++++++++ 4 files changed, 86 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Configuration/TaikoRulesetConfigManager.cs create mode 100644 osu.Game.Rulesets.Taiko/Configuration/TaikoTouchControlScheme.cs create mode 100644 osu.Game.Rulesets.Taiko/TaikoSettingsSubsection.cs diff --git a/osu.Game.Rulesets.Taiko/Configuration/TaikoRulesetConfigManager.cs b/osu.Game.Rulesets.Taiko/Configuration/TaikoRulesetConfigManager.cs new file mode 100644 index 0000000000..c3bc7f6439 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Configuration/TaikoRulesetConfigManager.cs @@ -0,0 +1,28 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Configuration; +using osu.Game.Rulesets.Configuration; + +namespace osu.Game.Rulesets.Taiko.Configuration +{ + public class TaikoRulesetConfigManager : RulesetConfigManager + { + public TaikoRulesetConfigManager(SettingsStore? settings, RulesetInfo ruleset, int? variant = null) + : base(settings, ruleset, variant) + { + } + + protected override void InitialiseDefaults() + { + base.InitialiseDefaults(); + + SetDefault(TaikoRulesetSetting.TouchControlScheme, TaikoTouchControlScheme.KDDK); + } + } + + public enum TaikoRulesetSetting + { + TouchControlScheme + } +} diff --git a/osu.Game.Rulesets.Taiko/Configuration/TaikoTouchControlScheme.cs b/osu.Game.Rulesets.Taiko/Configuration/TaikoTouchControlScheme.cs new file mode 100644 index 0000000000..b9aee7eff7 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Configuration/TaikoTouchControlScheme.cs @@ -0,0 +1,14 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable disable + +namespace osu.Game.Rulesets.Taiko.Configuration +{ + public enum TaikoTouchControlScheme + { + KDDK, + DDKK, + KKDD + } +} diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index fe12cf9765..e5a1a5d7ce 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -28,9 +28,13 @@ using osu.Game.Rulesets.Taiko.Skinning.Argon; using osu.Game.Rulesets.Taiko.Skinning.Legacy; using osu.Game.Rulesets.Taiko.UI; using osu.Game.Rulesets.UI; +using osu.Game.Overlays.Settings; using osu.Game.Scoring; using osu.Game.Screens.Ranking.Statistics; using osu.Game.Skinning; +using osu.Game.Rulesets.Configuration; +using osu.Game.Configuration; +using osu.Game.Rulesets.Taiko.Configuration; namespace osu.Game.Rulesets.Taiko { @@ -193,6 +197,10 @@ namespace osu.Game.Rulesets.Taiko public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new TaikoReplayFrame(); + public override IRulesetConfigManager CreateConfig(SettingsStore? settings) => new TaikoRulesetConfigManager(settings, RulesetInfo); + + public override RulesetSettingsSubsection CreateSettings() => new TaikoSettingsSubsection(this); + protected override IEnumerable GetValidHitResults() { return new[] diff --git a/osu.Game.Rulesets.Taiko/TaikoSettingsSubsection.cs b/osu.Game.Rulesets.Taiko/TaikoSettingsSubsection.cs new file mode 100644 index 0000000000..297a02df5b --- /dev/null +++ b/osu.Game.Rulesets.Taiko/TaikoSettingsSubsection.cs @@ -0,0 +1,36 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Localisation; +using osu.Game.Overlays.Settings; +using osu.Game.Rulesets.Taiko.Configuration; + +namespace osu.Game.Rulesets.Taiko +{ + public partial class TaikoSettingsSubsection : RulesetSettingsSubsection + { + protected override LocalisableString Header => "osu!taiko"; + + public TaikoSettingsSubsection(TaikoRuleset ruleset) + : base(ruleset) + { + } + + [BackgroundDependencyLoader] + private void load() + { + var config = (TaikoRulesetConfigManager)Config; + + Children = new Drawable[] + { + new SettingsEnumDropdown + { + LabelText = "Touch Control Scheme", + Current = config.GetBindable(TaikoRulesetSetting.TouchControlScheme) + } + }; + } + } +} From 6abbc7dc28472508edb9dc2341ca0461bb362cf0 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 9 Jan 2023 20:59:28 +0100 Subject: [PATCH 1353/2991] Further fix nullability --- osu.Game/Screens/Select/BeatmapCarousel.cs | 4 +++- osu.Game/Screens/Select/Carousel/CarouselItem.cs | 8 +------- .../Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs | 6 ++++-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 12dcdbd3dc..03085a8638 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -739,7 +739,9 @@ namespace osu.Game.Screens.Select foreach (var panel in Scroll.Children) { - if (toDisplay.Remove(panel.Item!)) + Debug.Assert(panel.Item != null); + + if (toDisplay.Remove(panel.Item)) { // panel already displayed. continue; diff --git a/osu.Game/Screens/Select/Carousel/CarouselItem.cs b/osu.Game/Screens/Select/Carousel/CarouselItem.cs index 38a1d7117f..4a5af6f6b1 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselItem.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using osu.Framework.Bindables; namespace osu.Game.Screens.Select.Carousel @@ -50,12 +49,7 @@ namespace osu.Game.Screens.Select.Carousel public virtual int CompareTo(FilterCriteria criteria, CarouselItem other) => ItemID.CompareTo(other.ItemID); - public int CompareTo(CarouselItem? other) - { - Debug.Assert(other != null); - - return CarouselYPosition.CompareTo(other.CarouselYPosition); - } + public int CompareTo(CarouselItem? other) => CarouselYPosition.CompareTo(other?.CarouselYPosition); } public enum CarouselItemState diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 8974b173fb..ea59c330b4 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -146,7 +146,7 @@ namespace osu.Game.Screens.Select.Carousel private void updateBeatmapDifficulties() { - if (Item == null) return; + Debug.Assert(Item != null); var carouselBeatmapSet = (CarouselBeatmapSet)Item; @@ -197,10 +197,12 @@ namespace osu.Game.Screens.Select.Carousel foreach (var panel in beatmapContainer.Children) { + Debug.Assert(panel.Item != null); + if (isSelected) { panel.MoveToY(yPos, 800, Easing.OutQuint); - yPos += panel.Item!.TotalHeight; + yPos += panel.Item.TotalHeight; } else panel.MoveToY(0, 800, Easing.OutQuint); From 602062f011e42531dc78f79b3ba099145607dd80 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 9 Jan 2023 21:04:51 +0100 Subject: [PATCH 1354/2991] Address unclear naming issue --- .../Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index d1b79afe35..2907695ce7 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -42,8 +42,8 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters [SettingSource("Label style", "How to show early/late extremities")] public Bindable LabelStyle { get; } = new Bindable(LabelStyles.Icons); - [SettingSource("Bar visibility")] - public Bindable BarVisibility { get; } = new Bindable(true); + [SettingSource("Show colour bars")] + public Bindable ColourBarVisibility { get; } = new Bindable(true); private const int judgement_line_width = 14; @@ -181,7 +181,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters CentreMarkerStyle.BindValueChanged(style => recreateCentreMarker(style.NewValue), true); LabelStyle.BindValueChanged(style => recreateLabels(style.NewValue), true); - BarVisibility.BindValueChanged(visible => + ColourBarVisibility.BindValueChanged(visible => { colourBarsEarly.FadeTo(visible.NewValue ? 1 : 0, 500, Easing.OutQuint); colourBarsLate.FadeTo(visible.NewValue ? 1 : 0, 500, Easing.OutQuint); From f216d7264b2f10500023ec97a4348884f662af5a Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 22:51:38 +0300 Subject: [PATCH 1355/2991] Improve missing beatmap failure logging on score import --- osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs | 13 +++++++++---- osu.Game/Scoring/ScoreImporter.cs | 10 ++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs index 15ed992c3e..a507bb73c6 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs @@ -8,6 +8,7 @@ using System.Diagnostics; using System.IO; using System.Linq; using Newtonsoft.Json; +using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Legacy; @@ -46,10 +47,12 @@ namespace osu.Game.Scoring.Legacy score.ScoreInfo = scoreInfo; int version = sr.ReadInt32(); + string beatmapHash = sr.ReadString(); + + workingBeatmap = GetBeatmap(beatmapHash); - workingBeatmap = GetBeatmap(sr.ReadString()); if (workingBeatmap is DummyWorkingBeatmap) - throw new BeatmapNotFoundException(); + throw new BeatmapNotFoundException(beatmapHash); scoreInfo.User = new APIUser { Username = sr.ReadString() }; @@ -334,9 +337,11 @@ namespace osu.Game.Scoring.Legacy public class BeatmapNotFoundException : Exception { - public BeatmapNotFoundException() - : base("No corresponding beatmap for the score could be found.") + public string Hash { get; } + + public BeatmapNotFoundException(string hash) { + Hash = hash; } } } diff --git a/osu.Game/Scoring/ScoreImporter.cs b/osu.Game/Scoring/ScoreImporter.cs index a3d7fe5de0..d63741e73b 100644 --- a/osu.Game/Scoring/ScoreImporter.cs +++ b/osu.Game/Scoring/ScoreImporter.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Linq; using System.Threading; using Newtonsoft.Json; +using osu.Framework.Graphics.Sprites; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Beatmaps; @@ -17,6 +18,7 @@ using osu.Game.Scoring.Legacy; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays.Notifications; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; using Realms; @@ -44,7 +46,9 @@ namespace osu.Game.Scoring protected override ScoreInfo? CreateModel(ArchiveReader archive) { - using (var stream = archive.GetStream(archive.Filenames.First(f => f.EndsWith(".osr", StringComparison.OrdinalIgnoreCase)))) + string name = archive.Filenames.First(f => f.EndsWith(".osr", StringComparison.OrdinalIgnoreCase)); + + using (var stream = archive.GetStream(name)) { try { @@ -52,7 +56,9 @@ namespace osu.Game.Scoring } catch (LegacyScoreDecoder.BeatmapNotFoundException e) { - Logger.Log(e.Message, LoggingTarget.Information, LogLevel.Error); + Logger.Log($@"Score '{name}' failed to import: no corresponding beatmap with the hash '{e.Hash}' could be found.", LoggingTarget.Database); + Logger.Log($@"Score '{name}' failed to import due to missing beatmap. Check database logs for more info.", LoggingTarget.Information, LogLevel.Error); + return null; } } From 20ed337ea863ce2288340f8c4fde5043e29bae82 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 23:25:52 +0300 Subject: [PATCH 1356/2991] Remove unused using directive --- osu.Game/Scoring/ScoreImporter.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Scoring/ScoreImporter.cs b/osu.Game/Scoring/ScoreImporter.cs index d63741e73b..2dfd461eb9 100644 --- a/osu.Game/Scoring/ScoreImporter.cs +++ b/osu.Game/Scoring/ScoreImporter.cs @@ -7,7 +7,6 @@ using System.Diagnostics; using System.Linq; using System.Threading; using Newtonsoft.Json; -using osu.Framework.Graphics.Sprites; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Beatmaps; @@ -18,7 +17,6 @@ using osu.Game.Scoring.Legacy; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; -using osu.Game.Overlays.Notifications; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; using Realms; From 91eab7985bb2a3fd83bd1202c81c16847dacf6af Mon Sep 17 00:00:00 2001 From: tsrk Date: Mon, 9 Jan 2023 21:35:27 +0100 Subject: [PATCH 1357/2991] feat(ui): Implement a segmented graph --- .../Graphics/UserInterface/SegmentedGraph.cs | 314 ++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 osu.Game/Graphics/UserInterface/SegmentedGraph.cs diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs new file mode 100644 index 0000000000..261e535fbc --- /dev/null +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -0,0 +1,314 @@ +// 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; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Threading; +using osuTK; + +namespace osu.Game.Graphics.UserInterface +{ + public abstract partial class SegmentedGraph : Container + where T : struct, IComparable, IConvertible, IEquatable + { + private BufferedContainer? rectSegments; + private float previousDrawWidth; + private bool graphNeedsUpdate; + + private T[]? values; + private int[] tiers = Array.Empty(); + private readonly SegmentManager segments; + + private readonly int tierCount; + + protected SegmentedGraph(int tierCount) + { + this.tierCount = tierCount; + TierColours = new Colour4[tierCount]; + segments = new SegmentManager(tierCount); + } + + public T[] Values + { + get => values ?? Array.Empty(); + set + { + if (value == values) return; + + values = value; + recalculateTiers(values); + graphNeedsUpdate = true; + } + } + + public readonly Colour4[] TierColours; + + private CancellationTokenSource? cts; + private ScheduledDelegate? scheduledCreate; + + protected override void Update() + { + base.Update(); + + if (graphNeedsUpdate || (values != null && DrawWidth != previousDrawWidth)) + { + rectSegments?.FadeOut(150, Easing.OutQuint).Expire(); + + scheduledCreate?.Cancel(); + scheduledCreate = Scheduler.AddDelayed(RecreateGraph, 150); + + previousDrawWidth = DrawWidth; + graphNeedsUpdate = false; + } + } + + protected virtual void RecreateGraph() + { + var newSegments = new BufferedContainer(cachedFrameBuffer: true) + { + RedrawOnScale = false, + RelativeSizeAxes = Axes.Both + }; + + cts?.Cancel(); + recalculateSegments(); + redrawSegments(newSegments); + + LoadComponentAsync(newSegments, s => + { + Children = new Drawable[] + { + rectSegments = s + }; + + s.FadeInFromZero(100); + }, (cts = new CancellationTokenSource()).Token); + } + + private void recalculateTiers(T[]? arr) + { + if (arr == null || arr.Length == 0) + { + tiers = Array.Empty(); + return; + } + + float[] floatValues = arr.Select(v => Convert.ToSingle(v)).ToArray(); + + // Shift values to eliminate negative ones + float min = floatValues.Min(); + + if (min < 0) + { + for (int i = 0; i < floatValues.Length; i++) + floatValues[i] += min; + } + + // Normalize values + float max = floatValues.Max(); + + for (int i = 0; i < floatValues.Length; i++) + floatValues[i] /= max; + + // Deduce tiers from values + tiers = floatValues.Select(v => (int)Math.Floor(v * tierCount)).ToArray(); + } + + private void recalculateSegments() + { + segments.Clear(); + + if (tiers.Length == 0) + { + segments.Add(0, 0, 1); + return; + } + + for (int i = 0; i < tiers.Length; i++) + { + for (int tier = 0; tier < tierCount; tier++) + { + if (tier < 0) + continue; + + // One tier covers itself and all tiers above it. + // By layering multiple transparent boxes, higher tiers will be brighter. + // If using opaque colors, higher tiers will be on front, covering lower tiers. + if (tiers[i] >= tier) + { + if (!segments.IsTierStarted(tier)) + segments.StartSegment(tier, i * 1f / tiers.Length); + } + else + { + if (segments.IsTierStarted(tier)) + segments.EndSegment(tier, i * 1f / tiers.Length); + } + } + } + + segments.EndAllPendingSegments(); + segments.Sort(); + } + + private Colour4 tierToColour(int tier) => tier >= 0 ? TierColours[tier] : new Colour4(0, 0, 0, 0); + + // Base implementation, could be drawn with draw node if preferred + private void redrawSegments(BufferedContainer container) + { + if (segments.Count == 0) + return; + + foreach (SegmentInfo segment in segments) // Lower tiers will be drawn first, putting them in the back + { + float width = segment.Length * DrawWidth; + + // If the segment width exceeds the DrawWidth, just fill the rest + if (width >= DrawWidth) + width = DrawWidth; + + container.Add(new Box + { + Name = $"Tier {segment.Tier} segment", + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Y, + Position = new Vector2(segment.Start * DrawWidth, 0), + Width = width, + Colour = tierToColour(segment.Tier) + }); + } + } + + protected struct SegmentInfo + { + /// + /// The tier this segment is at. + /// + public int Tier; + + /// + /// The progress at which this segment starts. + /// + /// + /// The value is a normalized float (from 0 to 1). + /// + public float Start; + + /// + /// The progress at which this segment ends. + /// + /// + /// The value is a normalized float (from 0 to 1). + /// + public float End; + + /// + /// The length of this segment. + /// + /// + /// The value is a normalized float (from 0 to 1). + /// + public float Length => End - Start; + } + + protected class SegmentManager : IEnumerable + { + private readonly List segments = new List(); + + private readonly SegmentInfo?[] pendingSegments; + + public SegmentManager(int tierCount) + { + pendingSegments = new SegmentInfo?[tierCount]; + } + + public void StartSegment(int tier, float start) + { + if (pendingSegments[tier] != null) + throw new InvalidOperationException($"Another {nameof(SegmentInfo)} of tier {tier.ToString()} has already been started."); + + pendingSegments[tier] = new SegmentInfo + { + Tier = tier, + Start = Math.Clamp(start, 0, 1) + }; + } + + public void EndSegment(int tier, float end) + { + SegmentInfo? pendingSegment = pendingSegments[tier]; + if (pendingSegment == null) + throw new InvalidOperationException($"Cannot end {nameof(SegmentInfo)} of tier {tier.ToString()} that has not been started."); + + SegmentInfo segment = pendingSegment.Value; + segment.End = Math.Clamp(end, 0, 1); + segments.Add(segment); + pendingSegments[tier] = null; + } + + public void EndAllPendingSegments() + { + foreach (SegmentInfo? pendingSegment in pendingSegments) + { + if (pendingSegment != null) + { + SegmentInfo finalizedSegment = pendingSegment.Value; + finalizedSegment.End = 1; + segments.Add(finalizedSegment); + } + } + } + + public void Sort() => + segments.Sort((a, b) => + a.Tier != b.Tier + ? a.Tier.CompareTo(b.Tier) + : a.Start.CompareTo(b.Start)); + + public void Add(SegmentInfo segment) => segments.Add(segment); + + public void Clear() + { + segments.Clear(); + + for (int i = 0; i < pendingSegments.Length; i++) + pendingSegments[i] = null; + } + + public int Count => segments.Count; + + public void Add(int tier, float start, float end) + { + SegmentInfo segment = new SegmentInfo + { + Tier = tier, + Start = Math.Clamp(start, 0, 1), + End = Math.Clamp(end, 0, 1) + }; + + if (segment.Start > segment.End) + throw new InvalidOperationException("Segment start cannot be after segment end."); + + Add(segment); + } + + public bool IsTierStarted(int tier) + { + if (tier < 0) + return false; + + return pendingSegments[tier].HasValue; + } + + public IEnumerator GetEnumerator() => segments.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } + } +} From 23e4cfb4691a4eea687e56bd90cb8d4463adabac Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 9 Jan 2023 23:37:36 +0300 Subject: [PATCH 1358/2991] Show spinner next to buttons and get rid of `EditorCommitButton` --- .../UserInterface/TestSceneCommentEditor.cs | 17 ++- osu.Game/Overlays/Comments/CommentEditor.cs | 116 ++++++++---------- 2 files changed, 58 insertions(+), 75 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index 799f5c52bd..e7840d4a2a 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -7,7 +7,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Framework.Testing; @@ -56,9 +55,9 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("press Enter", () => InputManager.Key(Key.Enter)); - AddUntilStep("button is loading", () => commentEditor.ButtonLoading); + AddUntilStep("button is loading", () => commentEditor.IsSpinnerShown); AddAssert("text committed", () => commentEditor.CommittedText == "text"); - AddUntilStep("button is not loading", () => !commentEditor.ButtonLoading); + AddUntilStep("button is not loading", () => !commentEditor.IsSpinnerShown); } [Test] @@ -72,7 +71,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("press Enter", () => InputManager.Key(Key.Enter)); - AddAssert("button is not loading", () => !commentEditor.ButtonLoading); + AddAssert("button is not loading", () => !commentEditor.IsSpinnerShown); AddAssert("no text committed", () => commentEditor.CommittedText.Length == 0); } @@ -92,9 +91,9 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.Click(MouseButton.Left); }); - AddUntilStep("button is loading", () => commentEditor.ButtonLoading); + AddUntilStep("button is loading", () => commentEditor.IsSpinnerShown); AddAssert("text committed", () => commentEditor.CommittedText == "some other text"); - AddUntilStep("button is not loading", () => !commentEditor.ButtonLoading); + AddUntilStep("button is not loading", () => !commentEditor.IsSpinnerShown); } [Test] @@ -116,13 +115,13 @@ namespace osu.Game.Tests.Visual.UserInterface public string CommittedText { get; private set; } = string.Empty; - public bool ButtonLoading => CommitButton.ChildrenOfType().Single().IsPresent && !CommitButton.ChildrenOfType().Single().IsPresent; + public bool IsSpinnerShown => this.ChildrenOfType().Single().IsPresent; protected override void OnCommit(string value) { - CommitButton.ShowLoadingSpinner = true; + ShowLoadingSpinner = true; CommittedText = value; - Scheduler.AddDelayed(() => CommitButton.ShowLoadingSpinner = false, 1000); + Scheduler.AddDelayed(() => ShowLoadingSpinner = false, 1000); } protected override LocalisableString FooterText => @"Footer text. And it is pretty long. Cool."; diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index da71d0f364..f11cef55d4 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -32,7 +32,24 @@ namespace osu.Game.Overlays.Comments protected readonly Bindable Current = new Bindable(); - protected EditorCommitButton CommitButton = null!; + private RoundedButton commitButton = null!; + private LoadingSpinner loadingSpinner = null!; + + private bool showLoadingSpinner; + + protected bool ShowLoadingSpinner + { + set + { + commitButton.Enabled.Value = !value && !string.IsNullOrEmpty(Current.Value); + showLoadingSpinner = value; + + if (value) + loadingSpinner.Show(); + else + loadingSpinner.Hide(); + } + } [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -82,36 +99,57 @@ namespace osu.Game.Overlays.Comments Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold), Text = FooterText }, - ButtonsContainer = new FillFlowContainer + new FillFlowContainer { - Name = @"Buttons", Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(5, 0), - Child = CommitButton = new EditorCommitButton + Children = new Drawable[] { - Text = CommitButtonText, - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Action = () => OnCommit(Current.Value) + ButtonsContainer = new FillFlowContainer + { + Name = @"Buttons", + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Child = commitButton = new RoundedButton + { + Width = 100, + Height = 30, + Text = CommitButtonText, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Action = () => OnCommit(Current.Value) + } + }, + loadingSpinner = new LoadingSpinner + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Size = new Vector2(18), + }, } - } + }, } } } } }); - textBox.OnCommit += (_, _) => CommitButton.TriggerClick(); + textBox.OnCommit += (_, _) => commitButton.TriggerClick(); } protected override void LoadComplete() { base.LoadComplete(); - - Current.BindValueChanged(text => CommitButton.IsBlocked.Value = string.IsNullOrEmpty(text.NewValue), true); + Current.BindValueChanged(text => + { + commitButton.Enabled.Value = !showLoadingSpinner && !string.IsNullOrEmpty(text.NewValue); + }, true); } protected abstract void OnCommit(string text); @@ -149,59 +187,5 @@ namespace osu.Game.Overlays.Comments Child = new OsuSpriteText { Text = c.ToString(), Font = OsuFont.GetFont(size: CalculatedTextSize) } }; } - - protected sealed partial class EditorCommitButton : RoundedButton - { - private const int duration = 200; - - private readonly LoadingSpinner spinner; - private SpriteText text = null!; - - public readonly BindableBool IsBlocked = new BindableBool(); - - private bool showLoadingSpinner; - - /// - /// Whether loading spinner shown. - /// - public bool ShowLoadingSpinner - { - get => showLoadingSpinner; - set - { - showLoadingSpinner = value; - Enabled.Value = !value && !IsBlocked.Value; - spinner.FadeTo(value ? 1f : 0f, duration, Easing.OutQuint); - text.FadeTo(value ? 0f : 1f, duration, Easing.OutQuint); - } - } - - public EditorCommitButton() - { - Width = 100; - Height = 30; - Add(spinner = new LoadingSpinner - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(16), - Depth = -2, - }); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - IsBlocked.BindValueChanged(e => - { - Enabled.Value = !ShowLoadingSpinner && !e.NewValue; - }, true); - } - - protected override SpriteText CreateText() - { - return text = base.CreateText(); - } - } } } From e6479b73ded35cc109627f9bcffbbc7b8ac3c676 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 23:43:35 +0300 Subject: [PATCH 1359/2991] Remove one more unused using directive --- osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs index a507bb73c6..6f0b0c62f8 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs @@ -8,7 +8,6 @@ using System.Diagnostics; using System.IO; using System.Linq; using Newtonsoft.Json; -using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Legacy; From 0f1fe1d6832d0c6dd2f29e30a5d142b2fbfc023e Mon Sep 17 00:00:00 2001 From: tsrk Date: Mon, 9 Jan 2023 21:48:53 +0100 Subject: [PATCH 1360/2991] refactor(hud/gameplay/SongProgress): Add interface to designate `SongProgressBar`s --- .../Visual/Gameplay/TestSceneHUDOverlay.cs | 16 +++++++++++++--- .../Multiplayer/TestSceneMultiSpectatorScreen.cs | 2 +- osu.Game/Screens/Play/HUD/DefaultSongProgress.cs | 2 +- osu.Game/Screens/Play/HUD/ISongProgressBar.cs | 16 ++++++++++++++++ osu.Game/Screens/Play/HUD/SongProgressBar.cs | 10 ++++------ 5 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 osu.Game/Screens/Play/HUD/ISongProgressBar.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 29fadd151f..713183ebaf 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -188,7 +188,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestInputDoesntWorkWhenHUDHidden() { - SongProgressBar? getSongProgress() => hudOverlay.ChildrenOfType().SingleOrDefault(); + ISongProgressBar? getSongProgress() => hudOverlay.ChildrenOfType().SingleOrDefault(); bool seeked = false; @@ -204,7 +204,7 @@ namespace osu.Game.Tests.Visual.Gameplay Debug.Assert(progress != null); - progress.ShowHandle = true; + progress.Interactive = true; progress.OnSeek += _ => seeked = true; }); @@ -213,7 +213,17 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("attempt seek", () => { - InputManager.MoveMouseTo(getSongProgress()); + switch (getSongProgress()) + { + case SongProgressBar defaultBar: + InputManager.MoveMouseTo(defaultBar); + break; + + case ArgonSongProgressBar argonBar: + InputManager.MoveMouseTo(argonBar); + break; + } + InputManager.Click(MouseButton.Left); }); diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs index c2036984c1..dd891b456c 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs @@ -121,7 +121,7 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("all interactive elements removed", () => this.ChildrenOfType().All(p => !p.ChildrenOfType().Any() && !p.ChildrenOfType().Any() && - p.ChildrenOfType().SingleOrDefault()?.ShowHandle == false)); + p.ChildrenOfType().SingleOrDefault()?.Interactive == false)); AddStep("restore config hud visibility", () => config.SetValue(OsuSetting.HUDVisibilityMode, originalConfigValue)); } diff --git a/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs b/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs index 53866312a0..cb629a0b77 100644 --- a/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs +++ b/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs @@ -133,7 +133,7 @@ namespace osu.Game.Screens.Play.HUD private void updateBarVisibility() { - bar.ShowHandle = AllowSeeking.Value; + bar.Interactive = AllowSeeking.Value; updateInfoMargin(); } diff --git a/osu.Game/Screens/Play/HUD/ISongProgressBar.cs b/osu.Game/Screens/Play/HUD/ISongProgressBar.cs new file mode 100644 index 0000000000..f1a219e18b --- /dev/null +++ b/osu.Game/Screens/Play/HUD/ISongProgressBar.cs @@ -0,0 +1,16 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; + +namespace osu.Game.Screens.Play.HUD +{ + public interface ISongProgressBar + { + public Action? OnSeek { get; set; } + public double StartTime { set; } + public double EndTime { set; } + public double CurrentTime { set; } + public bool Interactive { get; set; } + } +} diff --git a/osu.Game/Screens/Play/HUD/SongProgressBar.cs b/osu.Game/Screens/Play/HUD/SongProgressBar.cs index 28059d4911..fade562e3c 100644 --- a/osu.Game/Screens/Play/HUD/SongProgressBar.cs +++ b/osu.Game/Screens/Play/HUD/SongProgressBar.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osuTK; using osuTK.Graphics; @@ -15,9 +13,9 @@ using osu.Framework.Threading; namespace osu.Game.Screens.Play.HUD { - public partial class SongProgressBar : SliderBar + public partial class SongProgressBar : SliderBar, ISongProgressBar { - public Action OnSeek; + public Action? OnSeek { get; set; } private readonly Box fill; private readonly Container handleBase; @@ -25,7 +23,7 @@ namespace osu.Game.Screens.Play.HUD private bool showHandle; - public bool ShowHandle + public bool Interactive { get => showHandle; set @@ -142,7 +140,7 @@ namespace osu.Game.Screens.Play.HUD handleBase.X = newX; } - private ScheduledDelegate scheduledSeek; + private ScheduledDelegate? scheduledSeek; protected override void OnUserChange(double value) { From f6265197e84a44fe76df79a53feb3a54976cd6c2 Mon Sep 17 00:00:00 2001 From: tsrk Date: Mon, 9 Jan 2023 21:55:10 +0100 Subject: [PATCH 1361/2991] feat(hud/gameplay): Add Argon variant of `SongProgressBar` --- .../Screens/Play/HUD/ArgonSongProgressBar.cs | 249 ++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs new file mode 100644 index 0000000000..3ac7223f1d --- /dev/null +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs @@ -0,0 +1,249 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; +using osu.Framework.Threading; +using osu.Framework.Utils; +using osu.Game.Graphics; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Screens.Play.HUD +{ + public partial class ArgonSongProgressBar : SliderBar, ISongProgressBar + { + private readonly float baseHeight; + private readonly float catchupBaseDepth; + + private readonly RoundedBar playfieldBar; + private readonly RoundedBar catchupBar; + + private readonly Box background; + + private readonly BindableBool showBackground = new BindableBool(); + + public bool ShowBackground + { + get => showBackground.Value; + set => showBackground.Value = value; + } + + private const float alpha_threshold = 2500; + + public Action? OnSeek { get; set; } + + public double StartTime + { + private get => CurrentNumber.MinValue; + set => CurrentNumber.MinValue = value; + } + + public double EndTime + { + private get => CurrentNumber.MaxValue; + set => CurrentNumber.MaxValue = value; + } + + public double CurrentTime + { + private get => CurrentNumber.Value; + set => CurrentNumber.Value = value; + } + + public double ReferenceTime + { + private get => currentReference.Value; + set => currentReference.Value = value; + } + + private double length => EndTime - StartTime; + + private readonly BindableNumber currentReference; + + public bool Interactive { get; set; } + + public ArgonSongProgressBar(float barHeight) + { + currentReference = new BindableDouble(); + setupAlternateValue(); + + StartTime = 0; + EndTime = 1; + + RelativeSizeAxes = Axes.X; + baseHeight = barHeight; + Height = baseHeight; + + CornerRadius = 5; + Masking = true; + + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + }, + catchupBar = new RoundedBar + { + Name = "Audio bar", + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + CornerRadius = 5, + AlwaysPresent = true, + RelativeSizeAxes = Axes.Both + }, + playfieldBar = new RoundedBar + { + Name = "Playfield bar", + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + CornerRadius = 5, + AccentColour = Color4.White, + RelativeSizeAxes = Axes.Both + }, + }; + catchupBaseDepth = catchupBar.Depth; + } + + private void setupAlternateValue() + { + CurrentNumber.MaxValueChanged += v => currentReference.MaxValue = v; + CurrentNumber.MinValueChanged += v => currentReference.MinValue = v; + CurrentNumber.PrecisionChanged += v => currentReference.Precision = v; + } + + private float normalizedReference + { + get + { + if (EndTime - StartTime == 0) + return 1; + + return (float)((ReferenceTime - StartTime) / length); + } + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + catchupBar.AccentColour = colours.BlueLight; + showBackground.BindValueChanged(_ => updateBackground(), true); + } + + private void updateBackground() + { + background.FadeTo(showBackground.Value ? 1 : 0, 200, Easing.In); + } + + protected override bool OnHover(HoverEvent e) + { + if (Interactive) + this.ResizeHeightTo(baseHeight * 3.5f, 200, Easing.Out); + + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + if (Interactive) + this.ResizeHeightTo(baseHeight, 200, Easing.In); + + base.OnHoverLost(e); + } + + protected override void UpdateValue(float value) + { + // + } + + protected override void Update() + { + base.Update(); + + playfieldBar.Length = (float)Interpolation.Lerp(playfieldBar.Length, NormalizedValue, Math.Clamp(Time.Elapsed / 40, 0, 1)); + catchupBar.Length = (float)Interpolation.Lerp(catchupBar.Length, normalizedReference, Math.Clamp(Time.Elapsed / 40, 0, 1)); + + if (ReferenceTime < CurrentTime) + ChangeChildDepth(catchupBar, playfieldBar.Depth - 0.1f); + else + ChangeChildDepth(catchupBar, catchupBaseDepth); + + float timeDelta = (float)(Math.Abs(CurrentTime - ReferenceTime)); + catchupBar.Alpha = MathHelper.Clamp(timeDelta, 0, alpha_threshold) / alpha_threshold; + } + + private ScheduledDelegate? scheduledSeek; + + protected override void OnUserChange(double value) + { + scheduledSeek?.Cancel(); + scheduledSeek = Schedule(() => + { + if (Interactive) + OnSeek?.Invoke(value); + }); + } + + private partial class RoundedBar : Container + { + private readonly Box fill; + private readonly Container mask; + private float length; + + public RoundedBar() + { + Masking = true; + Children = new[] + { + mask = new Container + { + Masking = true, + RelativeSizeAxes = Axes.Y, + Size = new Vector2(1), + Child = fill = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Colour4.White + } + } + }; + } + + public float Length + { + get => length; + set + { + length = value; + mask.Width = value * DrawWidth; + fill.Width = value * DrawWidth; + } + } + + public new float CornerRadius + { + get => base.CornerRadius; + set + { + base.CornerRadius = value; + mask.CornerRadius = value; + } + } + + public ColourInfo AccentColour + { + get => fill.Colour; + set => fill.Colour = value; + } + } + } +} From 28d2d766ebdb595b138761f4da03149e0894e7af Mon Sep 17 00:00:00 2001 From: tsrk Date: Mon, 9 Jan 2023 21:57:32 +0100 Subject: [PATCH 1362/2991] refactor(hud/gameplay/SongProgressInfo): minor changes to text positioning, font and colour --- osu.Game/Screens/Play/HUD/SongProgressInfo.cs | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/SongProgressInfo.cs b/osu.Game/Screens/Play/HUD/SongProgressInfo.cs index fb5f5cc916..8a5c24a1f1 100644 --- a/osu.Game/Screens/Play/HUD/SongProgressInfo.cs +++ b/osu.Game/Screens/Play/HUD/SongProgressInfo.cs @@ -10,6 +10,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using System; +using osu.Framework.Graphics.Sprites; namespace osu.Game.Screens.Play.HUD { @@ -27,13 +28,33 @@ namespace osu.Game.Screens.Play.HUD private double songLength => endTime - startTime; - private const int margin = 10; + public FontUsage Font + { + set + { + timeCurrent.Font = value; + timeLeft.Font = value; + progress.Font = value; + } + } + + public Colour4 TextColour + { + set + { + timeCurrent.Colour = value; + timeLeft.Colour = value; + progress.Colour = value; + } + } public double StartTime { set => startTime = value; } + public bool ShowProgress = true; + public double EndTime { set => endTime = value; @@ -76,6 +97,7 @@ namespace osu.Game.Screens.Play.HUD Origin = Anchor.Centre, Anchor = Anchor.Centre, AutoSizeAxes = Axes.Both, + Alpha = ShowProgress ? 1 : 0, Child = new UprightAspectMaintainingContainer { Origin = Anchor.Centre, @@ -99,15 +121,15 @@ namespace osu.Game.Screens.Play.HUD AutoSizeAxes = Axes.Both, Child = new UprightAspectMaintainingContainer { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + Anchor = Anchor.CentreRight, AutoSizeAxes = Axes.Both, Scaling = ScaleMode.Vertical, ScalingFactor = 0.5f, Child = timeLeft = new SizePreservingSpriteText { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + Anchor = Anchor.CentreRight, Colour = colours.BlueLighter, Font = OsuFont.Numeric, } @@ -128,7 +150,7 @@ namespace osu.Game.Screens.Play.HUD if (currentPercent != previousPercent) { - progress.Text = currentPercent.ToString() + @"%"; + progress.Text = currentPercent + @"%"; previousPercent = currentPercent; } From 5952cd08a22e16d96f20815f21d3b7b50dcec71a Mon Sep 17 00:00:00 2001 From: tsrk Date: Mon, 9 Jan 2023 21:58:53 +0100 Subject: [PATCH 1363/2991] feat(hud/gameplay): implement Argon song progress density graph (SegmentedGraph) --- .../Play/HUD/ArgonSongProgressGraph.cs | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 osu.Game/Screens/Play/HUD/ArgonSongProgressGraph.cs diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgressGraph.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgressGraph.cs new file mode 100644 index 0000000000..2c82faf7b2 --- /dev/null +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgressGraph.cs @@ -0,0 +1,62 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using osu.Framework.Graphics; +using osu.Game.Rulesets.Objects; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Play.HUD +{ + public partial class ArgonSongProgressGraph : SegmentedGraph + { + private IEnumerable? objects; + + public IEnumerable Objects + { + set + { + objects = value; + + const int granularity = 300; + int[] values = new int[granularity]; + + if (!objects.Any()) + return; + + double firstHit = objects.First().StartTime; + double lastHit = objects.Max(o => o.GetEndTime()); + + if (lastHit == 0) + lastHit = objects.Last().StartTime; + + double interval = (lastHit - firstHit + 1) / granularity; + + foreach (var h in objects) + { + double endTime = h.GetEndTime(); + + Debug.Assert(endTime >= h.StartTime); + + int startRange = (int)((h.StartTime - firstHit) / interval); + int endRange = (int)((endTime - firstHit) / interval); + for (int i = startRange; i <= endRange; i++) + values[i]++; + } + + Values = values; + } + } + + public ArgonSongProgressGraph() + : base(5) + { + for (int i = 0; i < 5; i++) + { + TierColours[i] = Colour4.White.Opacity(1 / 5f * 0.85f); + } + } + } +} From 91cde5ffbff37689c318d7f49aef1f1819843f62 Mon Sep 17 00:00:00 2001 From: tsrk Date: Mon, 9 Jan 2023 21:59:48 +0100 Subject: [PATCH 1364/2991] feat(hud/gameplay): implement Argon variant of `SongProgress` --- .../Screens/Play/HUD/ArgonSongProgress.cs | 139 ++++++++++++++++++ osu.Game/Skinning/ArgonSkin.cs | 9 +- 2 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Screens/Play/HUD/ArgonSongProgress.cs diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs new file mode 100644 index 0000000000..c36f881ec2 --- /dev/null +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs @@ -0,0 +1,139 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Timing; +using osu.Game.Configuration; +using osu.Game.Graphics; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.UI; + +namespace osu.Game.Screens.Play.HUD +{ + public partial class ArgonSongProgress : SongProgress + { + private readonly SongProgressInfo info; + private readonly ArgonSongProgressGraph graph; + private readonly ArgonSongProgressBar bar; + + private const float bar_height = 10; + + public readonly Bindable AllowSeeking = new BindableBool(); + + [SettingSource("Show difficulty graph", "Whether a graph displaying difficulty throughout the beatmap should be shown")] + public Bindable ShowGraph { get; } = new BindableBool(true); + + [Resolved] + private DrawableRuleset? drawableRuleset { get; set; } + + private IClock referenceClock => drawableRuleset?.FrameStableClock ?? GameplayClock; + + [Resolved] + private Player? player { get; set; } + + public ArgonSongProgress() + { + Anchor = Anchor.BottomCentre; + Origin = Anchor.BottomCentre; + Children = new Drawable[] + { + info = new SongProgressInfo + { + Origin = Anchor.TopLeft, + Name = "Info", + Anchor = Anchor.TopLeft, + RelativeSizeAxes = Axes.X, + ShowProgress = false + }, + graph = new ArgonSongProgressGraph + { + Name = "Difficulty graph", + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Masking = true, + CornerRadius = 5, + }, + bar = new ArgonSongProgressBar(bar_height) + { + Name = "Seek bar", + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, + OnSeek = time => player?.Seek(time), + } + }; + RelativeSizeAxes = Axes.X; + } + + [BackgroundDependencyLoader] + private void load() + { + base.LoadComplete(); + + if (drawableRuleset != null) + { + if (player?.Configuration.AllowUserInteraction == true) + ((IBindable)AllowSeeking).BindTo(drawableRuleset.HasReplayLoaded); + } + + info.ShowProgress = false; + info.TextColour = Colour4.White; + info.Font = OsuFont.Torus.With(size: 18, weight: FontWeight.Bold); + } + + protected override void LoadComplete() + { + AllowSeeking.BindValueChanged(_ => updateBarVisibility(), true); + ShowGraph.BindValueChanged(_ => updateGraphVisibility(), true); + } + + protected override void UpdateObjects(IEnumerable objects) + { + graph.Objects = objects; + + info.StartTime = bar.StartTime = FirstHitTime; + info.EndTime = bar.EndTime = LastHitTime; + } + + private void updateBarVisibility() + { + bar.Interactive = AllowSeeking.Value; + } + + private void updateGraphVisibility() + { + graph.FadeTo(ShowGraph.Value ? 1 : 0, 200, Easing.In); + bar.ShowBackground = !ShowGraph.Value; + } + + protected override void Update() + { + base.Update(); + Height = bar.Height + bar_height + info.Height; + graph.Height = bar.Height; + } + + protected override void PopIn() + { + this.FadeIn(500, Easing.OutQuint); + } + + protected override void PopOut() + { + this.FadeOut(100); + } + + protected override void UpdateProgress(double progress, bool isIntro) + { + bar.ReferenceTime = GameplayClock.CurrentTime; + + if (isIntro) + bar.CurrentTime = 0; + else + bar.CurrentTime = referenceClock.CurrentTime; + } + } +} diff --git a/osu.Game/Skinning/ArgonSkin.cs b/osu.Game/Skinning/ArgonSkin.cs index d78147aaea..53c6c1e5ce 100644 --- a/osu.Game/Skinning/ArgonSkin.cs +++ b/osu.Game/Skinning/ArgonSkin.cs @@ -108,6 +108,7 @@ namespace osu.Game.Skinning var accuracy = container.OfType().FirstOrDefault(); var combo = container.OfType().FirstOrDefault(); var ppCounter = container.OfType().FirstOrDefault(); + var songProgress = container.OfType().FirstOrDefault(); if (score != null) { @@ -158,6 +159,12 @@ namespace osu.Game.Skinning // origin flipped to match scale above. hitError2.Origin = Anchor.CentreLeft; } + + if (songProgress != null) + { + songProgress.Position = new Vector2(0, -10); + songProgress.Scale = new Vector2(0.9f, 1); + } } }) { @@ -167,7 +174,7 @@ namespace osu.Game.Skinning new DefaultScoreCounter(), new DefaultAccuracyCounter(), new DefaultHealthDisplay(), - new DefaultSongProgress(), + new ArgonSongProgress(), new BarHitErrorMeter(), new BarHitErrorMeter(), new PerformancePointsCounter() From 48deef4056a3b0a25f6dda5e440aacaac69dfa23 Mon Sep 17 00:00:00 2001 From: tsrk Date: Mon, 9 Jan 2023 22:07:18 +0100 Subject: [PATCH 1365/2991] test: adapt and create tests to cover new components --- .../Archives/modified-argon-20221024.osk | Bin 0 -> 1412 bytes .../Skins/SkinDeserialisationTest.cs | 2 + .../SkinnableHUDComponentTestScene.cs | 5 +- .../TestSceneArgonSongProgressGraph.cs | 73 ++++++++++++++++++ .../Visual/Gameplay/TestSceneSongProgress.cs | 2 + 5 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/Resources/Archives/modified-argon-20221024.osk create mode 100644 osu.Game.Tests/Visual/Gameplay/TestSceneArgonSongProgressGraph.cs diff --git a/osu.Game.Tests/Resources/Archives/modified-argon-20221024.osk b/osu.Game.Tests/Resources/Archives/modified-argon-20221024.osk new file mode 100644 index 0000000000000000000000000000000000000000..28b6a001ebd37b63c3e6c1b64d2cab3af0b9e0a5 GIT binary patch literal 1412 zcmWIWW@Zs#U|`^2*fJ?1H1DEC$y^|BJ6ME)p*TA;PcJhsQ?yU#0!|wxs6MaP; zdzJ`Zio6+_sVX-6j+*73+fz@=Ddunf;8}N&Wp|_Gv)})wsK&52`R$p0vXFo61|e-9 z3nsOx4X>iU)Uj=urek7!Vuo2la7?jyoKPt{Z(p}a+qudl9+sz8TSXKnEOI@%_vE|u zq^=k8YP)rO|HeO+sD3EZ^(r7VTB9lAy5%Nrx$SD!swbU0f>2l803Y_ytI71tm6E<)z6*=1q6KZKI0p@DJbBSzFufZN1&IE*ZK3^fk77x zj0}t}gX&+xkqqC+{OAbWM=?)V1{?zTT%jxr`&!0|zULZ8D@~CQOrRvO1 z)tNsl=T&C@3~2s(r*YZ~*7WpePg9>QeQnwFhT&t0NWvtqJuzDuP#tJ`-1GGgMh1r0 zK-Y-@9q5~wndcGe;+&sbke`>DS5gdi>Dy_6*|!Y@j^F40%cpjJ+k{s~HnLTon3UUS zm^Q6Ue<}Z}s=^~8E9a!Fko^5_a`^Goucy7dWVR(5{8<0_e@oq*ck9ldU-Y8-bJwDa zskQuz%`cwV)m0;4t&rWxaBQMe_pCMRrloL72WIZyuseG9hN&ML3b*k0FJ9l^7iqls z$#r4(Zh;uZGdv-3t$m9Z?Yin!*YfL99ka3V)N6}(_{K*pulZq{v+!=9fcznGY2!l{ z&nxeoES+$fb7B9X{=G-VU%O^se3E~4tBBOEb+Hbwk5`oyD{mK@z4T?=ubx#Qz4rID z!};!1e`P3-{oR!P-m$=z$^Vi9N7$+T&Rc$P9`b#1BD!(EW_`Ks20OlQ^2b*{@`yX6 zEIVJSpQ#|ZP`#(+kk;e74U2=#6c;vsKKUbl{`|f>hLaw+N8{Hunu%t)%{2P{(%LSS{*LbeYD9784v0|*ks+ClG?0RBJpBb64Sq#;wnp5tDK#7{Tb)|74oU2A-DK1 zRJg34b=@ZA;%~vd(gyx}nh%@&JKNH@k~8A<{>w2_H(t2ue>u)4%z6i>UVn^?Nz3iK zb{js|Z2Qj|;LXS+!hpN<0R|WZG=eBtS%j_&J;OuwFfcS8hU$W6e{`+rSrMT%1sGx2 gGbXwj=uwO?BY+tr!UMcn*+2?dfbbKLu3-W3058Krn*aa+ literal 0 HcmV?d00001 diff --git a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs index ff665499ae..2e8eb48f0b 100644 --- a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs +++ b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs @@ -41,6 +41,8 @@ namespace osu.Game.Tests.Skins "Archives/modified-default-20220818.osk", // Covers longest combo counter "Archives/modified-default-20221012.osk", + // Covers Argon variant of song progress bar + "Archives/modified-argon-20221024.osk", // Covers TextElement and BeatmapInfoDrawable "Archives/modified-default-20221102.osk" }; diff --git a/osu.Game.Tests/Visual/Gameplay/SkinnableHUDComponentTestScene.cs b/osu.Game.Tests/Visual/Gameplay/SkinnableHUDComponentTestScene.cs index 545b3c2cf4..f54f50795e 100644 --- a/osu.Game.Tests/Visual/Gameplay/SkinnableHUDComponentTestScene.cs +++ b/osu.Game.Tests/Visual/Gameplay/SkinnableHUDComponentTestScene.cs @@ -20,7 +20,9 @@ namespace osu.Game.Tests.Visual.Gameplay { var implementation = skin is LegacySkin ? CreateLegacyImplementation() - : CreateDefaultImplementation(); + : skin is ArgonSkin + ? CreateArgonImplementation() + : CreateDefaultImplementation(); implementation.Anchor = Anchor.Centre; implementation.Origin = Anchor.Centre; @@ -29,6 +31,7 @@ namespace osu.Game.Tests.Visual.Gameplay }); protected abstract Drawable CreateDefaultImplementation(); + protected virtual Drawable CreateArgonImplementation() => CreateDefaultImplementation(); protected abstract Drawable CreateLegacyImplementation(); } } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneArgonSongProgressGraph.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneArgonSongProgressGraph.cs new file mode 100644 index 0000000000..159ee849e1 --- /dev/null +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneArgonSongProgressGraph.cs @@ -0,0 +1,73 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Diagnostics; +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Framework.Testing; +using osu.Framework.Utils; +using osu.Game.Rulesets.Objects; +using osu.Game.Screens.Play.HUD; + +namespace osu.Game.Tests.Visual.Gameplay +{ + [TestFixture] + public partial class TestSceneArgonSongProgressGraph : OsuTestScene + { + private TestArgonSongProgressGraph? graph; + + [SetUpSteps] + public void SetupSteps() + { + AddStep("add new big graph", () => + { + if (graph != null) + { + graph.Expire(); + graph = null; + } + + Add(graph = new TestArgonSongProgressGraph + { + RelativeSizeAxes = Axes.X, + Height = 200, + Anchor = Anchor.TopLeft, + Origin = Anchor.TopLeft, + }); + }); + } + + [Test] + public void TestGraphRecreation() + { + AddAssert("ensure not created", () => graph!.CreationCount == 0); + AddStep("display values", displayRandomValues); + AddUntilStep("wait for creation count", () => graph!.CreationCount == 1); + AddRepeatStep("new values", displayRandomValues, 5); + AddWaitStep("wait some", 5); + AddAssert("ensure recreation debounced", () => graph!.CreationCount == 2); + } + + private void displayRandomValues() + { + Debug.Assert(graph != null); + var objects = new List(); + for (double i = 0; i < 5000; i += RNG.NextDouble() * 10 + i / 1000) + objects.Add(new HitObject { StartTime = i }); + + graph.Objects = objects; + } + + private partial class TestArgonSongProgressGraph : ArgonSongProgressGraph + { + public int CreationCount { get; private set; } + + protected override void RecreateGraph() + { + base.RecreateGraph(); + CreationCount++; + } + } + } +} diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index 2e579cc522..415a3c5b07 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs @@ -72,6 +72,8 @@ namespace osu.Game.Tests.Visual.Gameplay protected override Drawable CreateDefaultImplementation() => new DefaultSongProgress(); + protected override Drawable CreateArgonImplementation() => new ArgonSongProgress(); + protected override Drawable CreateLegacyImplementation() => new LegacySongProgress(); } } From eac8e9f6fb2756b4a5529dec30065dc8706ed3c1 Mon Sep 17 00:00:00 2001 From: tsrk Date: Mon, 9 Jan 2023 22:21:34 +0100 Subject: [PATCH 1366/2991] test: make test not actually test anything --- .../Visual/Gameplay/TestSceneArgonSongProgressGraph.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneArgonSongProgressGraph.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneArgonSongProgressGraph.cs index 159ee849e1..e7feadc72b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneArgonSongProgressGraph.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneArgonSongProgressGraph.cs @@ -39,14 +39,10 @@ namespace osu.Game.Tests.Visual.Gameplay } [Test] - public void TestGraphRecreation() + public void Test() { AddAssert("ensure not created", () => graph!.CreationCount == 0); AddStep("display values", displayRandomValues); - AddUntilStep("wait for creation count", () => graph!.CreationCount == 1); - AddRepeatStep("new values", displayRandomValues, 5); - AddWaitStep("wait some", 5); - AddAssert("ensure recreation debounced", () => graph!.CreationCount == 2); } private void displayRandomValues() From f971405c8c3978d6603461316f3d37ec8be105c6 Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Tue, 10 Jan 2023 00:02:31 +0000 Subject: [PATCH 1367/2991] append time as well --- osu.Game/Database/LegacyScoreExporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index 7c0ba7c6ee..01f9afdc86 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -23,7 +23,7 @@ namespace osu.Game.Database protected override string GetFilename(ScoreInfo score) { string scoreString = score.GetDisplayString(); - string filename = $"{scoreString} ({score.Date.LocalDateTime:yyyy-MM-dd})"; + string filename = $"{scoreString} ({score.Date.LocalDateTime:yyyy-MM-dd_HH-mm})"; return filename; } From 46ffded1db0b8486800b9e5baa71bf87f9c838d4 Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Tue, 10 Jan 2023 08:27:21 +0000 Subject: [PATCH 1368/2991] Taiko touch control scheme setting now *almost* works (need to implement getting control scheme from config); Drum display is incorrect --- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- .../UI/DrumTouchInputArea.cs | 93 ++++++++++++++++--- 2 files changed, 82 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index e5a1a5d7ce..094a84d3fa 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -198,7 +198,7 @@ namespace osu.Game.Rulesets.Taiko public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new TaikoReplayFrame(); public override IRulesetConfigManager CreateConfig(SettingsStore? settings) => new TaikoRulesetConfigManager(settings, RulesetInfo); - + public override RulesetSettingsSubsection CreateSettings() => new TaikoSettingsSubsection(this); protected override IEnumerable GetValidHitResults() diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 0232c10d65..91829fd66a 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -1,6 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +#nullable disable +#pragma warning disable IDE0001 // Simplify Names + +using System; using System.Collections.Generic; using System.Diagnostics; using osu.Framework.Allocation; @@ -11,11 +15,13 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Game.Graphics; +using osu.Game.Rulesets.Taiko.Configuration; using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.UI { + using TaikoInput = TaikoAction; /// /// An overlay that captures and displays osu!taiko mouse and touch input. /// @@ -27,6 +33,7 @@ namespace osu.Game.Rulesets.Taiko.UI private KeyBindingContainer keyBindingContainer = null!; + private readonly Dictionary trackedActions = new Dictionary(); private Container mainContent = null!; @@ -37,7 +44,7 @@ namespace osu.Game.Rulesets.Taiko.UI private QuarterCircle rightRim = null!; [BackgroundDependencyLoader] - private void load(TaikoInputManager taikoInputManager, OsuColour colours) + private void load(TaikoInputManager taikoInputManager, TaikoRulesetConfigManager config, OsuColour colours) { Debug.Assert(taikoInputManager.KeyBindingContainer != null); keyBindingContainer = taikoInputManager.KeyBindingContainer; @@ -47,6 +54,7 @@ namespace osu.Game.Rulesets.Taiko.UI const float centre_region = 0.80f; + var touchControlScheme = config.GetBindable(TaikoRulesetSetting.TouchControlScheme).Value; Children = new Drawable[] { new Container @@ -65,27 +73,27 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - leftRim = new QuarterCircle(TaikoAction.LeftRim, colours.Blue) + leftRim = new QuarterCircle(TaikoInput.LeftRim, touchControlScheme, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, }, - rightRim = new QuarterCircle(TaikoAction.RightRim, colours.Blue) + rightRim = new QuarterCircle(TaikoInput.RightRim, touchControlScheme, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = 2, Rotation = 90, }, - leftCentre = new QuarterCircle(TaikoAction.LeftCentre, colours.Pink) + leftCentre = new QuarterCircle(TaikoInput.LeftCentre, touchControlScheme, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, Scale = new Vector2(centre_region), }, - rightCentre = new QuarterCircle(TaikoAction.RightCentre, colours.Pink) + rightCentre = new QuarterCircle(TaikoInput.RightCentre, touchControlScheme, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, @@ -123,14 +131,14 @@ namespace osu.Game.Rulesets.Taiko.UI { Show(); - TaikoAction taikoAction = getTaikoActionFromInput(position); + TaikoInput taikoInput = getTaikoActionFromPosition(position); // Not too sure how this can happen, but let's avoid throwing. if (trackedActions.ContainsKey(source)) return; - trackedActions.Add(source, taikoAction); - keyBindingContainer.TriggerPressed(taikoAction); + trackedActions.Add(source, taikoInput); + keyBindingContainer.TriggerPressed(taikoInput); } private void handleUp(object source) @@ -142,15 +150,61 @@ namespace osu.Game.Rulesets.Taiko.UI private bool validMouse(MouseButtonEvent e) => leftRim.Contains(e.ScreenSpaceMouseDownPosition) || rightRim.Contains(e.ScreenSpaceMouseDownPosition); - private TaikoAction getTaikoActionFromInput(Vector2 inputPosition) +#pragma warning disable format + private TaikoAction getTaikoActionFromPosition(TaikoInput input) + { + switch (TaikoTouchControlScheme.DDKK) + { + case TaikoTouchControlScheme.KDDK: +#pragma warning disable CS0162 // Unreachable code detected + switch (input) + { + case TaikoInput.LeftRim: return TaikoAction.LeftRim; + case TaikoInput.LeftCentre: return TaikoAction.LeftCentre; + case TaikoInput.RightCentre: return TaikoAction.RightCentre; + case TaikoInput.RightRim: return TaikoAction.RightRim; + } +#pragma warning restore CS0162 // Unreachable code detected + break; + + case TaikoTouchControlScheme.DDKK: + switch (input) + { + case TaikoInput.LeftRim: return TaikoAction.LeftCentre; + case TaikoInput.LeftCentre: return TaikoAction.RightCentre; + case TaikoInput.RightCentre: return TaikoAction.LeftRim; + case TaikoInput.RightRim: return TaikoAction.RightRim; + } + break; + + case TaikoTouchControlScheme.KKDD: +#pragma warning disable CS0162 // Unreachable code detected + switch (input) + { + case TaikoInput.LeftRim: return TaikoAction.LeftRim; + case TaikoInput.LeftCentre: return TaikoAction.RightRim; + case TaikoInput.RightCentre: return TaikoAction.LeftCentre; + case TaikoInput.RightRim: return TaikoAction.RightCentre; + } +#pragma warning restore CS0162 // Unreachable code detected + break; + } + return TaikoAction.LeftCentre; + } + +#pragma warning restore format + private TaikoAction getTaikoActionFromPosition(Vector2 inputPosition) { bool centreHit = leftCentre.Contains(inputPosition) || rightCentre.Contains(inputPosition); bool leftSide = ToLocalSpace(inputPosition).X < DrawWidth / 2; + TaikoInput input; if (leftSide) - return centreHit ? TaikoAction.LeftCentre : TaikoAction.LeftRim; + input = centreHit ? TaikoInput.LeftCentre : TaikoInput.LeftRim; + else + input = centreHit ? TaikoInput.RightCentre : TaikoInput.RightRim; - return centreHit ? TaikoAction.RightCentre : TaikoAction.RightRim; + return getTaikoActionFromPosition(input); } protected override void PopIn() @@ -173,8 +227,23 @@ namespace osu.Game.Rulesets.Taiko.UI public override bool Contains(Vector2 screenSpacePos) => circle.Contains(screenSpacePos); - public QuarterCircle(TaikoAction handledAction, Color4 colour) + public QuarterCircle(TaikoAction handledAction, TaikoTouchControlScheme touchControlScheme, OsuColour colours) { + Color4 colour = ((Func)(() => + { +#pragma warning disable format + switch (handledAction) + { + case TaikoAction.LeftRim: return colours.Blue; + case TaikoAction.LeftCentre: return colours.Red; + case TaikoAction.RightCentre: return colours.Red; + case TaikoAction.RightRim: return colours.Blue; + } +#pragma warning restore format + return colours.Red; + }))(); + + this.handledAction = handledAction; RelativeSizeAxes = Axes.Both; From 93038ce496164e19c9fb26d05455bf40c401c31d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 17:49:08 +0900 Subject: [PATCH 1369/2991] Use `OfType` instead of forceful nullability --- 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 03085a8638..19eced08d9 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -119,7 +119,7 @@ namespace osu.Game.Screens.Select { CarouselRoot newRoot = new CarouselRoot(this); - newRoot.AddItems(beatmapSets.Select(s => createCarouselSet(s.Detach())).Where(g => g != null)!); + newRoot.AddItems(beatmapSets.Select(s => createCarouselSet(s.Detach())).OfType()); root = newRoot; From d53dafa29fc539de5c21705c433976f7d3df15e8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 17:52:28 +0900 Subject: [PATCH 1370/2991] Revert `Debug.Assert` --- osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs index c283cca3c8..f065926eb7 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs @@ -126,7 +126,7 @@ namespace osu.Game.Screens.Select.Carousel protected virtual void ApplyState() { - if (Item == null) return; + Debug.Assert(Item != null); // Use the fact that we know the precise height of the item from the model to avoid the need for AutoSize overhead. // Additionally, AutoSize doesn't work well due to content starting off-screen and being masked away. From b7e845201f51019529fb913dbe214de4168ff127 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 18:03:17 +0900 Subject: [PATCH 1371/2991] Fix whitespace around `Debug.Assert` --- osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index ea59c330b4..3975bb6bb6 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -74,6 +74,7 @@ namespace osu.Game.Screens.Select.Carousel base.Update(); Debug.Assert(Item != null); + // position updates should not occur if the item is filtered away. // this avoids panels flying across the screen only to be eventually off-screen or faded out. if (!Item.Visible) return; From 63ce5787e7525ac0d73c3291f283946e20296f2f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 18:06:45 +0900 Subject: [PATCH 1372/2991] Start bars invisible --- osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index 2907695ce7..17d07ce16c 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -111,6 +111,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters Origin = Anchor.TopCentre, Width = bar_width, RelativeSizeAxes = Axes.Y, + Alpha = 0, Height = 0.5f, Scale = new Vector2(1, -1), }, @@ -118,6 +119,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters { Anchor = Anchor.Centre, Origin = Anchor.TopCentre, + Alpha = 0, Width = bar_width, RelativeSizeAxes = Axes.Y, Height = 0.5f, From 3c93d0551cf4c13479fc41d6bfdee64825b5e30a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 18:07:15 +0900 Subject: [PATCH 1373/2991] Move setting up to be in line with other toggle --- .../Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index 17d07ce16c..0337f66bd9 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -33,6 +33,9 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters Precision = 0.1f, }; + [SettingSource("Show colour bars")] + public Bindable ColourBarVisibility { get; } = new Bindable(true); + [SettingSource("Show moving average arrow", "Whether an arrow should move beneath the bar showing the average error.")] public Bindable ShowMovingAverage { get; } = new BindableBool(true); @@ -42,9 +45,6 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters [SettingSource("Label style", "How to show early/late extremities")] public Bindable LabelStyle { get; } = new Bindable(LabelStyles.Icons); - [SettingSource("Show colour bars")] - public Bindable ColourBarVisibility { get; } = new Bindable(true); - private const int judgement_line_width = 14; private const int max_concurrent_judgements = 50; From 85f542c3a80a88ddc258b302ac5403b8d99c5e37 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 18:15:08 +0900 Subject: [PATCH 1374/2991] Make `GameplayClock` `private` --- osu.Game/Screens/Play/HUD/BPMCounter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/BPMCounter.cs b/osu.Game/Screens/Play/HUD/BPMCounter.cs index 8d3cab40b0..b9f5deacb0 100644 --- a/osu.Game/Screens/Play/HUD/BPMCounter.cs +++ b/osu.Game/Screens/Play/HUD/BPMCounter.cs @@ -24,7 +24,7 @@ namespace osu.Game.Screens.Play.HUD private IBindable beatmap { get; set; } = null!; [Resolved] - protected IGameplayClock GameplayClock { get; private set; } = null!; + private IGameplayClock gameplayClock { get; set; } = null!; [BackgroundDependencyLoader] private void load(OsuColour colour) @@ -38,10 +38,10 @@ namespace osu.Game.Screens.Play.HUD base.Update(); //We dont want it going to 0 when we pause. so we block the updates - if (GameplayClock.IsPaused.Value) return; + if (gameplayClock.IsPaused.Value) return; // We want to check Rate every update to cover windup/down - Current.Value = beatmap.Value.Beatmap.ControlPointInfo.TimingPointAt(GameplayClock.CurrentTime).BPM * GameplayClock.Rate; + Current.Value = beatmap.Value.Beatmap.ControlPointInfo.TimingPointAt(gameplayClock.CurrentTime).BPM * gameplayClock.Rate; } protected override OsuSpriteText CreateSpriteText() From 37d219a8ad011814c7ad93a2a10bc5d3e1f0ea2d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 18:20:39 +0900 Subject: [PATCH 1375/2991] Fix comments, remove fixed width on "bpm" text and adjust baseline adjust slightly --- osu.Game/Screens/Play/HUD/BPMCounter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/BPMCounter.cs b/osu.Game/Screens/Play/HUD/BPMCounter.cs index b9f5deacb0..c07b203341 100644 --- a/osu.Game/Screens/Play/HUD/BPMCounter.cs +++ b/osu.Game/Screens/Play/HUD/BPMCounter.cs @@ -37,7 +37,7 @@ namespace osu.Game.Screens.Play.HUD { base.Update(); - //We dont want it going to 0 when we pause. so we block the updates + //We don't want it going to 0 when we pause. so we block the updates if (gameplayClock.IsPaused.Value) return; // We want to check Rate every update to cover windup/down @@ -84,9 +84,9 @@ namespace osu.Game.Screens.Play.HUD { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - Font = OsuFont.Numeric.With(size: 8, fixedWidth: true), + Font = OsuFont.Numeric.With(size: 8), Text = @"BPM", - Padding = new MarginPadding { Bottom = 1.5f }, // align baseline better + Padding = new MarginPadding { Bottom = 2f }, // align baseline better } } }; From c6b6d0dcfee83d39e698f7787ccd681c15305919 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 10 Jan 2023 13:31:29 +0300 Subject: [PATCH 1376/2991] Remove verbose log from notifications feed --- osu.Game/Scoring/ScoreImporter.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Scoring/ScoreImporter.cs b/osu.Game/Scoring/ScoreImporter.cs index 2dfd461eb9..f69c1b9385 100644 --- a/osu.Game/Scoring/ScoreImporter.cs +++ b/osu.Game/Scoring/ScoreImporter.cs @@ -55,8 +55,6 @@ namespace osu.Game.Scoring catch (LegacyScoreDecoder.BeatmapNotFoundException e) { Logger.Log($@"Score '{name}' failed to import: no corresponding beatmap with the hash '{e.Hash}' could be found.", LoggingTarget.Database); - Logger.Log($@"Score '{name}' failed to import due to missing beatmap. Check database logs for more info.", LoggingTarget.Information, LogLevel.Error); - return null; } } From ee80cc988ec80a78e0303e42ccfafb9cdfa0260f Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Tue, 10 Jan 2023 10:32:00 +0000 Subject: [PATCH 1377/2991] Fixed drums not displaying correctly; Fixed typo on a function name --- osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 91829fd66a..69c2942e45 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -73,27 +73,27 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - leftRim = new QuarterCircle(TaikoInput.LeftRim, touchControlScheme, colours) + leftRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftRim), touchControlScheme, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, }, - rightRim = new QuarterCircle(TaikoInput.RightRim, touchControlScheme, colours) + rightRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightRim), touchControlScheme, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = 2, Rotation = 90, }, - leftCentre = new QuarterCircle(TaikoInput.LeftCentre, touchControlScheme, colours) + leftCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftCentre), touchControlScheme, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, Scale = new Vector2(centre_region), }, - rightCentre = new QuarterCircle(TaikoInput.RightCentre, touchControlScheme, colours) + rightCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightCentre), touchControlScheme, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, @@ -151,7 +151,7 @@ namespace osu.Game.Rulesets.Taiko.UI leftRim.Contains(e.ScreenSpaceMouseDownPosition) || rightRim.Contains(e.ScreenSpaceMouseDownPosition); #pragma warning disable format - private TaikoAction getTaikoActionFromPosition(TaikoInput input) + private TaikoAction getTaikoActionFromInput(TaikoInput input) { switch (TaikoTouchControlScheme.DDKK) { @@ -204,7 +204,7 @@ namespace osu.Game.Rulesets.Taiko.UI else input = centreHit ? TaikoInput.RightCentre : TaikoInput.RightRim; - return getTaikoActionFromPosition(input); + return getTaikoActionFromInput(input); } protected override void PopIn() From 0d6b9ebc0f18aa2db7cde7b9a55bf91ced958e88 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 10 Jan 2023 13:32:03 +0300 Subject: [PATCH 1378/2991] Display number of failing models during batch-import --- osu.Game/Database/RealmArchiveModelImporter.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index d107a6a605..20cae725ad 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -154,9 +154,12 @@ namespace osu.Game.Database } else { - notification.CompletionText = imported.Count == 1 - ? $"Imported {imported.First().GetDisplayString()}!" - : $"Imported {imported.Count} {HumanisedModelName}s!"; + if (tasks.Length > imported.Count) + notification.CompletionText = $"Imported {imported.Count} out of {tasks.Length} {HumanisedModelName}s."; + else if (imported.Count > 1) + notification.CompletionText = $"Imported {imported.Count} {HumanisedModelName}s!"; + else + notification.CompletionText = $"Imported {imported.First().GetDisplayString()}!"; if (imported.Count > 0 && PresentImport != null) { From 3785dd01368a2faefffde17f2abbfab95140c814 Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Tue, 10 Jan 2023 10:59:57 +0000 Subject: [PATCH 1379/2991] Taiko touch control scheme is now read from settings --- .../TaikoRulesetConfigManager.cs | 2 ++ .../UI/DrumTouchInputArea.cs | 21 ++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Configuration/TaikoRulesetConfigManager.cs b/osu.Game.Rulesets.Taiko/Configuration/TaikoRulesetConfigManager.cs index c3bc7f6439..7e2c7e89b4 100644 --- a/osu.Game.Rulesets.Taiko/Configuration/TaikoRulesetConfigManager.cs +++ b/osu.Game.Rulesets.Taiko/Configuration/TaikoRulesetConfigManager.cs @@ -1,6 +1,8 @@ // 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.Configuration.Tracking; +using System; using osu.Game.Configuration; using osu.Game.Rulesets.Configuration; diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 69c2942e45..aa786f2573 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -27,6 +28,7 @@ namespace osu.Game.Rulesets.Taiko.UI /// public partial class DrumTouchInputArea : VisibilityContainer { + // visibility state affects our child. we always want to handle input. public override bool PropagatePositionalInputSubTree => true; public override bool PropagateNonPositionalInputSubTree => true; @@ -43,6 +45,8 @@ namespace osu.Game.Rulesets.Taiko.UI private QuarterCircle leftRim = null!; private QuarterCircle rightRim = null!; + private Bindable touchControlScheme = new Bindable(); + [BackgroundDependencyLoader] private void load(TaikoInputManager taikoInputManager, TaikoRulesetConfigManager config, OsuColour colours) { @@ -54,7 +58,7 @@ namespace osu.Game.Rulesets.Taiko.UI const float centre_region = 0.80f; - var touchControlScheme = config.GetBindable(TaikoRulesetSetting.TouchControlScheme).Value; + config.BindWith(TaikoRulesetSetting.TouchControlScheme, touchControlScheme); Children = new Drawable[] { new Container @@ -73,27 +77,27 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - leftRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftRim), touchControlScheme, colours) + leftRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftRim), touchControlScheme.Value, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, }, - rightRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightRim), touchControlScheme, colours) + rightRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightRim), touchControlScheme.Value, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = 2, Rotation = 90, }, - leftCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftCentre), touchControlScheme, colours) + leftCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftCentre), touchControlScheme.Value, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, Scale = new Vector2(centre_region), }, - rightCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightCentre), touchControlScheme, colours) + rightCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightCentre), touchControlScheme.Value, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, @@ -153,10 +157,10 @@ namespace osu.Game.Rulesets.Taiko.UI #pragma warning disable format private TaikoAction getTaikoActionFromInput(TaikoInput input) { - switch (TaikoTouchControlScheme.DDKK) + switch (touchControlScheme.Value) { case TaikoTouchControlScheme.KDDK: -#pragma warning disable CS0162 // Unreachable code detected + switch (input) { case TaikoInput.LeftRim: return TaikoAction.LeftRim; @@ -164,7 +168,6 @@ namespace osu.Game.Rulesets.Taiko.UI case TaikoInput.RightCentre: return TaikoAction.RightCentre; case TaikoInput.RightRim: return TaikoAction.RightRim; } -#pragma warning restore CS0162 // Unreachable code detected break; case TaikoTouchControlScheme.DDKK: @@ -178,7 +181,6 @@ namespace osu.Game.Rulesets.Taiko.UI break; case TaikoTouchControlScheme.KKDD: -#pragma warning disable CS0162 // Unreachable code detected switch (input) { case TaikoInput.LeftRim: return TaikoAction.LeftRim; @@ -186,7 +188,6 @@ namespace osu.Game.Rulesets.Taiko.UI case TaikoInput.RightCentre: return TaikoAction.LeftCentre; case TaikoInput.RightRim: return TaikoAction.RightCentre; } -#pragma warning restore CS0162 // Unreachable code detected break; } return TaikoAction.LeftCentre; From fd054081b8ec8aad0604c6f596c3d3479c03b207 Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Tue, 10 Jan 2023 11:29:38 +0000 Subject: [PATCH 1380/2991] Better name for touch control scheme config bindable --- osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index aa786f2573..17efcba1d5 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Taiko.UI private QuarterCircle leftRim = null!; private QuarterCircle rightRim = null!; - private Bindable touchControlScheme = new Bindable(); + private Bindable configTouchControlScheme = new Bindable(); [BackgroundDependencyLoader] private void load(TaikoInputManager taikoInputManager, TaikoRulesetConfigManager config, OsuColour colours) @@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Taiko.UI const float centre_region = 0.80f; - config.BindWith(TaikoRulesetSetting.TouchControlScheme, touchControlScheme); + config.BindWith(TaikoRulesetSetting.TouchControlScheme, configTouchControlScheme); Children = new Drawable[] { new Container @@ -77,27 +77,27 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - leftRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftRim), touchControlScheme.Value, colours) + leftRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftRim), configTouchControlScheme.Value, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, }, - rightRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightRim), touchControlScheme.Value, colours) + rightRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightRim), configTouchControlScheme.Value, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = 2, Rotation = 90, }, - leftCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftCentre), touchControlScheme.Value, colours) + leftCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftCentre), configTouchControlScheme.Value, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, Scale = new Vector2(centre_region), }, - rightCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightCentre), touchControlScheme.Value, colours) + rightCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightCentre), configTouchControlScheme.Value, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, @@ -157,7 +157,7 @@ namespace osu.Game.Rulesets.Taiko.UI #pragma warning disable format private TaikoAction getTaikoActionFromInput(TaikoInput input) { - switch (touchControlScheme.Value) + switch (configTouchControlScheme.Value) { case TaikoTouchControlScheme.KDDK: From e3d14db285995ba6f86086b82d852ee45cae9265 Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Tue, 10 Jan 2023 11:38:32 +0000 Subject: [PATCH 1381/2991] Removed unnecessary QuarterCircle paramenters --- osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 17efcba1d5..0f14e5d06f 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -47,8 +47,10 @@ namespace osu.Game.Rulesets.Taiko.UI private Bindable configTouchControlScheme = new Bindable(); + private static OsuColour colours; + [BackgroundDependencyLoader] - private void load(TaikoInputManager taikoInputManager, TaikoRulesetConfigManager config, OsuColour colours) + private void load(TaikoInputManager taikoInputManager, TaikoRulesetConfigManager config, OsuColour _colours) { Debug.Assert(taikoInputManager.KeyBindingContainer != null); keyBindingContainer = taikoInputManager.KeyBindingContainer; @@ -59,6 +61,8 @@ namespace osu.Game.Rulesets.Taiko.UI const float centre_region = 0.80f; config.BindWith(TaikoRulesetSetting.TouchControlScheme, configTouchControlScheme); + colours = _colours; + Children = new Drawable[] { new Container @@ -77,27 +81,27 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - leftRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftRim), configTouchControlScheme.Value, colours) + leftRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftRim)) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, }, - rightRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightRim), configTouchControlScheme.Value, colours) + rightRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightRim)) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = 2, Rotation = 90, }, - leftCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftCentre), configTouchControlScheme.Value, colours) + leftCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftCentre)) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, Scale = new Vector2(centre_region), }, - rightCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightCentre), configTouchControlScheme.Value, colours) + rightCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightCentre)) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, @@ -228,7 +232,7 @@ namespace osu.Game.Rulesets.Taiko.UI public override bool Contains(Vector2 screenSpacePos) => circle.Contains(screenSpacePos); - public QuarterCircle(TaikoAction handledAction, TaikoTouchControlScheme touchControlScheme, OsuColour colours) + public QuarterCircle(TaikoAction handledAction) { Color4 colour = ((Func)(() => { From b694e0d441c440fb84100c16f1ecd19f1cc5a3ba Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Tue, 10 Jan 2023 11:43:28 +0000 Subject: [PATCH 1382/2991] Added a comment and fixed some wonky formatting --- .../UI/DrumTouchInputArea.cs | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 0f14e5d06f..5a6dc70ea3 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -22,7 +22,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.UI { - using TaikoInput = TaikoAction; + using TaikoInput = TaikoAction; // Functionally identical to TaikoAction, it's just a readability thing /// /// An overlay that captures and displays osu!taiko mouse and touch input. /// @@ -158,7 +158,7 @@ namespace osu.Game.Rulesets.Taiko.UI private bool validMouse(MouseButtonEvent e) => leftRim.Contains(e.ScreenSpaceMouseDownPosition) || rightRim.Contains(e.ScreenSpaceMouseDownPosition); -#pragma warning disable format + #pragma warning disable format private TaikoAction getTaikoActionFromInput(TaikoInput input) { switch (configTouchControlScheme.Value) @@ -177,28 +177,28 @@ namespace osu.Game.Rulesets.Taiko.UI case TaikoTouchControlScheme.DDKK: switch (input) { - case TaikoInput.LeftRim: return TaikoAction.LeftCentre; - case TaikoInput.LeftCentre: return TaikoAction.RightCentre; + case TaikoInput.LeftRim: return TaikoAction.LeftCentre; + case TaikoInput.LeftCentre: return TaikoAction.RightCentre; case TaikoInput.RightCentre: return TaikoAction.LeftRim; - case TaikoInput.RightRim: return TaikoAction.RightRim; + case TaikoInput.RightRim: return TaikoAction.RightRim; } break; case TaikoTouchControlScheme.KKDD: switch (input) { - case TaikoInput.LeftRim: return TaikoAction.LeftRim; - case TaikoInput.LeftCentre: return TaikoAction.RightRim; + case TaikoInput.LeftRim: return TaikoAction.LeftRim; + case TaikoInput.LeftCentre: return TaikoAction.RightRim; case TaikoInput.RightCentre: return TaikoAction.LeftCentre; - case TaikoInput.RightRim: return TaikoAction.RightCentre; + case TaikoInput.RightRim: return TaikoAction.RightCentre; } break; } return TaikoAction.LeftCentre; } + #pragma warning restore format -#pragma warning restore format - private TaikoAction getTaikoActionFromPosition(Vector2 inputPosition) + private TaikoAction getTaikoActionFromPosition(Vector2 inputPosition) { bool centreHit = leftCentre.Contains(inputPosition) || rightCentre.Contains(inputPosition); bool leftSide = ToLocalSpace(inputPosition).X < DrawWidth / 2; @@ -236,15 +236,15 @@ namespace osu.Game.Rulesets.Taiko.UI { Color4 colour = ((Func)(() => { -#pragma warning disable format + #pragma warning disable format switch (handledAction) { - case TaikoAction.LeftRim: return colours.Blue; - case TaikoAction.LeftCentre: return colours.Red; + case TaikoAction.LeftRim: return colours.Blue; + case TaikoAction.LeftCentre: return colours.Red; case TaikoAction.RightCentre: return colours.Red; - case TaikoAction.RightRim: return colours.Blue; + case TaikoAction.RightRim: return colours.Blue; } -#pragma warning restore format + #pragma warning restore format return colours.Red; }))(); From 4949b44888af25e824303b297222dcf83899a793 Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Tue, 10 Jan 2023 11:57:21 +0000 Subject: [PATCH 1383/2991] Updated touch control scheme setting capitalization to be consistent with the rest of the settings menu --- osu.Game.Rulesets.Taiko/TaikoSettingsSubsection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/TaikoSettingsSubsection.cs b/osu.Game.Rulesets.Taiko/TaikoSettingsSubsection.cs index 297a02df5b..9fe861c08c 100644 --- a/osu.Game.Rulesets.Taiko/TaikoSettingsSubsection.cs +++ b/osu.Game.Rulesets.Taiko/TaikoSettingsSubsection.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Taiko { new SettingsEnumDropdown { - LabelText = "Touch Control Scheme", + LabelText = "Touch control scheme", Current = config.GetBindable(TaikoRulesetSetting.TouchControlScheme) } }; From a8f4f0042179cc20045b9b66f77e6583fec7a2f3 Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Tue, 10 Jan 2023 12:04:06 +0000 Subject: [PATCH 1384/2991] Removed nullable --- .../Configuration/TaikoTouchControlScheme.cs | 2 -- osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs | 1 - 2 files changed, 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Configuration/TaikoTouchControlScheme.cs b/osu.Game.Rulesets.Taiko/Configuration/TaikoTouchControlScheme.cs index b9aee7eff7..74e4a53746 100644 --- a/osu.Game.Rulesets.Taiko/Configuration/TaikoTouchControlScheme.cs +++ b/osu.Game.Rulesets.Taiko/Configuration/TaikoTouchControlScheme.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Taiko.Configuration { public enum TaikoTouchControlScheme diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 5a6dc70ea3..02454a5355 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.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. -#nullable disable #pragma warning disable IDE0001 // Simplify Names using System; From 906ea80d52ca03d93feb05de12751a49200fa21e Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Tue, 10 Jan 2023 12:11:33 +0000 Subject: [PATCH 1385/2991] Further improved method of getting OsuColour --- osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 02454a5355..523c28f8cb 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -46,8 +46,6 @@ namespace osu.Game.Rulesets.Taiko.UI private Bindable configTouchControlScheme = new Bindable(); - private static OsuColour colours; - [BackgroundDependencyLoader] private void load(TaikoInputManager taikoInputManager, TaikoRulesetConfigManager config, OsuColour _colours) { @@ -60,7 +58,6 @@ namespace osu.Game.Rulesets.Taiko.UI const float centre_region = 0.80f; config.BindWith(TaikoRulesetSetting.TouchControlScheme, configTouchControlScheme); - colours = _colours; Children = new Drawable[] { @@ -231,6 +228,9 @@ namespace osu.Game.Rulesets.Taiko.UI public override bool Contains(Vector2 screenSpacePos) => circle.Contains(screenSpacePos); + [Resolved] + private OsuColour colours { get; set; } = null!; + public QuarterCircle(TaikoAction handledAction) { Color4 colour = ((Func)(() => From ffd6168a618243faa33b27558adc17b312b995bf Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Tue, 10 Jan 2023 12:13:51 +0000 Subject: [PATCH 1386/2991] Removed unnecessary newlines --- osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 523c28f8cb..29f64dab93 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -27,14 +27,12 @@ namespace osu.Game.Rulesets.Taiko.UI /// public partial class DrumTouchInputArea : VisibilityContainer { - // visibility state affects our child. we always want to handle input. public override bool PropagatePositionalInputSubTree => true; public override bool PropagateNonPositionalInputSubTree => true; private KeyBindingContainer keyBindingContainer = null!; - private readonly Dictionary trackedActions = new Dictionary(); private Container mainContent = null!; @@ -247,7 +245,6 @@ namespace osu.Game.Rulesets.Taiko.UI return colours.Red; }))(); - this.handledAction = handledAction; RelativeSizeAxes = Axes.Both; From bf555e4579ca2c05a14ed8fac5593ce2efbdd645 Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Tue, 10 Jan 2023 12:44:27 +0000 Subject: [PATCH 1387/2991] Removed unnecessary directives that were added automatically and I forgot to remove --- .../Configuration/TaikoRulesetConfigManager.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Configuration/TaikoRulesetConfigManager.cs b/osu.Game.Rulesets.Taiko/Configuration/TaikoRulesetConfigManager.cs index 7e2c7e89b4..c3bc7f6439 100644 --- a/osu.Game.Rulesets.Taiko/Configuration/TaikoRulesetConfigManager.cs +++ b/osu.Game.Rulesets.Taiko/Configuration/TaikoRulesetConfigManager.cs @@ -1,8 +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 osu.Framework.Configuration.Tracking; -using System; using osu.Game.Configuration; using osu.Game.Rulesets.Configuration; From b3e620c8e57720b6caaa9ca50e912909b3fff429 Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Tue, 10 Jan 2023 13:07:07 +0000 Subject: [PATCH 1388/2991] Removed unnecessary parameter --- osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 29f64dab93..cdd9024e9d 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Taiko.UI private Bindable configTouchControlScheme = new Bindable(); [BackgroundDependencyLoader] - private void load(TaikoInputManager taikoInputManager, TaikoRulesetConfigManager config, OsuColour _colours) + private void load(TaikoInputManager taikoInputManager, TaikoRulesetConfigManager config) { Debug.Assert(taikoInputManager.KeyBindingContainer != null); keyBindingContainer = taikoInputManager.KeyBindingContainer; From a22b7298c6facab60b864886b460d42a8d906432 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 22:27:36 +0900 Subject: [PATCH 1389/2991] Adjust english slightly --- osu.Game/Database/RealmArchiveModelImporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index 20cae725ad..db8861c281 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -155,7 +155,7 @@ namespace osu.Game.Database else { if (tasks.Length > imported.Count) - notification.CompletionText = $"Imported {imported.Count} out of {tasks.Length} {HumanisedModelName}s."; + notification.CompletionText = $"Imported {imported.Count} of {tasks.Length} {HumanisedModelName}s."; else if (imported.Count > 1) notification.CompletionText = $"Imported {imported.Count} {HumanisedModelName}s!"; else From 23a78e6fad219de63eabdbe20ae36a3e61034e15 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 23:57:38 +0900 Subject: [PATCH 1390/2991] Combine commit button enabled handling --- osu.Game/Overlays/Comments/CommentEditor.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index f11cef55d4..8e02d015ed 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -35,19 +35,16 @@ namespace osu.Game.Overlays.Comments private RoundedButton commitButton = null!; private LoadingSpinner loadingSpinner = null!; - private bool showLoadingSpinner; - protected bool ShowLoadingSpinner { set { - commitButton.Enabled.Value = !value && !string.IsNullOrEmpty(Current.Value); - showLoadingSpinner = value; - if (value) loadingSpinner.Show(); else loadingSpinner.Hide(); + + updateCommitButtonState(); } } @@ -146,14 +143,14 @@ namespace osu.Game.Overlays.Comments protected override void LoadComplete() { base.LoadComplete(); - Current.BindValueChanged(text => - { - commitButton.Enabled.Value = !showLoadingSpinner && !string.IsNullOrEmpty(text.NewValue); - }, true); + Current.BindValueChanged(_ => updateCommitButtonState(), true); } protected abstract void OnCommit(string text); + private void updateCommitButtonState() => + commitButton.Enabled.Value = loadingSpinner.State.Value == Visibility.Hidden && !string.IsNullOrEmpty(Current.Value); + private partial class EditorTextBox : BasicTextBox { protected override float LeftRightPadding => side_padding; From 362c9050df9b3ad1e889628db439203ab4b7e1c3 Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Tue, 10 Jan 2023 15:08:18 +0000 Subject: [PATCH 1391/2991] Fixed OsuColour shenanigans --- .../UI/DrumTouchInputArea.cs | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index cdd9024e9d..50c7a7f69b 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -3,7 +3,6 @@ #pragma warning disable IDE0001 // Simplify Names -using System; using System.Collections.Generic; using System.Diagnostics; using osu.Framework.Allocation; @@ -44,6 +43,9 @@ namespace osu.Game.Rulesets.Taiko.UI private Bindable configTouchControlScheme = new Bindable(); + [Resolved] + private OsuColour colours { get; set; } = null!; + [BackgroundDependencyLoader] private void load(TaikoInputManager taikoInputManager, TaikoRulesetConfigManager config) { @@ -75,27 +77,27 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - leftRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftRim)) + leftRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftRim), getColourFromTaikoAction(getTaikoActionFromInput(TaikoInput.LeftRim))) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, }, - rightRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightRim)) + rightRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightRim), getColourFromTaikoAction(getTaikoActionFromInput(TaikoInput.RightRim))) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = 2, Rotation = 90, }, - leftCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftCentre)) + leftCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftCentre), getColourFromTaikoAction(getTaikoActionFromInput(TaikoInput.LeftCentre))) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, Scale = new Vector2(centre_region), }, - rightCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightCentre)) + rightCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightCentre), getColourFromTaikoAction(getTaikoActionFromInput(TaikoInput.RightCentre))) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, @@ -216,6 +218,19 @@ namespace osu.Game.Rulesets.Taiko.UI mainContent.FadeOut(300); } + private Color4 getColourFromTaikoAction(TaikoAction handledAction) + { + #pragma warning disable format + switch (handledAction) + { + case TaikoAction.LeftRim: return colours.Blue; + case TaikoAction.LeftCentre: return colours.Red; + case TaikoAction.RightCentre: return colours.Red; + case TaikoAction.RightRim: return colours.Blue; + } + #pragma warning restore format + return colours.Red; + } private partial class QuarterCircle : CompositeDrawable, IKeyBindingHandler { private readonly Circle overlay; @@ -226,24 +241,8 @@ namespace osu.Game.Rulesets.Taiko.UI public override bool Contains(Vector2 screenSpacePos) => circle.Contains(screenSpacePos); - [Resolved] - private OsuColour colours { get; set; } = null!; - - public QuarterCircle(TaikoAction handledAction) + public QuarterCircle(TaikoAction handledAction, Color4 colour) { - Color4 colour = ((Func)(() => - { - #pragma warning disable format - switch (handledAction) - { - case TaikoAction.LeftRim: return colours.Blue; - case TaikoAction.LeftCentre: return colours.Red; - case TaikoAction.RightCentre: return colours.Red; - case TaikoAction.RightRim: return colours.Blue; - } - #pragma warning restore format - return colours.Red; - }))(); this.handledAction = handledAction; RelativeSizeAxes = Axes.Both; From 21b617062ac8b027320f23c658ee103004da8315 Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Tue, 10 Jan 2023 16:24:02 +0000 Subject: [PATCH 1392/2991] Removed an unnecessary newline --- osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 50c7a7f69b..d92f99fc0b 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -243,7 +243,6 @@ namespace osu.Game.Rulesets.Taiko.UI public QuarterCircle(TaikoAction handledAction, Color4 colour) { - this.handledAction = handledAction; RelativeSizeAxes = Axes.Both; From aab84d50eb0113e1dba40752c487d6d55abfba0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 10 Jan 2023 18:29:56 +0100 Subject: [PATCH 1393/2991] Remove boxing overhead in `CarouselItem` comparator --- osu.Game/Screens/Select/Carousel/CarouselItem.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselItem.cs b/osu.Game/Screens/Select/Carousel/CarouselItem.cs index 4a5af6f6b1..5e425a4a1c 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselItem.cs @@ -49,7 +49,12 @@ namespace osu.Game.Screens.Select.Carousel public virtual int CompareTo(FilterCriteria criteria, CarouselItem other) => ItemID.CompareTo(other.ItemID); - public int CompareTo(CarouselItem? other) => CarouselYPosition.CompareTo(other?.CarouselYPosition); + public int CompareTo(CarouselItem? other) + { + if (other == null) return 1; + + return CarouselYPosition.CompareTo(other.CarouselYPosition); + } } public enum CarouselItemState From 9633a3f58f94efee23a006a7e7ebd976057b6579 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 10 Jan 2023 20:59:35 +0300 Subject: [PATCH 1394/2991] Add failing test coverage --- .../TestSceneOverlayContainer.cs | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneOverlayContainer.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayContainer.cs new file mode 100644 index 0000000000..d9c2774611 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayContainer.cs @@ -0,0 +1,106 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Overlays.Volume; +using osuTK; +using osuTK.Graphics; +using osuTK.Input; +using Box = osu.Framework.Graphics.Shapes.Box; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public partial class TestSceneOverlayContainer : OsuManualInputManagerTestScene + { + [SetUp] + public void SetUp() => Schedule(() => Child = new TestOverlay + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Size = new Vector2(0.5f) + }); + + [Test] + public void TestScrollBlocked() + { + OsuScrollContainer scroll = null!; + + AddStep("add scroll container", () => + { + Add(scroll = new OsuScrollContainer + { + RelativeSizeAxes = Axes.Both, + Depth = float.MaxValue, + Child = new Box + { + RelativeSizeAxes = Axes.X, + Height = DrawHeight * 10, + Colour = ColourInfo.GradientVertical(Colour4.Black, Colour4.White), + } + }); + }); + + AddStep("perform scroll", () => + { + InputManager.MoveMouseTo(Content); + InputManager.ScrollVerticalBy(-10); + }); + + AddAssert("scroll didn't receive input", () => scroll.Current == 0); + } + + [Test] + public void TestAltScrollNotBlocked() + { + bool scrollReceived = false; + + AddStep("add volume control receptor", () => Add(new VolumeControlReceptor + { + RelativeSizeAxes = Axes.Both, + Depth = float.MaxValue, + ScrollActionRequested = (_, _, _) => scrollReceived = true, + })); + + AddStep("hold alt", () => InputManager.PressKey(Key.AltLeft)); + AddStep("perform scroll", () => + { + InputManager.MoveMouseTo(Content); + InputManager.ScrollVerticalBy(10); + }); + + AddAssert("receptor received scroll input", () => scrollReceived); + AddStep("release alt", () => InputManager.ReleaseKey(Key.AltLeft)); + } + + private partial class TestOverlay : OsuFocusedOverlayContainer + { + [BackgroundDependencyLoader] + private void load() + { + State.Value = Visibility.Visible; + + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Text = "Overlay content", + Colour = Color4.Black, + }, + }; + } + } + } +} From 11648db91077a1cf27008374b821aed32f6dc780 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 10 Jan 2023 19:30:42 +0300 Subject: [PATCH 1395/2991] Fix game overlays not blocking scroll properly --- .../Graphics/Containers/OsuFocusedOverlayContainer.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 740c170f8f..07b5b53e0e 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -25,8 +25,6 @@ namespace osu.Game.Graphics.Containers protected virtual string PopInSampleName => "UI/overlay-pop-in"; protected virtual string PopOutSampleName => "UI/overlay-pop-out"; - protected override bool BlockScrollInput => false; - protected override bool BlockNonPositionalInput => true; /// @@ -90,6 +88,15 @@ namespace osu.Game.Graphics.Containers base.OnMouseUp(e); } + protected override bool OnScroll(ScrollEvent e) + { + // allow for controlling volume when alt is held. + // mostly for compatibility with osu-stable. + if (e.AltPressed) return false; + + return true; + } + public virtual bool OnPressed(KeyBindingPressEvent e) { if (e.Repeat) From 62e12277d826793da660871d0b8d44dc9e847356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 10 Jan 2023 19:24:54 +0100 Subject: [PATCH 1396/2991] Rename things yet again --- .../Online/TestSceneHistoricalSection.cs | 4 ++-- .../Online/TestScenePlayHistorySubsection.cs | 20 +++++++++---------- .../Online/TestSceneUserProfileHeader.cs | 10 +++++----- .../Visual/Online/TestSceneUserRanks.cs | 2 +- .../Profile/Header/BottomHeaderContainer.cs | 4 ++-- .../Profile/Header/CentreHeaderContainer.cs | 14 ++++++------- .../Header/Components/FollowersButton.cs | 4 ++-- .../Profile/Header/Components/LevelBadge.cs | 4 ++-- .../Header/Components/LevelProgressBar.cs | 4 ++-- .../Components/MappingSubscribersButton.cs | 4 ++-- .../Header/Components/MessageUserButton.cs | 6 +++--- .../Components/OverlinedTotalPlayTime.cs | 8 ++++---- .../Profile/Header/DetailHeaderContainer.cs | 6 +++--- .../Profile/Header/MedalHeaderContainer.cs | 4 ++-- .../Profile/Header/TopHeaderContainer.cs | 4 ++-- osu.Game/Overlays/Profile/ProfileHeader.cs | 16 +++++++-------- osu.Game/Overlays/Profile/ProfileSection.cs | 2 +- .../Beatmaps/PaginatedBeatmapContainer.cs | 4 ++-- .../Profile/Sections/BeatmapsSection.cs | 14 ++++++------- .../Historical/ChartProfileSubsection.cs | 6 +++--- .../PaginatedMostPlayedBeatmapContainer.cs | 4 ++-- .../Historical/PlayHistorySubsection.cs | 4 ++-- .../Sections/Historical/ReplaysSubsection.cs | 4 ++-- .../Profile/Sections/HistoricalSection.cs | 8 ++++---- .../Profile/Sections/Kudosu/KudosuInfo.cs | 8 ++++---- .../Kudosu/PaginatedKudosuHistoryContainer.cs | 4 ++-- .../Profile/Sections/KudosuSection.cs | 4 ++-- .../Sections/PaginatedProfileSubsection.cs | 10 +++++----- .../Profile/Sections/ProfileSubsection.cs | 6 +++--- .../Sections/Ranks/PaginatedScoreContainer.cs | 4 ++-- .../Overlays/Profile/Sections/RanksSection.cs | 6 +++--- .../PaginatedRecentActivityContainer.cs | 4 ++-- .../Profile/Sections/RecentSection.cs | 2 +- osu.Game/Overlays/UserProfileOverlay.cs | 6 +++--- 34 files changed, 107 insertions(+), 107 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs index 78e0c6fce4..dd37dced93 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs @@ -38,8 +38,8 @@ namespace osu.Game.Tests.Visual.Online Child = section = new HistoricalSection(), }); - AddStep("Show peppy", () => section.UserProfileData.Value = new UserProfileData(new APIUser { Id = 2 })); - AddStep("Show WubWoofWolf", () => section.UserProfileData.Value = new UserProfileData(new APIUser { Id = 39828 })); + AddStep("Show peppy", () => section.User.Value = new UserProfileData(new APIUser { Id = 2 })); + AddStep("Show WubWoofWolf", () => section.User.Value = new UserProfileData(new APIUser { Id = 39828 })); } } } diff --git a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs index 634b9df212..8bd4e398e4 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Online [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Red); - private readonly Bindable userProfileData = new Bindable(); + private readonly Bindable user = new Bindable(); private readonly PlayHistorySubsection section; public TestScenePlayHistorySubsection() @@ -33,7 +33,7 @@ namespace osu.Game.Tests.Visual.Online RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background4 }, - section = new PlayHistorySubsection(userProfileData) + section = new PlayHistorySubsection(user) { Anchor = Anchor.Centre, Origin = Anchor.Centre @@ -44,49 +44,49 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestNullValues() { - AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_null_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_null_values)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestEmptyValues() { - AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_empty_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_empty_values)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestOneValue() { - AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_one_value)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_one_value)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestTwoValues() { - AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_two_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_two_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantValues() { - AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_constant_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_constant_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantZeroValues() { - AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_zero_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_zero_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestFilledValues() { - AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_filled_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_filled_values)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is the same", () => user_with_filled_values.MonthlyPlayCounts.Length == getChartValuesLength()); } @@ -94,7 +94,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestMissingValues() { - AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_missing_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_missing_values)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is 7", () => getChartValuesLength() == 7); } diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index 9b565c1276..7f5cfb6179 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -29,13 +29,13 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestBasic() { - AddStep("Show example user", () => header.UserProfileData.Value = new UserProfileData(TestSceneUserProfileOverlay.TEST_USER)); + AddStep("Show example user", () => header.User.Value = new UserProfileData(TestSceneUserProfileOverlay.TEST_USER)); } [Test] public void TestOnlineState() { - AddStep("Show online user", () => header.UserProfileData.Value = new UserProfileData(new APIUser + AddStep("Show online user", () => header.User.Value = new UserProfileData(new APIUser { Id = 1001, Username = "IAmOnline", @@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual.Online IsOnline = true, })); - AddStep("Show offline user", () => header.UserProfileData.Value = new UserProfileData(new APIUser + AddStep("Show offline user", () => header.User.Value = new UserProfileData(new APIUser { Id = 1002, Username = "IAmOffline", @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestRankedState() { - AddStep("Show ranked user", () => header.UserProfileData.Value = new UserProfileData(new APIUser + AddStep("Show ranked user", () => header.User.Value = new UserProfileData(new APIUser { Id = 2001, Username = "RankedUser", @@ -72,7 +72,7 @@ namespace osu.Game.Tests.Visual.Online } })); - AddStep("Show unranked user", () => header.UserProfileData.Value = new UserProfileData(new APIUser + AddStep("Show unranked user", () => header.User.Value = new UserProfileData(new APIUser { Id = 2002, Username = "UnrankedUser", diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs index 6ec7ea008b..bab48806d4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Online } }); - AddStep("Show cookiezi", () => ranks.UserProfileData.Value = new UserProfileData(new APIUser { Id = 124493 })); + AddStep("Show cookiezi", () => ranks.User.Value = new UserProfileData(new APIUser { Id = 124493 })); } } } diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 091d04ad35..1e80257a57 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.Profile.Header { public partial class BottomHeaderContainer : CompositeDrawable { - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); private LinkFlowContainer topLinkContainer = null!; private LinkFlowContainer bottomLinkContainer = null!; @@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Profile.Header } }; - UserProfileData.BindValueChanged(data => updateDisplay(data.NewValue?.User)); + User.BindValueChanged(user => updateDisplay(user.NewValue?.User)); } private void updateDisplay(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 8910d3dc3b..ecf78e7b92 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Header public partial class CentreHeaderContainer : CompositeDrawable { public readonly BindableBool DetailsVisible = new BindableBool(true); - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); private OverlinedInfoContainer hiddenDetailGlobal = null!; private OverlinedInfoContainer hiddenDetailCountry = null!; @@ -53,15 +53,15 @@ namespace osu.Game.Overlays.Profile.Header { new FollowersButton { - UserProfileData = { BindTarget = UserProfileData } + User = { BindTarget = User } }, new MappingSubscribersButton { - UserProfileData = { BindTarget = UserProfileData } + User = { BindTarget = User } }, new MessageUserButton { - UserProfileData = { BindTarget = UserProfileData } + User = { BindTarget = User } }, } }, @@ -92,7 +92,7 @@ namespace osu.Game.Overlays.Profile.Header Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Size = new Vector2(40), - UserProfileData = { BindTarget = UserProfileData } + User = { BindTarget = User } }, expandedDetailContainer = new Container { @@ -104,7 +104,7 @@ namespace osu.Game.Overlays.Profile.Header Child = new LevelProgressBar { RelativeSizeAxes = Axes.Both, - UserProfileData = { BindTarget = UserProfileData } + User = { BindTarget = User } } }, hiddenDetailContainer = new FillFlowContainer @@ -141,7 +141,7 @@ namespace osu.Game.Overlays.Profile.Header expandedDetailContainer.FadeTo(visible.NewValue ? 1 : 0, 200, Easing.OutQuint); }); - UserProfileData.BindValueChanged(data => updateDisplay(data.NewValue?.User)); + User.BindValueChanged(user => updateDisplay(user.NewValue?.User)); } private void updateDisplay(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs index a73b3444f6..844efa5cf0 100644 --- a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class FollowersButton : ProfileHeaderStatisticsButton { - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); public override LocalisableString TooltipText => FriendsStrings.ButtonsDisabled; @@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Profile.Header.Components private void load() { // todo: when friending/unfriending is implemented, the APIAccess.Friends list should be updated accordingly. - UserProfileData.BindValueChanged(data => SetValue(data.NewValue?.User.FollowerCount ?? 0), true); + User.BindValueChanged(user => SetValue(user.NewValue?.User.FollowerCount ?? 0), true); } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index 501c7bd41b..78c5231736 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelBadge : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); public LocalisableString TooltipText { get; private set; } @@ -48,7 +48,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; - UserProfileData.BindValueChanged(data => updateLevel(data.NewValue?.User)); + User.BindValueChanged(user => updateLevel(user.NewValue?.User)); } private void updateLevel(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs index 6a5827a867..919ccb0dd4 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelProgressBar : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); public LocalisableString TooltipText { get; } @@ -56,7 +56,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; - UserProfileData.BindValueChanged(data => updateProgress(data.NewValue?.User)); + User.BindValueChanged(user => updateProgress(user.NewValue?.User)); } private void updateProgress(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs index 7265302a88..d509ec0f81 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class MappingSubscribersButton : ProfileHeaderStatisticsButton { - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); public override LocalisableString TooltipText => FollowsStrings.MappingFollowers; @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Profile.Header.Components [BackgroundDependencyLoader] private void load() { - UserProfileData.BindValueChanged(data => SetValue(data.NewValue?.User.MappingFollowerCount ?? 0), true); + User.BindValueChanged(user => SetValue(user.NewValue?.User.MappingFollowerCount ?? 0), true); } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs index 0b9fa437c2..5f934e3916 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs @@ -15,7 +15,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class MessageUserButton : ProfileHeaderButton { - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); public override LocalisableString TooltipText => UsersStrings.CardSendMessage; @@ -48,12 +48,12 @@ namespace osu.Game.Overlays.Profile.Header.Components { if (!Content.IsPresent) return; - channelManager?.OpenPrivateChannel(UserProfileData.Value?.User); + channelManager?.OpenPrivateChannel(User.Value?.User); userOverlay?.Hide(); chatOverlay?.Show(); }; - UserProfileData.ValueChanged += e => + User.ValueChanged += e => { var user = e.NewValue?.User; Content.Alpha = user != null && !user.PMFriendsOnly && apiProvider.LocalUser.Value.Id != user.Id ? 1 : 0; diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs index c2db9d8273..0396f42336 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class OverlinedTotalPlayTime : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); public LocalisableString TooltipText { get; set; } @@ -35,12 +35,12 @@ namespace osu.Game.Overlays.Profile.Header.Components LineColour = colourProvider.Highlight1, }; - UserProfileData.BindValueChanged(updateTime, true); + User.BindValueChanged(updateTime, true); } - private void updateTime(ValueChangedEvent data) + private void updateTime(ValueChangedEvent user) { - int? playTime = data.NewValue?.User.Statistics?.PlayTime; + int? playTime = user.NewValue?.User.Statistics?.PlayTime; TooltipText = (playTime ?? 0) / 3600 + " hours"; info.Content = formatTime(playTime); } diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index d2986c343d..3bab798caf 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Profile.Header private FillFlowContainer? fillFlow; private RankGraph rankGraph = null!; - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); private bool expanded = true; @@ -60,7 +60,7 @@ namespace osu.Game.Overlays.Profile.Header { AutoSizeAxes = Axes.Y; - UserProfileData.ValueChanged += e => updateDisplay(e.NewValue); + User.ValueChanged += e => updateDisplay(e.NewValue); InternalChildren = new Drawable[] { @@ -98,7 +98,7 @@ namespace osu.Game.Overlays.Profile.Header { new OverlinedTotalPlayTime { - UserProfileData = { BindTarget = UserProfileData } + User = { BindTarget = User } }, medalInfo = new OverlinedInfoContainer { diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index 2c2e2b3197..edb695a00e 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -20,14 +20,14 @@ namespace osu.Game.Overlays.Profile.Header { private FillFlowContainer badgeFlowContainer = null!; - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { Alpha = 0; AutoSizeAxes = Axes.Y; - UserProfileData.ValueChanged += e => updateDisplay(e.NewValue?.User); + User.ValueChanged += e => updateDisplay(e.NewValue?.User); InternalChildren = new Drawable[] { diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index c8a797e478..43ba8e64e4 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Profile.Header { private const float avatar_size = 110; - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); [Resolved] private IAPIProvider api { get; set; } = null!; @@ -170,7 +170,7 @@ namespace osu.Game.Overlays.Profile.Header } }; - UserProfileData.BindValueChanged(data => updateUser(data.NewValue)); + User.BindValueChanged(user => updateUser(user.NewValue)); } private void updateUser(UserProfileData? data) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 5f58960b15..5f5740a0aa 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile { private UserCoverBackground coverContainer = null!; - public Bindable UserProfileData = new Bindable(); + public Bindable User = new Bindable(); private CentreHeaderContainer centreHeaderContainer; private DetailHeaderContainer detailHeaderContainer; @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Profile { ContentSidePadding = UserProfileOverlay.CONTENT_X_MARGIN; - UserProfileData.ValueChanged += e => updateDisplay(e.NewValue); + User.ValueChanged += e => updateDisplay(e.NewValue); TabControl.AddItem(LayoutStrings.HeaderUsersShow); @@ -72,34 +72,34 @@ namespace osu.Game.Overlays.Profile new TopHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfileData = { BindTarget = UserProfileData }, + User = { BindTarget = User }, }, centreHeaderContainer = new CentreHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfileData = { BindTarget = UserProfileData }, + User = { BindTarget = User }, }, detailHeaderContainer = new DetailHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfileData = { BindTarget = UserProfileData }, + User = { BindTarget = User }, }, new MedalHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfileData = { BindTarget = UserProfileData }, + User = { BindTarget = User }, }, new BottomHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfileData = { BindTarget = UserProfileData }, + User = { BindTarget = User }, }, } }; protected override OverlayTitle CreateTitle() => new ProfileHeaderTitle(); - private void updateDisplay(UserProfileData? data) => coverContainer.User = data?.User; + private void updateDisplay(UserProfileData? user) => coverContainer.User = user?.User; private partial class ProfileHeaderTitle : OverlayTitle { diff --git a/osu.Game/Overlays/Profile/ProfileSection.cs b/osu.Game/Overlays/Profile/ProfileSection.cs index 009e0d1dac..edb3ec1733 100644 --- a/osu.Game/Overlays/Profile/ProfileSection.cs +++ b/osu.Game/Overlays/Profile/ProfileSection.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Profile protected override Container Content => content; - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); protected ProfileSection() { diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index 9c692cbeac..0e74aba369 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -22,8 +22,8 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps protected override int InitialItemsCount => type == BeatmapSetType.Graveyard ? 2 : 6; - public PaginatedBeatmapContainer(BeatmapSetType type, Bindable userProfileData, LocalisableString headerText) - : base(userProfileData, headerText) + public PaginatedBeatmapContainer(BeatmapSetType type, Bindable user, LocalisableString headerText) + : base(user, headerText) { this.type = type; } diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs index 8818cae735..3b304a79ef 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs @@ -18,13 +18,13 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedBeatmapContainer(BeatmapSetType.Favourite, UserProfileData, UsersStrings.ShowExtraBeatmapsFavouriteTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Ranked, UserProfileData, UsersStrings.ShowExtraBeatmapsRankedTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Loved, UserProfileData, UsersStrings.ShowExtraBeatmapsLovedTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Guest, UserProfileData, UsersStrings.ShowExtraBeatmapsGuestTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Pending, UserProfileData, UsersStrings.ShowExtraBeatmapsPendingTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, UserProfileData, UsersStrings.ShowExtraBeatmapsGraveyardTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Nominated, UserProfileData, UsersStrings.ShowExtraBeatmapsNominatedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Favourite, User, UsersStrings.ShowExtraBeatmapsFavouriteTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Ranked, User, UsersStrings.ShowExtraBeatmapsRankedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Loved, User, UsersStrings.ShowExtraBeatmapsLovedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Guest, User, UsersStrings.ShowExtraBeatmapsGuestTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Pending, User, UsersStrings.ShowExtraBeatmapsPendingTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, User, UsersStrings.ShowExtraBeatmapsGraveyardTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Nominated, User, UsersStrings.ShowExtraBeatmapsNominatedTitle), }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs index 2162adc2b7..583006031c 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs @@ -20,8 +20,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical /// protected abstract LocalisableString GraphCounterName { get; } - protected ChartProfileSubsection(Bindable userProfileData, LocalisableString headerText) - : base(userProfileData, headerText) + protected ChartProfileSubsection(Bindable user, LocalisableString headerText) + : base(user, headerText) { } @@ -41,7 +41,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical protected override void LoadComplete() { base.LoadComplete(); - UserProfileData.BindValueChanged(onUserChanged, true); + User.BindValueChanged(onUserChanged, true); } private void onUserChanged(ValueChangedEvent e) diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs index 7afb21e8ca..5d9cfb7a1d 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs @@ -16,8 +16,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { public partial class PaginatedMostPlayedBeatmapContainer : PaginatedProfileSubsection { - public PaginatedMostPlayedBeatmapContainer(Bindable userProfileData) - : base(userProfileData, UsersStrings.ShowExtraHistoricalMostPlayedTitle) + public PaginatedMostPlayedBeatmapContainer(Bindable user) + : base(user, UsersStrings.ShowExtraHistoricalMostPlayedTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs index cf8708d7b2..f472ded182 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs @@ -12,8 +12,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalMonthlyPlaycountsCountLabel; - public PlayHistorySubsection(Bindable userProfileData) - : base(userProfileData, UsersStrings.ShowExtraHistoricalMonthlyPlaycountsTitle) + public PlayHistorySubsection(Bindable user) + : base(user, UsersStrings.ShowExtraHistoricalMonthlyPlaycountsTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs index ab35680fd8..225eaa8c7e 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs @@ -12,8 +12,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalReplaysWatchedCountsCountLabel; - public ReplaysSubsection(Bindable userProfileData) - : base(userProfileData, UsersStrings.ShowExtraHistoricalReplaysWatchedCountsTitle) + public ReplaysSubsection(Bindable user) + : base(user, UsersStrings.ShowExtraHistoricalReplaysWatchedCountsTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs b/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs index 5590db6502..19f7a32d4d 100644 --- a/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs +++ b/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs @@ -20,10 +20,10 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new Drawable[] { - new PlayHistorySubsection(UserProfileData), - new PaginatedMostPlayedBeatmapContainer(UserProfileData), - new PaginatedScoreContainer(ScoreType.Recent, UserProfileData, UsersStrings.ShowExtraHistoricalRecentPlaysTitle), - new ReplaysSubsection(UserProfileData) + new PlayHistorySubsection(User), + new PaginatedMostPlayedBeatmapContainer(User), + new PaginatedScoreContainer(ScoreType.Recent, User, UsersStrings.ShowExtraHistoricalRecentPlaysTitle), + new ReplaysSubsection(User) }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs index d5a945b3da..5e0227de5b 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs @@ -19,11 +19,11 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class KudosuInfo : Container { - private readonly Bindable userProfileData = new Bindable(); + private readonly Bindable user = new Bindable(); - public KudosuInfo(Bindable userProfileData) + public KudosuInfo(Bindable user) { - this.userProfileData.BindTo(userProfileData); + this.user.BindTo(user); CountSection total; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu CornerRadius = 3; Child = total = new CountTotal(); - this.userProfileData.ValueChanged += u => total.Count = u.NewValue?.User.Kudosu.Total ?? 0; + this.user.ValueChanged += u => total.Count = u.NewValue?.User.Kudosu.Total ?? 0; } protected override bool OnClick(ClickEvent e) => true; diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs index a2ab104239..fad0095248 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs @@ -14,8 +14,8 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class PaginatedKudosuHistoryContainer : PaginatedProfileSubsection { - public PaginatedKudosuHistoryContainer(Bindable userProfileData) - : base(userProfileData, missingText: UsersStrings.ShowExtraKudosuEntryEmpty) + public PaginatedKudosuHistoryContainer(Bindable user) + : base(user, missingText: UsersStrings.ShowExtraKudosuEntryEmpty) { } diff --git a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs b/osu.Game/Overlays/Profile/Sections/KudosuSection.cs index 8fbaa1214f..482a853c44 100644 --- a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs +++ b/osu.Game/Overlays/Profile/Sections/KudosuSection.cs @@ -18,8 +18,8 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new Drawable[] { - new KudosuInfo(UserProfileData), - new PaginatedKudosuHistoryContainer(UserProfileData), + new KudosuInfo(User), + new PaginatedKudosuHistoryContainer(User), }; } } diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs index 6ed347e929..ddaa710d68 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs @@ -46,8 +46,8 @@ namespace osu.Game.Overlays.Profile.Sections private OsuSpriteText missing = null!; private readonly LocalisableString? missingText; - protected PaginatedProfileSubsection(Bindable userProfileData, LocalisableString? headerText = null, LocalisableString? missingText = null) - : base(userProfileData, headerText, CounterVisibilityState.AlwaysVisible) + protected PaginatedProfileSubsection(Bindable user, LocalisableString? headerText = null, LocalisableString? missingText = null) + : base(user, headerText, CounterVisibilityState.AlwaysVisible) { this.missingText = missingText; } @@ -89,7 +89,7 @@ namespace osu.Game.Overlays.Profile.Sections protected override void LoadComplete() { base.LoadComplete(); - UserProfileData.BindValueChanged(onUserChanged, true); + User.BindValueChanged(onUserChanged, true); } private void onUserChanged(ValueChangedEvent e) @@ -109,14 +109,14 @@ namespace osu.Game.Overlays.Profile.Sections private void showMore() { - if (UserProfileData.Value?.User == null) + if (User.Value?.User == null) return; loadCancellation = new CancellationTokenSource(); CurrentPage = CurrentPage?.TakeNext(ItemsPerPage) ?? new PaginationParameters(InitialItemsCount); - retrievalRequest = CreateRequest(UserProfileData.Value.User, CurrentPage.Value); + retrievalRequest = CreateRequest(User.Value.User, CurrentPage.Value); retrievalRequest.Success += items => UpdateItems(items, loadCancellation); api.Queue(retrievalRequest); diff --git a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs index 78e23da33a..35d3ac1579 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs @@ -11,18 +11,18 @@ namespace osu.Game.Overlays.Profile.Sections { public abstract partial class ProfileSubsection : FillFlowContainer { - protected readonly Bindable UserProfileData = new Bindable(); + protected readonly Bindable User = new Bindable(); private readonly LocalisableString headerText; private readonly CounterVisibilityState counterVisibilityState; private ProfileSubsectionHeader header = null!; - protected ProfileSubsection(Bindable userProfileData, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) + protected ProfileSubsection(Bindable user, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) { this.headerText = headerText ?? string.Empty; this.counterVisibilityState = counterVisibilityState; - UserProfileData.BindTo(userProfileData); + User.BindTo(user); } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index 14d57bfadc..735f5021fe 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -19,8 +19,8 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { private readonly ScoreType type; - public PaginatedScoreContainer(ScoreType type, Bindable userProfileData, LocalisableString headerText) - : base(userProfileData, headerText) + public PaginatedScoreContainer(ScoreType type, Bindable user, LocalisableString headerText) + : base(user, headerText) { this.type = type; } diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index 6b705a40d5..ce831b30a8 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -18,9 +18,9 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedScoreContainer(ScoreType.Pinned, UserProfileData, UsersStrings.ShowExtraTopRanksPinnedTitle), - new PaginatedScoreContainer(ScoreType.Best, UserProfileData, UsersStrings.ShowExtraTopRanksBestTitle), - new PaginatedScoreContainer(ScoreType.Firsts, UserProfileData, UsersStrings.ShowExtraTopRanksFirstTitle) + new PaginatedScoreContainer(ScoreType.Pinned, User, UsersStrings.ShowExtraTopRanksPinnedTitle), + new PaginatedScoreContainer(ScoreType.Best, User, UsersStrings.ShowExtraTopRanksBestTitle), + new PaginatedScoreContainer(ScoreType.Firsts, User, UsersStrings.ShowExtraTopRanksFirstTitle) }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 6f346b457a..9e8279cfc0 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -16,8 +16,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { public partial class PaginatedRecentActivityContainer : PaginatedProfileSubsection { - public PaginatedRecentActivityContainer(Bindable userProfileData) - : base(userProfileData, missingText: EventsStrings.Empty) + public PaginatedRecentActivityContainer(Bindable user) + : base(user, missingText: EventsStrings.Empty) { } diff --git a/osu.Game/Overlays/Profile/Sections/RecentSection.cs b/osu.Game/Overlays/Profile/Sections/RecentSection.cs index 95dbe7373c..e29dc7f635 100644 --- a/osu.Game/Overlays/Profile/Sections/RecentSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RecentSection.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedRecentActivityContainer(UserProfileData), + new PaginatedRecentActivityContainer(User), }; } } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index add90a0eed..a48d183047 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -47,7 +47,7 @@ namespace osu.Game.Overlays Show(); - if (user.OnlineID == Header?.UserProfileData.Value?.User.Id) + if (user.OnlineID == Header?.User.Value?.User.Id) return; if (sectionsContainer != null) @@ -126,7 +126,7 @@ namespace osu.Game.Overlays Debug.Assert(sections != null && sectionsContainer != null && tabs != null); var userProfile = new UserProfileData(user); - Header.UserProfileData.Value = userProfile; + Header.User.Value = userProfile; if (user.ProfileOrder != null) { @@ -136,7 +136,7 @@ namespace osu.Game.Overlays if (sec != null) { - sec.UserProfileData.Value = userProfile; + sec.User.Value = userProfile; sectionsContainer.Add(sec); tabs.AddItem(sec); From 18e114904a6f24f14e5651b7ac764a3edefca987 Mon Sep 17 00:00:00 2001 From: OpenSauce <48618519+OpenSauce04@users.noreply.github.com> Date: Tue, 10 Jan 2023 19:13:10 +0000 Subject: [PATCH 1397/2991] configTouchControlScheme is now read only Co-authored-by: Stedoss <29103029+Stedoss@users.noreply.github.com> --- osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index d92f99fc0b..76566b2ada 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Taiko.UI private QuarterCircle leftRim = null!; private QuarterCircle rightRim = null!; - private Bindable configTouchControlScheme = new Bindable(); + private readonly Bindable configTouchControlScheme = new Bindable(); [Resolved] private OsuColour colours { get; set; } = null!; From 7cb5ca905a4b1e976fcc9833e8106d99142e77a4 Mon Sep 17 00:00:00 2001 From: OpenSauce <48618519+OpenSauce04@users.noreply.github.com> Date: Tue, 10 Jan 2023 19:17:33 +0000 Subject: [PATCH 1398/2991] Simplified getColourFromTaikoAction switch case Co-authored-by: Stedoss <29103029+Stedoss@users.noreply.github.com> --- osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 76566b2ada..3a921267e2 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -223,10 +223,12 @@ namespace osu.Game.Rulesets.Taiko.UI #pragma warning disable format switch (handledAction) { - case TaikoAction.LeftRim: return colours.Blue; - case TaikoAction.LeftCentre: return colours.Red; - case TaikoAction.RightCentre: return colours.Red; - case TaikoAction.RightRim: return colours.Blue; + case TaikoAction.LeftRim: + case TaikoAction.RightRim: + return colours.Blue; + case TaikoAction.LeftCentre: + case TaikoAction.RightCentre: + return colours.Red; } #pragma warning restore format return colours.Red; From edd2084a0e6bb4b45041dcd3e2b965dd84080661 Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Tue, 10 Jan 2023 19:21:04 +0000 Subject: [PATCH 1399/2991] Replaced all instances of TaikoInput with TaikoAction --- .../UI/DrumTouchInputArea.cs | 47 +++++++++---------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index d92f99fc0b..87804a9389 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -20,7 +20,6 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.UI { - using TaikoInput = TaikoAction; // Functionally identical to TaikoAction, it's just a readability thing /// /// An overlay that captures and displays osu!taiko mouse and touch input. /// @@ -77,27 +76,27 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - leftRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftRim), getColourFromTaikoAction(getTaikoActionFromInput(TaikoInput.LeftRim))) + leftRim = new QuarterCircle(getTaikoActionFromInput(TaikoAction.LeftRim), getColourFromTaikoAction(getTaikoActionFromInput(TaikoAction.LeftRim))) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, }, - rightRim = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightRim), getColourFromTaikoAction(getTaikoActionFromInput(TaikoInput.RightRim))) + rightRim = new QuarterCircle(getTaikoActionFromInput(TaikoAction.RightRim), getColourFromTaikoAction(getTaikoActionFromInput(TaikoAction.RightRim))) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = 2, Rotation = 90, }, - leftCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.LeftCentre), getColourFromTaikoAction(getTaikoActionFromInput(TaikoInput.LeftCentre))) + leftCentre = new QuarterCircle(getTaikoActionFromInput(TaikoAction.LeftCentre), getColourFromTaikoAction(getTaikoActionFromInput(TaikoAction.LeftCentre))) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, Scale = new Vector2(centre_region), }, - rightCentre = new QuarterCircle(getTaikoActionFromInput(TaikoInput.RightCentre), getColourFromTaikoAction(getTaikoActionFromInput(TaikoInput.RightCentre))) + rightCentre = new QuarterCircle(getTaikoActionFromInput(TaikoAction.RightCentre), getColourFromTaikoAction(getTaikoActionFromInput(TaikoAction.RightCentre))) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, @@ -135,14 +134,14 @@ namespace osu.Game.Rulesets.Taiko.UI { Show(); - TaikoInput taikoInput = getTaikoActionFromPosition(position); + TaikoAction TaikoAction = getTaikoActionFromPosition(position); // Not too sure how this can happen, but let's avoid throwing. if (trackedActions.ContainsKey(source)) return; - trackedActions.Add(source, taikoInput); - keyBindingContainer.TriggerPressed(taikoInput); + trackedActions.Add(source, TaikoAction); + keyBindingContainer.TriggerPressed(TaikoAction); } private void handleUp(object source) @@ -155,7 +154,7 @@ namespace osu.Game.Rulesets.Taiko.UI leftRim.Contains(e.ScreenSpaceMouseDownPosition) || rightRim.Contains(e.ScreenSpaceMouseDownPosition); #pragma warning disable format - private TaikoAction getTaikoActionFromInput(TaikoInput input) + private TaikoAction getTaikoActionFromInput(TaikoAction input) { switch (configTouchControlScheme.Value) { @@ -163,30 +162,30 @@ namespace osu.Game.Rulesets.Taiko.UI switch (input) { - case TaikoInput.LeftRim: return TaikoAction.LeftRim; - case TaikoInput.LeftCentre: return TaikoAction.LeftCentre; - case TaikoInput.RightCentre: return TaikoAction.RightCentre; - case TaikoInput.RightRim: return TaikoAction.RightRim; + case TaikoAction.LeftRim: return TaikoAction.LeftRim; + case TaikoAction.LeftCentre: return TaikoAction.LeftCentre; + case TaikoAction.RightCentre: return TaikoAction.RightCentre; + case TaikoAction.RightRim: return TaikoAction.RightRim; } break; case TaikoTouchControlScheme.DDKK: switch (input) { - case TaikoInput.LeftRim: return TaikoAction.LeftCentre; - case TaikoInput.LeftCentre: return TaikoAction.RightCentre; - case TaikoInput.RightCentre: return TaikoAction.LeftRim; - case TaikoInput.RightRim: return TaikoAction.RightRim; + case TaikoAction.LeftRim: return TaikoAction.LeftCentre; + case TaikoAction.LeftCentre: return TaikoAction.RightCentre; + case TaikoAction.RightCentre: return TaikoAction.LeftRim; + case TaikoAction.RightRim: return TaikoAction.RightRim; } break; case TaikoTouchControlScheme.KKDD: switch (input) { - case TaikoInput.LeftRim: return TaikoAction.LeftRim; - case TaikoInput.LeftCentre: return TaikoAction.RightRim; - case TaikoInput.RightCentre: return TaikoAction.LeftCentre; - case TaikoInput.RightRim: return TaikoAction.RightCentre; + case TaikoAction.LeftRim: return TaikoAction.LeftRim; + case TaikoAction.LeftCentre: return TaikoAction.RightRim; + case TaikoAction.RightCentre: return TaikoAction.LeftCentre; + case TaikoAction.RightRim: return TaikoAction.RightCentre; } break; } @@ -198,12 +197,12 @@ namespace osu.Game.Rulesets.Taiko.UI { bool centreHit = leftCentre.Contains(inputPosition) || rightCentre.Contains(inputPosition); bool leftSide = ToLocalSpace(inputPosition).X < DrawWidth / 2; - TaikoInput input; + TaikoAction input; if (leftSide) - input = centreHit ? TaikoInput.LeftCentre : TaikoInput.LeftRim; + input = centreHit ? TaikoAction.LeftCentre : TaikoAction.LeftRim; else - input = centreHit ? TaikoInput.RightCentre : TaikoInput.RightRim; + input = centreHit ? TaikoAction.RightCentre : TaikoAction.RightRim; return getTaikoActionFromInput(input); } From 2800eeac560f8a498e480c3cb21982798b4ee605 Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Tue, 10 Jan 2023 19:23:49 +0000 Subject: [PATCH 1400/2991] Simplified formatting; Removed warning suppressors --- .../UI/DrumTouchInputArea.cs | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index c1e98b7102..25ea930fe3 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#pragma warning disable IDE0001 // Simplify Names - using System.Collections.Generic; using System.Diagnostics; using osu.Framework.Allocation; @@ -153,7 +151,6 @@ namespace osu.Game.Rulesets.Taiko.UI private bool validMouse(MouseButtonEvent e) => leftRim.Contains(e.ScreenSpaceMouseDownPosition) || rightRim.Contains(e.ScreenSpaceMouseDownPosition); - #pragma warning disable format private TaikoAction getTaikoActionFromInput(TaikoAction input) { switch (configTouchControlScheme.Value) @@ -162,36 +159,35 @@ namespace osu.Game.Rulesets.Taiko.UI switch (input) { - case TaikoAction.LeftRim: return TaikoAction.LeftRim; - case TaikoAction.LeftCentre: return TaikoAction.LeftCentre; + case TaikoAction.LeftRim: return TaikoAction.LeftRim; + case TaikoAction.LeftCentre: return TaikoAction.LeftCentre; case TaikoAction.RightCentre: return TaikoAction.RightCentre; - case TaikoAction.RightRim: return TaikoAction.RightRim; + case TaikoAction.RightRim: return TaikoAction.RightRim; } break; case TaikoTouchControlScheme.DDKK: switch (input) { - case TaikoAction.LeftRim: return TaikoAction.LeftCentre; - case TaikoAction.LeftCentre: return TaikoAction.RightCentre; + case TaikoAction.LeftRim: return TaikoAction.LeftCentre; + case TaikoAction.LeftCentre: return TaikoAction.RightCentre; case TaikoAction.RightCentre: return TaikoAction.LeftRim; - case TaikoAction.RightRim: return TaikoAction.RightRim; + case TaikoAction.RightRim: return TaikoAction.RightRim; } break; case TaikoTouchControlScheme.KKDD: switch (input) { - case TaikoAction.LeftRim: return TaikoAction.LeftRim; - case TaikoAction.LeftCentre: return TaikoAction.RightRim; + case TaikoAction.LeftRim: return TaikoAction.LeftRim; + case TaikoAction.LeftCentre: return TaikoAction.RightRim; case TaikoAction.RightCentre: return TaikoAction.LeftCentre; - case TaikoAction.RightRim: return TaikoAction.RightCentre; + case TaikoAction.RightRim: return TaikoAction.RightCentre; } break; } return TaikoAction.LeftCentre; } - #pragma warning restore format private TaikoAction getTaikoActionFromPosition(Vector2 inputPosition) { @@ -219,7 +215,6 @@ namespace osu.Game.Rulesets.Taiko.UI private Color4 getColourFromTaikoAction(TaikoAction handledAction) { - #pragma warning disable format switch (handledAction) { case TaikoAction.LeftRim: @@ -229,7 +224,6 @@ namespace osu.Game.Rulesets.Taiko.UI case TaikoAction.RightCentre: return colours.Red; } - #pragma warning restore format return colours.Red; } private partial class QuarterCircle : CompositeDrawable, IKeyBindingHandler From 2b58862567e37ecd81fac5625f70155b74c2d902 Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Tue, 10 Jan 2023 19:31:31 +0000 Subject: [PATCH 1401/2991] Added ArgumentOutOfRangeException throws --- osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 25ea930fe3..b39025e6dc 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.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 System.Collections.Generic; using System.Diagnostics; using osu.Framework.Allocation; @@ -186,7 +187,7 @@ namespace osu.Game.Rulesets.Taiko.UI } break; } - return TaikoAction.LeftCentre; + throw new ArgumentOutOfRangeException(); } private TaikoAction getTaikoActionFromPosition(Vector2 inputPosition) @@ -224,7 +225,7 @@ namespace osu.Game.Rulesets.Taiko.UI case TaikoAction.RightCentre: return colours.Red; } - return colours.Red; + throw new ArgumentOutOfRangeException(); } private partial class QuarterCircle : CompositeDrawable, IKeyBindingHandler { From 57467e7b3905ed6008dba82d6429050b29485ed3 Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Tue, 10 Jan 2023 20:04:57 +0000 Subject: [PATCH 1402/2991] Touchscreen drum now uses a 2d array rather than nested switches to get TaikoActions for control scheme --- .../UI/DrumTouchInputArea.cs | 94 ++++++++----------- 1 file changed, 41 insertions(+), 53 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index b39025e6dc..8dad25c8e4 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -75,34 +75,34 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - leftRim = new QuarterCircle(getTaikoActionFromInput(TaikoAction.LeftRim), getColourFromTaikoAction(getTaikoActionFromInput(TaikoAction.LeftRim))) + leftRim = new QuarterCircle(getTaikoActionFromDrumSegment(0), getColourFromTaikoAction(getTaikoActionFromDrumSegment(0))) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, }, - rightRim = new QuarterCircle(getTaikoActionFromInput(TaikoAction.RightRim), getColourFromTaikoAction(getTaikoActionFromInput(TaikoAction.RightRim))) - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomRight, - X = 2, - Rotation = 90, - }, - leftCentre = new QuarterCircle(getTaikoActionFromInput(TaikoAction.LeftCentre), getColourFromTaikoAction(getTaikoActionFromInput(TaikoAction.LeftCentre))) + leftCentre = new QuarterCircle(getTaikoActionFromDrumSegment(1), getColourFromTaikoAction(getTaikoActionFromDrumSegment(1))) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, Scale = new Vector2(centre_region), }, - rightCentre = new QuarterCircle(getTaikoActionFromInput(TaikoAction.RightCentre), getColourFromTaikoAction(getTaikoActionFromInput(TaikoAction.RightCentre))) + rightCentre = new QuarterCircle(getTaikoActionFromDrumSegment(2), getColourFromTaikoAction(getTaikoActionFromDrumSegment(2))) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = 2, Scale = new Vector2(centre_region), Rotation = 90, - } + }, + rightRim = new QuarterCircle(getTaikoActionFromDrumSegment(3), getColourFromTaikoAction(getTaikoActionFromDrumSegment(3))) + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomRight, + X = 2, + Rotation = 90, + }, } }, } @@ -110,6 +110,32 @@ namespace osu.Game.Rulesets.Taiko.UI }; } + private readonly TaikoAction[,] mappedTaikoAction = { + { // KDDK + TaikoAction.LeftRim, + TaikoAction.LeftCentre, + TaikoAction.RightCentre, + TaikoAction.RightRim + }, + { // DDKK + TaikoAction.LeftCentre, + TaikoAction.RightCentre, + TaikoAction.LeftRim, + TaikoAction.RightRim + }, + { // KKDD + TaikoAction.LeftRim, + TaikoAction.RightRim, + TaikoAction.LeftCentre, + TaikoAction.RightCentre + } + }; + + private TaikoAction getTaikoActionFromDrumSegment(int drumSegment) + { + return mappedTaikoAction[(int)configTouchControlScheme.Value, drumSegment]; + } + protected override bool OnKeyDown(KeyDownEvent e) { // Hide whenever the keyboard is used. @@ -152,56 +178,18 @@ namespace osu.Game.Rulesets.Taiko.UI private bool validMouse(MouseButtonEvent e) => leftRim.Contains(e.ScreenSpaceMouseDownPosition) || rightRim.Contains(e.ScreenSpaceMouseDownPosition); - private TaikoAction getTaikoActionFromInput(TaikoAction input) - { - switch (configTouchControlScheme.Value) - { - case TaikoTouchControlScheme.KDDK: - - switch (input) - { - case TaikoAction.LeftRim: return TaikoAction.LeftRim; - case TaikoAction.LeftCentre: return TaikoAction.LeftCentre; - case TaikoAction.RightCentre: return TaikoAction.RightCentre; - case TaikoAction.RightRim: return TaikoAction.RightRim; - } - break; - - case TaikoTouchControlScheme.DDKK: - switch (input) - { - case TaikoAction.LeftRim: return TaikoAction.LeftCentre; - case TaikoAction.LeftCentre: return TaikoAction.RightCentre; - case TaikoAction.RightCentre: return TaikoAction.LeftRim; - case TaikoAction.RightRim: return TaikoAction.RightRim; - } - break; - - case TaikoTouchControlScheme.KKDD: - switch (input) - { - case TaikoAction.LeftRim: return TaikoAction.LeftRim; - case TaikoAction.LeftCentre: return TaikoAction.RightRim; - case TaikoAction.RightCentre: return TaikoAction.LeftCentre; - case TaikoAction.RightRim: return TaikoAction.RightCentre; - } - break; - } - throw new ArgumentOutOfRangeException(); - } - private TaikoAction getTaikoActionFromPosition(Vector2 inputPosition) { bool centreHit = leftCentre.Contains(inputPosition) || rightCentre.Contains(inputPosition); bool leftSide = ToLocalSpace(inputPosition).X < DrawWidth / 2; - TaikoAction input; + int drumSegment; if (leftSide) - input = centreHit ? TaikoAction.LeftCentre : TaikoAction.LeftRim; + drumSegment = centreHit ? 1 : 0; else - input = centreHit ? TaikoAction.RightCentre : TaikoAction.RightRim; + drumSegment = centreHit ? 2 : 3; - return getTaikoActionFromInput(input); + return getTaikoActionFromDrumSegment(drumSegment); } protected override void PopIn() From ce37760b276b9c95d6215eca9ad1aafcae06f047 Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Tue, 10 Jan 2023 20:05:41 +0000 Subject: [PATCH 1403/2991] Removed unnecessary coma --- osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 8dad25c8e4..31654ac17d 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -102,7 +102,7 @@ namespace osu.Game.Rulesets.Taiko.UI Origin = Anchor.BottomRight, X = 2, Rotation = 90, - }, + } } }, } From 38bb7ac0c7901cbca12a4f787fe2d28eaa0591a8 Mon Sep 17 00:00:00 2001 From: Wleter Date: Tue, 10 Jan 2023 21:16:34 +0100 Subject: [PATCH 1404/2991] add fields for path's end location --- .../Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs | 4 ++++ osu.Game.Rulesets.Osu/Skinning/SliderBody.cs | 6 ++++++ osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs | 8 ++++++++ 3 files changed, 18 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs index ecd840dda6..c44bbbfa03 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs @@ -22,6 +22,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components /// public Vector2 PathStartLocation => body.PathOffset; + /// + /// Offset in absolute (local) coordinates from the end of the curve. + /// + public Vector2 PathEndLocation => body.PathEndOffset; public SliderBodyPiece() { InternalChild = body = new ManualSliderBody diff --git a/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs index 283687adfd..8a54723a8e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs @@ -31,6 +31,12 @@ namespace osu.Game.Rulesets.Osu.Skinning /// public virtual Vector2 PathOffset => path.PositionInBoundingBox(path.Vertices[0]); + /// + /// Offset in absolute coordinates from the end of the curve. + /// + public virtual Vector2 PathEndOffset => path.PositionInBoundingBox(path.Vertices[^1]); + + /// /// Used to colour the path. /// diff --git a/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs index f8ee465cd6..0b7acc1f47 100644 --- a/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs @@ -43,6 +43,8 @@ namespace osu.Game.Rulesets.Osu.Skinning public override Vector2 PathOffset => snakedPathOffset; + public override Vector2 PathEndOffset => snakedPathEndOffset; + /// /// The top-left position of the path when fully snaked. /// @@ -53,6 +55,11 @@ namespace osu.Game.Rulesets.Osu.Skinning /// private Vector2 snakedPathOffset; + /// + /// The offset of the end of path from when fully snaked. + /// + private Vector2 snakedPathEndOffset; + private DrawableSlider drawableSlider = null!; [BackgroundDependencyLoader] @@ -109,6 +116,7 @@ namespace osu.Game.Rulesets.Osu.Skinning snakedPosition = Path.PositionInBoundingBox(Vector2.Zero); snakedPathOffset = Path.PositionInBoundingBox(Path.Vertices[0]); + snakedPathEndOffset = Path.PositionInBoundingBox(Path.Vertices[^1]); double lastSnakedStart = SnakedStart ?? 0; double lastSnakedEnd = SnakedEnd ?? 0; From e5863fbaf1f4f9f7918459aff1a38e0941752301 Mon Sep 17 00:00:00 2001 From: Wleter Date: Tue, 10 Jan 2023 21:20:09 +0100 Subject: [PATCH 1405/2991] add ScreenSpaceEndPoint field --- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 4 ++++ osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs | 2 ++ osu.Game/Rulesets/Edit/SelectionBlueprint.cs | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index a51c223785..3737a44ad2 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -409,6 +409,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders public override Vector2 ScreenSpaceSelectionPoint => DrawableObject.SliderBody?.ToScreenSpace(DrawableObject.SliderBody.PathOffset) ?? BodyPiece.ToScreenSpace(BodyPiece.PathStartLocation); + + public override Vector2 ScreenSpaceEndPoint => DrawableObject.SliderBody?.ToScreenSpace(DrawableObject.SliderBody.PathEndOffset) + ?? BodyPiece.ToScreenSpace(BodyPiece.PathEndLocation); + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => BodyPiece.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true; diff --git a/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs b/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs index 93b889792b..3aa086582f 100644 --- a/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs @@ -48,6 +48,8 @@ namespace osu.Game.Rulesets.Edit public override Vector2 ScreenSpaceSelectionPoint => DrawableObject.ScreenSpaceDrawQuad.Centre; + public override Vector2 ScreenSpaceEndPoint => DrawableObject.ScreenSpaceDrawQuad.Centre; + public override Quad SelectionQuad => DrawableObject.ScreenSpaceDrawQuad; } diff --git a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs index 4e0e45e0f5..a27a59be34 100644 --- a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs @@ -129,6 +129,11 @@ namespace osu.Game.Rulesets.Edit /// public virtual Vector2 ScreenSpaceSelectionPoint => ScreenSpaceDrawQuad.Centre; + /// + /// The screen-space point that mark end of this . + /// + public virtual Vector2 ScreenSpaceEndPoint => ScreenSpaceDrawQuad.Centre; + /// /// The screen-space quad that outlines this for selections. /// From 88060a3ea097d3dbad513e08f582288825cbaf9b Mon Sep 17 00:00:00 2001 From: Wleter Date: Tue, 10 Jan 2023 21:21:09 +0100 Subject: [PATCH 1406/2991] add snapping for slider's end --- .../Compose/Components/BlueprintContainer.cs | 60 +++++++++++++------ 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 77892f21e6..826a16b83b 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -440,6 +440,7 @@ namespace osu.Game.Screens.Edit.Compose.Components #region Selection Movement private Vector2[] movementBlueprintOriginalPositions; + private Vector2[] movementBlueprintEndPositions; private SelectionBlueprint[] movementBlueprints; private bool isDraggingBlueprint; @@ -459,7 +460,12 @@ namespace osu.Game.Screens.Edit.Compose.Components // Movement is tracked from the blueprint of the earliest item, since it only makes sense to distance snap from that item movementBlueprints = SortForMovement(SelectionHandler.SelectedBlueprints).ToArray(); - movementBlueprintOriginalPositions = movementBlueprints.Select(m => m.ScreenSpaceSelectionPoint).ToArray(); + movementBlueprintOriginalPositions = movementBlueprints.Select(m => m.ScreenSpaceSelectionPoint) + .ToArray(); + movementBlueprintEndPositions = movementBlueprints.Where(m => m.ScreenSpaceSelectionPoint != m.ScreenSpaceEndPoint) + .Select(m => m.ScreenSpaceEndPoint) + .ToArray(); + return true; } @@ -470,6 +476,33 @@ namespace osu.Game.Screens.Edit.Compose.Components /// Sorted blueprints. protected virtual IEnumerable> SortForMovement(IReadOnlyList> blueprints) => blueprints; + /// + /// Check for positional snap for every given positions. + /// + /// Distance traveled since start of dragging action. + /// The positions to check for snapping before start of dragging action. + /// The positions to check for snapping at the current time. + /// Whether found object to snap to. + private bool checkSnappingForNearbyObjects(Vector2 distanceTraveled, Vector2[] originalPositions, Vector2[] currentPositions) + { + for (int i = 0; i < originalPositions.Length; i++) + { + Vector2 originalPosition = originalPositions[i]; + var testPosition = originalPosition + distanceTraveled; + + var positionalResult = snapProvider.FindSnappedPositionAndTime(testPosition, SnapType.NearbyObjects); + + if (positionalResult.ScreenSpacePosition == testPosition) continue; + + var delta = positionalResult.ScreenSpacePosition - currentPositions[i]; + + // attempt to move the objects, and abort any time based snapping if we can. + if (SelectionHandler.HandleMovement(new MoveSelectionEvent(movementBlueprints[i], delta))) + return true; + } + return false; + } + /// /// Moves the current selected blueprints. /// @@ -482,33 +515,24 @@ namespace osu.Game.Screens.Edit.Compose.Components Debug.Assert(movementBlueprintOriginalPositions != null); - Vector2 distanceTravelled = e.ScreenSpaceMousePosition - e.ScreenSpaceMouseDownPosition; + Vector2 distanceTraveled = e.ScreenSpaceMousePosition - e.ScreenSpaceMouseDownPosition; if (snapProvider != null) { - // check for positional snap for every object in selection (for things like object-object snapping) - for (int i = 0; i < movementBlueprintOriginalPositions.Length; i++) - { - Vector2 originalPosition = movementBlueprintOriginalPositions[i]; - var testPosition = originalPosition + distanceTravelled; + var currentSelectionPointPositions = movementBlueprints.Select(m => m.ScreenSpaceSelectionPoint).ToArray(); + if (checkSnappingForNearbyObjects(distanceTraveled, movementBlueprintOriginalPositions, currentSelectionPointPositions)) + return true; - var positionalResult = snapProvider.FindSnappedPositionAndTime(testPosition, SnapType.NearbyObjects); - - if (positionalResult.ScreenSpacePosition == testPosition) continue; - - var delta = positionalResult.ScreenSpacePosition - movementBlueprints[i].ScreenSpaceSelectionPoint; - - // attempt to move the objects, and abort any time based snapping if we can. - if (SelectionHandler.HandleMovement(new MoveSelectionEvent(movementBlueprints[i], delta))) - return true; - } + var currentEndPointPositions = movementBlueprints.Select(m => m.ScreenSpaceEndPoint).ToArray(); + if (checkSnappingForNearbyObjects(distanceTraveled, movementBlueprintEndPositions, currentEndPointPositions)) + return true; } // if no positional snapping could be performed, try unrestricted snapping from the earliest // item in the selection. // The final movement position, relative to movementBlueprintOriginalPosition. - Vector2 movePosition = movementBlueprintOriginalPositions.First() + distanceTravelled; + Vector2 movePosition = movementBlueprintOriginalPositions.First() + distanceTraveled; // Retrieve a snapped position. var result = snapProvider?.FindSnappedPositionAndTime(movePosition, ~SnapType.NearbyObjects); From 21073f36012ede15d245f2813520ba5b4267c406 Mon Sep 17 00:00:00 2001 From: tsrk Date: Tue, 10 Jan 2023 22:49:35 +0100 Subject: [PATCH 1407/2991] reafactor: use DrawNode to draw SegmenteddGraph --- .../Graphics/UserInterface/SegmentedGraph.cs | 138 +++++++++--------- 1 file changed, 72 insertions(+), 66 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index 261e535fbc..65c2146889 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -5,20 +5,19 @@ using System; using System.Collections; using System.Collections.Generic; using System.Linq; -using System.Threading; +using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Threading; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Rendering; +using osu.Framework.Graphics.Shaders; +using osu.Framework.Graphics.Textures; using osuTK; namespace osu.Game.Graphics.UserInterface { - public abstract partial class SegmentedGraph : Container + public abstract partial class SegmentedGraph : Drawable where T : struct, IComparable, IConvertible, IEquatable { - private BufferedContainer? rectSegments; - private float previousDrawWidth; private bool graphNeedsUpdate; private T[]? values; @@ -44,53 +43,33 @@ namespace osu.Game.Graphics.UserInterface values = value; recalculateTiers(values); graphNeedsUpdate = true; + Invalidate(Invalidation.DrawNode); } } public readonly Colour4[] TierColours; - private CancellationTokenSource? cts; - private ScheduledDelegate? scheduledCreate; + private Texture texture = null!; + private IShader shader = null!; + + [BackgroundDependencyLoader] + private void load(IRenderer renderer, ShaderManager shaders) + { + texture = renderer.WhitePixel; + shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE); + } protected override void Update() { base.Update(); - if (graphNeedsUpdate || (values != null && DrawWidth != previousDrawWidth)) + if (graphNeedsUpdate) { - rectSegments?.FadeOut(150, Easing.OutQuint).Expire(); - - scheduledCreate?.Cancel(); - scheduledCreate = Scheduler.AddDelayed(RecreateGraph, 150); - - previousDrawWidth = DrawWidth; - graphNeedsUpdate = false; + recalculateSegments(); + Invalidate(Invalidation.DrawNode); } } - protected virtual void RecreateGraph() - { - var newSegments = new BufferedContainer(cachedFrameBuffer: true) - { - RedrawOnScale = false, - RelativeSizeAxes = Axes.Both - }; - - cts?.Cancel(); - recalculateSegments(); - redrawSegments(newSegments); - - LoadComponentAsync(newSegments, s => - { - Children = new Drawable[] - { - rectSegments = s - }; - - s.FadeInFromZero(100); - }, (cts = new CancellationTokenSource()).Token); - } - private void recalculateTiers(T[]? arr) { if (arr == null || arr.Length == 0) @@ -159,32 +138,7 @@ namespace osu.Game.Graphics.UserInterface private Colour4 tierToColour(int tier) => tier >= 0 ? TierColours[tier] : new Colour4(0, 0, 0, 0); - // Base implementation, could be drawn with draw node if preferred - private void redrawSegments(BufferedContainer container) - { - if (segments.Count == 0) - return; - - foreach (SegmentInfo segment in segments) // Lower tiers will be drawn first, putting them in the back - { - float width = segment.Length * DrawWidth; - - // If the segment width exceeds the DrawWidth, just fill the rest - if (width >= DrawWidth) - width = DrawWidth; - - container.Add(new Box - { - Name = $"Tier {segment.Tier} segment", - Origin = Anchor.BottomLeft, - Anchor = Anchor.BottomLeft, - RelativeSizeAxes = Axes.Y, - Position = new Vector2(segment.Start * DrawWidth, 0), - Width = width, - Colour = tierToColour(segment.Tier) - }); - } - } + protected override DrawNode CreateDrawNode() => new SegmentedGraphDrawNode(this); protected struct SegmentInfo { @@ -218,6 +172,58 @@ namespace osu.Game.Graphics.UserInterface public float Length => End - Start; } + private class SegmentedGraphDrawNode : DrawNode + { + public new SegmentedGraph Source => (SegmentedGraph)base.Source; + + private Texture texture = null!; + private IShader shader = null!; + private readonly List segments = new List(); + private Vector2 drawSize; + + public SegmentedGraphDrawNode(SegmentedGraph source) + : base(source) + { + } + + public override void ApplyState() + { + base.ApplyState(); + + texture = Source.texture; + shader = Source.shader; + drawSize = Source.DrawSize; + segments.Clear(); + segments.AddRange(Source.segments); + } + + public override void Draw(IRenderer renderer) + { + base.Draw(renderer); + + shader.Bind(); + + foreach (SegmentInfo segment in segments) + { + Vector2 topLeft = new Vector2(segment.Start * drawSize.X, 0); + Vector2 topRight = new Vector2(segment.End * drawSize.X, 0); + Vector2 bottomLeft = new Vector2(segment.Start * drawSize.X, drawSize.Y); + Vector2 bottomRight = new Vector2(segment.End * drawSize.X, drawSize.Y); + + renderer.DrawQuad( + texture, + new Quad( + Vector2Extensions.Transform(topLeft, DrawInfo.Matrix), + Vector2Extensions.Transform(topRight, DrawInfo.Matrix), + Vector2Extensions.Transform(bottomLeft, DrawInfo.Matrix), + Vector2Extensions.Transform(bottomRight, DrawInfo.Matrix)), + Source.tierToColour(segment.Tier)); + } + + shader.Unbind(); + } + } + protected class SegmentManager : IEnumerable { private readonly List segments = new List(); From 944c6759d912934d7ce1fc99ab045e4ddd884e00 Mon Sep 17 00:00:00 2001 From: OpenSauce <48618519+OpenSauce04@users.noreply.github.com> Date: Tue, 10 Jan 2023 23:13:22 +0000 Subject: [PATCH 1408/2991] Fixed right rim being incorrectly layered above right centre --- osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 31654ac17d..b7a0d46d51 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -88,6 +88,13 @@ namespace osu.Game.Rulesets.Taiko.UI X = -2, Scale = new Vector2(centre_region), }, + rightRim = new QuarterCircle(getTaikoActionFromDrumSegment(3), getColourFromTaikoAction(getTaikoActionFromDrumSegment(3))) + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomRight, + X = 2, + Rotation = 90, + }, rightCentre = new QuarterCircle(getTaikoActionFromDrumSegment(2), getColourFromTaikoAction(getTaikoActionFromDrumSegment(2))) { Anchor = Anchor.BottomCentre, @@ -95,13 +102,6 @@ namespace osu.Game.Rulesets.Taiko.UI X = 2, Scale = new Vector2(centre_region), Rotation = 90, - }, - rightRim = new QuarterCircle(getTaikoActionFromDrumSegment(3), getColourFromTaikoAction(getTaikoActionFromDrumSegment(3))) - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomRight, - X = 2, - Rotation = 90, } } }, From b38cf8c56c4323f074e3acd90001258ae650b99c Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 11 Jan 2023 02:26:25 +0300 Subject: [PATCH 1409/2991] Use empty string as default --- osu.Game/Overlays/Comments/CommentEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 8e02d015ed..906ff0c4a2 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -30,7 +30,7 @@ namespace osu.Game.Overlays.Comments protected FillFlowContainer ButtonsContainer { get; private set; } = null!; - protected readonly Bindable Current = new Bindable(); + protected readonly Bindable Current = new Bindable(string.Empty); private RoundedButton commitButton = null!; private LoadingSpinner loadingSpinner = null!; From 44de24f15397faf8b0c49401e65c543326f215cc Mon Sep 17 00:00:00 2001 From: Stedoss <29103029+Stedoss@users.noreply.github.com> Date: Tue, 10 Jan 2023 23:30:09 +0000 Subject: [PATCH 1410/2991] `BeatmapSetOverlay` fetch on login state change --- osu.Game/Overlays/BeatmapSetOverlay.cs | 79 ++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index fd831ad4ae..e905308066 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -10,6 +10,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.BeatmapSet; @@ -30,6 +31,14 @@ namespace osu.Game.Overlays private readonly Bindable beatmapSet = new Bindable(); + [Resolved] + private IAPIProvider api { get; set; } + + private IBindable apiUser; + + private int? lastRequestedBeatmapId; + private BeatmapSetLookupType? lastBeatmapSetLookupType; + /// /// Isolates the beatmap set overlay from the game-wide selected mods bindable /// to avoid affecting the beatmap details section (i.e. ). @@ -72,6 +81,17 @@ namespace osu.Game.Overlays }; } + [BackgroundDependencyLoader] + private void load() + { + apiUser = api.LocalUser.GetBoundCopy(); + apiUser.BindValueChanged(_ => Schedule(() => + { + if (api.IsLoggedIn) + fetchAndSetLastRequestedBeatmap(); + })); + } + protected override BeatmapSetHeader CreateHeader() => new BeatmapSetHeader(); protected override Color4 BackgroundColour => ColourProvider.Background6; @@ -84,26 +104,24 @@ namespace osu.Game.Overlays public void FetchAndShowBeatmap(int beatmapId) { + lastRequestedBeatmapId = beatmapId; + lastBeatmapSetLookupType = BeatmapSetLookupType.BeatmapId; + beatmapSet.Value = null; - var req = new GetBeatmapSetRequest(beatmapId, BeatmapSetLookupType.BeatmapId); - req.Success += res => - { - beatmapSet.Value = res; - Header.HeaderContent.Picker.Beatmap.Value = Header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineID == beatmapId); - }; - API.Queue(req); + fetchAndSetBeatmap(beatmapId); Show(); } public void FetchAndShowBeatmapSet(int beatmapSetId) { + lastRequestedBeatmapId = beatmapSetId; + lastBeatmapSetLookupType = BeatmapSetLookupType.SetId; + beatmapSet.Value = null; - var req = new GetBeatmapSetRequest(beatmapSetId); - req.Success += res => beatmapSet.Value = res; - API.Queue(req); + fetchAndSetBeatmapSet(beatmapSetId); Show(); } @@ -118,6 +136,47 @@ namespace osu.Game.Overlays Show(); } + private void fetchAndSetBeatmap(int beatmapId) + { + if (!api.IsLoggedIn) + return; + + var req = new GetBeatmapSetRequest(beatmapId, BeatmapSetLookupType.BeatmapId); + req.Success += res => + { + beatmapSet.Value = res; + Header.HeaderContent.Picker.Beatmap.Value = Header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineID == beatmapId); + }; + API.Queue(req); + } + + private void fetchAndSetBeatmapSet(int beatmapSetId) + { + if (!api.IsLoggedIn) + return; + + var req = new GetBeatmapSetRequest(beatmapSetId); + req.Success += res => beatmapSet.Value = res; + API.Queue(req); + } + + private void fetchAndSetLastRequestedBeatmap() + { + if (lastRequestedBeatmapId == null) + return; + + switch (lastBeatmapSetLookupType) + { + case BeatmapSetLookupType.SetId: + fetchAndSetBeatmapSet(lastRequestedBeatmapId.Value); + break; + + case BeatmapSetLookupType.BeatmapId: + fetchAndSetBeatmap(lastRequestedBeatmapId.Value); + break; + } + } + private partial class CommentsSection : BeatmapSetLayoutSection { public readonly Bindable BeatmapSet = new Bindable(); From 776b60f3b3b133ecd41bc284e727e333c670f949 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 10 Jan 2023 14:05:08 -0800 Subject: [PATCH 1411/2991] Fix manual input manager test scenes not matching game input hierarchy Fix popover using on key down Fix popover not expiring when using global action --- osu.Game/Graphics/UserInterfaceV2/OsuPopover.cs | 12 +++++++++++- .../Tests/Visual/OsuManualInputManagerTestScene.cs | 10 ++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuPopover.cs b/osu.Game/Graphics/UserInterfaceV2/OsuPopover.cs index e66e48373c..d89322cecd 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuPopover.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuPopover.cs @@ -5,6 +5,7 @@ using JetBrains.Annotations; using osu.Framework.Allocation; +using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; @@ -14,6 +15,7 @@ using osu.Framework.Input.Events; using osu.Game.Input.Bindings; using osu.Game.Overlays; using osuTK; +using osuTK.Input; namespace osu.Game.Graphics.UserInterfaceV2 { @@ -58,6 +60,14 @@ namespace osu.Game.Graphics.UserInterfaceV2 this.FadeOut(fade_duration, Easing.OutQuint); } + protected override bool OnKeyDown(KeyDownEvent e) + { + if (e.Key == Key.Escape) + return false; // disable the framework-level handling of escape key for conformity (we use GlobalAction.Back). + + return base.OnKeyDown(e); + } + public bool OnPressed(KeyBindingPressEvent e) { if (e.Repeat) @@ -68,7 +78,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 if (e.Action == GlobalAction.Back) { - Hide(); + this.HidePopover(); return true; } diff --git a/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs b/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs index b0043b902c..8e0ee896a5 100644 --- a/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs +++ b/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs @@ -46,21 +46,23 @@ namespace osu.Game.Tests.Visual { var mainContent = content = new Container { RelativeSizeAxes = Axes.Both }; + var inputContainer = new Container { RelativeSizeAxes = Axes.Both }; + if (DisplayCursorForManualInput) { var cursorDisplay = new GlobalCursorDisplay { RelativeSizeAxes = Axes.Both }; - cursorDisplay.Add(new OsuTooltipContainer(cursorDisplay.MenuCursor) + cursorDisplay.Add(content = new OsuTooltipContainer(cursorDisplay.MenuCursor) { RelativeSizeAxes = Axes.Both, - Child = mainContent }); - mainContent = cursorDisplay; + inputContainer.Add(cursorDisplay); + mainContent = inputContainer; } if (CreateNestedActionContainer) - mainContent = new GlobalActionContainer(null).WithChild(mainContent); + inputContainer.Add(new GlobalActionContainer(null)); base.Content.AddRange(new Drawable[] { From 51dbe2c3a33fb6033e1af6730cb49b1ba50c9a55 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 10 Jan 2023 15:43:06 -0800 Subject: [PATCH 1412/2991] Refactor pause test to actually use back action keybinding --- .../Visual/Gameplay/TestScenePause.cs | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs index 7880a849a2..910a6f28cf 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs @@ -5,6 +5,7 @@ using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -34,6 +35,12 @@ namespace osu.Game.Tests.Visual.Gameplay base.Content.Add(content = new GlobalCursorDisplay { RelativeSizeAxes = Axes.Both }); } + [BackgroundDependencyLoader] + private void load() + { + LocalConfig.SetValue(OsuSetting.UIHoldActivationDelay, 0.0); + } + [SetUpSteps] public override void SetUpSteps() { @@ -144,7 +151,7 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("disable pause support", () => Player.Configuration.AllowPause = false); - pauseFromUserExitKey(); + pauseViaBackAction(); confirmExited(); } @@ -156,7 +163,7 @@ namespace osu.Game.Tests.Visual.Gameplay pauseAndConfirm(); resume(); - pauseFromUserExitKey(); + pauseViaBackAction(); confirmResumed(); confirmNotExited(); @@ -214,7 +221,7 @@ namespace osu.Game.Tests.Visual.Gameplay confirmClockRunning(false); - AddStep("exit via user pause", () => Player.ExitViaPause()); + pauseViaBackAction(); confirmExited(); } @@ -224,11 +231,11 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for fail", () => Player.GameplayState.HasFailed); // will finish the fail animation and show the fail/pause screen. - AddStep("attempt exit via pause key", () => Player.ExitViaPause()); + pauseViaBackAction(); AddAssert("fail overlay shown", () => Player.FailOverlayVisible); // will actually exit. - AddStep("exit via pause key", () => Player.ExitViaPause()); + pauseViaBackAction(); confirmExited(); } @@ -327,7 +334,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void pauseAndConfirm() { - pauseFromUserExitKey(); + pauseViaBackAction(); confirmPaused(); } @@ -374,7 +381,7 @@ namespace osu.Game.Tests.Visual.Gameplay } private void restart() => AddStep("restart", () => Player.Restart()); - private void pauseFromUserExitKey() => AddStep("user pause", () => Player.ExitViaPause()); + private void pauseViaBackAction() => AddStep("press escape", () => InputManager.Key(Key.Escape)); private void resume() => AddStep("resume", () => Player.Resume()); private void confirmPauseOverlayShown(bool isShown) => @@ -405,8 +412,6 @@ namespace osu.Game.Tests.Visual.Gameplay public bool PauseOverlayVisible => PauseOverlay.State.Value == Visibility.Visible; - public void ExitViaPause() => PerformExit(true); - public void ExitViaQuickExit() => PerformExit(false); public override void OnEntering(ScreenTransitionEvent e) From 404d34f5920d8caced05226cc9f234ce585d3b7e Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 10 Jan 2023 15:43:50 -0800 Subject: [PATCH 1413/2991] Refactor pause test to actually use quick exit action keybinding --- .../Visual/Gameplay/TestScenePause.cs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs index 910a6f28cf..ca221b6b1c 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs @@ -177,7 +177,7 @@ namespace osu.Game.Tests.Visual.Gameplay pauseAndConfirm(); resume(); - AddStep("pause via exit key", () => Player.ExitViaQuickExit()); + exitViaQuickExitAction(); confirmResumed(); AddAssert("exited", () => !Player.IsCurrentScreen()); @@ -252,7 +252,7 @@ namespace osu.Game.Tests.Visual.Gameplay public void TestQuickExitFromFailedGameplay() { AddUntilStep("wait for fail", () => Player.GameplayState.HasFailed); - AddStep("quick exit", () => Player.GameplayClockContainer.ChildrenOfType().First().Action?.Invoke()); + exitViaQuickExitAction(); confirmExited(); } @@ -268,7 +268,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestQuickExitFromGameplay() { - AddStep("quick exit", () => Player.GameplayClockContainer.ChildrenOfType().First().Action?.Invoke()); + exitViaQuickExitAction(); confirmExited(); } @@ -382,6 +382,15 @@ namespace osu.Game.Tests.Visual.Gameplay private void restart() => AddStep("restart", () => Player.Restart()); private void pauseViaBackAction() => AddStep("press escape", () => InputManager.Key(Key.Escape)); + + private void exitViaQuickExitAction() => AddStep("press ctrl-tilde", () => + { + InputManager.PressKey(Key.ControlLeft); + InputManager.PressKey(Key.Tilde); + InputManager.ReleaseKey(Key.Tilde); + InputManager.ReleaseKey(Key.ControlLeft); + }); + private void resume() => AddStep("resume", () => Player.Resume()); private void confirmPauseOverlayShown(bool isShown) => @@ -412,8 +421,6 @@ namespace osu.Game.Tests.Visual.Gameplay public bool PauseOverlayVisible => PauseOverlay.State.Value == Visibility.Visible; - public void ExitViaQuickExit() => PerformExit(false); - public override void OnEntering(ScreenTransitionEvent e) { base.OnEntering(e); From 974a8d520c0a630d8610447a4112ab73404c3a11 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 10 Jan 2023 15:51:22 -0800 Subject: [PATCH 1414/2991] Add basic toggle pause tests --- .../Visual/Gameplay/TestScenePause.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs index ca221b6b1c..f1435094b3 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs @@ -50,6 +50,22 @@ namespace osu.Game.Tests.Visual.Gameplay confirmClockRunning(true); } + [Test] + public void TestTogglePauseViaBackAction() + { + pauseViaBackAction(); + pauseViaBackAction(); + confirmPausedWithNoOverlay(); + } + + [Test] + public void TestTogglePauseViaPauseGameplayAction() + { + pauseViaPauseGameplayAction(); + pauseViaPauseGameplayAction(); + confirmPausedWithNoOverlay(); + } + [Test] public void TestPauseWithLargeOffset() { @@ -382,6 +398,7 @@ namespace osu.Game.Tests.Visual.Gameplay private void restart() => AddStep("restart", () => Player.Restart()); private void pauseViaBackAction() => AddStep("press escape", () => InputManager.Key(Key.Escape)); + private void pauseViaPauseGameplayAction() => AddStep("press middle mouse", () => InputManager.Click(MouseButton.Middle)); private void exitViaQuickExitAction() => AddStep("press ctrl-tilde", () => { From b5caa1b778bc9f663e38ba16c5f13ec6907d893f Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 10 Jan 2023 15:53:41 -0800 Subject: [PATCH 1415/2991] Rename pause gameplay keybind to reflect other behavior --- osu.Game/Localisation/GlobalActionKeyBindingStrings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs b/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs index 14e0bbbced..303dbb6f46 100644 --- a/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs +++ b/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs @@ -155,9 +155,9 @@ namespace osu.Game.Localisation public static LocalisableString ToggleProfile => new TranslatableString(getKey(@"toggle_profile"), @"Toggle profile"); /// - /// "Pause gameplay" + /// "Pause / resume gameplay" /// - public static LocalisableString PauseGameplay => new TranslatableString(getKey(@"pause_gameplay"), @"Pause gameplay"); + public static LocalisableString PauseGameplay => new TranslatableString(getKey(@"pause_gameplay"), @"Pause / resume gameplay"); /// /// "Setup mode" From 43d9c289784d3b8367c794b638bea37aa66f4fc9 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 11 Jan 2023 11:31:05 +0900 Subject: [PATCH 1416/2991] Add triage action --- .github/workflows/triage.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/triage.yml diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml new file mode 100644 index 0000000000..8ba653bafc --- /dev/null +++ b/.github/workflows/triage.yml @@ -0,0 +1,14 @@ +name: Triage +on: + issues: + types: [opened] + +jobs: + build: + name: Triage + runs-on: ubuntu-latest + steps: + - uses: Logerfo/triage-action@0.0.2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + label: needs-triage From 5d3218418074027aec8f0865c135df0d9bcb78c2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jan 2023 12:31:25 +0900 Subject: [PATCH 1417/2991] Revert "Add triage action" This reverts commit 43d9c289784d3b8367c794b638bea37aa66f4fc9. Not working for us --- .github/workflows/triage.yml | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 .github/workflows/triage.yml diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml deleted file mode 100644 index 8ba653bafc..0000000000 --- a/.github/workflows/triage.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: Triage -on: - issues: - types: [opened] - -jobs: - build: - name: Triage - runs-on: ubuntu-latest - steps: - - uses: Logerfo/triage-action@0.0.2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - label: needs-triage From d9a6e4b8621af6909d5aeafc7137b1dd53b96452 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 11 Jan 2023 13:01:11 +0900 Subject: [PATCH 1418/2991] Ensure drain lenience of 1.0 completly removes drain --- osu.Game/Rulesets/Scoring/DrainingHealthProcessor.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/DrainingHealthProcessor.cs b/osu.Game/Rulesets/Scoring/DrainingHealthProcessor.cs index d94c6dd2e0..592dcbfeb8 100644 --- a/osu.Game/Rulesets/Scoring/DrainingHealthProcessor.cs +++ b/osu.Game/Rulesets/Scoring/DrainingHealthProcessor.cs @@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Scoring public DrainingHealthProcessor(double drainStartTime, double drainLenience = 0) { this.drainStartTime = drainStartTime; - this.drainLenience = drainLenience; + this.drainLenience = Math.Clamp(drainLenience, 0, 1); } protected override void Update() @@ -79,7 +79,8 @@ namespace osu.Game.Rulesets.Scoring double lastGameplayTime = Math.Clamp(Time.Current - Time.Elapsed, drainStartTime, gameplayEndTime); double currentGameplayTime = Math.Clamp(Time.Current, drainStartTime, gameplayEndTime); - Health.Value -= drainRate * (currentGameplayTime - lastGameplayTime); + if (drainLenience < 1) + Health.Value -= drainRate * (currentGameplayTime - lastGameplayTime); } public override void ApplyBeatmap(IBeatmap beatmap) From f03677f39479d2dfb58e17ae75a631367885f457 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 11 Jan 2023 13:01:18 +0900 Subject: [PATCH 1419/2991] Remove HP drain from mania --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- osu.Game.Rulesets.Mania/Scoring/ManiaHealthProcessor.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 6162184c9a..0cec0ee075 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Mania public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(); - public override HealthProcessor CreateHealthProcessor(double drainStartTime) => new ManiaHealthProcessor(drainStartTime, 0.5); + public override HealthProcessor CreateHealthProcessor(double drainStartTime) => new ManiaHealthProcessor(drainStartTime); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap, this); diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaHealthProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaHealthProcessor.cs index 5c6682ed73..16f7af0d0a 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaHealthProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaHealthProcessor.cs @@ -11,8 +11,8 @@ namespace osu.Game.Rulesets.Mania.Scoring public partial class ManiaHealthProcessor : DrainingHealthProcessor { /// - public ManiaHealthProcessor(double drainStartTime, double drainLenience = 0) - : base(drainStartTime, drainLenience) + public ManiaHealthProcessor(double drainStartTime) + : base(drainStartTime, 1.0) { } From 5441c02a1a8fa01d1a33fb6b633ac2de5b157740 Mon Sep 17 00:00:00 2001 From: StanR Date: Wed, 11 Jan 2023 07:11:38 +0300 Subject: [PATCH 1420/2991] Implement user group badges --- .../Online/TestSceneUserProfileHeader.cs | 1 + .../Online/TestSceneUserProfileOverlay.cs | 5 + .../Online/API/Requests/Responses/APIUser.cs | 3 + .../API/Requests/Responses/APIUserGroup.cs | 37 ++++++ .../Header/Components/GroupInfoContainer.cs | 106 ++++++++++++++++++ .../Profile/Header/TopHeaderContainer.cs | 9 +- 6 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Online/API/Requests/Responses/APIUserGroup.cs create mode 100644 osu.Game/Overlays/Profile/Header/Components/GroupInfoContainer.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index bfd6372e6f..3c0ea4f590 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -59,6 +59,7 @@ namespace osu.Game.Tests.Visual.Online { Id = 2001, Username = "RankedUser", + Groups = new[] { new APIUserGroup() { Colour = "#EB47D0", ShortName = "DEV", Name = "Developers" } }, Statistics = new UserStatistics { IsRanked = true, diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs index 35c7e7bf28..cab883c0da 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs @@ -27,6 +27,11 @@ namespace osu.Game.Tests.Visual.Online JoinDate = DateTimeOffset.Now.AddDays(-1), LastVisit = DateTimeOffset.Now, ProfileOrder = new[] { "me" }, + Groups = new[] + { + new APIUserGroup { Colour = "#EB47D0", ShortName = "DEV", Name = "Developers" }, + new APIUserGroup { Colour = "#A347EB", ShortName = "BN", Name = "Beatmap Nominators", Playmodes = new[] { "osu", "taiko" } } + }, Statistics = new UserStatistics { IsRanked = true, diff --git a/osu.Game/Online/API/Requests/Responses/APIUser.cs b/osu.Game/Online/API/Requests/Responses/APIUser.cs index 9cb0c0704d..0e62b03f1a 100644 --- a/osu.Game/Online/API/Requests/Responses/APIUser.cs +++ b/osu.Game/Online/API/Requests/Responses/APIUser.cs @@ -255,6 +255,9 @@ namespace osu.Game.Online.API.Requests.Responses [CanBeNull] public Dictionary RulesetsStatistics { get; set; } + [JsonProperty("groups")] + public APIUserGroup[] Groups; + public override string ToString() => Username; /// diff --git a/osu.Game/Online/API/Requests/Responses/APIUserGroup.cs b/osu.Game/Online/API/Requests/Responses/APIUserGroup.cs new file mode 100644 index 0000000000..5f943e583e --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIUserGroup.cs @@ -0,0 +1,37 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Newtonsoft.Json; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIUserGroup + { + [JsonProperty(@"colour")] + public string Colour { get; set; } = null!; + + [JsonProperty(@"has_listing")] + public bool HasListings { get; set; } + + [JsonProperty(@"has_playmodes")] + public bool HasPlaymodes { get; set; } + + [JsonProperty(@"id")] + public int Id { get; set; } + + [JsonProperty(@"identifier")] + public string Identifier { get; set; } = null!; + + [JsonProperty(@"is_probationary")] + public bool IsProbationary { get; set; } + + [JsonProperty(@"name")] + public string Name { get; set; } = null!; + + [JsonProperty(@"short_name")] + public string ShortName { get; set; } = null!; + + [JsonProperty(@"playmodes")] + public string[]? Playmodes { get; set; } + } +} diff --git a/osu.Game/Overlays/Profile/Header/Components/GroupInfoContainer.cs b/osu.Game/Overlays/Profile/Header/Components/GroupInfoContainer.cs new file mode 100644 index 0000000000..363a74b5c1 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/Components/GroupInfoContainer.cs @@ -0,0 +1,106 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Rulesets; +using osuTK; + +namespace osu.Game.Overlays.Profile.Header.Components +{ + public partial class GroupBadge : Container, IHasTooltip + { + public LocalisableString TooltipText { get; } + + public int TextSize { get; set; } = 12; + + private readonly APIUserGroup group; + + public GroupBadge(APIUserGroup group) + { + this.group = group; + + AutoSizeAxes = Axes.Both; + Masking = true; + CornerRadius = 8; + + TooltipText = group.Name; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider? colourProvider, RulesetStore rulesets) + { + FillFlowContainer innerContainer; + + AddRangeInternal(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider?.Background6 ?? Colour4.Black + }, + innerContainer = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Padding = new MarginPadding { Vertical = 2, Horizontal = 10 }, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5), + Children = new[] + { + new OsuSpriteText + { + Text = group.ShortName, + Colour = Color4Extensions.FromHex(group.Colour), + Shadow = false, + Font = OsuFont.GetFont(size: TextSize, weight: FontWeight.Bold, italics: true) + } + } + } + }); + + if (group.Playmodes?.Length > 0) + { + innerContainer.AddRange(group.Playmodes.Select(p => + (rulesets.GetRuleset(p)?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle }).With(icon => + { + icon.Size = new Vector2(TextSize - 1); + })).ToList() + ); + } + } + } + + public partial class GroupInfoContainer : FillFlowContainer + { + public readonly Bindable User = new Bindable(); + + public GroupInfoContainer() + { + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Horizontal; + Spacing = new Vector2(2); + + User.BindValueChanged(val => + { + if (val.NewValue?.Groups?.Length > 0) + { + Clear(true); + Children = val.NewValue?.Groups.Select(g => new GroupBadge(g)).ToList(); + } + }); + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index a6501f567f..c26efaf271 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -40,6 +40,7 @@ namespace osu.Game.Overlays.Profile.Header private UpdateableFlag userFlag = null!; private OsuSpriteText userCountryText = null!; private FillFlowContainer userStats = null!; + private GroupInfoContainer groupInfoContainer = null!; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -90,6 +91,7 @@ namespace osu.Game.Overlays.Profile.Header { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, + Spacing = new Vector2(5), Children = new Drawable[] { usernameText = new OsuSpriteText @@ -98,10 +100,14 @@ namespace osu.Game.Overlays.Profile.Header }, openUserExternally = new ExternalLinkButton { - Margin = new MarginPadding { Left = 5 }, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, }, + groupInfoContainer = new GroupInfoContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + } } }, titleText = new OsuSpriteText @@ -184,6 +190,7 @@ namespace osu.Game.Overlays.Profile.Header supporterTag.SupportLevel = user?.SupportLevel ?? 0; titleText.Text = user?.Title ?? string.Empty; titleText.Colour = Color4Extensions.FromHex(user?.Colour ?? "fff"); + groupInfoContainer.User.Value = user; userStats.Clear(); From b710f86d7559d6b469797f39d3267f3f2139bcef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jan 2023 16:15:28 +0900 Subject: [PATCH 1421/2991] Refactor to use tuples and de-duplicate request code --- osu.Game/Overlays/BeatmapSetOverlay.cs | 55 ++++++-------------------- 1 file changed, 13 insertions(+), 42 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index e905308066..7b9b43f368 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -36,8 +36,7 @@ namespace osu.Game.Overlays private IBindable apiUser; - private int? lastRequestedBeatmapId; - private BeatmapSetLookupType? lastBeatmapSetLookupType; + private (BeatmapSetLookupType type, int id)? lastLookup; /// /// Isolates the beatmap set overlay from the game-wide selected mods bindable @@ -88,7 +87,7 @@ namespace osu.Game.Overlays apiUser.BindValueChanged(_ => Schedule(() => { if (api.IsLoggedIn) - fetchAndSetLastRequestedBeatmap(); + performFetch(); })); } @@ -104,25 +103,20 @@ namespace osu.Game.Overlays public void FetchAndShowBeatmap(int beatmapId) { - lastRequestedBeatmapId = beatmapId; - lastBeatmapSetLookupType = BeatmapSetLookupType.BeatmapId; - + lastLookup = (BeatmapSetLookupType.BeatmapId, beatmapId); beatmapSet.Value = null; - fetchAndSetBeatmap(beatmapId); - + performFetch(); Show(); } public void FetchAndShowBeatmapSet(int beatmapSetId) { - lastRequestedBeatmapId = beatmapSetId; - lastBeatmapSetLookupType = BeatmapSetLookupType.SetId; + lastLookup = (BeatmapSetLookupType.SetId, beatmapSetId); beatmapSet.Value = null; - fetchAndSetBeatmapSet(beatmapSetId); - + performFetch(); Show(); } @@ -136,47 +130,24 @@ namespace osu.Game.Overlays Show(); } - private void fetchAndSetBeatmap(int beatmapId) + private void performFetch() { if (!api.IsLoggedIn) return; - var req = new GetBeatmapSetRequest(beatmapId, BeatmapSetLookupType.BeatmapId); + if (lastLookup == null) + return; + + var req = new GetBeatmapSetRequest(lastLookup.Value.id, BeatmapSetLookupType.BeatmapId); req.Success += res => { beatmapSet.Value = res; - Header.HeaderContent.Picker.Beatmap.Value = Header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineID == beatmapId); + if (lastLookup.Value.type == BeatmapSetLookupType.BeatmapId) + Header.HeaderContent.Picker.Beatmap.Value = Header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineID == lastLookup.Value.id); }; API.Queue(req); } - private void fetchAndSetBeatmapSet(int beatmapSetId) - { - if (!api.IsLoggedIn) - return; - - var req = new GetBeatmapSetRequest(beatmapSetId); - req.Success += res => beatmapSet.Value = res; - API.Queue(req); - } - - private void fetchAndSetLastRequestedBeatmap() - { - if (lastRequestedBeatmapId == null) - return; - - switch (lastBeatmapSetLookupType) - { - case BeatmapSetLookupType.SetId: - fetchAndSetBeatmapSet(lastRequestedBeatmapId.Value); - break; - - case BeatmapSetLookupType.BeatmapId: - fetchAndSetBeatmap(lastRequestedBeatmapId.Value); - break; - } - } - private partial class CommentsSection : BeatmapSetLayoutSection { public readonly Bindable BeatmapSet = new Bindable(); From e0d58d51b61296e3a1b5b0783d8d3bce9838b234 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jan 2023 16:47:29 +0900 Subject: [PATCH 1422/2991] Split out classes into own files and rename `GroupInfoContainer` to a flow --- .../{GroupInfoContainer.cs => GroupBadge.cs} | 26 ++------------- .../Header/Components/GroupBadgeFlow.cs | 33 +++++++++++++++++++ .../Profile/Header/TopHeaderContainer.cs | 6 ++-- 3 files changed, 38 insertions(+), 27 deletions(-) rename osu.Game/Overlays/Profile/Header/Components/{GroupInfoContainer.cs => GroupBadge.cs} (74%) create mode 100644 osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs diff --git a/osu.Game/Overlays/Profile/Header/Components/GroupInfoContainer.cs b/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs similarity index 74% rename from osu.Game/Overlays/Profile/Header/Components/GroupInfoContainer.cs rename to osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs index 363a74b5c1..b469fbbcd1 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GroupInfoContainer.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs @@ -1,9 +1,8 @@ -// 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.Linq; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -74,7 +73,7 @@ namespace osu.Game.Overlays.Profile.Header.Components if (group.Playmodes?.Length > 0) { innerContainer.AddRange(group.Playmodes.Select(p => - (rulesets.GetRuleset(p)?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle }).With(icon => + (rulesets.GetRuleset((string)p)?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle }).With(icon => { icon.Size = new Vector2(TextSize - 1); })).ToList() @@ -82,25 +81,4 @@ namespace osu.Game.Overlays.Profile.Header.Components } } } - - public partial class GroupInfoContainer : FillFlowContainer - { - public readonly Bindable User = new Bindable(); - - public GroupInfoContainer() - { - AutoSizeAxes = Axes.Both; - Direction = FillDirection.Horizontal; - Spacing = new Vector2(2); - - User.BindValueChanged(val => - { - if (val.NewValue?.Groups?.Length > 0) - { - Clear(true); - Children = val.NewValue?.Groups.Select(g => new GroupBadge(g)).ToList(); - } - }); - } - } } diff --git a/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs b/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs new file mode 100644 index 0000000000..062cba2581 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs @@ -0,0 +1,33 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Online.API.Requests.Responses; +using osuTK; + +namespace osu.Game.Overlays.Profile.Header.Components +{ + public partial class GroupBadgeFlow : FillFlowContainer + { + public readonly Bindable User = new Bindable(); + + public GroupBadgeFlow() + { + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Horizontal; + Spacing = new Vector2(2); + + User.BindValueChanged(val => + { + if (val.NewValue?.Groups?.Length > 0) + { + Clear(true); + Children = val.NewValue?.Groups.Select(g => new GroupBadge(g)).ToList(); + } + }); + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index c26efaf271..d6f2faf5e5 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -40,7 +40,7 @@ namespace osu.Game.Overlays.Profile.Header private UpdateableFlag userFlag = null!; private OsuSpriteText userCountryText = null!; private FillFlowContainer userStats = null!; - private GroupInfoContainer groupInfoContainer = null!; + private GroupBadgeFlow groupBadgeFlow = null!; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -103,7 +103,7 @@ namespace osu.Game.Overlays.Profile.Header Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, }, - groupInfoContainer = new GroupInfoContainer + groupBadgeFlow = new GroupBadgeFlow { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, @@ -190,7 +190,7 @@ namespace osu.Game.Overlays.Profile.Header supporterTag.SupportLevel = user?.SupportLevel ?? 0; titleText.Text = user?.Title ?? string.Empty; titleText.Colour = Color4Extensions.FromHex(user?.Colour ?? "fff"); - groupInfoContainer.User.Value = user; + groupBadgeFlow.User.Value = user; userStats.Clear(); From 318867f486db0895ade53249401de2b697351e08 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jan 2023 16:48:47 +0900 Subject: [PATCH 1423/2991] Fix previous badges potentially not being cleared if new user has no badges --- .../Profile/Header/Components/GroupBadgeFlow.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs b/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs index 062cba2581..8a2c8b4874 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs @@ -20,13 +20,12 @@ namespace osu.Game.Overlays.Profile.Header.Components Direction = FillDirection.Horizontal; Spacing = new Vector2(2); - User.BindValueChanged(val => + User.BindValueChanged(user => { - if (val.NewValue?.Groups?.Length > 0) - { - Clear(true); - Children = val.NewValue?.Groups.Select(g => new GroupBadge(g)).ToList(); - } + Clear(true); + + if (user.NewValue != null) + AddRange(user.NewValue.Groups.Select(g => new GroupBadge(g))); }); } } From b1a13286a34054e7fee38956413b5135a3d73543 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jan 2023 16:50:37 +0900 Subject: [PATCH 1424/2991] Remove some redundancies --- osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs | 2 +- osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index 3c0ea4f590..15c5afe1db 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -59,7 +59,7 @@ namespace osu.Game.Tests.Visual.Online { Id = 2001, Username = "RankedUser", - Groups = new[] { new APIUserGroup() { Colour = "#EB47D0", ShortName = "DEV", Name = "Developers" } }, + Groups = new[] { new APIUserGroup { Colour = "#EB47D0", ShortName = "DEV", Name = "Developers" } }, Statistics = new UserStatistics { IsRanked = true, diff --git a/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs b/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs index b469fbbcd1..ce56768a72 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs @@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Profile.Header.Components if (group.Playmodes?.Length > 0) { innerContainer.AddRange(group.Playmodes.Select(p => - (rulesets.GetRuleset((string)p)?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle }).With(icon => + (rulesets.GetRuleset(p)?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle }).With(icon => { icon.Size = new Vector2(TextSize - 1); })).ToList() From df544100755827e7a3888756ed3b1a0b780b3833 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jan 2023 17:31:26 +0900 Subject: [PATCH 1425/2991] Fix skin fail sound not correctly playing Closes #21719. Tested using skin in issue thread. --- osu.Game/Screens/Play/FailAnimation.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index 24171c25a8..3f21f811c1 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -15,11 +15,13 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Utils; +using osu.Game.Audio; using osu.Game.Audio.Effects; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Skinning; using osuTK; using osuTK.Graphics; @@ -48,7 +50,7 @@ namespace osu.Game.Screens.Play private const float duration = 2500; - private Sample? failSample; + private ISample? failSample; [Resolved] private OsuConfigManager config { get; set; } = null!; @@ -73,10 +75,10 @@ namespace osu.Game.Screens.Play } [BackgroundDependencyLoader] - private void load(AudioManager audio, IBindable beatmap) + private void load(AudioManager audio, ISkinSource skin, IBindable beatmap) { track = beatmap.Value.Track; - failSample = audio.Samples.Get(@"Gameplay/failsound"); + failSample = skin.GetSample(new SampleInfo(@"Gameplay/failsound")); AddRangeInternal(new Drawable[] { From 2dcc61caf59f9980387aacec456923c2b9d94f72 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jan 2023 17:38:08 +0900 Subject: [PATCH 1426/2991] Add extra level of nullabiliy checking because NRT is not present --- osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs b/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs index 8a2c8b4874..33b3de94db 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs @@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { Clear(true); - if (user.NewValue != null) + if (user.NewValue?.Groups != null) AddRange(user.NewValue.Groups.Select(g => new GroupBadge(g))); }); } From 578d16f2bce9f21fa4b5c01ba5ea78e76d31f3cb Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 11 Jan 2023 11:11:31 +0100 Subject: [PATCH 1427/2991] perf: Do not draw sectoins that are less than 1px --- osu.Game/Graphics/UserInterface/SegmentedGraph.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index 65c2146889..9a8fd1c4c5 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -194,7 +194,7 @@ namespace osu.Game.Graphics.UserInterface shader = Source.shader; drawSize = Source.DrawSize; segments.Clear(); - segments.AddRange(Source.segments); + segments.AddRange(Source.segments.Where(s => s.Length * drawSize.X > 1)); } public override void Draw(IRenderer renderer) From 621c75daed39de1713040bb12ece80c31586112d Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Wed, 11 Jan 2023 11:16:24 +0100 Subject: [PATCH 1428/2991] Add updated SkinDeserialisationTest.cs including BPM counter --- .../Archives/modified-default-20221211.osk | Bin 1650 -> 0 bytes .../Archives/modified-default-20230111.osk | Bin 0 -> 1685 bytes osu.Game.Tests/Skins/SkinDeserialisationTest.cs | 4 +++- 3 files changed, 3 insertions(+), 1 deletion(-) delete mode 100644 osu.Game.Tests/Resources/Archives/modified-default-20221211.osk create mode 100644 osu.Game.Tests/Resources/Archives/modified-default-20230111.osk diff --git a/osu.Game.Tests/Resources/Archives/modified-default-20221211.osk b/osu.Game.Tests/Resources/Archives/modified-default-20221211.osk deleted file mode 100644 index 07190db267cfcbf0abf44a5eb95b4e43bb0955d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1650 zcmWIWW@Zs#U|`^2__41$)V#A{#{nQOh#4fpz)+l>nWvYTm-)2cFptSlz_ogQ(hG;C zH@8F=E%uturR8F1usI>|yvx0fVRLj{`=)5Kh%9yb!m&$#@A~!s>-O!N%@*d~<`;ZP z@f71Xtz$_B3H%Yh#!+{Yz0w_&)Nagm{B6aw>S`{J3j_M*Aq3^;H=}T|8F6)dAv(Ab<5aqY1+2Z>O|HRMo z=|^O*rEI>?cH!LLn%^>Fr~Wd|K|=s@#Vyw=@NZF-`xgcUZ^iK^V0J5 zvWoNbO8Yi)9WoGc{a$y}IG8)v!$>ro{pF)YewP#{EU~$@&tcLdg@3!*&fa)i^sco! zPLyHyi>sTI4dk~oU(sB!EOX<=#;UJuvQd{0EIx8BV)=H}QZEhFs+;}Rb47yQmU*3; zxb^2Bku`pHPySnM)8007O90!Ns(J=g zhwp#q^9Xfu&d)8#&r8iKDF*xC?R4Ml#|8pz?|+J_rMsWl zm~))lvSjXE-romjEqlB4%K|N7_mGKQD$Zv&{jYs`jPJ6-FWs`BcD?Mo z>hJ};;YEEHA3v|2DIJqF!&_tRvP0iLeF`i1#=MHVl)XsLTk+Vxd)4cBw&!h&K3He# zS6$HCz>?8rs8+W+%#T;OMgDgE?3d3^T}rEZTcy8FLbM=h!`nO`R$1@#Nx4(kSx<8N zxwi6P_UTOJ7%7AJpUi9clg&dUGWIrYjS*W`c1P;$wwN`hSKQX+yY+7V|8!rHmvj7` zLiXT}c7?hCHmAB{5i2!U|5{{M>HAWy?eL*^CegCp51!pC{W9-^?UU+Ts&-!(7pF|j z4$Uxlru&KS@nn&HcBOq!zI9*o`p;CpM&irNSISRyFYy;l|L6E~!T*?Flb5U8SDOAP zz97A{JjCdP==5tmp;wL=7M1Jv-49HhY?)Sm%r$}4=Va;jyU`1slUx=}XpwEm6nUVb zc%H|jBgu!ObJ62hD?{h+GUW5RfAHr^y#xbW`wc-olOm_69JfB)IpfIX@-4>uroUz? zQ^DtQ)=Hi-THF6kzeb!+_4#F^7J1$uPry5p|;f1 zQSkropj>mUWReY~TlDD8rhZwUB}upTn8nIe8{If2()ak$1dF(o?Juq^sB5Wxb@_m8!|%4ok*}6K zT=BL4fr+ohoJ~S9Uz}eBZ9jZ#L0o%@#wDL=&$irW@K=rA7M6(ANZGIP>R}+Y)!F-u0p5&E zA`H08T3}>BKqH8PmAvS>(915U9tMWSXHZ@6k_=rddg+1CIvnWvYTm-%#pVHcC5fa_;F*O{6x z&iOPeq`A$`-6GxTn0YlLx%}#-;Ij{In%z*YWEC|uF%Uk>b?^D-c-jB|R&(tu=UIDf zMePLLoRFTQ3y$+`n4z|1!$ArD1{a?Vb`52z3?ZLX1r%tg$H=jzfa z7S2h|PKWuo|4Dh+Q}}e>xz3+kGcqg}Fztl?Zxw18LVI4+{A1kKV5c;=7MF3n>IETePff23O=ZN{8+^D>6)fq8mdt@@0rgK z3CcB6{Z=ozI((yE#N3*QyX#CQ)nC~DUQ^ANv((Ao*7E=6=f}?r*U3%f$b2yUPfBjq z3Ffdp_fVaFRMl)UHxmQHD?tVZF`(0Z6EpKXLS3Bma|`nGQu9iR!G3r<{e1py1(DFpBiq9J&s4Mh+D)-^lICapXoQ^Pgx5T2Tpx@#kS)7 zl4r-xZPT_`b3BWG+rvQqpAyNhw!ONyO2y&F#=o0q{_~Z(=CeLl{z&LKFAKvPW#-HF z%v)+aF@NbQ>qTxqS5+L$KJBR-lX*e@2lJZ#Wb-vwE>y85@6afDyTf!=UggfP0O_6k zW}2M)H|4k1bgs5XebqBKfxr~T)e zZ0(N2JESMieBNrNWhlAN;_qz7nRou6rTj*z`V-ZR3=9u|nVcV(e1h}y(t}fTQj<%- z>E>u~Y&J0M*M1LAseR{k>&xjzey!Vb$7Y<#(|_c=w%lxn+EPzP!T-O5a?Q1x4b3GL z`M;}JJ}>fnx2FBVxtx|Y710f)%{nW!YUV#_Se~uMBCKsQtx}PdW9*{uQF#K90v|~&1wXM$+UkS~>U~F7)>v7wKEAi6r zC)pS53%zt~$E~{&VVP|uY#OPlryOG=WxvL&f6>1zG)rHmC9phV5rg%!_0{RmTsFLC z&y%RQcXETw!w*f5KS@T#eQ=TYx! From 42ff8c75fa9bb211f6e1478a49447a3d1f74f558 Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 11 Jan 2023 11:22:18 +0100 Subject: [PATCH 1429/2991] refactor: make class not abstract --- osu.Game/Graphics/UserInterface/SegmentedGraph.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index 9a8fd1c4c5..977594d9b0 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterface { - public abstract partial class SegmentedGraph : Drawable + public partial class SegmentedGraph : Drawable where T : struct, IComparable, IConvertible, IEquatable { private bool graphNeedsUpdate; From a87debab0fae30685a9f22b97867b89e6ba1c2a7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 20:15:20 +0900 Subject: [PATCH 1430/2991] Fix kiai flash opacity on legacy skins being too intense --- osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs b/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs index fd9434e02a..427a0ede4d 100644 --- a/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs +++ b/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs @@ -13,7 +13,7 @@ namespace osu.Game.Skinning { private readonly Drawable flashingDrawable; - private const float flash_opacity = 0.55f; + private const float flash_opacity = 0.3f; public LegacyKiaiFlashingDrawable(Func creationFunc) { From 0d1046ed833c54a245970a88a8c951981368a3d1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 21:25:53 +0900 Subject: [PATCH 1431/2991] Add full colour application to kiai sprites --- .../Skinning/Legacy/LegacyMainCirclePiece.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs index 6547b058c2..989f5a8a7c 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.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.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.ObjectExtensions; @@ -66,17 +67,28 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy // the conditional above handles the case where a sliderendcircle.png is retrieved from the skin, but sliderendcircleoverlay.png doesn't exist. // expected behaviour in this scenario is not showing the overlay, rather than using hitcircleoverlay.png. + Color4 objectColour = drawableOsuObject!.AccentColour.Value; + int add = Math.Max(25, 300 - (int)(objectColour.R * 255) - (int)(objectColour.G * 255) - (int)(objectColour.B * 255)); + + Color4 finalColour = new Color4( + (byte)Math.Min((byte)(objectColour.R * 255) + add, 255), + (byte)Math.Min((byte)(objectColour.G * 255) + add, 255), + (byte)Math.Min((byte)(objectColour.B * 255) + add, 255), + 255); + InternalChildren = new[] { CircleSprite = new LegacyKiaiFlashingDrawable(() => new Sprite { Texture = skin.GetTexture(circleName) }) { Anchor = Anchor.Centre, Origin = Anchor.Centre, + Colour = finalColour, }, OverlayLayer = new Container { Anchor = Anchor.Centre, Origin = Anchor.Centre, + Colour = finalColour, Child = OverlaySprite = new LegacyKiaiFlashingDrawable(() => skin.GetAnimation(@$"{circleName}overlay", true, true, frameLength: 1000 / 2d)) { Anchor = Anchor.Centre, From e9571be4abac6f16569fb034ef8b64bae9e2381b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jan 2023 18:25:24 +0900 Subject: [PATCH 1432/2991] Fix incorrect application layer causing completely discoloured circles --- .../Skinning/Legacy/LegacyMainCirclePiece.cs | 32 ++++++++++--------- .../Skinning/LegacyKiaiFlashingDrawable.cs | 7 ++++ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs index 989f5a8a7c..cadac4d319 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs @@ -30,8 +30,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy private readonly bool hasNumber; - protected Drawable CircleSprite = null!; - protected Drawable OverlaySprite = null!; + protected LegacyKiaiFlashingDrawable CircleSprite = null!; + protected LegacyKiaiFlashingDrawable OverlaySprite = null!; protected Container OverlayLayer { get; private set; } = null!; @@ -66,29 +66,17 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy // at this point, any further texture fetches should be correctly using the priority source if the base texture was retrieved using it. // the conditional above handles the case where a sliderendcircle.png is retrieved from the skin, but sliderendcircleoverlay.png doesn't exist. // expected behaviour in this scenario is not showing the overlay, rather than using hitcircleoverlay.png. - - Color4 objectColour = drawableOsuObject!.AccentColour.Value; - int add = Math.Max(25, 300 - (int)(objectColour.R * 255) - (int)(objectColour.G * 255) - (int)(objectColour.B * 255)); - - Color4 finalColour = new Color4( - (byte)Math.Min((byte)(objectColour.R * 255) + add, 255), - (byte)Math.Min((byte)(objectColour.G * 255) + add, 255), - (byte)Math.Min((byte)(objectColour.B * 255) + add, 255), - 255); - InternalChildren = new[] { CircleSprite = new LegacyKiaiFlashingDrawable(() => new Sprite { Texture = skin.GetTexture(circleName) }) { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Colour = finalColour, }, OverlayLayer = new Container { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Colour = finalColour, Child = OverlaySprite = new LegacyKiaiFlashingDrawable(() => skin.GetAnimation(@$"{circleName}overlay", true, true, frameLength: 1000 / 2d)) { Anchor = Anchor.Centre, @@ -126,7 +114,21 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { base.LoadComplete(); - accentColour.BindValueChanged(colour => CircleSprite.Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue), true); + accentColour.BindValueChanged(colour => + { + Color4 objectColour = colour.NewValue; + int add = Math.Max(25, 300 - (int)(objectColour.R * 255) - (int)(objectColour.G * 255) - (int)(objectColour.B * 255)); + + var kiaiTintColour = new Color4( + (byte)Math.Min((byte)(objectColour.R * 255) + add, 255), + (byte)Math.Min((byte)(objectColour.G * 255) + add, 255), + (byte)Math.Min((byte)(objectColour.B * 255) + add, 255), + 255); + + CircleSprite.Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue); + OverlaySprite.KiaiGlowColour = CircleSprite.KiaiGlowColour = LegacyColourCompatibility.DisallowZeroAlpha(kiaiTintColour); + }, true); + if (hasNumber) indexInCurrentCombo.BindValueChanged(index => hitCircleText.Text = (index.NewValue + 1).ToString(), true); diff --git a/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs b/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs index 427a0ede4d..2f79512ed8 100644 --- a/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs +++ b/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs @@ -6,11 +6,18 @@ using osu.Framework.Audio.Track; using osu.Framework.Graphics; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.Containers; +using osuTK.Graphics; namespace osu.Game.Skinning { public partial class LegacyKiaiFlashingDrawable : BeatSyncedContainer { + public Color4 KiaiGlowColour + { + get => flashingDrawable.Colour; + set => flashingDrawable.Colour = value; + } + private readonly Drawable flashingDrawable; private const float flash_opacity = 0.3f; From d2247f704d2db5ca09cdffb9fe1103fa0f080aa5 Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Wed, 11 Jan 2023 11:26:26 +0000 Subject: [PATCH 1433/2991] Fixed DrumTouchInputArea test crashing --- osu.Game.Rulesets.Taiko.Tests/TestSceneDrumTouchInputArea.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumTouchInputArea.cs index 6514b760bb..ee780204a2 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumTouchInputArea.cs @@ -45,5 +45,7 @@ namespace osu.Game.Rulesets.Taiko.Tests { AddStep("show drum", () => drumTouchInputArea.Show()); } + + protected override Ruleset CreateRuleset() => new TaikoRuleset(); } } From 32d1d5a34a874e9c868bcf414ae1478c9e6b58bc Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Wed, 11 Jan 2023 12:04:52 +0000 Subject: [PATCH 1434/2991] Added tests for new Taiko touch control schemes --- .../TestSceneDrumTouchInputArea.cs | 44 ++++++++++--------- .../UI/DrumTouchInputArea.cs | 6 ++- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumTouchInputArea.cs index ee780204a2..6b02b0078a 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumTouchInputArea.cs @@ -3,7 +3,7 @@ using NUnit.Framework; using osu.Framework.Graphics; -using osu.Framework.Testing; +using osu.Game.Rulesets.Taiko.Configuration; using osu.Game.Rulesets.Taiko.UI; using osu.Game.Tests.Visual; @@ -14,35 +14,37 @@ namespace osu.Game.Rulesets.Taiko.Tests { private DrumTouchInputArea drumTouchInputArea = null!; - [SetUpSteps] - public void SetUpSteps() + private void createDrum(TaikoTouchControlScheme _forcedControlScheme) { - AddStep("create drum", () => + Child = new TaikoInputManager(new TaikoRuleset().RulesetInfo) { - Child = new TaikoInputManager(new TaikoRuleset().RulesetInfo) - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new InputDrum { - new InputDrum - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Height = 0.2f, - }, - drumTouchInputArea = new DrumTouchInputArea - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - }, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Height = 0.2f, }, - }; - }); + drumTouchInputArea = new DrumTouchInputArea + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + ForceControlScheme = _forcedControlScheme + } + } + }; } [Test] public void TestDrum() { + AddStep("create drum (kddk)", () => createDrum(TaikoTouchControlScheme.KDDK)); + AddStep("show drum", () => drumTouchInputArea.Show()); + AddStep("create drum (ddkk)", () => createDrum(TaikoTouchControlScheme.DDKK)); + AddStep("show drum", () => drumTouchInputArea.Show()); + AddStep("create drum (kkdd)", () => createDrum(TaikoTouchControlScheme.KKDD)); AddStep("show drum", () => drumTouchInputArea.Show()); } diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index b7a0d46d51..8208aaba39 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -24,6 +24,7 @@ namespace osu.Game.Rulesets.Taiko.UI /// public partial class DrumTouchInputArea : VisibilityContainer { + public TaikoTouchControlScheme? ForceControlScheme { get; set; } // visibility state affects our child. we always want to handle input. public override bool PropagatePositionalInputSubTree => true; public override bool PropagateNonPositionalInputSubTree => true; @@ -55,7 +56,10 @@ namespace osu.Game.Rulesets.Taiko.UI const float centre_region = 0.80f; - config.BindWith(TaikoRulesetSetting.TouchControlScheme, configTouchControlScheme); + if (ForceControlScheme == null) + config.BindWith(TaikoRulesetSetting.TouchControlScheme, configTouchControlScheme); + else + configTouchControlScheme.Value = (TaikoTouchControlScheme)ForceControlScheme; Children = new Drawable[] { From e128b9ee5cb75e9522493d09866d92bb653632dc Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 11 Jan 2023 14:02:18 +0100 Subject: [PATCH 1435/2991] fix(SegmentedGraph): make ctor public --- osu.Game/Graphics/UserInterface/SegmentedGraph.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index 977594d9b0..2a63d53870 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -26,7 +26,7 @@ namespace osu.Game.Graphics.UserInterface private readonly int tierCount; - protected SegmentedGraph(int tierCount) + public SegmentedGraph(int tierCount) { this.tierCount = tierCount; TierColours = new Colour4[tierCount]; From 6249322a32bf6b3314a2d69add184eb131269fed Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 11 Jan 2023 14:03:36 +0100 Subject: [PATCH 1436/2991] fix(SegmentedGraph): solve issue for negatives values --- osu.Game/Graphics/UserInterface/SegmentedGraph.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index 2a63d53870..f8c5c08bbf 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -86,7 +86,7 @@ namespace osu.Game.Graphics.UserInterface if (min < 0) { for (int i = 0; i < floatValues.Length; i++) - floatValues[i] += min; + floatValues[i] += Math.Abs(min); } // Normalize values From 845cdb3097ce2781c2575f0c8277900852fcccf5 Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 11 Jan 2023 14:03:49 +0100 Subject: [PATCH 1437/2991] test: add visual tests for SegmentedGraph class --- .../UserInterface/TestSceneSegmentedGraph.cs | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs new file mode 100644 index 0000000000..ab7078d1b7 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs @@ -0,0 +1,96 @@ +// 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.Graphics; +using osu.Game.Graphics.UserInterface; +using osuTK; +using Vector4 = System.Numerics.Vector4; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public partial class TestSceneSegmentedGraph : OsuTestScene + { + private readonly SegmentedGraph graph; + + public TestSceneSegmentedGraph() + { + Children = new Drawable[] + { + graph = new SegmentedGraph(10) + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(1, 0.5f), + }, + }; + + for (int i = 0; i < graph.TierColours.Length; i++) + { + graph.TierColours[i] = + new Colour4(Vector4.Lerp(Colour4.Blue.Vector, Colour4.White.Vector, i * 1f / (graph.TierColours.Length - 1))); + } + + AddStep("values from 1-10", () => graph.Values = Enumerable.Range(1, 10).ToArray()); + AddStep("values from 1-100", () => graph.Values = Enumerable.Range(1, 100).ToArray()); + AddStep("values from 1-500", () => graph.Values = Enumerable.Range(1, 500).ToArray()); + AddStep("sin() function of size 100", () => sinFunction()); + AddStep("sin() function of size 500", () => sinFunction(500)); + AddStep("bumps of size 100", () => bumps()); + AddStep("bumps of size 500", () => bumps(500)); + AddStep("100 random values", () => randomValues()); + AddStep("500 random values", () => randomValues(500)); + AddStep("reversed values from 1-10", () => graph.Values = Enumerable.Range(1, 10).Reverse().ToArray()); + } + + private void sinFunction(int size = 100) + { + const int max_value = 255; + int[] values = new int[size]; + + float step = 2 * MathF.PI / size; + float x = 0; + + for (int i = 0; i < size; i++) + { + values[i] = (int)(max_value * MathF.Sin(x)); + x += step; + } + + graph.Values = values; + } + + private void bumps(int size = 100) + { + const int max_value = 255; + int[] values = new int[size]; + + float step = 2 * MathF.PI / size; + float x = 0; + + for (int i = 0; i < size; i++) + { + values[i] = (int)(max_value * Math.Abs(MathF.Sin(x))); + x += step; + } + + graph.Values = values; + } + + private void randomValues(int size = 100) + { + Random rng = new Random(); + + int[] values = new int[size]; + + for (int i = 0; i < size; i++) + { + values[i] = rng.Next(255); + } + + graph.Values = values; + } + } +} From 442b2238b8cdf0f04d0054cb12c73571b51cba59 Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 11 Jan 2023 14:37:57 +0100 Subject: [PATCH 1438/2991] test(SegmentedGraph): add concrete application test with beatmap density --- .../UserInterface/TestSceneSegmentedGraph.cs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs index ab7078d1b7..f8df0528d6 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs @@ -2,9 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using osu.Framework.Graphics; using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Osu; using osuTK; using Vector4 = System.Numerics.Vector4; @@ -42,6 +46,8 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("bumps of size 500", () => bumps(500)); AddStep("100 random values", () => randomValues()); AddStep("500 random values", () => randomValues(500)); + AddStep("beatmap density with granularity of 200", () => beatmapDensity()); + AddStep("beatmap density with granularity of 300", () => beatmapDensity(300)); AddStep("reversed values from 1-10", () => graph.Values = Enumerable.Range(1, 10).Reverse().ToArray()); } @@ -92,5 +98,40 @@ namespace osu.Game.Tests.Visual.UserInterface graph.Values = values; } + + private void beatmapDensity(int granularity = 200) + { + var ruleset = new OsuRuleset(); + var beatmap = CreateBeatmap(ruleset.RulesetInfo); + IEnumerable objects = beatmap.HitObjects; + + // Taken from SongProgressGraph + int[] values = new int[granularity]; + + if (!objects.Any()) + return; + + double firstHit = objects.First().StartTime; + double lastHit = objects.Max(o => o.GetEndTime()); + + if (lastHit == 0) + lastHit = objects.Last().StartTime; + + double interval = (lastHit - firstHit + 1) / granularity; + + foreach (var h in objects) + { + double endTime = h.GetEndTime(); + + Debug.Assert(endTime >= h.StartTime); + + int startRange = (int)((h.StartTime - firstHit) / interval); + int endRange = (int)((endTime - firstHit) / interval); + for (int i = startRange; i <= endRange; i++) + values[i]++; + } + + graph.Values = values; + } } } From ca84b885dcc6695cb7da3549757f7e6338bc37de Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Wed, 11 Jan 2023 17:51:41 +0100 Subject: [PATCH 1439/2991] Add more detail to bubbles --- osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs | 58 ++++++++++++++++----- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs index 2e4d574148..f5e7e035b2 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs @@ -12,6 +12,7 @@ using osu.Framework.Graphics.Performance; using osu.Framework.Graphics.Pooling; using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; +using osu.Game.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Pooling; @@ -21,6 +22,7 @@ using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Scoring; using osuTK; +using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Mods { @@ -178,21 +180,38 @@ namespace osu.Game.Rulesets.Osu.Mods } } - private partial class BubbleDrawable : CompositeDrawable + private partial class BubbleDrawable : CompositeDrawable, IHasAccentColour { + public Color4 AccentColour { get; set; } + + private Circle outerCircle = null!; + private Circle innerCircle = null!; + [BackgroundDependencyLoader] private void load() { - InternalChild = new Circle + InternalChildren = new Drawable[] { - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Masking = true, - EdgeEffect = new EdgeEffectParameters + outerCircle = new Circle { - Colour = Colour4.Black.Opacity(0.05f), - Type = EdgeEffectType.Shadow, - Radius = 5 + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Masking = true, + MaskingSmoothness = 2, + BorderThickness = 0, + BorderColour = Colour4.Transparent, + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Radius = 3, + Colour = Colour4.Black.Opacity(0.05f) + } + }, + innerCircle = new Circle + { + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Scale = new Vector2(0.5f) } }; } @@ -202,12 +221,25 @@ namespace osu.Game.Rulesets.Osu.Mods Size = entry.InitialSize; this .ScaleTo(entry.MaxSize, entry.FadeTime * 6, Easing.OutSine) - .FadeColour(entry.IsHit ? entry.Colour : Colour4.Black, entry.FadeTime, Easing.OutSine) - .Delay(entry.FadeTime) - .FadeColour(entry.IsHit ? entry.Colour.Darken(.4f) : Colour4.Black, entry.FadeTime * 5, Easing.OutSine) .Then() .ScaleTo(entry.MaxSize * 1.5f, entry.FadeTime, Easing.OutSine) - .FadeTo(0, entry.FadeTime, Easing.OutQuint); + .FadeTo(0, entry.FadeTime, Easing.OutExpo); + + animateCircles(entry); + } + + private void animateCircles(BubbleLifeTimeEntry entry) + { + innerCircle.FadeColour(entry.IsHit ? entry.Colour.Darken(0.2f) : Colour4.Black) + .FadeColour(entry.IsHit ? entry.Colour.Lighten(0.2f) : Colour4.Black, entry.FadeTime * 7); + + innerCircle.FadeTo(0.5f, entry.FadeTime * 7, Easing.InExpo) + .ScaleTo(1.1f, entry.FadeTime * 7, Easing.InSine); + + outerCircle + .FadeColour(entry.IsHit ? entry.Colour : Colour4.Black, entry.FadeTime, Easing.OutSine) + .Delay(entry.FadeTime) + .FadeColour(entry.IsHit ? entry.Colour.Darken(.4f) : Colour4.Black, entry.FadeTime * 5, Easing.OutSine); } } From 1f129d4e163132c6355eb0c397c64d5bfacd8052 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 11 Jan 2023 21:20:56 +0300 Subject: [PATCH 1440/2991] Add failing test --- .../TestScenePlacementBeforeTrackStart.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 osu.Game.Rulesets.Mania.Tests/Editor/TestScenePlacementBeforeTrackStart.cs diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/TestScenePlacementBeforeTrackStart.cs b/osu.Game.Rulesets.Mania.Tests/Editor/TestScenePlacementBeforeTrackStart.cs new file mode 100644 index 0000000000..00dd75ceee --- /dev/null +++ b/osu.Game.Rulesets.Mania.Tests/Editor/TestScenePlacementBeforeTrackStart.cs @@ -0,0 +1,30 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using NUnit.Framework; +using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; +using osu.Game.Tests.Visual; +using osuTK.Input; + +namespace osu.Game.Rulesets.Mania.Tests.Editor +{ + public partial class TestScenePlacementBeforeTrackStart : EditorTestScene + { + protected override Ruleset CreateEditorRuleset() => new ManiaRuleset(); + + [Test] + public void TestPlacement() + { + AddStep("Seek to 0", () => EditorClock.Seek(0)); + AddStep("Select note", () => InputManager.Key(Key.Number2)); + AddStep("Hover negative span", () => + { + InputManager.MoveMouseTo(this.ChildrenOfType().First(x => x.Name == "Icons").Children[0]); + }); + AddStep("Click", () => InputManager.Click(MouseButton.Left)); + AddAssert("No notes placed", () => EditorBeatmap.HitObjects.All(x => x.StartTime >= 0)); + } + } +} From 6c52b8339b5cacbb960f43bc74b0cc187104109f Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 11 Jan 2023 22:02:06 +0300 Subject: [PATCH 1441/2991] Fix game-level components finishing load after content --- osu.Game/OsuGame.cs | 4 +-- osu.Game/OsuGameBase.cs | 54 +++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index dc4d56de11..4113c9be8f 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -933,9 +933,9 @@ namespace osu.Game loadComponentSingleFile(dashboard = new DashboardOverlay(), overlayContent.Add, true); loadComponentSingleFile(news = new NewsOverlay(), overlayContent.Add, true); var rankingsOverlay = loadComponentSingleFile(new RankingsOverlay(), overlayContent.Add, true); - loadComponentSingleFile(channelManager = new ChannelManager(API), AddInternal, true); + loadComponentSingleFile(channelManager = new ChannelManager(API), Add, true); loadComponentSingleFile(chatOverlay = new ChatOverlay(), overlayContent.Add, true); - loadComponentSingleFile(new MessageNotifier(), AddInternal, true); + loadComponentSingleFile(new MessageNotifier(), Add, true); loadComponentSingleFile(Settings = new SettingsOverlay(), leftFloatingOverlayContent.Add, true); loadComponentSingleFile(changelogOverlay = new ChangelogOverlay(), overlayContent.Add, true); loadComponentSingleFile(userProfile = new UserProfileOverlay(), overlayContent.Add, true); diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 36e248c1f2..c78a527514 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -206,7 +206,7 @@ namespace osu.Game /// private readonly FramedBeatmapClock beatmapClock = new FramedBeatmapClock(true); - protected override Container Content => content; + protected override Container Content => content ?? base.Content; private Container content; @@ -296,7 +296,7 @@ namespace osu.Game dependencies.Cache(ScoreDownloader = new ScoreModelDownloader(ScoreManager, API)); // Add after all the above cache operations as it depends on them. - AddInternal(difficultyCache); + Add(difficultyCache); // TODO: OsuGame or OsuGameBase? dependencies.CacheAs(beatmapUpdater = new BeatmapUpdater(BeatmapManager, difficultyCache, API, Storage)); @@ -305,19 +305,19 @@ namespace osu.Game dependencies.CacheAs(metadataClient = new OnlineMetadataClient(endpoints)); dependencies.CacheAs(soloStatisticsWatcher = new SoloStatisticsWatcher()); - AddInternal(new BeatmapOnlineChangeIngest(beatmapUpdater, realm, metadataClient)); + Add(new BeatmapOnlineChangeIngest(beatmapUpdater, realm, metadataClient)); BeatmapManager.ProcessBeatmap = args => beatmapUpdater.Process(args.beatmapSet, !args.isBatch); dependencies.Cache(userCache = new UserLookupCache()); - AddInternal(userCache); + Add(userCache); dependencies.Cache(beatmapCache = new BeatmapLookupCache()); - AddInternal(beatmapCache); + Add(beatmapCache); var scorePerformanceManager = new ScorePerformanceCache(); dependencies.Cache(scorePerformanceManager); - AddInternal(scorePerformanceManager); + Add(scorePerformanceManager); dependencies.CacheAs(rulesetConfigCache = new RulesetConfigCache(realm, RulesetStore)); @@ -344,27 +344,34 @@ namespace osu.Game // add api components to hierarchy. if (API is APIAccess apiAccess) - AddInternal(apiAccess); + Add(apiAccess); - AddInternal(spectatorClient); - AddInternal(MultiplayerClient); - AddInternal(metadataClient); - AddInternal(soloStatisticsWatcher); + Add(spectatorClient); + Add(MultiplayerClient); + Add(metadataClient); + Add(soloStatisticsWatcher); - AddInternal(rulesetConfigCache); + Add(rulesetConfigCache); + + PreviewTrackManager previewTrackManager; + dependencies.Cache(previewTrackManager = new PreviewTrackManager(BeatmapManager.BeatmapTrackStore)); + Add(previewTrackManager); + + Add(MusicController = new MusicController()); + dependencies.CacheAs(MusicController); + + MusicController.TrackChanged += onTrackChanged; + Add(beatmapClock); GlobalActionContainer globalBindings; - base.Content.Add(SafeAreaContainer = new SafeAreaContainer + Add(SafeAreaContainer = new SafeAreaContainer { SafeAreaOverrideEdges = SafeAreaOverrideEdges, RelativeSizeAxes = Axes.Both, Child = CreateScalingContainer().WithChildren(new Drawable[] { (GlobalCursorDisplay = new GlobalCursorDisplay - { - RelativeSizeAxes = Axes.Both - }).WithChild(content = new OsuTooltipContainer(GlobalCursorDisplay.MenuCursor) { RelativeSizeAxes = Axes.Both }), @@ -373,21 +380,16 @@ namespace osu.Game }) }); + GlobalCursorDisplay.Child = content = new OsuTooltipContainer(GlobalCursorDisplay.MenuCursor) + { + RelativeSizeAxes = Axes.Both + }; + KeyBindingStore = new RealmKeyBindingStore(realm, keyCombinationProvider); KeyBindingStore.Register(globalBindings, RulesetStore.AvailableRulesets); dependencies.Cache(globalBindings); - PreviewTrackManager previewTrackManager; - dependencies.Cache(previewTrackManager = new PreviewTrackManager(BeatmapManager.BeatmapTrackStore)); - Add(previewTrackManager); - - AddInternal(MusicController = new MusicController()); - dependencies.CacheAs(MusicController); - - MusicController.TrackChanged += onTrackChanged; - AddInternal(beatmapClock); - Ruleset.BindValueChanged(onRulesetChanged); Beatmap.BindValueChanged(onBeatmapChanged); } From 1f4e0303f733265aa574d21d648d1ec1e3a5fa41 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Wed, 11 Jan 2023 14:13:29 -0500 Subject: [PATCH 1442/2991] add mania FadeIn mod configuration --- osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs | 10 +++++++--- osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs | 1 - osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs | 2 ++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs index 800973ede5..196514c7b1 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs @@ -20,8 +20,12 @@ namespace osu.Game.Rulesets.Mania.Mods protected override CoverExpandDirection ExpandDirection => CoverExpandDirection.AlongScroll; - // This could be customisable like ManiaModHidden in the future if there's any demand. - // At that point, the bindable could be moved to `ManiaModPlayfieldCover`. - public override BindableNumber Coverage { get; } = new BindableFloat(0.5f); + public override BindableNumber Coverage { get; } = new BindableFloat(0.5f) + { + Precision = 0.1f, + MinValue = 0.1f, + MaxValue = 0.7f, + Default = 0.5f, + }; } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs index 50d40249c1..8f0d5a770e 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs @@ -15,7 +15,6 @@ namespace osu.Game.Rulesets.Mania.Mods public override LocalisableString Description => @"Keys fade out before you hit them!"; public override double ScoreMultiplier => 1; - [SettingSource("Coverage", "The proportion of playfield height that notes will be hidden for.")] public override BindableNumber Coverage { get; } = new BindableFloat(0.5f) { Precision = 0.1f, diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs index 45d0184d1d..09abe8d7f4 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs @@ -6,6 +6,7 @@ using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Configuration; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Mods; @@ -23,6 +24,7 @@ namespace osu.Game.Rulesets.Mania.Mods /// protected abstract CoverExpandDirection ExpandDirection { get; } + [SettingSource("Coverage", "The proportion of playfield height that notes will be hidden for.")] public abstract BindableNumber Coverage { get; } public virtual void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) From 4fce7f03bd48c2dbe091949a6c60fa4814d5b7a9 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Wed, 11 Jan 2023 14:14:17 -0500 Subject: [PATCH 1443/2991] add mania mod fadein test --- .../Mods/TestSceneManiaModFadeIn.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModFadeIn.cs diff --git a/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModFadeIn.cs b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModFadeIn.cs new file mode 100644 index 0000000000..2c8c151e7f --- /dev/null +++ b/osu.Game.Rulesets.Mania.Tests/Mods/TestSceneManiaModFadeIn.cs @@ -0,0 +1,19 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Rulesets.Mania.Mods; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Mania.Tests.Mods +{ + public partial class TestSceneManiaModFadeIn : ModTestScene + { + protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset(); + + [TestCase(0.5f)] + [TestCase(0.1f)] + [TestCase(0.7f)] + public void TestCoverage(float coverage) => CreateModTest(new ModTestData { Mod = new ManiaModFadeIn { Coverage = { Value = coverage } }, PassCondition = () => true }); + } +} From e23c565c8418a31bd5746eb36f112983702f876c Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Wed, 11 Jan 2023 14:28:11 -0500 Subject: [PATCH 1444/2991] code quality --- osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs index 8f0d5a770e..f23cb335a5 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs @@ -4,7 +4,6 @@ using System; using System.Linq; using osu.Framework.Localisation; -using osu.Game.Configuration; using osu.Game.Rulesets.Mania.UI; using osu.Framework.Bindables; From a0ff03def3b5ab3defc691b3715c931e5cf9c099 Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Wed, 11 Jan 2023 20:06:43 +0000 Subject: [PATCH 1445/2991] Fixed some formatting --- osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 8208aaba39..681ddb65ad 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -114,20 +114,24 @@ namespace osu.Game.Rulesets.Taiko.UI }; } - private readonly TaikoAction[,] mappedTaikoAction = { - { // KDDK + private readonly TaikoAction[,] mappedTaikoAction = + { + { + // KDDK TaikoAction.LeftRim, TaikoAction.LeftCentre, TaikoAction.RightCentre, TaikoAction.RightRim }, - { // DDKK + { + // DDKK TaikoAction.LeftCentre, TaikoAction.RightCentre, TaikoAction.LeftRim, TaikoAction.RightRim }, - { // KKDD + { + // KKDD TaikoAction.LeftRim, TaikoAction.RightRim, TaikoAction.LeftCentre, From 624e90b213f4e328add5723206555fd1b56e0374 Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 11 Jan 2023 21:32:12 +0100 Subject: [PATCH 1446/2991] style: nitpicks --- .../Graphics/UserInterface/SegmentedGraph.cs | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index f8c5c08bbf..d0356e6327 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -136,7 +136,7 @@ namespace osu.Game.Graphics.UserInterface segments.Sort(); } - private Colour4 tierToColour(int tier) => tier >= 0 ? TierColours[tier] : new Colour4(0, 0, 0, 0); + private Colour4 getTierColour(int tier) => tier >= 0 ? TierColours[tier] : new Colour4(0, 0, 0, 0); protected override DrawNode CreateDrawNode() => new SegmentedGraphDrawNode(this); @@ -217,7 +217,7 @@ namespace osu.Game.Graphics.UserInterface Vector2Extensions.Transform(topRight, DrawInfo.Matrix), Vector2Extensions.Transform(bottomLeft, DrawInfo.Matrix), Vector2Extensions.Transform(bottomRight, DrawInfo.Matrix)), - Source.tierToColour(segment.Tier)); + Source.getTierColour(segment.Tier)); } shader.Unbind(); @@ -263,12 +263,12 @@ namespace osu.Game.Graphics.UserInterface { foreach (SegmentInfo? pendingSegment in pendingSegments) { - if (pendingSegment != null) - { - SegmentInfo finalizedSegment = pendingSegment.Value; - finalizedSegment.End = 1; - segments.Add(finalizedSegment); - } + if (pendingSegment == null) + continue; + + SegmentInfo finalizedSegment = pendingSegment.Value; + finalizedSegment.End = 1; + segments.Add(finalizedSegment); } } @@ -305,13 +305,7 @@ namespace osu.Game.Graphics.UserInterface Add(segment); } - public bool IsTierStarted(int tier) - { - if (tier < 0) - return false; - - return pendingSegments[tier].HasValue; - } + public bool IsTierStarted(int tier) => tier >= 0 && pendingSegments[tier].HasValue; public IEnumerator GetEnumerator() => segments.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); From 026a223129658b44528ea5dffad105b0699f80ea Mon Sep 17 00:00:00 2001 From: OpenSauce <48618519+OpenSauce04@users.noreply.github.com> Date: Wed, 11 Jan 2023 20:39:45 +0000 Subject: [PATCH 1447/2991] Cleaner way of getting ForceControlScheme value Co-authored-by: Susko3 --- osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 681ddb65ad..a8bad36381 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -59,7 +59,7 @@ namespace osu.Game.Rulesets.Taiko.UI if (ForceControlScheme == null) config.BindWith(TaikoRulesetSetting.TouchControlScheme, configTouchControlScheme); else - configTouchControlScheme.Value = (TaikoTouchControlScheme)ForceControlScheme; + configTouchControlScheme.Value = ForceControlScheme.Value; Children = new Drawable[] { From f80112187ec81ad83410ee419ee75ac4ce6b4e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 11 Jan 2023 23:27:20 +0100 Subject: [PATCH 1448/2991] Rewrite contributing guidelines - Includes changes to process discussed in development meeting today. - Describes issue vs discussion axis which wasn't present at the time the document was originally created. - Reduces amount of unnecessary text in hopes that the document will actually be read in full. --- CONTRIBUTING.md | 156 ++++++++++++++++-------------------------------- 1 file changed, 53 insertions(+), 103 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c72a3b442e..9f7d88f5c7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,137 +2,87 @@ Thank you for showing interest in the development of osu!. We aim to provide a good collaborating environment for everyone involved, and as such have decided to list some of the most important things to keep in mind in the process. The guidelines below have been chosen based on past experience. -These are not "official rules" *per se*, but following them will help everyone deal with things in the most efficient manner. - ## Table of contents -1. [I would like to submit an issue!](#i-would-like-to-submit-an-issue) -2. [I would like to submit a pull request!](#i-would-like-to-submit-a-pull-request) +1. [Reporting bugs](#reporting-bugs) +2. [Providing general feedback](#providing-general-feedback) +3. [Issue or discussion?](#issue-or-discussion) +4. [Submitting pull requests](#submitting-pull-requests) +5. [Resources](#resources) -## I would like to submit an issue! +## Reporting bugs -Issues, bug reports and feature suggestions are welcomed, though please keep in mind that at any point in time, hundreds of issues are open, which vary in severity and the amount of time needed to address them. As such it's not uncommon for issues to remain unresolved for a long time or even closed outright if they are deemed not important enough to fix in the foreseeable future. Issues that are required to "go live" or otherwise achieve parity with stable are prioritised the most. +A **bug** is a situation in which there is something clearly *and objectively* wrong with the game. Examples of applicable bug reports are: -* **Before submitting an issue, try searching existing issues first.** +- The game crashes to desktop when I start a beatmap +- Friends appear twice in the friend listing +- The game slows down a lot when I play this specific map +- A piece of text is overlapping another piece of text on the screen - For housekeeping purposes, we close issues that overlap with or duplicate other pre-existing issues - you can help us not to have to do that by searching existing issues yourself first. The issue search box, as well as the issue tag system, are tools you can use to check if an issue has been reported before. +To track bug reports, we primarily use GitHub **issues**. When opening an issue, please keep in mind the following: -* **When submitting a bug report, please try to include as much detail as possible.** +- Before opening the issue, please search for any similar existing issues using the text search bar and the issue labels. This includes both open and closed issues (we may have already fixed something, but the fix hasn't yet been released). +- When opening the issue, please fill out as much of the issue template as you can. In particular, please make sure to include logs and screenshots as much as possible. The instructions on how to find the log files are included in the issue template. +- We may ask you for follow-up information to reproduce or debug the problem. Please look out for this and provide follow-up info if we request it. - Bugs are not equal - some of them will be reproducible every time on pretty much all hardware, while others will be hard to track down due to being specific to particular hardware or even somewhat random in nature. As such, providing as much detail as possible when reporting a bug is hugely appreciated. A good starting set of information consists of: +If we cannot reproduce the issue, it is deemed low priority, or it is deemed to be specific to your setup in some way, the issue may be downgraded to a discussion. This will be done by a maintainer for you. - * the in-game logs, which are located at: - * `%AppData%/osu/logs` (on Windows), - * `~/.local/share/osu/logs` (on Linux), - * `~/Library/Application Support/osu/logs` (on macOS), - * `Android/data/sh.ppy.osulazer/files/logs` (on Android), - * on iOS they can be obtained by connecting your device to your desktop and [copying the `logs` directory from the app's own document storage using iTunes](https://support.apple.com/en-us/HT201301#copy-to-computer), - * your system specifications (including the operating system and platform you are playing on), - * a reproduction scenario (list of steps you have performed leading up to the occurrence of the bug), - * a video or picture of the bug, if at all possible. +## Providing general feedback -* **Provide more information when asked to do so.** +If you wish to: - Sometimes when a bug is more elusive or complicated, none of the information listed above will pinpoint a concrete cause of the problem. In this case we will most likely ask you for additional info, such as a Windows Event Log dump or a copy of your local osu! database (`client.db`). Providing that information is beneficial to both parties - we can track down the problem better, and hopefully fix it for you at some point once we know where it is! +- provide *subjective* feedback on the game (about how the UI looks, about how the default skin works, about game mechanics, about how the PP and scoring systems work, etc.), +- suggest a new feature to be added to the game, +- report a non-specific problem with the game that you think may be connected to your hardware or operating system specifically, -* **When submitting a feature proposal, please describe it in the most understandable way you can.** +then it is generally best to start with a **discussion** first. Discussions are a good avenue to group subjective feedback on a single topic, or gauge interest in a particular feature request. - Communicating your idea for a feature can often be hard, and we would like to avoid any misunderstandings. As such, please try to explain your idea in a short, but understandable manner - it's best to avoid jargon or terms and references that could be considered obscure. A mock-up picture (doesn't have to be good!) of the feature can also go a long way in explaining. +When opening a discussion, please keep in mind the following: -* **Refrain from posting "+1" comments.** +- Use the search function to see if your idea has been proposed before, or if there is already a thread about a particular issue you wish to raise. +- If proposing a feature, please try to explain the feature in as much detail as possible. +- If you're reporting a non-specific problem, please provide applicable logs, screenshots, or video that illustrate the issue. - If an issue has already been created, saying that you also experience it without providing any additional details doesn't really help us in any way. To express support for a proposal or indicate that you are also affected by a particular bug, you can use comment reactions instead. +If a discussion gathers enough traction, then it may be converted into an issue. This will be done by a maintainer for you. -* **Refrain from asking if an issue has been resolved yet.** +## Issue or discussion? - As mentioned above, the issue tracker has hundreds of issues open at any given time. Currently the game is being worked on by two members of the core team, and a handful of outside contributors who offer their free time to help out. As such, it can happen that an issue gets placed on the backburner due to being less important; generally posting a comment demanding its resolution some months or years after it is reported is not very likely to increase its priority. +We realise that the line between an issue and a discussion may be fuzzy, so while we ask you to use your best judgement based on the description above, please don't think about it too hard either. Feedback in a slightly wrong place is better than no feedback at all. -* **Avoid long discussions about non-development topics.** +When in doubt, it's probably best to start with a discussion first. We will escalate to issues as needed. - GitHub is mostly a developer space, and as such isn't really fit for lengthened discussions about gameplay mechanics (which might not even be in any way confirmed for the final release) and similar non-technical matters. Such matters are probably best addressed at the osu! forums. +## Submitting pull requests -## I would like to submit a pull request! +While pull requests from unaffiliated contributors are welcome, please note that due to significant community interest and limited review throughput, the core team's primary focus is on the issues which are currently [on the roadmap](https://github.com/orgs/ppy/projects/7/views/6). Reviewing PRs that fall outside of the scope of the roadmap is done on a best-effort basis, so please be aware that it may take a while before a core maintainer gets around to review your change. -We also welcome pull requests from unaffiliated contributors. The [issue tracker](https://github.com/ppy/osu/issues) should provide plenty of issues that you can work on; we also mark issues that we think would be good for newcomers with the [`good-first-issue`](https://github.com/ppy/osu/issues?q=is%3Aissue+is%3Aopen+label%3Agood-first-issue) label. +The [issue tracker](https://github.com/ppy/osu/issues) should provide plenty of issues to start with. We also have a [`good-first-issue`](https://github.com/ppy/osu/issues?q=is%3Aissue+is%3Aopen+label%3Agood-first-issue) label, although from experience it is not used very often, as it is relatively rare that we can spot an issue that will definitively be a good first issue for a new contributor regardless of their programming experience. -However, do keep in mind that the core team is committed to bringing osu!(lazer) up to par with osu!(stable) first and foremost, so depending on what your contribution concerns, it might not be merged and released right away. Our approach to managing issues and their priorities is described [in the wiki](https://github.com/ppy/osu/wiki/Project-management). +In the case of simple issues, a direct PR is okay. However, if you decide to work on an existing issue which doesn't seem trivial, **please ask us first**. This way we can try to estimate if it is a good fit for you and provide the correct direction on how to address it. In addition, note that while we do not rule out external contributors from working on roadmapped issues, we will generally prefer to handle them ourselves unless they're not very time sensitive. -Here are some key things to note before jumping in: +If you'd like to propose a subjective change to one of the visual aspects of the game, or there is a bigger task you'd like to work on, but there is no corresponding issue or discussion thread yet for it, **please open a discussion or issue first** to avoid wasted effort. This in particular applies if you want to work on [one of the available designs from the osu! public Figma library](https://www.figma.com/file/6m10GiGEncVFWmgOoSyakH/osu!-Figma-Library). -* **Make sure you are comfortable with C\# and your development environment.** +Aside from the above, below is a brief checklist of things to watch out when you're preparing your code changes: - While we are accepting of all kinds of contributions, we also have a certain quality standard we'd like to uphold and limited time to review your code. Therefore, we would like to avoid providing entry-level advice, and as such if you're not very familiar with C\# as a programming language, we'd recommend that you start off with a few personal projects to get acquainted with the language's syntax, toolchain and principles of object-oriented programming first. +- Make sure you're comfortable with the principles of object-oriented programming, the syntax of C\# and your development environment. +- Make sure you are familiar with [git](https://git-scm.com/) and [the pull request workflow](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/proposing-changes-to-your-work-with-pull-requests). +- Please do not make code changes via the GitHub web interface. +- Please add tests for your changes. We expect most new features and bugfixes to have test coverage, unless the effort of adding them is prohibitive. The visual testing methodology we use is described in more detail [here](https://github.com/ppy/osu-framework/wiki/Development-and-Testing). +- Please run tests and code style analysis (via `InspectCode.{ps1,sh}` scripts in the root of this repository) before opening the PR. This is particularly important if you're a first-time contributor, as CI will not run for your PR until we allow it to do so. - In addition, please take the time to take a look at and get acquainted with the [development and testing](https://github.com/ppy/osu-framework/wiki/Development-and-Testing) procedure we have set up. +After you're done with your changes and you wish to open the PR, please observe the following recommendations: -* **Make sure you are familiar with git and the pull request workflow.** +- Please submit the pull request from a [topic branch](https://git-scm.com/book/en/v2/Git-Branching-Branching-Workflows#_topic_branch) (not `master`), and keep the *Allow edits from maintainers* check box selected, so that we can push fixes to your PR if necessary. +- Please avoid pushing untested or incomplete code. +- Please do not force-push or rebase unless we ask you to. +- Please do not merge `master` continually if there are no conflicts to resolve. We will do this for you when the change is ready for merge. - [git](https://git-scm.com/) is a distributed version control system that might not be very intuitive at the beginning if you're not familiar with version control. In particular, projects using git have a particular workflow for submitting code changes, which is called the pull request workflow. +We are highly committed to quality when it comes to the osu! project. This means that contributions from less experienced community members can take multiple rounds of review to get to a mergeable state. We try our utmost best to never conflate a person with the code they authored, and to keep the discussion focused on the code at all times. Please consider our comments and requests a learning experience. - To make things run more smoothly, we recommend that you look up some online resources to familiarise yourself with the git vocabulary and commands, and practice working with forks and submitting pull requests at your own pace. A high-level overview of the process can be found in [this article by GitHub](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/proposing-changes-to-your-work-with-pull-requests). +If you're uncertain about some part of the codebase or some inner workings of the game and framework, please reach out either by leaving a comment in the relevant issue, discussion, or PR thread, or by posting a message in the [development Discord server](https://discord.gg/ppy). We will try to help you as much as we can. -* **Double-check designs before starting work on new functionality.** +## Resources - When implementing new features, keep in mind that we already have a lot of the UI designed. If you wish to work on something with the intention of having it included in the official distribution, please open an issue for discussion and we will give you what you need from a design perspective to proceed. If you want to make *changes* to the design, we recommend you open an issue with your intentions before spending too much time to ensure no effort is wasted. - -* **Make sure to submit pull requests off of a topic branch.** - - As described in the article linked in the previous point, topic branches help you parallelise your work and separate it from the main `master` branch, and additionally are easier for maintainers to work with. Working with multiple `master` branches across many remotes is difficult to keep track of, and it's easy to make a mistake and push to the wrong `master` branch by accident. - -* **Refrain from making changes through the GitHub web interface.** - - Even though GitHub provides an option to edit code or replace files in the repository using the web interface, we strongly discourage using it in most scenarios. Editing files this way is inefficient and likely to introduce whitespace or file encoding changes that make it more difficult to review the code. - - Code written through the web interface will also very likely be questioned outright by the reviewers, as it is likely that it has not been properly tested or that it will fail continuous integration checks. We strongly encourage using an IDE like [Visual Studio](https://visualstudio.microsoft.com/), [Visual Studio Code](https://code.visualstudio.com/) or [JetBrains Rider](https://www.jetbrains.com/rider/) instead. - -* **Add tests for your code whenever possible.** - - Automated tests are an essential part of a quality and reliable codebase. They help to make the code more maintainable by ensuring it is safe to reorganise (or refactor) the code in various ways, and also prevent regressions - bugs that resurface after having been fixed at some point in the past. If it is viable, please put in the time to add tests, so that the changes you make can last for a (hopefully) very long time. - -* **Run tests before opening a pull request.** - - Tying into the previous point, sometimes changes in one part of the codebase can result in unpredictable changes in behaviour in other pieces of the code. This is why it is best to always try to run tests before opening a PR. - - Continuous integration will always run the tests for you (and us), too, but it is best not to rely on it, as there might be many builds queued at any time. Running tests on your own will help you be more certain that at the point of clicking the "Create pull request" button, your changes are as ready as can be. - -* **Run code style analysis before opening a pull request.** - - As part of continuous integration, we also run code style analysis, which is supposed to make sure that your code is formatted the same way as all the pre-existing code in the repository. The reason we enforce a particular code style everywhere is to make sure the codebase is consistent in that regard - having one whitespace convention in one place and another one elsewhere causes disorganisation. - -* **Make sure that the pull request is complete before opening it.** - - Whether it's fixing a bug or implementing new functionality, it's best that you make sure that the change you want to submit as a pull request is as complete as it can be before clicking the *Create pull request* button. Having to track if a pull request is ready for review or not places additional burden on reviewers. - - Draft pull requests are an option, but use them sparingly and within reason. They are best suited to discuss code changes that cannot be easily described in natural language or have a potential large impact on the future direction of the project. When in doubt, don't open drafts unless a maintainer asks you to do so. - -* **Only push code when it's ready.** - - As an extension of the above, when making changes to an already-open PR, please try to only push changes you are reasonably certain of. Pushing after every commit causes the continuous integration build queue to grow in size, slowing down work and taking up time that could be spent verifying other changes. - -* **Make sure to keep the *Allow edits from maintainers* check box checked.** - - To speed up the merging process, collaborators and team members will sometimes want to push changes to your branch themselves, to make minor code style adjustments or to otherwise refactor the code without having to describe how they'd like the code to look like in painstaking detail. Having the *Allow edits from maintainers* check box checked lets them do that; without it they are forced to report issues back to you and wait for you to address them. - -* **Refrain from continually merging the master branch back to the PR.** - - Unless there are merge conflicts that need resolution, there is no need to keep merging `master` back to a branch over and over again. One of the maintainers will merge `master` themselves before merging the PR itself anyway, and continual merge commits can cause CI to get overwhelmed due to queueing up too many builds. - -* **Refrain from force-pushing to the PR branch.** - - Force-pushing should be avoided, as it can lead to accidentally overwriting a maintainer's changes or CI building wrong commits. We value all history in the project, so there is no need to squash or amend commits in most cases. - - The cases in which force-pushing is warranted are very rare (such as accidentally leaking sensitive info in one of the files committed, adding unrelated files, or mis-merging a dependent PR). - -* **Be patient when waiting for the code to be reviewed and merged.** - - As much as we'd like to review all contributions as fast as possible, our time is limited, as team members have to work on their own tasks in addition to reviewing code. As such, work needs to be prioritised, and it can unfortunately take weeks or months for your PR to be merged, depending on how important it is deemed to be. - -* **Don't mistake criticism of code for criticism of your person.** - - As mentioned before, we are highly committed to quality when it comes to the osu! project. This means that contributions from less experienced community members can take multiple rounds of review to get to a mergeable state. We try our utmost best to never conflate a person with the code they authored, and to keep the discussion focused on the code at all times. Please consider our comments and requests a learning experience, and don't treat it as a personal attack. - -* **Feel free to reach out for help.** - - If you're uncertain about some part of the codebase or some inner workings of the game and framework, please reach out either by leaving a comment in the relevant issue or PR thread, or by posting a message in the [development Discord server](https://discord.gg/ppy). We will try to help you as much as we can. - - When it comes to which form of communication is best, GitHub generally lends better to longer-form discussions, while Discord is better for snappy call-and-response answers. Use your best discretion when deciding, and try to keep a single discussion in one place instead of moving back and forth. +- [Development roadmap](https://github.com/orgs/ppy/projects/7/views/6): What the core team is currently working on +- [`ppy/osu-framework` wiki](https://github.com/ppy/osu-framework/wiki): Contains introductory information about osu!framework, the bespoke 2D game framework we use for the game +- [`ppy/osu` wiki](https://github.com/ppy/osu/wiki): Contains articles about various technical aspects of the game +- [Public Figma library](https://www.figma.com/file/6m10GiGEncVFWmgOoSyakH/osu!-Figma-Library): Contains finished and draft designs for osu! From 03ac2fd7d74b446f62328648c83e857d7aef1cd9 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 12 Jan 2023 03:33:20 +0300 Subject: [PATCH 1449/2991] More tests --- .../Editing/TestSceneSnappingNearZero.cs | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 osu.Game.Tests/Editing/TestSceneSnappingNearZero.cs diff --git a/osu.Game.Tests/Editing/TestSceneSnappingNearZero.cs b/osu.Game.Tests/Editing/TestSceneSnappingNearZero.cs new file mode 100644 index 0000000000..59081215ba --- /dev/null +++ b/osu.Game.Tests/Editing/TestSceneSnappingNearZero.cs @@ -0,0 +1,79 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Beatmaps.ControlPoints; + +namespace osu.Game.Tests.Editing +{ + [TestFixture] + public class TestSceneSnappingNearZero + { + private readonly ControlPointInfo cpi = new ControlPointInfo(); + + [Test] + public void TestOnZero() + { + test(0, 500, 0, 0); + test(0, 500, 100, 0); + test(0, 500, 250, 500); + test(0, 500, 600, 500); + + test(0, 500, -600, 0); + } + + [Test] + public void TestAlmostOnZero() + { + test(50, 500, 0, 50); + test(50, 500, 50, 50); + test(50, 500, 100, 50); + test(50, 500, 299, 50); + test(50, 500, 300, 550); + + test(50, 500, -500, 50); + } + + [Test] + public void TestAlmostOnOne() + { + test(499, 500, -1, 499); + test(499, 500, 0, 499); + test(499, 500, 1, 499); + test(499, 500, 499, 499); + test(499, 500, 600, 499); + test(499, 500, 800, 999); + } + + [Test] + public void TestOnOne() + { + test(500, 500, -500, 0); + test(500, 500, 0, 0); + test(500, 500, 200, 0); + test(500, 500, 400, 500); + test(500, 500, 500, 500); + test(500, 500, 600, 500); + test(500, 500, 900, 1000); + } + + [Test] + public void TestNegative() + { + test(-600, 500, -600, 400); + test(-600, 500, -100, 400); + test(-600, 500, 0, 400); + test(-600, 500, 200, 400); + test(-600, 500, 400, 400); + test(-600, 500, 600, 400); + test(-600, 500, 1000, 900); + } + + private void test(double pointTime, double beatLength, double from, double expected) + { + cpi.Clear(); + cpi.Add(pointTime, new TimingControlPoint { BeatLength = beatLength }); + Assert.That(cpi.GetClosestSnappedTime(from, 1), Is.EqualTo(expected), $"From: {from}"); + } + } +} From 51e21ee6f00962c396a1987ab248c236e1865f96 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 12 Jan 2023 03:38:57 +0300 Subject: [PATCH 1450/2991] Make snapped time always positive --- osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs index 29b7191ecf..1a15db98e4 100644 --- a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs +++ b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs @@ -183,9 +183,15 @@ namespace osu.Game.Beatmaps.ControlPoints private static double getClosestSnappedTime(TimingControlPoint timingPoint, double time, int beatDivisor) { double beatLength = timingPoint.BeatLength / beatDivisor; - int beatLengths = (int)Math.Round((time - timingPoint.Time) / beatLength, MidpointRounding.AwayFromZero); + double beats = (Math.Max(time, 0) - timingPoint.Time) / beatLength; - return timingPoint.Time + beatLengths * beatLength; + int roundedBeats = (int)Math.Round(beats, MidpointRounding.AwayFromZero); + double snappedTime = timingPoint.Time + roundedBeats * beatLength; + + if (snappedTime >= 0) + return snappedTime; + + return snappedTime + beatLength; } /// From e8029e63908fff723cdabe43152ca534a1ed3f5e Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 12 Jan 2023 03:39:27 +0300 Subject: [PATCH 1451/2991] Fix unrelated tests --- osu.Game.Tests/NonVisual/ClosestBeatDivisorTest.cs | 8 ++++---- osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/NonVisual/ClosestBeatDivisorTest.cs b/osu.Game.Tests/NonVisual/ClosestBeatDivisorTest.cs index 6f3fe875e3..8ebf34b1ca 100644 --- a/osu.Game.Tests/NonVisual/ClosestBeatDivisorTest.cs +++ b/osu.Game.Tests/NonVisual/ClosestBeatDivisorTest.cs @@ -17,7 +17,7 @@ namespace osu.Game.Tests.NonVisual public void TestExactDivisors() { var cpi = new ControlPointInfo(); - cpi.Add(-1000, new TimingControlPoint { BeatLength = 1000 }); + cpi.Add(0, new TimingControlPoint { BeatLength = 1000 }); double[] divisors = { 3, 1, 16, 12, 8, 6, 4, 3, 2, 1 }; @@ -47,7 +47,7 @@ namespace osu.Game.Tests.NonVisual public void TestExactDivisorsHighBPMStream() { var cpi = new ControlPointInfo(); - cpi.Add(-50, new TimingControlPoint { BeatLength = 50 }); // 1200 BPM 1/4 (limit testing) + cpi.Add(0, new TimingControlPoint { BeatLength = 50 }); // 1200 BPM 1/4 (limit testing) // A 1/4 stream should land on 1/1, 1/2 and 1/4 divisors. double[] divisors = { 4, 4, 4, 4, 4, 4, 4, 4 }; @@ -60,7 +60,7 @@ namespace osu.Game.Tests.NonVisual public void TestApproximateDivisors() { var cpi = new ControlPointInfo(); - cpi.Add(-1000, new TimingControlPoint { BeatLength = 1000 }); + cpi.Add(0, new TimingControlPoint { BeatLength = 1000 }); double[] divisors = { 3.03d, 0.97d, 14, 13, 7.94d, 6.08d, 3.93d, 2.96d, 2.02d, 64 }; double[] closestDivisors = { 3, 1, 16, 12, 8, 6, 4, 3, 2, 1 }; @@ -68,7 +68,7 @@ namespace osu.Game.Tests.NonVisual assertClosestDivisors(divisors, closestDivisors, cpi); } - private void assertClosestDivisors(IReadOnlyList divisors, IReadOnlyList closestDivisors, ControlPointInfo cpi, double step = 1) + private static void assertClosestDivisors(IReadOnlyList divisors, IReadOnlyList closestDivisors, ControlPointInfo cpi, double step = 1) { List hitobjects = new List(); double offset = cpi.TimingPoints[0].Time; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs index 70118e0b67..b396b382ff 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs @@ -144,7 +144,7 @@ namespace osu.Game.Tests.Visual.Editing double lastStarRating = 0; double lastLength = 0; - AddStep("Add timing point", () => EditorBeatmap.ControlPointInfo.Add(500, new TimingControlPoint())); + AddStep("Add timing point", () => EditorBeatmap.ControlPointInfo.Add(200, new TimingControlPoint { BeatLength = 600 })); AddStep("Change to placement mode", () => InputManager.Key(Key.Number2)); AddStep("Move to playfield", () => InputManager.MoveMouseTo(Game.ScreenSpaceDrawQuad.Centre)); AddStep("Place single hitcircle", () => InputManager.Click(MouseButton.Left)); From 5694487a7bfbdee738a464daa4b5ae6a9b380577 Mon Sep 17 00:00:00 2001 From: tsrk Date: Thu, 12 Jan 2023 02:36:35 +0100 Subject: [PATCH 1452/2991] fix(SegmentedGraph): update `graphNeedsUpdate` variable during `Update()` loop --- .../UserInterface/TestSceneSegmentedGraph.cs | 24 +++++++------------ .../Graphics/UserInterface/SegmentedGraph.cs | 9 +++++-- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs index f8df0528d6..a3426b36b4 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs @@ -54,49 +54,43 @@ namespace osu.Game.Tests.Visual.UserInterface private void sinFunction(int size = 100) { const int max_value = 255; - int[] values = new int[size]; + graph.Values = new int[size]; float step = 2 * MathF.PI / size; float x = 0; for (int i = 0; i < size; i++) { - values[i] = (int)(max_value * MathF.Sin(x)); + graph.Values[i] = (int)(max_value * MathF.Sin(x)); x += step; } - - graph.Values = values; } private void bumps(int size = 100) { const int max_value = 255; - int[] values = new int[size]; + graph.Values = new int[size]; float step = 2 * MathF.PI / size; float x = 0; for (int i = 0; i < size; i++) { - values[i] = (int)(max_value * Math.Abs(MathF.Sin(x))); + graph.Values[i] = (int)(max_value * Math.Abs(MathF.Sin(x))); x += step; } - - graph.Values = values; } private void randomValues(int size = 100) { Random rng = new Random(); - int[] values = new int[size]; + graph.Values = new int[size]; for (int i = 0; i < size; i++) { - values[i] = rng.Next(255); + graph.Values[i] = rng.Next(255); } - - graph.Values = values; } private void beatmapDensity(int granularity = 200) @@ -106,7 +100,7 @@ namespace osu.Game.Tests.Visual.UserInterface IEnumerable objects = beatmap.HitObjects; // Taken from SongProgressGraph - int[] values = new int[granularity]; + graph.Values = new int[granularity]; if (!objects.Any()) return; @@ -128,10 +122,8 @@ namespace osu.Game.Tests.Visual.UserInterface int startRange = (int)((h.StartTime - firstHit) / interval); int endRange = (int)((endTime - firstHit) / interval); for (int i = startRange; i <= endRange; i++) - values[i]++; + graph.Values[i]++; } - - graph.Values = values; } } } diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index d0356e6327..af457edc11 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -41,9 +41,7 @@ namespace osu.Game.Graphics.UserInterface if (value == values) return; values = value; - recalculateTiers(values); graphNeedsUpdate = true; - Invalidate(Invalidation.DrawNode); } } @@ -65,8 +63,10 @@ namespace osu.Game.Graphics.UserInterface if (graphNeedsUpdate) { + recalculateTiers(values); recalculateSegments(); Invalidate(Invalidation.DrawNode); + graphNeedsUpdate = false; } } @@ -170,6 +170,11 @@ namespace osu.Game.Graphics.UserInterface /// The value is a normalized float (from 0 to 1). /// public float Length => End - Start; + + public override string ToString() + { + return $"({Tier}, {Start * 100}%, {End * 100}%)"; + } } private class SegmentedGraphDrawNode : DrawNode From f8fade79677657b8cb75886170a311fe87ccf624 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Wed, 11 Jan 2023 19:04:55 -0800 Subject: [PATCH 1453/2991] Add failing beatmap set lookup type test --- .../Online/TestSceneBeatmapSetOverlay.cs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 7d978b9726..5d13421195 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -14,6 +14,8 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Testing; using osu.Game.Beatmaps.Drawables; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.BeatmapSet.Scores; using osu.Game.Resources.Localisation.Web; @@ -241,6 +243,44 @@ namespace osu.Game.Tests.Visual.Online AddStep(@"show without reload", overlay.Show); } + [TestCase(BeatmapSetLookupType.BeatmapId)] + [TestCase(BeatmapSetLookupType.SetId)] + public void TestFetchLookupType(BeatmapSetLookupType lookupType) + { + string type = string.Empty; + + AddStep("register request handling", () => + { + ((DummyAPIAccess)API).HandleRequest = req => + { + switch (req) + { + case GetBeatmapSetRequest getBeatmapSet: + type = getBeatmapSet.Type.ToString(); + return true; + } + + return false; + }; + }); + + AddStep(@"fetch", () => + { + switch (lookupType) + { + case BeatmapSetLookupType.BeatmapId: + overlay.FetchAndShowBeatmap(55); + break; + + case BeatmapSetLookupType.SetId: + overlay.FetchAndShowBeatmapSet(55); + break; + } + }); + + AddAssert(@"type is correct", () => type == lookupType.ToString()); + } + private APIBeatmapSet createManyDifficultiesBeatmapSet() { var set = getBeatmapSet(); From 2076f9fd087463da325eebeb39de9d84c0a5bfbf Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Wed, 11 Jan 2023 19:06:51 -0800 Subject: [PATCH 1454/2991] Fix lookup type being incorrect when fetching beatmap set --- osu.Game/Overlays/BeatmapSetOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 7b9b43f368..237ce22767 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -138,7 +138,7 @@ namespace osu.Game.Overlays if (lastLookup == null) return; - var req = new GetBeatmapSetRequest(lastLookup.Value.id, BeatmapSetLookupType.BeatmapId); + var req = new GetBeatmapSetRequest(lastLookup.Value.id, lastLookup.Value.type); req.Success += res => { beatmapSet.Value = res; From 425d1350e266aee4221898ab52a7e272d6840a8e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Jan 2023 12:31:25 +0900 Subject: [PATCH 1455/2991] Update README slightly to work better with new document --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 0de82eba75..f3f025fa10 100644 --- a/README.md +++ b/README.md @@ -101,9 +101,7 @@ JetBrains ReSharper InspectCode is also used for wider rule sets. You can run it ## Contributing -When it comes to contributing to the project, the two main things you can do to help out are reporting issues and submitting pull requests. Based on past experiences, we have prepared a [list of contributing guidelines](CONTRIBUTING.md) that should hopefully ease you into our collaboration process and answer the most frequently-asked questions. - -Note that while we already have certain standards in place, nothing is set in stone. If you have an issue with the way code is structured, with any libraries we are using, or with any processes involved with contributing, *please* bring it up. We welcome all feedback so we can make contributing to this project as painless as possible. +When it comes to contributing to the project, the two main things you can do to help out are reporting issues and submitting pull requests. Please refer to the [contributing guidelines](CONTRIBUTING.md) to understand how to help in the most effective way possible. If you wish to help with localisation efforts, head over to [crowdin](https://crowdin.com/project/osu-web). From bbec42c00ee377535a4879f0ccbf28c2983f0b65 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Thu, 12 Jan 2023 14:18:21 +0900 Subject: [PATCH 1456/2991] Fix incorrect max combo after watching imported legacy replays --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 13276a8748..ff0d91c0dd 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -423,6 +423,8 @@ namespace osu.Game.Rulesets.Scoring score.Accuracy = Accuracy.Value; score.Rank = Rank.Value; score.HitEvents = hitEvents; + score.Statistics.Clear(); + score.MaximumStatistics.Clear(); foreach (var result in HitResultExtensions.ALL_TYPES) score.Statistics[result] = scoreResultCounts.GetValueOrDefault(result); From 0548ca2aa8edbcdf2eddd62bda7fe153b4899f1d Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Jan 2023 09:48:38 +0300 Subject: [PATCH 1457/2991] Avoid changing target content midway through code --- osu.Game/OsuGameBase.cs | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index c78a527514..33d33fe181 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -206,7 +206,7 @@ namespace osu.Game /// private readonly FramedBeatmapClock beatmapClock = new FramedBeatmapClock(true); - protected override Container Content => content ?? base.Content; + protected override Container Content => content; private Container content; @@ -296,7 +296,7 @@ namespace osu.Game dependencies.Cache(ScoreDownloader = new ScoreModelDownloader(ScoreManager, API)); // Add after all the above cache operations as it depends on them. - Add(difficultyCache); + base.Content.Add(difficultyCache); // TODO: OsuGame or OsuGameBase? dependencies.CacheAs(beatmapUpdater = new BeatmapUpdater(BeatmapManager, difficultyCache, API, Storage)); @@ -305,19 +305,19 @@ namespace osu.Game dependencies.CacheAs(metadataClient = new OnlineMetadataClient(endpoints)); dependencies.CacheAs(soloStatisticsWatcher = new SoloStatisticsWatcher()); - Add(new BeatmapOnlineChangeIngest(beatmapUpdater, realm, metadataClient)); + base.Content.Add(new BeatmapOnlineChangeIngest(beatmapUpdater, realm, metadataClient)); BeatmapManager.ProcessBeatmap = args => beatmapUpdater.Process(args.beatmapSet, !args.isBatch); dependencies.Cache(userCache = new UserLookupCache()); - Add(userCache); + base.Content.Add(userCache); dependencies.Cache(beatmapCache = new BeatmapLookupCache()); - Add(beatmapCache); + base.Content.Add(beatmapCache); var scorePerformanceManager = new ScorePerformanceCache(); dependencies.Cache(scorePerformanceManager); - Add(scorePerformanceManager); + base.Content.Add(scorePerformanceManager); dependencies.CacheAs(rulesetConfigCache = new RulesetConfigCache(realm, RulesetStore)); @@ -344,34 +344,37 @@ namespace osu.Game // add api components to hierarchy. if (API is APIAccess apiAccess) - Add(apiAccess); + base.Content.Add(apiAccess); - Add(spectatorClient); - Add(MultiplayerClient); - Add(metadataClient); - Add(soloStatisticsWatcher); + base.Content.Add(spectatorClient); + base.Content.Add(MultiplayerClient); + base.Content.Add(metadataClient); + base.Content.Add(soloStatisticsWatcher); - Add(rulesetConfigCache); + base.Content.Add(rulesetConfigCache); PreviewTrackManager previewTrackManager; dependencies.Cache(previewTrackManager = new PreviewTrackManager(BeatmapManager.BeatmapTrackStore)); - Add(previewTrackManager); + base.Content.Add(previewTrackManager); - Add(MusicController = new MusicController()); + base.Content.Add(MusicController = new MusicController()); dependencies.CacheAs(MusicController); MusicController.TrackChanged += onTrackChanged; - Add(beatmapClock); + base.Content.Add(beatmapClock); GlobalActionContainer globalBindings; - Add(SafeAreaContainer = new SafeAreaContainer + base.Content.Add(SafeAreaContainer = new SafeAreaContainer { SafeAreaOverrideEdges = SafeAreaOverrideEdges, RelativeSizeAxes = Axes.Both, Child = CreateScalingContainer().WithChildren(new Drawable[] { (GlobalCursorDisplay = new GlobalCursorDisplay + { + RelativeSizeAxes = Axes.Both + }).WithChild(content = new OsuTooltipContainer(GlobalCursorDisplay.MenuCursor) { RelativeSizeAxes = Axes.Both }), @@ -380,11 +383,6 @@ namespace osu.Game }) }); - GlobalCursorDisplay.Child = content = new OsuTooltipContainer(GlobalCursorDisplay.MenuCursor) - { - RelativeSizeAxes = Axes.Both - }; - KeyBindingStore = new RealmKeyBindingStore(realm, keyCombinationProvider); KeyBindingStore.Register(globalBindings, RulesetStore.AvailableRulesets); From 7cbc03dce6703b863d2c0349fe7454c247f36e5c Mon Sep 17 00:00:00 2001 From: tsrk Date: Thu, 12 Jan 2023 10:13:16 +0100 Subject: [PATCH 1458/2991] refactor(SegmentedGraph): use (get/set)ters to expose TierColour --- .../UserInterface/TestSceneSegmentedGraph.cs | 15 +++++--- .../Graphics/UserInterface/SegmentedGraph.cs | 38 +++++++++++++++++-- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs index a3426b36b4..5c0b3e0a20 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs @@ -10,7 +10,6 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu; using osuTK; -using Vector4 = System.Numerics.Vector4; namespace osu.Game.Tests.Visual.UserInterface { @@ -22,7 +21,7 @@ namespace osu.Game.Tests.Visual.UserInterface { Children = new Drawable[] { - graph = new SegmentedGraph(10) + graph = new SegmentedGraph(6) { RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, @@ -31,11 +30,15 @@ namespace osu.Game.Tests.Visual.UserInterface }, }; - for (int i = 0; i < graph.TierColours.Length; i++) + graph.TierColours = new[] { - graph.TierColours[i] = - new Colour4(Vector4.Lerp(Colour4.Blue.Vector, Colour4.White.Vector, i * 1f / (graph.TierColours.Length - 1))); - } + Colour4.Red, + Colour4.OrangeRed, + Colour4.Orange, + Colour4.Yellow, + Colour4.YellowGreen, + Colour4.Green + }; AddStep("values from 1-10", () => graph.Values = Enumerable.Range(1, 10).ToArray()); AddStep("values from 1-100", () => graph.Values = Enumerable.Range(1, 100).ToArray()); diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index af457edc11..456274e559 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -29,7 +29,7 @@ namespace osu.Game.Graphics.UserInterface public SegmentedGraph(int tierCount) { this.tierCount = tierCount; - TierColours = new Colour4[tierCount]; + tierColours = new Colour4[tierCount]; segments = new SegmentManager(tierCount); } @@ -45,7 +45,39 @@ namespace osu.Game.Graphics.UserInterface } } - public readonly Colour4[] TierColours; + private Colour4[] tierColours; + + public Colour4[] TierColours + { + get => tierColours; + set + { + if (value.Length == 0 || value == tierColours) + return; + + if (value.Length == tierCount) + { + tierColours = value; + } + else if (value.Length < tierCount) + { + var colourList = new List(value); + + for (int i = value.Length; i < tierCount; i++) + { + colourList.Add(value.Last()); + } + + tierColours = colourList.ToArray(); + } + else + { + tierColours = value[..tierCount]; + } + + graphNeedsUpdate = true; + } + } private Texture texture = null!; private IShader shader = null!; @@ -136,7 +168,7 @@ namespace osu.Game.Graphics.UserInterface segments.Sort(); } - private Colour4 getTierColour(int tier) => tier >= 0 ? TierColours[tier] : new Colour4(0, 0, 0, 0); + private Colour4 getTierColour(int tier) => tier >= 0 ? tierColours[tier] : new Colour4(0, 0, 0, 0); protected override DrawNode CreateDrawNode() => new SegmentedGraphDrawNode(this); From bb2ece5c71bed3c8ebc0f68d24e4f30ef02023c6 Mon Sep 17 00:00:00 2001 From: tsrk Date: Thu, 12 Jan 2023 10:57:12 +0100 Subject: [PATCH 1459/2991] refactor(SegmentedGraph): adjust tierCount based on passed Colours --- .../UserInterface/TestSceneSegmentedGraph.cs | 22 ++++++++++++++ .../Graphics/UserInterface/SegmentedGraph.cs | 30 +++++-------------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs index 5c0b3e0a20..80941569af 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs @@ -52,6 +52,28 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("beatmap density with granularity of 200", () => beatmapDensity()); AddStep("beatmap density with granularity of 300", () => beatmapDensity(300)); AddStep("reversed values from 1-10", () => graph.Values = Enumerable.Range(1, 10).Reverse().ToArray()); + AddStep("change colour", () => + { + graph.TierColours = new[] + { + Colour4.White, + Colour4.LightBlue, + Colour4.Aqua, + Colour4.Blue + }; + }); + AddStep("reset colour", () => + { + graph.TierColours = new[] + { + Colour4.Red, + Colour4.OrangeRed, + Colour4.Orange, + Colour4.Yellow, + Colour4.YellowGreen, + Colour4.Green + }; + }); } private void sinFunction(int size = 100) diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index 456274e559..8ccba710b8 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -24,12 +24,15 @@ namespace osu.Game.Graphics.UserInterface private int[] tiers = Array.Empty(); private readonly SegmentManager segments; - private readonly int tierCount; + private int tierCount; - public SegmentedGraph(int tierCount) + public SegmentedGraph(int tierCount = 1) { this.tierCount = tierCount; - tierColours = new Colour4[tierCount]; + tierColours = new[] + { + new Colour4(0, 0, 0, 0) + }; segments = new SegmentManager(tierCount); } @@ -55,25 +58,8 @@ namespace osu.Game.Graphics.UserInterface if (value.Length == 0 || value == tierColours) return; - if (value.Length == tierCount) - { - tierColours = value; - } - else if (value.Length < tierCount) - { - var colourList = new List(value); - - for (int i = value.Length; i < tierCount; i++) - { - colourList.Add(value.Last()); - } - - tierColours = colourList.ToArray(); - } - else - { - tierColours = value[..tierCount]; - } + tierCount = value.Length; + tierColours = value; graphNeedsUpdate = true; } From 4439698867b7f9b98d862d49903524d244edb215 Mon Sep 17 00:00:00 2001 From: Ruki Date: Thu, 12 Jan 2023 13:19:03 +0100 Subject: [PATCH 1460/2991] Update osu.Game/Screens/Play/HUD/ArgonSongProgress.cs --- osu.Game/Screens/Play/HUD/ArgonSongProgress.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs index c36f881ec2..e5ee42e72a 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs @@ -54,8 +54,6 @@ namespace osu.Game.Screens.Play.HUD Origin = Anchor.BottomLeft, Anchor = Anchor.BottomLeft, RelativeSizeAxes = Axes.X, - Masking = true, - CornerRadius = 5, }, bar = new ArgonSongProgressBar(bar_height) { From b0385123795ea37dffb2b42fe7135cc37ee6ebb4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Jan 2023 22:14:41 +0900 Subject: [PATCH 1461/2991] Remove `CFBundleVersion` from iOS plist file This allows using `-p:ApplicationVersion:1234.5.6` to specify a version at build / publish time. Without removing it the plist file's value always takes precedence. --- osu.iOS/Info.plist | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.iOS/Info.plist b/osu.iOS/Info.plist index c4b08ab78e..8bddce4ad2 100644 --- a/osu.iOS/Info.plist +++ b/osu.iOS/Info.plist @@ -10,8 +10,6 @@ osu! CFBundleShortVersionString 0.1 - CFBundleVersion - 0.1.0 LSRequiresIPhoneOS MinimumOSVersion From f77db12c1e1ee34c307aafa4c834485d779075c6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Jan 2023 23:09:43 +0900 Subject: [PATCH 1462/2991] Also remove `CFBundleShortVersionString` --- osu.iOS/Info.plist | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.iOS/Info.plist b/osu.iOS/Info.plist index 8bddce4ad2..0ce1d952d0 100644 --- a/osu.iOS/Info.plist +++ b/osu.iOS/Info.plist @@ -8,8 +8,6 @@ osu! CFBundleDisplayName osu! - CFBundleShortVersionString - 0.1 LSRequiresIPhoneOS MinimumOSVersion From 2365b065a4994f38fe67bab7d193e5a09bee538c Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 12 Jan 2023 18:07:54 +0300 Subject: [PATCH 1463/2991] Enable nullability for editor components --- osu.Game/Screens/Edit/Components/BottomBarContainer.cs | 2 -- osu.Game/Screens/Edit/Components/EditorSidebar.cs | 2 -- .../Screens/Edit/Components/EditorSidebarSection.cs | 2 -- .../Components/Menus/EditorScreenSwitcherControl.cs | 4 +--- osu.Game/Screens/Edit/Components/PlaybackControl.cs | 8 +++----- .../Edit/Components/RadioButtons/EditorRadioButton.cs | 10 ++++------ .../RadioButtons/EditorRadioButtonCollection.cs | 7 +++---- .../Edit/Components/RadioButtons/RadioButton.cs | 8 +++----- .../Components/TernaryButtons/DrawableTernaryButton.cs | 4 +--- .../Edit/Components/TernaryButtons/TernaryButton.cs | 6 ++---- osu.Game/Screens/Edit/Components/TimeInfoContainer.cs | 10 ++++------ .../Components/Timelines/Summary/Parts/BookmarkPart.cs | 2 -- .../Components/Timelines/Summary/Parts/BreakPart.cs | 2 -- .../Timelines/Summary/Parts/ControlPointPart.cs | 2 -- .../Summary/Parts/ControlPointVisualisation.cs | 2 -- .../Timelines/Summary/Parts/GroupVisualisation.cs | 2 -- .../Summary/Parts/IControlPointVisualisation.cs | 2 -- .../Components/Timelines/Summary/Parts/MarkerPart.cs | 8 +++----- .../Components/Timelines/Summary/Parts/TimelinePart.cs | 6 ++---- .../Components/Timelines/Summary/SummaryTimeline.cs | 2 -- .../Components/Timelines/Summary/TestGameplayButton.cs | 2 -- .../Summary/Visualisations/DurationVisualisation.cs | 2 -- .../Summary/Visualisations/PointVisualisation.cs | 2 -- .../Components/Timeline/TimelineHitObjectBlueprint.cs | 2 +- 24 files changed, 27 insertions(+), 72 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs index 32ec3b6833..0ba1ab9258 100644 --- a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs +++ b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Bindables; diff --git a/osu.Game/Screens/Edit/Components/EditorSidebar.cs b/osu.Game/Screens/Edit/Components/EditorSidebar.cs index cfcfcd75e6..9a8c5115dd 100644 --- a/osu.Game/Screens/Edit/Components/EditorSidebar.cs +++ b/osu.Game/Screens/Edit/Components/EditorSidebar.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game/Screens/Edit/Components/EditorSidebarSection.cs b/osu.Game/Screens/Edit/Components/EditorSidebarSection.cs index 4e8c55efa1..279793c0a1 100644 --- a/osu.Game/Screens/Edit/Components/EditorSidebarSection.cs +++ b/osu.Game/Screens/Edit/Components/EditorSidebarSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs b/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs index e88138def4..3d51874082 100644 --- a/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs +++ b/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; @@ -38,7 +36,7 @@ namespace osu.Game.Screens.Edit.Components.Menus }); } - protected override Dropdown CreateDropdown() => null; + protected override Dropdown CreateDropdown() => null!; protected override TabItem CreateTabItem(EditorScreenMode value) => new TabItem(value); diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs index f403551a62..87cbcb8aff 100644 --- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs +++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osuTK; using osuTK.Graphics; @@ -25,10 +23,10 @@ namespace osu.Game.Screens.Edit.Components { public partial class PlaybackControl : BottomBarContainer { - private IconButton playButton; + private IconButton playButton = null!; [Resolved] - private EditorClock editorClock { get; set; } + private EditorClock editorClock { get; set; } = null!; private readonly BindableNumber freqAdjust = new BindableDouble(1); @@ -108,7 +106,7 @@ namespace osu.Game.Screens.Edit.Components protected override TabItem CreateTabItem(double value) => new PlaybackTabItem(value); - protected override Dropdown CreateDropdown() => null; + protected override Dropdown CreateDropdown() => null!; public PlaybackTabControl() { diff --git a/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButton.cs b/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButton.cs index bfcc0084bd..65f3e41c13 100644 --- a/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButton.cs +++ b/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; @@ -24,7 +22,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons /// /// Invoked when this has been selected. /// - public Action Selected; + public Action? Selected; public readonly RadioButton Button; @@ -33,10 +31,10 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons private Color4 selectedBackgroundColour; private Color4 selectedIconColour; - private Drawable icon; + private Drawable icon = null!; - [Resolved(canBeNull: true)] - private EditorBeatmap editorBeatmap { get; set; } + [Resolved] + private EditorBeatmap? editorBeatmap { get; set; } public EditorRadioButton(RadioButton button) { diff --git a/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButtonCollection.cs b/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButtonCollection.cs index 92dd47dc81..4391729adc 100644 --- a/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButtonCollection.cs +++ b/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButtonCollection.cs @@ -1,8 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - +using System; using System.Collections.Generic; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; @@ -13,7 +12,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons { public partial class EditorRadioButtonCollection : CompositeDrawable { - private IReadOnlyList items; + private IReadOnlyList items = Array.Empty(); public IReadOnlyList Items { @@ -45,7 +44,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons }; } - private RadioButton currentlySelected; + private RadioButton? currentlySelected; private void addButton(RadioButton button) { diff --git a/osu.Game/Screens/Edit/Components/RadioButtons/RadioButton.cs b/osu.Game/Screens/Edit/Components/RadioButtons/RadioButton.cs index 03745ce19d..9dcd29bf83 100644 --- a/osu.Game/Screens/Edit/Components/RadioButtons/RadioButton.cs +++ b/osu.Game/Screens/Edit/Components/RadioButtons/RadioButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -24,11 +22,11 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons /// /// A function which creates a drawable icon to represent this item. If null, a sane default should be used. /// - public readonly Func CreateIcon; + public readonly Func? CreateIcon; - private readonly Action action; + private readonly Action? action; - public RadioButton(string label, Action action, Func createIcon = null) + public RadioButton(string label, Action? action, Func? createIcon = null) { Label = label; CreateIcon = createIcon; diff --git a/osu.Game/Screens/Edit/Components/TernaryButtons/DrawableTernaryButton.cs b/osu.Game/Screens/Edit/Components/TernaryButtons/DrawableTernaryButton.cs index 45b7cd1b7c..873551db77 100644 --- a/osu.Game/Screens/Edit/Components/TernaryButtons/DrawableTernaryButton.cs +++ b/osu.Game/Screens/Edit/Components/TernaryButtons/DrawableTernaryButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -23,7 +21,7 @@ namespace osu.Game.Screens.Edit.Components.TernaryButtons private Color4 selectedBackgroundColour; private Color4 selectedIconColour; - private Drawable icon; + private Drawable icon = null!; public readonly TernaryButton Button; diff --git a/osu.Game/Screens/Edit/Components/TernaryButtons/TernaryButton.cs b/osu.Game/Screens/Edit/Components/TernaryButtons/TernaryButton.cs index 8eb781c947..0ff2aa83b5 100644 --- a/osu.Game/Screens/Edit/Components/TernaryButtons/TernaryButton.cs +++ b/osu.Game/Screens/Edit/Components/TernaryButtons/TernaryButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -19,9 +17,9 @@ namespace osu.Game.Screens.Edit.Components.TernaryButtons /// /// A function which creates a drawable icon to represent this item. If null, a sane default should be used. /// - public readonly Func CreateIcon; + public readonly Func? CreateIcon; - public TernaryButton(Bindable bindable, string description, Func createIcon = null) + public TernaryButton(Bindable bindable, string description, Func? createIcon = null) { Bindable = bindable; Description = description; diff --git a/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs b/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs index 1c16671ce4..9c51258f17 100644 --- a/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs +++ b/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Graphics.Sprites; using osu.Framework.Allocation; @@ -15,14 +13,14 @@ namespace osu.Game.Screens.Edit.Components { public partial class TimeInfoContainer : BottomBarContainer { - private OsuSpriteText trackTimer; - private OsuSpriteText bpm; + private OsuSpriteText trackTimer = null!; + private OsuSpriteText bpm = null!; [Resolved] - private EditorBeatmap editorBeatmap { get; set; } + private EditorBeatmap editorBeatmap { get; set; } = null!; [Resolved] - private EditorClock editorClock { get; set; } + private EditorClock editorClock { get; set; } = null!; [BackgroundDependencyLoader] private void load(OsuColour colours, OverlayColourProvider colourProvider) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs index f1023ade8c..3102bf7c06 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Game.Graphics; using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs index de5d074c51..e502dd951b 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Game.Beatmaps.Timing; using osu.Game.Graphics; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs index 111ba0b732..6f53f710ba 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Specialized; using System.Diagnostics; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointVisualisation.cs index aa494271f8..12620963e1 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointVisualisation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps.ControlPoints; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/GroupVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/GroupVisualisation.cs index 64c0745596..b39365277f 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/GroupVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/GroupVisualisation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/IControlPointVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/IControlPointVisualisation.cs index b9e2a969a5..c81f1828f7 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/IControlPointVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/IControlPointVisualisation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Beatmaps.ControlPoints; namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs index 5be6db55a4..d42c02e03d 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -20,10 +18,10 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts /// public partial class MarkerPart : TimelinePart { - private Drawable marker; + private Drawable marker = null!; [Resolved] - private EditorClock editorClock { get; set; } + private EditorClock editorClock { get; set; } = null!; [BackgroundDependencyLoader] private void load() @@ -44,7 +42,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts return true; } - private ScheduledDelegate scheduledSeek; + private ScheduledDelegate? scheduledSeek; /// /// Seeks the to the time closest to a position on the screen relative to the . diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index e380a2063b..ee7e759ebc 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Audio.Track; @@ -26,7 +24,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts private readonly IBindable beatmap = new Bindable(); [Resolved] - protected EditorBeatmap EditorBeatmap { get; private set; } + protected EditorBeatmap EditorBeatmap { get; private set; } = null!; protected readonly IBindable Track = new Bindable(); @@ -34,7 +32,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts protected override Container Content => content; - public TimelinePart(Container content = null) + public TimelinePart(Container? content = null) { AddInternal(this.content = content ?? new Container { RelativeSizeAxes = Axes.Both }); diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs index 075d47d82e..6199cefb57 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs index a3a003947c..9b45464e81 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs index 6fc994b8b1..bfb50a05ea 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs index 75dacdf3e7..3f0c125ada 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index 03e67306df..4e5087c004 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -291,7 +291,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved] private Timeline timeline { get; set; } = null!; - [Resolved(CanBeNull = true)] + [Resolved] private IEditorChangeHandler? changeHandler { get; set; } private ScheduledDelegate? dragOperation; From 985b126cba7568018769942fb1bf0cdf10d37036 Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Thu, 12 Jan 2023 16:06:03 +0000 Subject: [PATCH 1464/2991] getTaikoActionFromDrumSegment and getColorFromTaikoAction are now run from within QuarterCircle constructor --- .../UI/DrumTouchInputArea.cs | 63 +++++++++++-------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index a8bad36381..99a21e231d 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Taiko.UI private QuarterCircle leftRim = null!; private QuarterCircle rightRim = null!; - private readonly Bindable configTouchControlScheme = new Bindable(); + private static readonly Bindable configTouchControlScheme = new Bindable(); [Resolved] private OsuColour colours { get; set; } = null!; @@ -79,27 +79,27 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - leftRim = new QuarterCircle(getTaikoActionFromDrumSegment(0), getColourFromTaikoAction(getTaikoActionFromDrumSegment(0))) + leftRim = new QuarterCircle(0, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, }, - leftCentre = new QuarterCircle(getTaikoActionFromDrumSegment(1), getColourFromTaikoAction(getTaikoActionFromDrumSegment(1))) + leftCentre = new QuarterCircle(1, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, Scale = new Vector2(centre_region), }, - rightRim = new QuarterCircle(getTaikoActionFromDrumSegment(3), getColourFromTaikoAction(getTaikoActionFromDrumSegment(3))) + rightRim = new QuarterCircle(3, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = 2, Rotation = 90, }, - rightCentre = new QuarterCircle(getTaikoActionFromDrumSegment(2), getColourFromTaikoAction(getTaikoActionFromDrumSegment(2))) + rightCentre = new QuarterCircle(2, colours) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, @@ -114,7 +114,7 @@ namespace osu.Game.Rulesets.Taiko.UI }; } - private readonly TaikoAction[,] mappedTaikoAction = + private static readonly TaikoAction[,] mappedTaikoAction = { { // KDDK @@ -139,7 +139,7 @@ namespace osu.Game.Rulesets.Taiko.UI } }; - private TaikoAction getTaikoActionFromDrumSegment(int drumSegment) + private static TaikoAction getTaikoActionFromDrumSegment(int drumSegment) { return mappedTaikoAction[(int)configTouchControlScheme.Value, drumSegment]; } @@ -210,36 +210,35 @@ namespace osu.Game.Rulesets.Taiko.UI mainContent.FadeOut(300); } - private Color4 getColourFromTaikoAction(TaikoAction handledAction) - { - switch (handledAction) - { - case TaikoAction.LeftRim: - case TaikoAction.RightRim: - return colours.Blue; - case TaikoAction.LeftCentre: - case TaikoAction.RightCentre: - return colours.Red; - } - throw new ArgumentOutOfRangeException(); - } private partial class QuarterCircle : CompositeDrawable, IKeyBindingHandler { private readonly Circle overlay; - private readonly TaikoAction handledAction; + private readonly int drumSegment; + + private readonly TaikoAction taikoAction; + + private readonly OsuColour colours; + + private readonly Color4 colour; private readonly Circle circle; public override bool Contains(Vector2 screenSpacePos) => circle.Contains(screenSpacePos); - public QuarterCircle(TaikoAction handledAction, Color4 colour) + public QuarterCircle(int drumSegment, OsuColour colours) { - this.handledAction = handledAction; + this.drumSegment = drumSegment; + this.colours = colours; + RelativeSizeAxes = Axes.Both; FillMode = FillMode.Fit; + taikoAction = getTaikoActionFromDrumSegment(drumSegment); + + colour = getColorFromTaikoAction(taikoAction); + InternalChildren = new Drawable[] { new Container @@ -268,16 +267,30 @@ namespace osu.Game.Rulesets.Taiko.UI }; } + private Color4 getColorFromTaikoAction(TaikoAction handledAction) + { + switch (handledAction) + { + case TaikoAction.LeftRim: + case TaikoAction.RightRim: + return colours.Blue; + case TaikoAction.LeftCentre: + case TaikoAction.RightCentre: + return colours.Red; + } + throw new ArgumentOutOfRangeException(); + } + public bool OnPressed(KeyBindingPressEvent e) { - if (e.Action == handledAction) + if (e.Action == taikoAction) overlay.FadeTo(1f, 80, Easing.OutQuint); return false; } public void OnReleased(KeyBindingReleaseEvent e) { - if (e.Action == handledAction) + if (e.Action == taikoAction) overlay.FadeOut(1000, Easing.OutQuint); } } From 0bd1c46c7481fbac28933810195f5a9a8a2a2d0d Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 12 Jan 2023 19:48:11 +0300 Subject: [PATCH 1465/2991] Undo sizing changes --- .../Comments/CancellableCommentEditor.cs | 8 +----- osu.Game/Overlays/Comments/CommentEditor.cs | 28 ++++++++++++++----- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs index 7418ba344b..02abc5b6cf 100644 --- a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -3,8 +3,6 @@ using System; using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments @@ -16,14 +14,10 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load() { - ButtonsContainer.Add(new RoundedButton + ButtonsContainer.Add(new EditorButton { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, Action = () => OnCancel?.Invoke(), Text = CommonStrings.ButtonsCancel, - Width = 100, - Height = 30, }); } } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 906ff0c4a2..769263b3fc 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -85,7 +85,7 @@ namespace osu.Game.Overlays.Comments { Name = @"Footer", RelativeSizeAxes = Axes.X, - Height = 40, + Height = 35, Padding = new MarginPadding { Horizontal = side_padding }, Children = new Drawable[] { @@ -93,7 +93,7 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold), + Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold), Text = FooterText }, new FillFlowContainer @@ -113,13 +113,9 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(5, 0), - Child = commitButton = new RoundedButton + Child = commitButton = new EditorButton { - Width = 100, - Height = 30, Text = CommitButtonText, - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, Action = () => OnCommit(Current.Value) } }, @@ -184,5 +180,23 @@ namespace osu.Game.Overlays.Comments Child = new OsuSpriteText { Text = c.ToString(), Font = OsuFont.GetFont(size: CalculatedTextSize) } }; } + + protected partial class EditorButton : RoundedButton + { + public EditorButton() + { + Width = 80; + Height = 25; + Anchor = Anchor.CentreRight; + Origin = Anchor.CentreRight; + } + + protected override SpriteText CreateText() + { + var t = base.CreateText(); + t.Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 12); + return t; + } + } } } From 767c3cb523913350eee131dcff80b6bcd758dd2e Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Thu, 12 Jan 2023 17:20:07 +0000 Subject: [PATCH 1466/2991] Revert "getTaikoActionFromDrumSegment and getColorFromTaikoAction are now run from within QuarterCircle constructor" This reverts commit 985b126cba7568018769942fb1bf0cdf10d37036. I really don't think this is going to work cleanly --- .../UI/DrumTouchInputArea.cs | 63 ++++++++----------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 99a21e231d..a8bad36381 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Taiko.UI private QuarterCircle leftRim = null!; private QuarterCircle rightRim = null!; - private static readonly Bindable configTouchControlScheme = new Bindable(); + private readonly Bindable configTouchControlScheme = new Bindable(); [Resolved] private OsuColour colours { get; set; } = null!; @@ -79,27 +79,27 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - leftRim = new QuarterCircle(0, colours) + leftRim = new QuarterCircle(getTaikoActionFromDrumSegment(0), getColourFromTaikoAction(getTaikoActionFromDrumSegment(0))) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, }, - leftCentre = new QuarterCircle(1, colours) + leftCentre = new QuarterCircle(getTaikoActionFromDrumSegment(1), getColourFromTaikoAction(getTaikoActionFromDrumSegment(1))) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, Scale = new Vector2(centre_region), }, - rightRim = new QuarterCircle(3, colours) + rightRim = new QuarterCircle(getTaikoActionFromDrumSegment(3), getColourFromTaikoAction(getTaikoActionFromDrumSegment(3))) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = 2, Rotation = 90, }, - rightCentre = new QuarterCircle(2, colours) + rightCentre = new QuarterCircle(getTaikoActionFromDrumSegment(2), getColourFromTaikoAction(getTaikoActionFromDrumSegment(2))) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, @@ -114,7 +114,7 @@ namespace osu.Game.Rulesets.Taiko.UI }; } - private static readonly TaikoAction[,] mappedTaikoAction = + private readonly TaikoAction[,] mappedTaikoAction = { { // KDDK @@ -139,7 +139,7 @@ namespace osu.Game.Rulesets.Taiko.UI } }; - private static TaikoAction getTaikoActionFromDrumSegment(int drumSegment) + private TaikoAction getTaikoActionFromDrumSegment(int drumSegment) { return mappedTaikoAction[(int)configTouchControlScheme.Value, drumSegment]; } @@ -210,35 +210,36 @@ namespace osu.Game.Rulesets.Taiko.UI mainContent.FadeOut(300); } + private Color4 getColourFromTaikoAction(TaikoAction handledAction) + { + switch (handledAction) + { + case TaikoAction.LeftRim: + case TaikoAction.RightRim: + return colours.Blue; + case TaikoAction.LeftCentre: + case TaikoAction.RightCentre: + return colours.Red; + } + throw new ArgumentOutOfRangeException(); + } private partial class QuarterCircle : CompositeDrawable, IKeyBindingHandler { private readonly Circle overlay; - private readonly int drumSegment; - - private readonly TaikoAction taikoAction; - - private readonly OsuColour colours; - - private readonly Color4 colour; + private readonly TaikoAction handledAction; private readonly Circle circle; public override bool Contains(Vector2 screenSpacePos) => circle.Contains(screenSpacePos); - public QuarterCircle(int drumSegment, OsuColour colours) + public QuarterCircle(TaikoAction handledAction, Color4 colour) { - this.drumSegment = drumSegment; - this.colours = colours; - + this.handledAction = handledAction; RelativeSizeAxes = Axes.Both; FillMode = FillMode.Fit; - taikoAction = getTaikoActionFromDrumSegment(drumSegment); - - colour = getColorFromTaikoAction(taikoAction); - InternalChildren = new Drawable[] { new Container @@ -267,30 +268,16 @@ namespace osu.Game.Rulesets.Taiko.UI }; } - private Color4 getColorFromTaikoAction(TaikoAction handledAction) - { - switch (handledAction) - { - case TaikoAction.LeftRim: - case TaikoAction.RightRim: - return colours.Blue; - case TaikoAction.LeftCentre: - case TaikoAction.RightCentre: - return colours.Red; - } - throw new ArgumentOutOfRangeException(); - } - public bool OnPressed(KeyBindingPressEvent e) { - if (e.Action == taikoAction) + if (e.Action == handledAction) overlay.FadeTo(1f, 80, Easing.OutQuint); return false; } public void OnReleased(KeyBindingReleaseEvent e) { - if (e.Action == taikoAction) + if (e.Action == handledAction) overlay.FadeOut(1000, Easing.OutQuint); } } From 927fccb7be4bcf5589a9b7593b1dc9506a2543fe Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Thu, 12 Jan 2023 17:55:05 +0000 Subject: [PATCH 1467/2991] Taiko touch control scheme can now be changed mid-map --- .../UI/DrumTouchInputArea.cs | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index a8bad36381..1fe45a96dd 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -57,7 +57,10 @@ namespace osu.Game.Rulesets.Taiko.UI const float centre_region = 0.80f; if (ForceControlScheme == null) + { config.BindWith(TaikoRulesetSetting.TouchControlScheme, configTouchControlScheme); + configTouchControlScheme.ValueChanged += reloadTouchDrums; + } else configTouchControlScheme.Value = ForceControlScheme.Value; @@ -225,11 +228,11 @@ namespace osu.Game.Rulesets.Taiko.UI } private partial class QuarterCircle : CompositeDrawable, IKeyBindingHandler { - private readonly Circle overlay; + private TaikoAction handledAction; - private readonly TaikoAction handledAction; + private Circle overlay; - private readonly Circle circle; + private Circle circle; public override bool Contains(Vector2 screenSpacePos) => circle.Contains(screenSpacePos); @@ -280,6 +283,22 @@ namespace osu.Game.Rulesets.Taiko.UI if (e.Action == handledAction) overlay.FadeOut(1000, Easing.OutQuint); } + + public void ReloadDrumSegmentProperties(TaikoAction handledAction, Color4 colour) + { + this.handledAction = handledAction; + + circle.Colour = colour.Multiply(1.4f).Darken(2.8f); + overlay.Colour = colour; + } + } + + private void reloadTouchDrums(object _) + { + leftRim.ReloadDrumSegmentProperties(getTaikoActionFromDrumSegment(0), getColourFromTaikoAction(getTaikoActionFromDrumSegment(0))); + leftCentre.ReloadDrumSegmentProperties(getTaikoActionFromDrumSegment(1), getColourFromTaikoAction(getTaikoActionFromDrumSegment(1))); + rightRim.ReloadDrumSegmentProperties(getTaikoActionFromDrumSegment(3), getColourFromTaikoAction(getTaikoActionFromDrumSegment(3))); + rightCentre.ReloadDrumSegmentProperties(getTaikoActionFromDrumSegment(2), getColourFromTaikoAction(getTaikoActionFromDrumSegment(2))); } } } From f2ec0b21766c1c00856b98e01607e1c6b9a36a34 Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Thu, 12 Jan 2023 18:17:50 +0000 Subject: [PATCH 1468/2991] Made QuarterCircle property loading less clapped --- .../UI/DrumTouchInputArea.cs | 46 ++++++++++++++----- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 1fe45a96dd..6e91ed10a5 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -45,6 +45,23 @@ namespace osu.Game.Rulesets.Taiko.UI [Resolved] private OsuColour colours { get; set; } = null!; + private class DrumSegmentProperties + { + public TaikoAction TaikoAction { get; set; } + public Color4 Color { get; set; } + + public DrumSegmentProperties(TaikoAction taikoAction, Color4 color) + { + TaikoAction = taikoAction; + Color = color; + } + } + + private DrumSegmentProperties getDrumSegmentProperties(int drumSegment) + { + var taikoAction = getTaikoActionFromDrumSegment(drumSegment); + return new DrumSegmentProperties(taikoAction, getColourFromTaikoAction(taikoAction)); + } [BackgroundDependencyLoader] private void load(TaikoInputManager taikoInputManager, TaikoRulesetConfigManager config) { @@ -82,27 +99,27 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - leftRim = new QuarterCircle(getTaikoActionFromDrumSegment(0), getColourFromTaikoAction(getTaikoActionFromDrumSegment(0))) + leftRim = new QuarterCircle(getDrumSegmentProperties(0)) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, }, - leftCentre = new QuarterCircle(getTaikoActionFromDrumSegment(1), getColourFromTaikoAction(getTaikoActionFromDrumSegment(1))) + leftCentre = new QuarterCircle(getDrumSegmentProperties(1)) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, Scale = new Vector2(centre_region), }, - rightRim = new QuarterCircle(getTaikoActionFromDrumSegment(3), getColourFromTaikoAction(getTaikoActionFromDrumSegment(3))) + rightRim = new QuarterCircle(getDrumSegmentProperties(3)) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = 2, Rotation = 90, }, - rightCentre = new QuarterCircle(getTaikoActionFromDrumSegment(2), getColourFromTaikoAction(getTaikoActionFromDrumSegment(2))) + rightCentre = new QuarterCircle(getDrumSegmentProperties(2)) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, @@ -236,13 +253,16 @@ namespace osu.Game.Rulesets.Taiko.UI public override bool Contains(Vector2 screenSpacePos) => circle.Contains(screenSpacePos); - public QuarterCircle(TaikoAction handledAction, Color4 colour) + public QuarterCircle(DrumSegmentProperties properties) { - this.handledAction = handledAction; + handledAction = properties.TaikoAction; + RelativeSizeAxes = Axes.Both; FillMode = FillMode.Fit; + var colour = properties.Color; + InternalChildren = new Drawable[] { new Container @@ -284,9 +304,11 @@ namespace osu.Game.Rulesets.Taiko.UI overlay.FadeOut(1000, Easing.OutQuint); } - public void ReloadDrumSegmentProperties(TaikoAction handledAction, Color4 colour) + public void SetProperties(DrumSegmentProperties properties) { - this.handledAction = handledAction; + handledAction = properties.TaikoAction; + + var colour = properties.Color; circle.Colour = colour.Multiply(1.4f).Darken(2.8f); overlay.Colour = colour; @@ -295,10 +317,10 @@ namespace osu.Game.Rulesets.Taiko.UI private void reloadTouchDrums(object _) { - leftRim.ReloadDrumSegmentProperties(getTaikoActionFromDrumSegment(0), getColourFromTaikoAction(getTaikoActionFromDrumSegment(0))); - leftCentre.ReloadDrumSegmentProperties(getTaikoActionFromDrumSegment(1), getColourFromTaikoAction(getTaikoActionFromDrumSegment(1))); - rightRim.ReloadDrumSegmentProperties(getTaikoActionFromDrumSegment(3), getColourFromTaikoAction(getTaikoActionFromDrumSegment(3))); - rightCentre.ReloadDrumSegmentProperties(getTaikoActionFromDrumSegment(2), getColourFromTaikoAction(getTaikoActionFromDrumSegment(2))); + leftRim.SetProperties(getDrumSegmentProperties(0)); + leftCentre.SetProperties(getDrumSegmentProperties(1)); + rightRim.SetProperties(getDrumSegmentProperties(3)); + rightCentre.SetProperties(getDrumSegmentProperties(2)); } } } From 92def3daf4720535073cb264dd485f9672eabf9a Mon Sep 17 00:00:00 2001 From: OpenSauce Date: Thu, 12 Jan 2023 18:20:03 +0000 Subject: [PATCH 1469/2991] Renamed QuarterCircle class to DrumSegment --- .../UI/DrumTouchInputArea.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 6e91ed10a5..753b7f2da9 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -35,10 +35,10 @@ namespace osu.Game.Rulesets.Taiko.UI private Container mainContent = null!; - private QuarterCircle leftCentre = null!; - private QuarterCircle rightCentre = null!; - private QuarterCircle leftRim = null!; - private QuarterCircle rightRim = null!; + private DrumSegment leftCentre = null!; + private DrumSegment rightCentre = null!; + private DrumSegment leftRim = null!; + private DrumSegment rightRim = null!; private readonly Bindable configTouchControlScheme = new Bindable(); @@ -99,27 +99,27 @@ namespace osu.Game.Rulesets.Taiko.UI RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - leftRim = new QuarterCircle(getDrumSegmentProperties(0)) + leftRim = new DrumSegment(getDrumSegmentProperties(0)) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, }, - leftCentre = new QuarterCircle(getDrumSegmentProperties(1)) + leftCentre = new DrumSegment(getDrumSegmentProperties(1)) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = -2, Scale = new Vector2(centre_region), }, - rightRim = new QuarterCircle(getDrumSegmentProperties(3)) + rightRim = new DrumSegment(getDrumSegmentProperties(3)) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, X = 2, Rotation = 90, }, - rightCentre = new QuarterCircle(getDrumSegmentProperties(2)) + rightCentre = new DrumSegment(getDrumSegmentProperties(2)) { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomRight, @@ -243,7 +243,7 @@ namespace osu.Game.Rulesets.Taiko.UI } throw new ArgumentOutOfRangeException(); } - private partial class QuarterCircle : CompositeDrawable, IKeyBindingHandler + private partial class DrumSegment : CompositeDrawable, IKeyBindingHandler { private TaikoAction handledAction; @@ -253,7 +253,7 @@ namespace osu.Game.Rulesets.Taiko.UI public override bool Contains(Vector2 screenSpacePos) => circle.Contains(screenSpacePos); - public QuarterCircle(DrumSegmentProperties properties) + public DrumSegment(DrumSegmentProperties properties) { handledAction = properties.TaikoAction; From 25a920732fa6cba7c51ab1eaf44f16b0df79e627 Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Thu, 12 Jan 2023 19:04:37 +0000 Subject: [PATCH 1470/2991] Addressed code formatting issues --- .../TestSceneDrumTouchInputArea.cs | 6 +++--- .../UI/DrumTouchInputArea.cs | 18 +++++++++++++----- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumTouchInputArea.cs index 6b02b0078a..23b871dcd8 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumTouchInputArea.cs @@ -14,13 +14,13 @@ namespace osu.Game.Rulesets.Taiko.Tests { private DrumTouchInputArea drumTouchInputArea = null!; - private void createDrum(TaikoTouchControlScheme _forcedControlScheme) + private void createDrum(TaikoTouchControlScheme forcedControlScheme) { Child = new TaikoInputManager(new TaikoRuleset().RulesetInfo) { RelativeSizeAxes = Axes.Both, Children = new Drawable[] - { + { new InputDrum { Anchor = Anchor.TopCentre, @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Taiko.Tests { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, - ForceControlScheme = _forcedControlScheme + ForceControlScheme = forcedControlScheme } } }; diff --git a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs index 753b7f2da9..e4c20dd1bf 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumTouchInputArea.cs @@ -25,6 +25,7 @@ namespace osu.Game.Rulesets.Taiko.UI public partial class DrumTouchInputArea : VisibilityContainer { public TaikoTouchControlScheme? ForceControlScheme { get; set; } + // visibility state affects our child. we always want to handle input. public override bool PropagatePositionalInputSubTree => true; public override bool PropagateNonPositionalInputSubTree => true; @@ -62,10 +63,12 @@ namespace osu.Game.Rulesets.Taiko.UI var taikoAction = getTaikoActionFromDrumSegment(drumSegment); return new DrumSegmentProperties(taikoAction, getColourFromTaikoAction(taikoAction)); } + [BackgroundDependencyLoader] private void load(TaikoInputManager taikoInputManager, TaikoRulesetConfigManager config) { Debug.Assert(taikoInputManager.KeyBindingContainer != null); + keyBindingContainer = taikoInputManager.KeyBindingContainer; // Container should handle input everywhere. @@ -187,14 +190,14 @@ namespace osu.Game.Rulesets.Taiko.UI { Show(); - TaikoAction TaikoAction = getTaikoActionFromPosition(position); + TaikoAction taikoAction = getTaikoActionFromPosition(position); // Not too sure how this can happen, but let's avoid throwing. if (trackedActions.ContainsKey(source)) return; - trackedActions.Add(source, TaikoAction); - keyBindingContainer.TriggerPressed(TaikoAction); + trackedActions.Add(source, taikoAction); + keyBindingContainer.TriggerPressed(taikoAction); } private void handleUp(object source) @@ -236,20 +239,25 @@ namespace osu.Game.Rulesets.Taiko.UI { case TaikoAction.LeftRim: case TaikoAction.RightRim: + return colours.Blue; + case TaikoAction.LeftCentre: case TaikoAction.RightCentre: + return colours.Red; } + throw new ArgumentOutOfRangeException(); } + private partial class DrumSegment : CompositeDrawable, IKeyBindingHandler { private TaikoAction handledAction; - private Circle overlay; + private readonly Circle overlay; - private Circle circle; + private readonly Circle circle; public override bool Contains(Vector2 screenSpacePos) => circle.Contains(screenSpacePos); From a9915d6a6419405f304da760cd2d05b6a6877815 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 12 Jan 2023 22:44:41 +0300 Subject: [PATCH 1471/2991] Make OverlayRulesetSelector display only legacy rulesets --- osu.Game/Overlays/OverlayRulesetSelector.cs | 1 + osu.Game/Rulesets/RulesetSelector.cs | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs index bcce2ce433..daef2edc4a 100644 --- a/osu.Game/Overlays/OverlayRulesetSelector.cs +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -14,6 +14,7 @@ namespace osu.Game.Overlays public partial class OverlayRulesetSelector : RulesetSelector { public OverlayRulesetSelector() + : base(true) { AutoSizeAxes = Axes.Both; } diff --git a/osu.Game/Rulesets/RulesetSelector.cs b/osu.Game/Rulesets/RulesetSelector.cs index 062f8d6450..91fc89b164 100644 --- a/osu.Game/Rulesets/RulesetSelector.cs +++ b/osu.Game/Rulesets/RulesetSelector.cs @@ -16,11 +16,23 @@ namespace osu.Game.Rulesets protected override Dropdown CreateDropdown() => null; + private readonly bool legacyOnly; + + public RulesetSelector(bool legacyOnly = false) + { + this.legacyOnly = legacyOnly; + } + [BackgroundDependencyLoader] private void load() { foreach (var ruleset in Rulesets.AvailableRulesets) { + int id = ruleset.OnlineID; + + if ((id < 0 || id > 3) && legacyOnly) + continue; + try { AddItem(ruleset); From 1dae1149cb458f4e0aac468f0f1f76dbc20c3ec1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 12 Jan 2023 22:52:45 +0300 Subject: [PATCH 1472/2991] Don't display non-legacy rulesets in beatmap listing --- .../BeatmapListing/BeatmapSearchRulesetFilterRow.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs index fa37810f37..88a62701fc 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs @@ -28,7 +28,14 @@ namespace osu.Game.Overlays.BeatmapListing AddTabItem(new RulesetFilterTabItemAny()); foreach (var r in rulesets.AvailableRulesets) + { + // Don't display non-legacy rulesets + int id = r.OnlineID; + if (id < 0 || id > 3) + continue; + AddItem(r); + } } } From 115cb0d2973ab96a5ccb62fd11981b15ef1db6b5 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Jan 2023 23:14:21 +0300 Subject: [PATCH 1473/2991] Fix channel manager test scene not waiting for notifications client connection --- osu.Game.Tests/Chat/TestSceneChannelManager.cs | 2 ++ osu.Game/Online/Chat/ChannelManager.cs | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/osu.Game.Tests/Chat/TestSceneChannelManager.cs b/osu.Game.Tests/Chat/TestSceneChannelManager.cs index cdd192cfe1..3a4c55c65c 100644 --- a/osu.Game.Tests/Chat/TestSceneChannelManager.cs +++ b/osu.Game.Tests/Chat/TestSceneChannelManager.cs @@ -75,6 +75,8 @@ namespace osu.Game.Tests.Chat return false; }; }); + + AddUntilStep("wait for notifications client", () => channelManager.NotificationsConnected); } [Test] diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 1e3921bac0..7ab678775f 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -64,6 +64,11 @@ namespace osu.Game.Online.Chat /// public IBindableList AvailableChannels => availableChannels; + /// + /// Whether the client responsible for channel notifications is connected. + /// + public bool NotificationsConnected => connector.IsConnected.Value; + private readonly IAPIProvider api; private readonly NotificationsClientConnector connector; From a7ac31fa3435a90be9f7483ed93d081c32bf9e6e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 12 Jan 2023 23:21:33 +0300 Subject: [PATCH 1474/2991] Use IsLegacyRuleset extension method --- .../Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs | 4 ++-- osu.Game/Rulesets/RulesetSelector.cs | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs index 88a62701fc..96626d0ac6 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; +using osu.Game.Extensions; using osu.Game.Resources.Localisation.Web; using osu.Game.Rulesets; @@ -30,8 +31,7 @@ namespace osu.Game.Overlays.BeatmapListing foreach (var r in rulesets.AvailableRulesets) { // Don't display non-legacy rulesets - int id = r.OnlineID; - if (id < 0 || id > 3) + if (!r.IsLegacyRuleset()) continue; AddItem(r); diff --git a/osu.Game/Rulesets/RulesetSelector.cs b/osu.Game/Rulesets/RulesetSelector.cs index 91fc89b164..1451f0d55d 100644 --- a/osu.Game/Rulesets/RulesetSelector.cs +++ b/osu.Game/Rulesets/RulesetSelector.cs @@ -6,6 +6,7 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Allocation; using osu.Framework.Logging; +using osu.Game.Extensions; namespace osu.Game.Rulesets { @@ -28,9 +29,7 @@ namespace osu.Game.Rulesets { foreach (var ruleset in Rulesets.AvailableRulesets) { - int id = ruleset.OnlineID; - - if ((id < 0 || id > 3) && legacyOnly) + if (!ruleset.IsLegacyRuleset() && legacyOnly) continue; try From d74a5ef9e6e76da206e3f68fcb15eeec09418b3d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 12 Jan 2023 23:26:29 +0300 Subject: [PATCH 1475/2991] Use property instead of ctor parameter --- osu.Game/Overlays/OverlayRulesetSelector.cs | 4 +++- osu.Game/Rulesets/RulesetSelector.cs | 9 ++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs index daef2edc4a..b9274231b0 100644 --- a/osu.Game/Overlays/OverlayRulesetSelector.cs +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -13,8 +13,10 @@ namespace osu.Game.Overlays { public partial class OverlayRulesetSelector : RulesetSelector { + // Since this component is used in online overlays and currently web-side doesn't support non-legacy rulesets - let's disable them for now. + protected override bool LegacyOnly => true; + public OverlayRulesetSelector() - : base(true) { AutoSizeAxes = Axes.Both; } diff --git a/osu.Game/Rulesets/RulesetSelector.cs b/osu.Game/Rulesets/RulesetSelector.cs index 1451f0d55d..ba10033a98 100644 --- a/osu.Game/Rulesets/RulesetSelector.cs +++ b/osu.Game/Rulesets/RulesetSelector.cs @@ -17,19 +17,14 @@ namespace osu.Game.Rulesets protected override Dropdown CreateDropdown() => null; - private readonly bool legacyOnly; - - public RulesetSelector(bool legacyOnly = false) - { - this.legacyOnly = legacyOnly; - } + protected virtual bool LegacyOnly => false; [BackgroundDependencyLoader] private void load() { foreach (var ruleset in Rulesets.AvailableRulesets) { - if (!ruleset.IsLegacyRuleset() && legacyOnly) + if (!ruleset.IsLegacyRuleset() && LegacyOnly) continue; try From a16050534d3a72c7225d5ecff22ea82e7be59c60 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Thu, 12 Jan 2023 14:20:16 -0800 Subject: [PATCH 1476/2991] Fix mute button not blocking outside overlay closing presses --- osu.Game/Overlays/Volume/MuteButton.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index 9cc346a38b..5acbbd2803 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -88,5 +88,11 @@ namespace osu.Game.Overlays.Volume { Content.TransformTo, ColourInfo>("BorderColour", unhoveredColour, 500, Easing.OutQuint); } + + protected override bool OnMouseDown(MouseDownEvent e) + { + base.OnMouseDown(e); + return true; + } } } From c554a34eaf8ebeedf306a2192f980d2f3774c77b Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 13 Jan 2023 02:11:05 +0300 Subject: [PATCH 1477/2991] Add "fps" keyword to frame limiter dropdown --- .../Overlays/Settings/Sections/Graphics/RendererSettings.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index 775606caf0..a5fdfdc105 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -27,7 +27,8 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics new SettingsEnumDropdown { LabelText = GraphicsSettingsStrings.FrameLimiter, - Current = config.GetBindable(FrameworkSetting.FrameSync) + Current = config.GetBindable(FrameworkSetting.FrameSync), + Keywords = new[] { @"fps" }, }, new SettingsEnumDropdown { From 403ca05e5e61aeecb19ce9afeb59ca91bf2a49db Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Fri, 13 Jan 2023 00:52:14 +0100 Subject: [PATCH 1478/2991] Enable nullability for song select --- .../Multiplayer/MultiplayerMatchSongSelect.cs | 2 + .../OnlinePlay/OnlinePlaySongSelect.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 155 ++++++++++-------- 3 files changed, 87 insertions(+), 72 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs index 873a1b0d50..6a4ce7aff5 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using osu.Framework.Allocation; @@ -105,6 +106,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer Schedule(() => { + Debug.Assert(Carousel != null); Carousel.AllowSelection = true; }); }); diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs b/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs index b9d8912170..e0ae437d49 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs @@ -173,7 +173,7 @@ namespace osu.Game.Screens.OnlinePlay IsValidMod = IsValidMod }; - protected override IEnumerable<(FooterButton, OverlayContainer)> CreateFooterButtons() + protected override IEnumerable<(FooterButton, OverlayContainer?)> CreateFooterButtons() { var buttons = base.CreateFooterButtons().ToList(); buttons.Insert(buttons.FindIndex(b => b.Item1 is FooterButtonMods) + 1, (new FooterButtonFreeMods { Current = FreeMods }, freeModSelectOverlay)); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index f4804c6a6c..6826dffd5f 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; @@ -36,7 +34,6 @@ using osu.Framework.Input.Bindings; using osu.Game.Collections; using osu.Game.Graphics.UserInterface; using System.Diagnostics; -using JetBrains.Annotations; using osu.Game.Screens.Play; using osu.Game.Skinning; @@ -49,7 +46,7 @@ namespace osu.Game.Screens.Select protected const float BACKGROUND_BLUR = 20; private const float left_area_padding = 20; - public FilterControl FilterControl { get; private set; } + public FilterControl FilterControl { get; private set; } = null!; /// /// Whether this song select instance should take control of the global track, @@ -64,18 +61,18 @@ namespace osu.Game.Screens.Select /// /// Can be null if is false. /// - protected BeatmapOptionsOverlay BeatmapOptions { get; private set; } + protected BeatmapOptionsOverlay BeatmapOptions { get; private set; } = null!; /// /// Can be null if is false. /// - protected Footer Footer { get; private set; } + protected Footer? Footer { get; private set; } /// /// Contains any panel which is triggered by a footer button. /// Helps keep them located beneath the footer itself. /// - protected Container FooterPanels { get; private set; } + protected Container FooterPanels { get; private set; } = null!; /// /// Whether entering editor mode should be allowed. @@ -85,50 +82,49 @@ namespace osu.Game.Screens.Select public bool BeatmapSetsLoaded => IsLoaded && Carousel?.BeatmapSetsLoaded == true; [Resolved] - private Bindable> selectedMods { get; set; } + private Bindable> selectedMods { get; set; } = null!; - protected BeatmapCarousel Carousel { get; private set; } + protected BeatmapCarousel? Carousel { get; private set; } - private ParallaxContainer wedgeBackground; + private ParallaxContainer wedgeBackground = null!; - protected Container LeftArea { get; private set; } + protected Container LeftArea { get; private set; } = null!; - private BeatmapInfoWedge beatmapInfoWedge; - - [Resolved(canBeNull: true)] - private IDialogOverlay dialogOverlay { get; set; } + private BeatmapInfoWedge beatmapInfoWedge = null!; [Resolved] - private BeatmapManager beatmaps { get; set; } + private IDialogOverlay? dialogOverlay { get; set; } - protected ModSelectOverlay ModSelect { get; private set; } + [Resolved] + private BeatmapManager beatmaps { get; set; } = null!; - protected Sample SampleConfirm { get; private set; } + protected ModSelectOverlay ModSelect { get; private set; } = null!; - private Sample sampleChangeDifficulty; - private Sample sampleChangeBeatmap; + protected Sample? SampleConfirm { get; private set; } - private Container carouselContainer; + private Sample sampleChangeDifficulty = null!; + private Sample sampleChangeBeatmap = null!; - protected BeatmapDetailArea BeatmapDetails { get; private set; } + private Container carouselContainer = null!; - private FooterButtonOptions beatmapOptionsButton; + protected BeatmapDetailArea BeatmapDetails { get; private set; } = null!; + + private FooterButtonOptions beatmapOptionsButton = null!; private readonly Bindable decoupledRuleset = new Bindable(); private double audioFeedbackLastPlaybackTime; - [CanBeNull] - private IDisposable modSelectOverlayRegistration; + private IDisposable? modSelectOverlayRegistration; [Resolved] - private MusicController music { get; set; } + private MusicController? music { get; set; } - [Resolved(CanBeNull = true)] - internal IOverlayManager OverlayManager { get; private set; } + [Resolved] + internal IOverlayManager? OverlayManager { get; private set; } [BackgroundDependencyLoader(true)] - private void load(AudioManager audio, OsuColour colours, ManageCollectionsDialog manageCollectionsDialog, DifficultyRecommender recommender) + private void load(AudioManager audio, OsuColour colours, ManageCollectionsDialog? manageCollectionsDialog, DifficultyRecommender? recommender) { // initial value transfer is required for FilterControl (it uses our re-cached bindables in its async load for the initial filter). transferRulesetValue(); @@ -273,7 +269,7 @@ namespace osu.Game.Screens.Select BeatmapOptions = new BeatmapOptionsOverlay(), } }, - Footer = new Footer(), + Footer = new Footer() }); } @@ -318,16 +314,20 @@ namespace osu.Game.Screens.Select /// Creates the buttons to be displayed in the footer. /// /// A set of and an optional which the button opens when pressed. - protected virtual IEnumerable<(FooterButton, OverlayContainer)> CreateFooterButtons() => new (FooterButton, OverlayContainer)[] + protected virtual IEnumerable<(FooterButton, OverlayContainer?)> CreateFooterButtons() { - (new FooterButtonMods { Current = Mods }, ModSelect), - (new FooterButtonRandom + Debug.Assert(Carousel != null); + return new (FooterButton, OverlayContainer?)[] { - NextRandom = () => Carousel.SelectNextRandom(), - PreviousRandom = Carousel.SelectPreviousRandom - }, null), - (beatmapOptionsButton = new FooterButtonOptions(), BeatmapOptions) - }; + (new FooterButtonMods { Current = Mods }, ModSelect), + (new FooterButtonRandom + { + NextRandom = () => Carousel.SelectNextRandom(), + PreviousRandom = Carousel.SelectPreviousRandom + }, null), + (beatmapOptionsButton = new FooterButtonOptions(), BeatmapOptions) + }; + } protected virtual ModSelectOverlay CreateModSelectOverlay() => new SoloModSelectOverlay(); @@ -336,10 +336,11 @@ namespace osu.Game.Screens.Select // if not the current screen, we want to get carousel in a good presentation state before displaying (resume or enter). bool shouldDebounce = this.IsCurrentScreen(); + Debug.Assert(Carousel != null); Carousel.Filter(criteria, shouldDebounce); } - private DependencyContainer dependencies; + private DependencyContainer dependencies = null!; protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { @@ -357,7 +358,7 @@ namespace osu.Game.Screens.Select /// protected abstract BeatmapDetailArea CreateBeatmapDetailArea(); - public void Edit(BeatmapInfo beatmapInfo = null) + public void Edit(BeatmapInfo? beatmapInfo = null) { if (!AllowEditing) throw new InvalidOperationException($"Attempted to edit when {nameof(AllowEditing)} is disabled"); @@ -372,8 +373,10 @@ namespace osu.Game.Screens.Select /// An optional beatmap to override the current carousel selection. /// An optional ruleset to override the current carousel selection. /// An optional custom action to perform instead of . - public void FinaliseSelection(BeatmapInfo beatmapInfo = null, RulesetInfo ruleset = null, Action customStartAction = null) + public void FinaliseSelection(BeatmapInfo? beatmapInfo = null, RulesetInfo? ruleset = null, Action? customStartAction = null) { + Debug.Assert(Carousel != null); + // This is very important as we have not yet bound to screen-level bindables before the carousel load is completed. if (!Carousel.BeatmapSetsLoaded) { @@ -419,43 +422,44 @@ namespace osu.Game.Screens.Select /// If a resultant action occurred that takes the user away from SongSelect. protected abstract bool OnStart(); - private ScheduledDelegate selectionChangedDebounce; + private ScheduledDelegate? selectionChangedDebounce; - private void updateCarouselSelection(ValueChangedEvent e = null) + private void updateCarouselSelection(ValueChangedEvent? e = null) { var beatmap = e?.NewValue ?? Beatmap.Value; if (beatmap is DummyWorkingBeatmap || !this.IsCurrentScreen()) return; Logger.Log($"Song select working beatmap updated to {beatmap}"); - if (!Carousel.SelectBeatmap(beatmap.BeatmapInfo, false)) + Debug.Assert(Carousel != null); + + if (Carousel.SelectBeatmap(beatmap.BeatmapInfo, false)) return; + + // A selection may not have been possible with filters applied. + + // There was possibly a ruleset mismatch. This is a case we can help things along by updating the game-wide ruleset to match. + if (!beatmap.BeatmapInfo.Ruleset.Equals(decoupledRuleset.Value)) { - // A selection may not have been possible with filters applied. - - // There was possibly a ruleset mismatch. This is a case we can help things along by updating the game-wide ruleset to match. - if (!beatmap.BeatmapInfo.Ruleset.Equals(decoupledRuleset.Value)) - { - Ruleset.Value = beatmap.BeatmapInfo.Ruleset; - transferRulesetValue(); - } - - // Even if a ruleset mismatch was not the cause (ie. a text filter is applied), - // we still want to temporarily show the new beatmap, bypassing filters. - // This will be undone the next time the user changes the filter. - var criteria = FilterControl.CreateCriteria(); - criteria.SelectedBeatmapSet = beatmap.BeatmapInfo.BeatmapSet; - Carousel.Filter(criteria); - - Carousel.SelectBeatmap(beatmap.BeatmapInfo); + Ruleset.Value = beatmap.BeatmapInfo.Ruleset; + transferRulesetValue(); } + + // Even if a ruleset mismatch was not the cause (ie. a text filter is applied), + // we still want to temporarily show the new beatmap, bypassing filters. + // This will be undone the next time the user changes the filter. + var criteria = FilterControl.CreateCriteria(); + criteria.SelectedBeatmapSet = beatmap.BeatmapInfo.BeatmapSet; + Carousel.Filter(criteria); + + Carousel.SelectBeatmap(beatmap.BeatmapInfo); } // We need to keep track of the last selected beatmap ignoring debounce to play the correct selection sounds. - private BeatmapInfo beatmapInfoPrevious; - private BeatmapInfo beatmapInfoNoDebounce; - private RulesetInfo rulesetNoDebounce; + private BeatmapInfo? beatmapInfoPrevious; + private BeatmapInfo? beatmapInfoNoDebounce; + private RulesetInfo? rulesetNoDebounce; - private void updateSelectedBeatmap(BeatmapInfo beatmapInfo) + private void updateSelectedBeatmap(BeatmapInfo? beatmapInfo) { if (beatmapInfo == null && beatmapInfoNoDebounce == null) return; @@ -467,7 +471,7 @@ namespace osu.Game.Screens.Select performUpdateSelected(); } - private void updateSelectedRuleset(RulesetInfo ruleset) + private void updateSelectedRuleset(RulesetInfo? ruleset) { if (ruleset == null && rulesetNoDebounce == null) return; @@ -485,7 +489,7 @@ namespace osu.Game.Screens.Select private void performUpdateSelected() { var beatmap = beatmapInfoNoDebounce; - var ruleset = rulesetNoDebounce; + RulesetInfo? ruleset = rulesetNoDebounce; selectionChangedDebounce?.Cancel(); @@ -518,6 +522,7 @@ namespace osu.Game.Screens.Select if (transferRulesetValue()) { + Debug.Assert(Carousel != null); // transferRulesetValue() may trigger a re-filter. If the current selection does not match the new ruleset, we want to switch away from it. // The default logic on WorkingBeatmap change is to switch to a matching ruleset (see workingBeatmapChanged()), but we don't want that here. // We perform an early selection attempt and clear out the beatmap selection to avoid a second ruleset change (revert). @@ -604,6 +609,7 @@ namespace osu.Game.Screens.Select ModSelect.SelectedMods.Disabled = false; ModSelect.SelectedMods.BindTo(selectedMods); + Debug.Assert(Carousel != null); Carousel.AllowSelection = true; BeatmapDetails.Refresh(); @@ -620,6 +626,7 @@ namespace osu.Game.Screens.Select { // restart playback on returning to song select, regardless. // not sure this should be a permanent thing (we may want to leave a user pause paused even on returning) + Debug.Assert(music != null); music.ResetTrackAdjustments(); music.Play(requestedByUser: true); } @@ -665,6 +672,7 @@ namespace osu.Game.Screens.Select BeatmapOptions.Hide(); + Debug.Assert(Carousel != null); Carousel.AllowSelection = false; endLooping(); @@ -694,6 +702,8 @@ namespace osu.Game.Screens.Select isHandlingLooping = true; ensureTrackLooping(Beatmap.Value, TrackChangeDirection.None); + + Debug.Assert(music != null); music.TrackChanged += ensureTrackLooping; } @@ -703,6 +713,7 @@ namespace osu.Game.Screens.Select if (!isHandlingLooping) return; + Debug.Assert(music != null); music.CurrentTrack.Looping = isHandlingLooping = false; music.TrackChanged -= ensureTrackLooping; @@ -763,7 +774,7 @@ namespace osu.Game.Screens.Select } } - private readonly WeakReference lastTrack = new WeakReference(null); + private readonly WeakReference lastTrack = new WeakReference(null); /// /// Ensures some music is playing for the current track. @@ -774,6 +785,7 @@ namespace osu.Game.Screens.Select if (!ControlGlobalMusic) return; + Debug.Assert(music != null); ITrack track = music.CurrentTrack; bool isNewTrack = !lastTrack.TryGetTarget(out var last) || last != track; @@ -791,6 +803,7 @@ namespace osu.Game.Screens.Select { bindBindables(); + Debug.Assert(Carousel != null); Carousel.AllowSelection = true; // If a selection was already obtained, do not attempt to update the selected beatmap. @@ -868,14 +881,14 @@ namespace osu.Game.Screens.Select return true; } - private void delete(BeatmapSetInfo beatmap) + private void delete(BeatmapSetInfo? beatmap) { if (beatmap == null) return; dialogOverlay?.Push(new BeatmapDeleteDialog(beatmap)); } - private void clearScores(BeatmapInfo beatmapInfo) + private void clearScores(BeatmapInfo? beatmapInfo) { if (beatmapInfo == null) return; @@ -950,7 +963,7 @@ namespace osu.Game.Screens.Select private partial class ResetScrollContainer : Container { - private readonly Action onHoverAction; + private readonly Action? onHoverAction; public ResetScrollContainer(Action onHoverAction) { From 464c5eaa2f430dd293df5f5fb016a0dbce064082 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jan 2023 12:16:35 +0900 Subject: [PATCH 1479/2991] Fix grammar --- osu.Game/Overlays/OverlayRulesetSelector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs index b9274231b0..9205a14d9f 100644 --- a/osu.Game/Overlays/OverlayRulesetSelector.cs +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays { public partial class OverlayRulesetSelector : RulesetSelector { - // Since this component is used in online overlays and currently web-side doesn't support non-legacy rulesets - let's disable them for now. + // Since this component is used in online overlays and currently web-side doesn't support non-legacy rulesets, let's disable them for now. protected override bool LegacyOnly => true; public OverlayRulesetSelector() From d8e0e67c458d2955b4f1dfc0d5165a2a2102bf10 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jan 2023 12:26:45 +0900 Subject: [PATCH 1480/2991] Add default version specifications to iOS csproj file Matches implementation for android. --- osu.iOS/osu.iOS.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.iOS/osu.iOS.csproj b/osu.iOS/osu.iOS.csproj index def538af1a..fa4c61372f 100644 --- a/osu.iOS/osu.iOS.csproj +++ b/osu.iOS/osu.iOS.csproj @@ -4,6 +4,9 @@ 13.4 Exe true + 0.0.0 + 1 + $(Version) From 5a38abe67923ab550a3b60936b864d544d09893b Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Thu, 12 Jan 2023 19:32:53 -0800 Subject: [PATCH 1481/2991] Add comment highlighting reason for blocking mouse down --- osu.Game/Overlays/Volume/MuteButton.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index 5acbbd2803..c83ad4ac0d 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -92,6 +92,8 @@ namespace osu.Game.Overlays.Volume protected override bool OnMouseDown(MouseDownEvent e) { base.OnMouseDown(e); + + // Block mouse down to avoid dismissing overlays sitting behind the mute button return true; } } From bdf901e490ca972a7142bd947a48a68a090e935e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jan 2023 15:27:56 +0900 Subject: [PATCH 1482/2991] Use more correct default version to avoid startup crash on attempting to parse --- osu.iOS/osu.iOS.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.iOS/osu.iOS.csproj b/osu.iOS/osu.iOS.csproj index fa4c61372f..9a31525517 100644 --- a/osu.iOS/osu.iOS.csproj +++ b/osu.iOS/osu.iOS.csproj @@ -4,8 +4,8 @@ 13.4 Exe true - 0.0.0 - 1 + 1.0.0 + $(Version) $(Version) From 5658c3a12325035c3a751fcaf4fcc092ee5c4faa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jan 2023 15:20:18 +0900 Subject: [PATCH 1483/2991] Enable NRT on account creation classes --- osu.Game/Online/API/RegistrationRequest.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/osu.Game/Online/API/RegistrationRequest.cs b/osu.Game/Online/API/RegistrationRequest.cs index 6dc867481a..dfedaa30e0 100644 --- a/osu.Game/Online/API/RegistrationRequest.cs +++ b/osu.Game/Online/API/RegistrationRequest.cs @@ -1,17 +1,16 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - +using System; using Newtonsoft.Json; namespace osu.Game.Online.API { public class RegistrationRequest : OsuWebRequest { - internal string Username; - internal string Email; - internal string Password; + internal string Username = string.Empty; + internal string Email = string.Empty; + internal string Password = string.Empty; protected override void PrePerform() { @@ -24,18 +23,18 @@ namespace osu.Game.Online.API public class RegistrationRequestErrors { - public UserErrors User; + public UserErrors? User; public class UserErrors { [JsonProperty("username")] - public string[] Username; + public string[] Username = Array.Empty(); [JsonProperty("user_email")] - public string[] Email; + public string[] Email = Array.Empty(); [JsonProperty("password")] - public string[] Password; + public string[] Password = Array.Empty(); } } } From a7327b02a2b3ecb2df7713ed86dc3a0e12ac83e8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jan 2023 15:32:53 +0900 Subject: [PATCH 1484/2991] Add API level support for error message and redirect during registration flow --- osu.Game/Online/API/APIAccess.cs | 29 +++++++++++++++++++--- osu.Game/Online/API/RegistrationRequest.cs | 10 ++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 757f6598e7..94bb77d6ec 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -329,12 +329,35 @@ namespace osu.Game.Online.API { try { - return JObject.Parse(req.GetResponseString().AsNonNull()).SelectToken("form_error", true).AsNonNull().ToObject(); + return JObject.Parse(req.GetResponseString().AsNonNull()).SelectToken(@"form_error", true).AsNonNull().ToObject(); } catch { - // if we couldn't deserialize the error message let's throw the original exception outwards. - e.Rethrow(); + try + { + // attempt to parse a non-form error message + var response = JObject.Parse(req.GetResponseString().AsNonNull()); + + string redirect = (string)response.SelectToken(@"url", true); + string message = (string)response.SelectToken(@"error", false); + + if (!string.IsNullOrEmpty(redirect)) + { + return new RegistrationRequest.RegistrationRequestErrors + { + Redirect = redirect, + Message = message, + }; + } + + // if we couldn't deserialize the error message let's throw the original exception outwards. + e.Rethrow(); + } + catch + { + // if we couldn't deserialize the error message let's throw the original exception outwards. + e.Rethrow(); + } } } diff --git a/osu.Game/Online/API/RegistrationRequest.cs b/osu.Game/Online/API/RegistrationRequest.cs index dfedaa30e0..78633f70b7 100644 --- a/osu.Game/Online/API/RegistrationRequest.cs +++ b/osu.Game/Online/API/RegistrationRequest.cs @@ -23,6 +23,16 @@ namespace osu.Game.Online.API public class RegistrationRequestErrors { + /// + /// An optional error message. + /// + public string? Message; + + /// + /// An optional URL which the user should be directed towards to complete registration. + /// + public string? Redirect; + public UserErrors? User; public class UserErrors From 4d58e6d8d2ab35b3addd1c70a5e1d46de1b8d836 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jan 2023 15:36:45 +0900 Subject: [PATCH 1485/2991] Add UI support for redirecting the user to web registration --- .../Overlays/AccountCreation/ScreenEntry.cs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs index ea1ee2c9a9..fe53ca0309 100644 --- a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs +++ b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs @@ -47,6 +47,9 @@ namespace osu.Game.Overlays.AccountCreation [Resolved] private GameHost host { get; set; } + [Resolved] + private OsuGame game { get; set; } + [BackgroundDependencyLoader] private void load() { @@ -194,9 +197,20 @@ namespace osu.Game.Overlays.AccountCreation { if (errors != null) { - usernameDescription.AddErrors(errors.User.Username); - emailAddressDescription.AddErrors(errors.User.Email); - passwordDescription.AddErrors(errors.User.Password); + if (errors.User != null) + { + usernameDescription.AddErrors(errors.User.Username); + emailAddressDescription.AddErrors(errors.User.Email); + passwordDescription.AddErrors(errors.User.Password); + } + + if (!string.IsNullOrEmpty(errors.Redirect)) + { + if (!string.IsNullOrEmpty(errors.Message)) + passwordDescription.AddErrors(new[] { errors.Message }); + + game.OpenUrlExternally(errors.Redirect); + } } else { From 11f630d49d9491b8f44a23abafce13ac1f4d9b80 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jan 2023 15:42:34 +0900 Subject: [PATCH 1486/2991] Prefill username and email --- osu.Game/Overlays/AccountCreation/ScreenEntry.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs index fe53ca0309..2e20f83e9e 100644 --- a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs +++ b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs @@ -209,7 +209,7 @@ namespace osu.Game.Overlays.AccountCreation if (!string.IsNullOrEmpty(errors.Message)) passwordDescription.AddErrors(new[] { errors.Message }); - game.OpenUrlExternally(errors.Redirect); + game.OpenUrlExternally($"{errors.Redirect}?username={usernameTextBox.Text}&email={emailTextBox.Text}"); } } else From 911cc78094b82b41a9909bc79d7e3b8db21eeb67 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jan 2023 16:21:13 +0900 Subject: [PATCH 1487/2991] Fix debug build thinking it's deployed due to major version >= 1 --- osu.iOS/osu.iOS.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.iOS/osu.iOS.csproj b/osu.iOS/osu.iOS.csproj index 9a31525517..2d61b73125 100644 --- a/osu.iOS/osu.iOS.csproj +++ b/osu.iOS/osu.iOS.csproj @@ -4,7 +4,7 @@ 13.4 Exe true - 1.0.0 + 0.1.0 $(Version) $(Version) From 653376f5f2814476a3a29da545896d8c23badec7 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Fri, 13 Jan 2023 09:32:36 +0100 Subject: [PATCH 1488/2991] Fix test failures --- osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index cfee02dfb8..97ffd896c6 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -1151,7 +1151,7 @@ namespace osu.Game.Tests.Visual.SongSelect public WorkingBeatmap CurrentBeatmap => Beatmap.Value; public IWorkingBeatmap CurrentBeatmapDetailsBeatmap => BeatmapDetails.Beatmap; - public new BeatmapCarousel Carousel => base.Carousel; + public new BeatmapCarousel Carousel => base.Carousel!; public new ModSelectOverlay ModSelect => base.ModSelect; public new void PresentScore(ScoreInfo score) => base.PresentScore(score); From a6b6fb864eaa673e9f5cd325a1965624fb482973 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Fri, 13 Jan 2023 13:10:29 +0100 Subject: [PATCH 1489/2991] Make carousel non nullable and ensure pre load usages of methods that reference it are protected against failure --- .../SongSelect/TestScenePlaySongSelect.cs | 2 +- .../Multiplayer/MultiplayerMatchSongSelect.cs | 2 -- osu.Game/Screens/Select/SongSelect.cs | 29 +++++++------------ 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 97ffd896c6..cfee02dfb8 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -1151,7 +1151,7 @@ namespace osu.Game.Tests.Visual.SongSelect public WorkingBeatmap CurrentBeatmap => Beatmap.Value; public IWorkingBeatmap CurrentBeatmapDetailsBeatmap => BeatmapDetails.Beatmap; - public new BeatmapCarousel Carousel => base.Carousel!; + public new BeatmapCarousel Carousel => base.Carousel; public new ModSelectOverlay ModSelect => base.ModSelect; public new void PresentScore(ScoreInfo score) => base.PresentScore(score); diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs index 6a4ce7aff5..873a1b0d50 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using osu.Framework.Allocation; @@ -106,7 +105,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer Schedule(() => { - Debug.Assert(Carousel != null); Carousel.AllowSelection = true; }); }); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 6826dffd5f..ef5827fad7 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -79,12 +79,12 @@ namespace osu.Game.Screens.Select /// public virtual bool AllowEditing => true; - public bool BeatmapSetsLoaded => IsLoaded && Carousel?.BeatmapSetsLoaded == true; + public bool BeatmapSetsLoaded => IsLoaded && Carousel.BeatmapSetsLoaded; [Resolved] private Bindable> selectedMods { get; set; } = null!; - protected BeatmapCarousel? Carousel { get; private set; } + protected BeatmapCarousel Carousel { get; private set; } = null!; private ParallaxContainer wedgeBackground = null!; @@ -127,7 +127,7 @@ namespace osu.Game.Screens.Select private void load(AudioManager audio, OsuColour colours, ManageCollectionsDialog? manageCollectionsDialog, DifficultyRecommender? recommender) { // initial value transfer is required for FilterControl (it uses our re-cached bindables in its async load for the initial filter). - transferRulesetValue(); + transferRulesetValue(false); LoadComponentAsync(Carousel = new BeatmapCarousel { @@ -314,10 +314,8 @@ namespace osu.Game.Screens.Select /// Creates the buttons to be displayed in the footer. /// /// A set of and an optional which the button opens when pressed. - protected virtual IEnumerable<(FooterButton, OverlayContainer?)> CreateFooterButtons() - { - Debug.Assert(Carousel != null); - return new (FooterButton, OverlayContainer?)[] + protected virtual IEnumerable<(FooterButton, OverlayContainer?)> CreateFooterButtons() => + new (FooterButton, OverlayContainer?)[] { (new FooterButtonMods { Current = Mods }, ModSelect), (new FooterButtonRandom @@ -327,7 +325,6 @@ namespace osu.Game.Screens.Select }, null), (beatmapOptionsButton = new FooterButtonOptions(), BeatmapOptions) }; - } protected virtual ModSelectOverlay CreateModSelectOverlay() => new SoloModSelectOverlay(); @@ -336,7 +333,6 @@ namespace osu.Game.Screens.Select // if not the current screen, we want to get carousel in a good presentation state before displaying (resume or enter). bool shouldDebounce = this.IsCurrentScreen(); - Debug.Assert(Carousel != null); Carousel.Filter(criteria, shouldDebounce); } @@ -375,8 +371,6 @@ namespace osu.Game.Screens.Select /// An optional custom action to perform instead of . public void FinaliseSelection(BeatmapInfo? beatmapInfo = null, RulesetInfo? ruleset = null, Action? customStartAction = null) { - Debug.Assert(Carousel != null); - // This is very important as we have not yet bound to screen-level bindables before the carousel load is completed. if (!Carousel.BeatmapSetsLoaded) { @@ -431,8 +425,6 @@ namespace osu.Game.Screens.Select Logger.Log($"Song select working beatmap updated to {beatmap}"); - Debug.Assert(Carousel != null); - if (Carousel.SelectBeatmap(beatmap.BeatmapInfo, false)) return; // A selection may not have been possible with filters applied. @@ -522,7 +514,6 @@ namespace osu.Game.Screens.Select if (transferRulesetValue()) { - Debug.Assert(Carousel != null); // transferRulesetValue() may trigger a re-filter. If the current selection does not match the new ruleset, we want to switch away from it. // The default logic on WorkingBeatmap change is to switch to a matching ruleset (see workingBeatmapChanged()), but we don't want that here. // We perform an early selection attempt and clear out the beatmap selection to avoid a second ruleset change (revert). @@ -609,7 +600,6 @@ namespace osu.Game.Screens.Select ModSelect.SelectedMods.Disabled = false; ModSelect.SelectedMods.BindTo(selectedMods); - Debug.Assert(Carousel != null); Carousel.AllowSelection = true; BeatmapDetails.Refresh(); @@ -672,7 +662,6 @@ namespace osu.Game.Screens.Select BeatmapOptions.Hide(); - Debug.Assert(Carousel != null); Carousel.AllowSelection = false; endLooping(); @@ -803,7 +792,6 @@ namespace osu.Game.Screens.Select { bindBindables(); - Debug.Assert(Carousel != null); Carousel.AllowSelection = true; // If a selection was already obtained, do not attempt to update the selected beatmap. @@ -867,7 +855,7 @@ namespace osu.Game.Screens.Select /// Will immediately run filter operations if required. /// /// Whether a transfer occurred. - private bool transferRulesetValue() + private bool transferRulesetValue(bool carouselLoaded = true) { if (decoupledRuleset.Value?.Equals(Ruleset.Value) == true) return false; @@ -875,9 +863,12 @@ namespace osu.Game.Screens.Select Logger.Log($"decoupled ruleset transferred (\"{decoupledRuleset.Value}\" -> \"{Ruleset.Value}\")"); rulesetNoDebounce = decoupledRuleset.Value = Ruleset.Value; + // We don't want to declare the carousel as nullable, so this check allows us to avoid running the carousel flush during the loading process + if (!carouselLoaded) return true; + // if we have a pending filter operation, we want to run it now. // it could change selection (ie. if the ruleset has been changed). - Carousel?.FlushPendingFilterOperations(); + Carousel.FlushPendingFilterOperations(); return true; } From e38075c4ef06b0db3b436ddf374193d6ccefd609 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Fri, 13 Jan 2023 09:37:23 -0500 Subject: [PATCH 1490/2991] Use PlacementState to check juice stream placement --- osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs | 2 +- .../Edit/Compose/Components/ComposeBlueprintContainer.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index fbe897b484..0b9d1ad41d 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -188,7 +188,7 @@ namespace osu.Game.Rulesets.Catch.Edit if (EditorBeatmap.PlacementObject.Value is JuiceStream) { // Juice stream path is not subject to snapping. - if (((JuiceStream)EditorBeatmap.PlacementObject.Value).Distance != 0) + if (BlueprintContainer.currentPlacement.PlacementActive is PlacementBlueprint.PlacementState.Active) return null; } diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index f955ae9cd6..b1fcd57c51 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -35,7 +35,7 @@ namespace osu.Game.Screens.Edit.Compose.Components protected new EditorSelectionHandler SelectionHandler => (EditorSelectionHandler)base.SelectionHandler; - private PlacementBlueprint currentPlacement; + public PlacementBlueprint currentPlacement { get; private set; } /// /// Positional input must be received outside the container's bounds, From 6028abff3926f4e8b021e2e273e7b2927a0a0f52 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Fri, 13 Jan 2023 10:16:52 -0500 Subject: [PATCH 1491/2991] Code Quality --- .../Edit/CatchHitObjectComposer.cs | 2 +- .../Components/ComposeBlueprintContainer.cs | 30 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index 0b9d1ad41d..cdf0ccfae9 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -188,7 +188,7 @@ namespace osu.Game.Rulesets.Catch.Edit if (EditorBeatmap.PlacementObject.Value is JuiceStream) { // Juice stream path is not subject to snapping. - if (BlueprintContainer.currentPlacement.PlacementActive is PlacementBlueprint.PlacementState.Active) + if (BlueprintContainer.CurrentPlacement.PlacementActive is PlacementBlueprint.PlacementState.Active) return null; } diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index 8ec1cb9198..836fceea22 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -36,7 +36,7 @@ namespace osu.Game.Screens.Edit.Compose.Components protected new EditorSelectionHandler SelectionHandler => (EditorSelectionHandler)base.SelectionHandler; - public PlacementBlueprint currentPlacement { get; private set; } + public PlacementBlueprint CurrentPlacement { get; private set; } /// /// Positional input must be received outside the container's bounds, @@ -137,13 +137,13 @@ namespace osu.Game.Screens.Edit.Compose.Components private void updatePlacementNewCombo() { - if (currentPlacement?.HitObject is IHasComboInformation c) + if (CurrentPlacement?.HitObject is IHasComboInformation c) c.NewCombo = NewCombo.Value == TernaryState.True; } private void updatePlacementSamples() { - if (currentPlacement == null) return; + if (CurrentPlacement == null) return; foreach (var kvp in SelectionHandler.SelectionSampleStates) sampleChanged(kvp.Key, kvp.Value.Value); @@ -151,9 +151,9 @@ namespace osu.Game.Screens.Edit.Compose.Components private void sampleChanged(string sampleName, TernaryState state) { - if (currentPlacement == null) return; + if (CurrentPlacement == null) return; - var samples = currentPlacement.HitObject.Samples; + var samples = CurrentPlacement.HitObject.Samples; var existingSample = samples.FirstOrDefault(s => s.Name == sampleName); @@ -225,7 +225,7 @@ namespace osu.Game.Screens.Edit.Compose.Components // if no time was found from positional snapping, we should still quantize to the beat. snapResult.Time ??= Beatmap.SnapTime(EditorClock.CurrentTime, null); - currentPlacement.UpdateTimeAndPosition(snapResult); + CurrentPlacement.UpdateTimeAndPosition(snapResult); } #endregion @@ -234,9 +234,9 @@ namespace osu.Game.Screens.Edit.Compose.Components { base.Update(); - if (currentPlacement != null) + if (CurrentPlacement != null) { - switch (currentPlacement.PlacementActive) + switch (CurrentPlacement.PlacementActive) { case PlacementBlueprint.PlacementState.Waiting: if (!Composer.CursorInPlacementArea) @@ -252,7 +252,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (Composer.CursorInPlacementArea) ensurePlacementCreated(); - if (currentPlacement != null) + if (CurrentPlacement != null) updatePlacementPosition(); } @@ -281,13 +281,13 @@ namespace osu.Game.Screens.Edit.Compose.Components private void ensurePlacementCreated() { - if (currentPlacement != null) return; + if (CurrentPlacement != null) return; var blueprint = CurrentTool?.CreatePlacementBlueprint(); if (blueprint != null) { - placementBlueprintContainer.Child = currentPlacement = blueprint; + placementBlueprintContainer.Child = CurrentPlacement = blueprint; // Fixes a 1-frame position discrepancy due to the first mouse move event happening in the next frame updatePlacementPosition(); @@ -300,11 +300,11 @@ namespace osu.Game.Screens.Edit.Compose.Components private void removePlacement() { - if (currentPlacement == null) return; + if (CurrentPlacement == null) return; - currentPlacement.EndPlacement(false); - currentPlacement.Expire(); - currentPlacement = null; + CurrentPlacement.EndPlacement(false); + CurrentPlacement.Expire(); + CurrentPlacement = null; } private HitObjectCompositionTool currentTool; From 112cf403ecb08b19e43e1d00c96415d32dca096e Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Jan 2023 18:32:56 +0300 Subject: [PATCH 1492/2991] Fix intermittent failure in certain beatmap carousel tests --- osu.Game/Screens/Select/Carousel/SetPanelContent.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/SetPanelContent.cs b/osu.Game/Screens/Select/Carousel/SetPanelContent.cs index 7ca0e92ac8..8d6fbbf256 100644 --- a/osu.Game/Screens/Select/Carousel/SetPanelContent.cs +++ b/osu.Game/Screens/Select/Carousel/SetPanelContent.cs @@ -21,6 +21,8 @@ namespace osu.Game.Screens.Select.Carousel private readonly CarouselBeatmapSet carouselSet; + private FillFlowContainer iconFlow = null!; + public SetPanelContent(CarouselBeatmapSet carouselSet) { this.carouselSet = carouselSet; @@ -82,13 +84,12 @@ namespace osu.Game.Screens.Select.Carousel TextPadding = new MarginPadding { Horizontal = 8, Vertical = 2 }, Status = beatmapSet.Status }, - new FillFlowContainer + iconFlow = new FillFlowContainer { AutoSizeAxes = Axes.Both, Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, Spacing = new Vector2(3), - ChildrenEnumerable = getDifficultyIcons(), }, } } @@ -96,6 +97,12 @@ namespace osu.Game.Screens.Select.Carousel }; } + protected override void LoadComplete() + { + base.LoadComplete(); + iconFlow.ChildrenEnumerable = getDifficultyIcons(); + } + private const int maximum_difficulty_icons = 18; private IEnumerable getDifficultyIcons() From 777c3f447cfb4acedd8a017504e0dc7ad4fc2d4b Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Jan 2023 19:29:13 +0300 Subject: [PATCH 1493/2991] Add leading zeros to test beatmaps for correct title sorting --- osu.Game.Tests/Resources/TestResources.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Resources/TestResources.cs b/osu.Game.Tests/Resources/TestResources.cs index 9c85f61330..adf28afc8e 100644 --- a/osu.Game.Tests/Resources/TestResources.cs +++ b/osu.Game.Tests/Resources/TestResources.cs @@ -12,6 +12,7 @@ using System.Threading; using NUnit.Framework; using osu.Framework.Extensions; using osu.Framework.IO.Stores; +using osu.Framework.Logging; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; @@ -93,10 +94,12 @@ namespace osu.Game.Tests.Resources { // Create random metadata, then we can check if sorting works based on these Artist = "Some Artist " + RNG.Next(0, 9), - Title = $"Some Song (set id {setId}) {Guid.NewGuid()}", + Title = $"Some Song (set id {setId:000}) {Guid.NewGuid()}", Author = { Username = "Some Guy " + RNG.Next(0, 9) }, }; + Logger.Log($"🛠️ Generating beatmap set \"{metadata}\" for test consumption."); + var beatmapSet = new BeatmapSetInfo { OnlineID = setId, From e6ff262521119fbfd9ebfb4c5400de1836ecbcbf Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Jan 2023 19:31:49 +0300 Subject: [PATCH 1494/2991] Fix potential nullref in certain beatmap carousel tests --- .../SongSelect/TestSceneBeatmapCarousel.cs | 42 +++++++++++++++---- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 1a466dea58..ea9508ecff 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -16,7 +16,9 @@ using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets; +using osu.Game.Rulesets.Catch; using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Taiko; using osu.Game.Screens.Select; using osu.Game.Screens.Select.Carousel; using osu.Game.Screens.Select.Filter; @@ -926,10 +928,7 @@ namespace osu.Game.Tests.Visual.SongSelect // 10 sets that go osu! -> taiko -> catch -> osu! -> ... for (int i = 0; i < 10; i++) - { - var rulesetInfo = rulesets.AvailableRulesets.ElementAt(i % 3); - sets.Add(TestResources.CreateTestBeatmapSetInfo(5, new[] { rulesetInfo })); - } + sets.Add(TestResources.CreateTestBeatmapSetInfo(5, new[] { getRuleset(i) })); // Sort mode is important to keep the ruleset order loadBeatmaps(sets, () => new FilterCriteria { Sort = SortMode.Title }); @@ -937,13 +936,29 @@ namespace osu.Game.Tests.Visual.SongSelect for (int i = 1; i < 10; i++) { - var rulesetInfo = rulesets.AvailableRulesets.ElementAt(i % 3); + var rulesetInfo = getRuleset(i % 3); + AddStep($"Set ruleset to {rulesetInfo.ShortName}", () => { carousel.Filter(new FilterCriteria { Ruleset = rulesetInfo, Sort = SortMode.Title }, false); }); waitForSelection(i + 1, 1); } + + static RulesetInfo getRuleset(int index) + { + switch (index % 3) + { + default: + return new OsuRuleset().RulesetInfo; + + case 1: + return new TaikoRuleset().RulesetInfo; + + case 2: + return new CatchRuleset().RulesetInfo; + } + } } [Test] @@ -953,10 +968,7 @@ namespace osu.Game.Tests.Visual.SongSelect // 10 sets that go taiko, osu!, osu!, osu!, taiko, osu!, osu!, osu!, ... for (int i = 0; i < 10; i++) - { - var rulesetInfo = rulesets.AvailableRulesets.ElementAt(i % 4 == 0 ? 1 : 0); - sets.Add(TestResources.CreateTestBeatmapSetInfo(5, new[] { rulesetInfo })); - } + sets.Add(TestResources.CreateTestBeatmapSetInfo(5, new[] { getRuleset(i) })); // Sort mode is important to keep the ruleset order loadBeatmaps(sets, () => new FilterCriteria { Sort = SortMode.Title }); @@ -974,6 +986,18 @@ namespace osu.Game.Tests.Visual.SongSelect carousel.Filter(new FilterCriteria { Sort = SortMode.Title }, false); }); } + + static RulesetInfo getRuleset(int index) + { + switch (index % 4) + { + case 0: + return new TaikoRuleset().RulesetInfo; + + default: + return new OsuRuleset().RulesetInfo; + } + } } private void loadBeatmaps(List beatmapSets = null, Func initialCriteria = null, Action carouselAdjust = null, int? count = null, From c62d416680e3b1a4a019fd7d7b1d09f3fba9cc4f Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 13 Jan 2023 22:54:38 +0300 Subject: [PATCH 1495/2991] Add localisation for notification overlay --- osu.Game/Localisation/NotificationsStrings.cs | 17 ++++++++++++++++- osu.Game/Overlays/NotificationOverlay.cs | 4 ++-- .../Notifications/NotificationSection.cs | 6 +++--- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/osu.Game/Localisation/NotificationsStrings.cs b/osu.Game/Localisation/NotificationsStrings.cs index 382e0d81f4..c7df185543 100644 --- a/osu.Game/Localisation/NotificationsStrings.cs +++ b/osu.Game/Localisation/NotificationsStrings.cs @@ -19,6 +19,21 @@ namespace osu.Game.Localisation /// public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"waiting for 'ya"); - private static string getKey(string key) => $"{prefix}:{key}"; + /// + /// "Running Tasks" + /// + public static LocalisableString RunningTasks => new TranslatableString(getKey(@"running_tasks"), @"Running Tasks"); + + /// + /// "Clear All" + /// + public static LocalisableString ClearAll => new TranslatableString(getKey(@"clear_all"), @"Clear All"); + + /// + /// "Cancel All" + /// + public static LocalisableString CancelAll => new TranslatableString(getKey(@"cancel_all"), @"Cancel All"); + + private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 3f3c6551c6..71a4c58afd 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -92,8 +92,8 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.X, Children = new[] { - new NotificationSection(AccountsStrings.NotificationsTitle, new[] { typeof(SimpleNotification) }, "Clear All"), - new NotificationSection(@"Running Tasks", new[] { typeof(ProgressNotification) }, @"Cancel All"), + new NotificationSection(AccountsStrings.NotificationsTitle, new[] { typeof(SimpleNotification) }, NotificationsStrings.ClearAll), + new NotificationSection(NotificationsStrings.RunningTasks, new[] { typeof(ProgressNotification) }, NotificationsStrings.CancelAll), } } } diff --git a/osu.Game/Overlays/Notifications/NotificationSection.cs b/osu.Game/Overlays/Notifications/NotificationSection.cs index d55a2abd2a..de4c72e473 100644 --- a/osu.Game/Overlays/Notifications/NotificationSection.cs +++ b/osu.Game/Overlays/Notifications/NotificationSection.cs @@ -33,15 +33,15 @@ namespace osu.Game.Overlays.Notifications public IEnumerable AcceptedNotificationTypes { get; } - private readonly string clearButtonText; + private readonly LocalisableString clearButtonText; private readonly LocalisableString titleText; - public NotificationSection(LocalisableString title, IEnumerable acceptedNotificationTypes, string clearButtonText) + public NotificationSection(LocalisableString title, IEnumerable acceptedNotificationTypes, LocalisableString clearButtonText) { AcceptedNotificationTypes = acceptedNotificationTypes.ToArray(); - this.clearButtonText = clearButtonText.ToUpperInvariant(); + this.clearButtonText = clearButtonText.ToUpper(); titleText = title; } From b681a0d47fd796bab5c8ec3c04b08f76f86af0a6 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Jan 2023 22:50:59 +0300 Subject: [PATCH 1496/2991] Fix intermittent failure in score submission tests --- .../Visual/Gameplay/TestScenePlayerScoreSubmission.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerScoreSubmission.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerScoreSubmission.cs index d5031bc606..1a7ea20cc0 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerScoreSubmission.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerScoreSubmission.cs @@ -181,7 +181,8 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for fail", () => Player.GameplayState.HasFailed); AddStep("exit", () => Player.Exit()); - AddAssert("ensure failing submission", () => Player.SubmittedScore?.ScoreInfo.Passed == false); + AddUntilStep("wait for submission", () => Player.SubmittedScore != null); + AddAssert("ensure failing submission", () => Player.SubmittedScore.ScoreInfo.Passed == false); } [Test] @@ -209,7 +210,9 @@ namespace osu.Game.Tests.Visual.Gameplay addFakeHit(); AddStep("exit", () => Player.Exit()); - AddAssert("ensure failing submission", () => Player.SubmittedScore?.ScoreInfo.Passed == false); + + AddUntilStep("wait for submission", () => Player.SubmittedScore != null); + AddAssert("ensure failing submission", () => Player.SubmittedScore.ScoreInfo.Passed == false); } [Test] From a41a031909090e2d952990c2cf0818b78d652568 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 13 Jan 2023 23:11:25 +0300 Subject: [PATCH 1497/2991] Localise some notifications --- osu.Game/Localisation/NotificationsStrings.cs | 27 ++++++++++++++++++- osu.Game/Screens/Menu/IntroScreen.cs | 3 ++- osu.Game/Screens/Play/HUDOverlay.cs | 3 ++- osu.Game/Screens/Play/PlayerLoader.cs | 5 ++-- osu.Game/Screens/Select/PlaySongSelect.cs | 3 ++- 5 files changed, 35 insertions(+), 6 deletions(-) diff --git a/osu.Game/Localisation/NotificationsStrings.cs b/osu.Game/Localisation/NotificationsStrings.cs index c7df185543..737a4b4391 100644 --- a/osu.Game/Localisation/NotificationsStrings.cs +++ b/osu.Game/Localisation/NotificationsStrings.cs @@ -15,7 +15,7 @@ namespace osu.Game.Localisation public static LocalisableString HeaderTitle => new TranslatableString(getKey(@"header_title"), @"notifications"); /// - /// "waiting for 'ya" + /// "waiting for 'ya" /// public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"waiting for 'ya"); @@ -34,6 +34,31 @@ namespace osu.Game.Localisation /// public static LocalisableString CancelAll => new TranslatableString(getKey(@"cancel_all"), @"Cancel All"); + /// + /// "Your battery level is low! Charge your device to prevent interruptions during gameplay." + /// + public static LocalisableString LowBatteryWarning => new TranslatableString(getKey(@"low_battery_warning"), @"Your battery level is low! Charge your device to prevent interruptions during gameplay."); + + /// + /// "Your game volume is too low to hear anything! Click here to restore it." + /// + public static LocalisableString GameVolumeTooLow => new TranslatableString(getKey(@"game_volume_too_low"), @"Your game volume is too low to hear anything! Click here to restore it."); + + /// + /// "The current ruleset doesn't have an autoplay mod available!" + /// + public static LocalisableString NoAutoplayMod => new TranslatableString(getKey(@"no_autoplay_mod"), @"The current ruleset doesn't have an autoplay mod available!"); + + /// + /// "osu! doesn't seem to be able to play audio correctly.\n\nPlease try changing your audio device to a working setting." + /// + public static LocalisableString AudioPlaybackIssue => new TranslatableString(getKey(@"audio_playback_issue"), @"osu! doesn't seem to be able to play audio correctly.\n\nPlease try changing your audio device to a working setting."); + + /// + /// "The score overlay is currently disabled. You can toggle this by pressing {0}." + /// + public static LocalisableString TheScoreOverlayIsDisabled(LocalisableString arg0) => new TranslatableString(getKey(@"the_score_overlay_is_disabled"), @"The score overlay is currently disabled. You can toggle this by pressing {0}.", arg0); + private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index f632d9ee73..de7732dd5e 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -20,6 +20,7 @@ using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Database; +using osu.Game.Localisation; using osu.Game.Online.API; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; @@ -201,7 +202,7 @@ namespace osu.Game.Screens.Menu { notifications.Post(new SimpleErrorNotification { - Text = "osu! doesn't seem to be able to play audio correctly.\n\nPlease try changing your audio device to a working setting." + Text = NotificationsStrings.AudioPlaybackIssue }); } }, 5000); diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 4c2483a0e6..ee198d0209 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -24,6 +24,7 @@ using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.HUD.ClicksPerSecond; using osu.Game.Skinning; using osuTK; +using osu.Game.Localisation; namespace osu.Game.Screens.Play { @@ -172,7 +173,7 @@ namespace osu.Game.Screens.Play notificationOverlay?.Post(new SimpleNotification { - Text = $"The score overlay is currently disabled. You can toggle this by pressing {config.LookupKeyBindings(GlobalAction.ToggleInGameInterface)}." + Text = NotificationsStrings.TheScoreOverlayIsDisabled(config.LookupKeyBindings(GlobalAction.ToggleInGameInterface)) }); } diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 5cedd4f793..324dd1ddaf 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -20,6 +20,7 @@ using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Input; +using osu.Game.Localisation; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; using osu.Game.Screens.Menu; @@ -550,7 +551,7 @@ namespace osu.Game.Screens.Play public MutedNotification() { - Text = "Your game volume is too low to hear anything! Click here to restore it."; + Text = NotificationsStrings.GameVolumeTooLow; } [BackgroundDependencyLoader] @@ -605,7 +606,7 @@ namespace osu.Game.Screens.Play public BatteryWarningNotification() { - Text = "Your battery level is low! Charge your device to prevent interruptions during gameplay."; + Text = NotificationsStrings.LowBatteryWarning; } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index f73cfe8d55..00a45d5d5a 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Framework.Screens; using osu.Game.Graphics; +using osu.Game.Localisation; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; using osu.Game.Rulesets.Mods; @@ -89,7 +90,7 @@ namespace osu.Game.Screens.Select { notifications?.Post(new SimpleNotification { - Text = "The current ruleset doesn't have an autoplay mod avalaible!" + Text = NotificationsStrings.NoAutoplayMod }); return false; } From 515ada6815eee1dbf9f1166a42c6f4f4ecb0bdd8 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 13 Jan 2023 23:11:50 +0300 Subject: [PATCH 1498/2991] Remove `CanBeNull` where it's no longer requered --- osu.Game/Screens/Play/PlayerLoader.cs | 6 +++--- osu.Game/Screens/Select/PlaySongSelect.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 324dd1ddaf..de67642104 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -131,16 +131,16 @@ namespace osu.Game.Screens.Play private bool quickRestart; - [Resolved(CanBeNull = true)] + [Resolved] private INotificationOverlay? notificationOverlay { get; set; } - [Resolved(CanBeNull = true)] + [Resolved] private VolumeOverlay? volumeOverlay { get; set; } [Resolved] private AudioManager audioManager { get; set; } = null!; - [Resolved(CanBeNull = true)] + [Resolved] private BatteryInfo? batteryInfo { get; set; } public PlayerLoader(Func createPlayer) diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 00a45d5d5a..9edca1d0c0 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -25,7 +25,7 @@ namespace osu.Game.Screens.Select { private OsuScreen? playerLoader; - [Resolved(CanBeNull = true)] + [Resolved] private INotificationOverlay? notifications { get; set; } public override bool AllowExternalScreenChange => true; From 2e28f5ed335b588bb5bff9cf2a660f6c836c4dff Mon Sep 17 00:00:00 2001 From: StanR Date: Fri, 13 Jan 2023 23:18:24 +0300 Subject: [PATCH 1499/2991] Add `StatusIcon` --- osu.Game/Users/Drawables/StatusIcon.cs | 26 ++++++++++++++++++++++++++ osu.Game/Users/ExtendedUserPanel.cs | 9 ++------- 2 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 osu.Game/Users/Drawables/StatusIcon.cs diff --git a/osu.Game/Users/Drawables/StatusIcon.cs b/osu.Game/Users/Drawables/StatusIcon.cs new file mode 100644 index 0000000000..108d81ed57 --- /dev/null +++ b/osu.Game/Users/Drawables/StatusIcon.cs @@ -0,0 +1,26 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osuTK; + +namespace osu.Game.Users.Drawables +{ + public partial class StatusIcon : CircularContainer + { + public StatusIcon() + { + Size = new Vector2(25); + BorderThickness = 4; + BorderColour = Colour; + Masking = true; + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Colour4.White.Opacity(0) + }; + } + } +} diff --git a/osu.Game/Users/ExtendedUserPanel.cs b/osu.Game/Users/ExtendedUserPanel.cs index 85b71a5bc7..4ea3c036c1 100644 --- a/osu.Game/Users/ExtendedUserPanel.cs +++ b/osu.Game/Users/ExtendedUserPanel.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Framework.Graphics.Sprites; using osu.Game.Users.Drawables; using osu.Framework.Input.Events; using osu.Game.Online.API.Requests.Responses; @@ -25,7 +24,7 @@ namespace osu.Game.Users protected TextFlowContainer LastVisitMessage { get; private set; } - private SpriteIcon statusIcon; + private StatusIcon statusIcon; private OsuSpriteText statusMessage; protected ExtendedUserPanel(APIUser user) @@ -59,11 +58,7 @@ namespace osu.Game.Users Action = Action, }; - protected SpriteIcon CreateStatusIcon() => statusIcon = new SpriteIcon - { - Icon = FontAwesome.Regular.Circle, - Size = new Vector2(25) - }; + protected Container CreateStatusIcon() => statusIcon = new StatusIcon(); protected FillFlowContainer CreateStatusMessage(bool rightAlignedChildren) { From 5750d82c0a6979fc02aca02f5624af02592b4b27 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Fri, 13 Jan 2023 12:50:12 -0800 Subject: [PATCH 1500/2991] Move overlay ruleset selectors to tab control --- .../UserInterface/TestSceneOverlayHeader.cs | 2 +- .../Overlays/BeatmapSet/BeatmapSetHeader.cs | 11 ++++++++-- osu.Game/Overlays/OverlayHeader.cs | 22 ++++--------------- osu.Game/Overlays/Profile/ProfileHeader.cs | 12 +++++----- .../Rankings/RankingsOverlayHeader.cs | 2 +- osu.Game/Overlays/TabControlOverlayHeader.cs | 20 ++++++++++++++--- 6 files changed, 37 insertions(+), 32 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs index 8f10065d17..e90041774e 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs @@ -108,7 +108,7 @@ namespace osu.Game.Tests.Visual.UserInterface protected override OverlayTitle CreateTitle() => new TestTitle(); - protected override Drawable CreateTitleContent() => new OverlayRulesetSelector(); + protected override Drawable CreateTabControlContent() => new OverlayRulesetSelector(); public TestStringTabControlHeader() { diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs index fa9c9b5018..858742648c 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs @@ -8,6 +8,7 @@ using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Effects; +using osu.Framework.Localisation; using osu.Game.Online.API.Requests.Responses; using osu.Game.Resources.Localisation.Web; using osu.Game.Rulesets; @@ -16,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet { - public partial class BeatmapSetHeader : OverlayHeader + public partial class BeatmapSetHeader : TabControlOverlayHeader { public readonly Bindable BeatmapSet = new Bindable(); @@ -46,7 +47,7 @@ namespace osu.Game.Overlays.BeatmapSet BeatmapSet = { BindTarget = BeatmapSet } }; - protected override Drawable CreateTitleContent() => RulesetSelector = new BeatmapRulesetSelector + protected override Drawable CreateTabControlContent() => RulesetSelector = new BeatmapRulesetSelector { Current = ruleset }; @@ -62,4 +63,10 @@ namespace osu.Game.Overlays.BeatmapSet } } } + + public enum BeatmapSetTabs + { + [LocalisableDescription(typeof(LayoutStrings), nameof(LayoutStrings.HeaderBeatmapsetsShow))] + Info, + } } diff --git a/osu.Game/Overlays/OverlayHeader.cs b/osu.Game/Overlays/OverlayHeader.cs index f8935f7f0a..f28d40c429 100644 --- a/osu.Game/Overlays/OverlayHeader.cs +++ b/osu.Game/Overlays/OverlayHeader.cs @@ -75,19 +75,11 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Children = new[] + Child = Title = CreateTitle().With(title => { - Title = CreateTitle().With(title => - { - title.Anchor = Anchor.CentreLeft; - title.Origin = Anchor.CentreLeft; - }), - CreateTitleContent().With(content => - { - content.Anchor = Anchor.CentreRight; - content.Origin = Anchor.CentreRight; - }) - } + title.Anchor = Anchor.CentreLeft; + title.Origin = Anchor.CentreLeft; + }), } } }, @@ -112,12 +104,6 @@ namespace osu.Game.Overlays [NotNull] protected virtual Drawable CreateBackground() => Empty(); - /// - /// Creates a on the opposite side of the . Used mostly to create . - /// - [NotNull] - protected virtual Drawable CreateTitleContent() => Empty(); - protected abstract OverlayTitle CreateTitle(); } } diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 4620cc7318..bd12837343 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -36,13 +36,6 @@ namespace osu.Game.Overlays.Profile // todo: pending implementation. // TabControl.AddItem(LayoutStrings.HeaderUsersModding); - TabControlContainer.Add(new ProfileRulesetSelector - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - User = { BindTarget = User } - }); - // Haphazardly guaranteed by OverlayHeader constructor (see CreateBackground / CreateContent). Debug.Assert(centreHeaderContainer != null); Debug.Assert(detailHeaderContainer != null); @@ -107,6 +100,11 @@ namespace osu.Game.Overlays.Profile protected override OverlayTitle CreateTitle() => new ProfileHeaderTitle(); + protected override Drawable CreateTabControlContent() => new ProfileRulesetSelector + { + User = { BindTarget = User } + }; + private void updateDisplay(UserProfileData? user) => coverContainer.User = user?.User; private partial class ProfileHeaderTitle : OverlayTitle diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index 3e0f780eeb..44f278a237 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.Rankings protected override OverlayTitle CreateTitle() => new RankingsTitle(); - protected override Drawable CreateTitleContent() => rulesetSelector = new OverlayRulesetSelector(); + protected override Drawable CreateTabControlContent() => rulesetSelector = new OverlayRulesetSelector(); protected override Drawable CreateContent() => countryFilter = new CountryFilter(); diff --git a/osu.Game/Overlays/TabControlOverlayHeader.cs b/osu.Game/Overlays/TabControlOverlayHeader.cs index 8613bac40c..2b87535708 100644 --- a/osu.Game/Overlays/TabControlOverlayHeader.cs +++ b/osu.Game/Overlays/TabControlOverlayHeader.cs @@ -62,10 +62,18 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Padding = new MarginPadding { Horizontal = ContentSidePadding }, - Child = TabControl = CreateTabControl().With(control => + Children = new[] { - control.Current = Current; - }) + TabControl = CreateTabControl().With(control => + { + control.Current = Current; + }), + CreateTabControlContent().With(content => + { + content.Anchor = Anchor.CentreRight; + content.Origin = Anchor.CentreRight; + }), + } } } }); @@ -80,6 +88,12 @@ namespace osu.Game.Overlays [NotNull] protected virtual OsuTabControl CreateTabControl() => new OverlayHeaderTabControl(); + /// + /// Creates a on the opposite side of the . Used mostly to create . + /// + [NotNull] + protected virtual Drawable CreateTabControlContent() => Empty(); + public partial class OverlayHeaderTabControl : OverlayTabControl { private const float bar_height = 1; From f950b624ae4f0659f12f43148b2782aff60b98df Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 00:26:35 +0300 Subject: [PATCH 1501/2991] Use existing string --- osu.Game/Localisation/NotificationsStrings.cs | 5 ----- osu.Game/Overlays/NotificationOverlay.cs | 4 +++- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Localisation/NotificationsStrings.cs b/osu.Game/Localisation/NotificationsStrings.cs index 737a4b4391..101e18d777 100644 --- a/osu.Game/Localisation/NotificationsStrings.cs +++ b/osu.Game/Localisation/NotificationsStrings.cs @@ -24,11 +24,6 @@ namespace osu.Game.Localisation /// public static LocalisableString RunningTasks => new TranslatableString(getKey(@"running_tasks"), @"Running Tasks"); - /// - /// "Clear All" - /// - public static LocalisableString ClearAll => new TranslatableString(getKey(@"clear_all"), @"Clear All"); - /// /// "Cancel All" /// diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 71a4c58afd..ed2a67cd6b 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -17,6 +17,7 @@ using osu.Game.Overlays.Notifications; using osu.Game.Resources.Localisation.Web; using osuTK; using NotificationsStrings = osu.Game.Localisation.NotificationsStrings; +using WebNotificationsStrings = osu.Game.Resources.Localisation.Web.NotificationsStrings; namespace osu.Game.Overlays { @@ -92,7 +93,8 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.X, Children = new[] { - new NotificationSection(AccountsStrings.NotificationsTitle, new[] { typeof(SimpleNotification) }, NotificationsStrings.ClearAll), + new NotificationSection(AccountsStrings.NotificationsTitle, new[] { typeof(SimpleNotification) }, + WebNotificationsStrings.MarkRead(WebNotificationsStrings.FiltersDefault)), new NotificationSection(NotificationsStrings.RunningTasks, new[] { typeof(ProgressNotification) }, NotificationsStrings.CancelAll), } } From d67184bd80e6410658140e0664525cf647c455da Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 00:26:44 +0300 Subject: [PATCH 1502/2991] Autoformat code --- osu.Game/Localisation/NotificationsStrings.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Localisation/NotificationsStrings.cs b/osu.Game/Localisation/NotificationsStrings.cs index 101e18d777..f5c3589c60 100644 --- a/osu.Game/Localisation/NotificationsStrings.cs +++ b/osu.Game/Localisation/NotificationsStrings.cs @@ -32,7 +32,8 @@ namespace osu.Game.Localisation /// /// "Your battery level is low! Charge your device to prevent interruptions during gameplay." /// - public static LocalisableString LowBatteryWarning => new TranslatableString(getKey(@"low_battery_warning"), @"Your battery level is low! Charge your device to prevent interruptions during gameplay."); + public static LocalisableString LowBatteryWarning => + new TranslatableString(getKey(@"low_battery_warning"), @"Your battery level is low! Charge your device to prevent interruptions during gameplay."); /// /// "Your game volume is too low to hear anything! Click here to restore it." @@ -47,12 +48,14 @@ namespace osu.Game.Localisation /// /// "osu! doesn't seem to be able to play audio correctly.\n\nPlease try changing your audio device to a working setting." /// - public static LocalisableString AudioPlaybackIssue => new TranslatableString(getKey(@"audio_playback_issue"), @"osu! doesn't seem to be able to play audio correctly.\n\nPlease try changing your audio device to a working setting."); + public static LocalisableString AudioPlaybackIssue => new TranslatableString(getKey(@"audio_playback_issue"), + @"osu! doesn't seem to be able to play audio correctly.\n\nPlease try changing your audio device to a working setting."); /// /// "The score overlay is currently disabled. You can toggle this by pressing {0}." /// - public static LocalisableString TheScoreOverlayIsDisabled(LocalisableString arg0) => new TranslatableString(getKey(@"the_score_overlay_is_disabled"), @"The score overlay is currently disabled. You can toggle this by pressing {0}.", arg0); + public static LocalisableString TheScoreOverlayIsDisabled(LocalisableString arg0) => new TranslatableString(getKey(@"the_score_overlay_is_disabled"), + @"The score overlay is currently disabled. You can toggle this by pressing {0}.", arg0); private static string getKey(string key) => $@"{prefix}:{key}"; } From 85b2154f3a7ff6ca61934ad0710fcfba38b7cf83 Mon Sep 17 00:00:00 2001 From: StanR Date: Sat, 14 Jan 2023 01:12:17 +0300 Subject: [PATCH 1503/2991] Set border colour to white --- osu.Game/Users/Drawables/StatusIcon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Users/Drawables/StatusIcon.cs b/osu.Game/Users/Drawables/StatusIcon.cs index 108d81ed57..18d06a48f8 100644 --- a/osu.Game/Users/Drawables/StatusIcon.cs +++ b/osu.Game/Users/Drawables/StatusIcon.cs @@ -14,7 +14,7 @@ namespace osu.Game.Users.Drawables { Size = new Vector2(25); BorderThickness = 4; - BorderColour = Colour; + BorderColour = Colour4.White; // the colour is being applied through Colour - since it's multiplicative it applies to the border as well Masking = true; Child = new Box { From 0b5c89d01fde788848440d474b3d50de8e30383e Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Fri, 13 Jan 2023 23:07:21 +0000 Subject: [PATCH 1504/2991] revert additions to `SessionStatics` --- osu.Game.Tests/NonVisual/SessionStaticsTest.cs | 6 ------ osu.Game/Configuration/SessionStatics.cs | 4 ---- .../Screens/Play/HUD/PlayerSettingsOverlay.cs | 15 --------------- 3 files changed, 25 deletions(-) diff --git a/osu.Game.Tests/NonVisual/SessionStaticsTest.cs b/osu.Game.Tests/NonVisual/SessionStaticsTest.cs index 499c0e5d34..5c8254b947 100644 --- a/osu.Game.Tests/NonVisual/SessionStaticsTest.cs +++ b/osu.Game.Tests/NonVisual/SessionStaticsTest.cs @@ -24,16 +24,12 @@ namespace osu.Game.Tests.NonVisual sessionStatics.SetValue(Static.MutedAudioNotificationShownOnce, true); sessionStatics.SetValue(Static.LowBatteryNotificationShownOnce, true); sessionStatics.SetValue(Static.LastHoverSoundPlaybackTime, (double?)1d); - sessionStatics.SetValue(Static.ReplayPlaybackSettingExpanded, false); - sessionStatics.SetValue(Static.ReplayVisualSettingsExpanded, true); sessionStatics.SetValue(Static.SeasonalBackgrounds, new APISeasonalBackgrounds { EndDate = new DateTimeOffset(2022, 1, 1, 0, 0, 0, TimeSpan.Zero) }); Assert.IsFalse(sessionStatics.GetBindable(Static.LoginOverlayDisplayed).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.MutedAudioNotificationShownOnce).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.LowBatteryNotificationShownOnce).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.LastHoverSoundPlaybackTime).IsDefault); - Assert.IsFalse(sessionStatics.GetBindable(Static.ReplayPlaybackSettingExpanded).IsDefault); - Assert.IsFalse(sessionStatics.GetBindable(Static.ReplayVisualSettingsExpanded).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.SeasonalBackgrounds).IsDefault); sessionStatics.ResetAfterInactivity(); @@ -43,8 +39,6 @@ namespace osu.Game.Tests.NonVisual Assert.IsTrue(sessionStatics.GetBindable(Static.LowBatteryNotificationShownOnce).IsDefault); // some statics should not reset despite inactivity. Assert.IsFalse(sessionStatics.GetBindable(Static.LastHoverSoundPlaybackTime).IsDefault); - Assert.IsFalse(sessionStatics.GetBindable(Static.ReplayPlaybackSettingExpanded).IsDefault); - Assert.IsFalse(sessionStatics.GetBindable(Static.ReplayVisualSettingsExpanded).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.SeasonalBackgrounds).IsDefault); } } diff --git a/osu.Game/Configuration/SessionStatics.cs b/osu.Game/Configuration/SessionStatics.cs index f08658f182..12a30a0c84 100644 --- a/osu.Game/Configuration/SessionStatics.cs +++ b/osu.Game/Configuration/SessionStatics.cs @@ -20,8 +20,6 @@ namespace osu.Game.Configuration SetDefault(Static.MutedAudioNotificationShownOnce, false); SetDefault(Static.LowBatteryNotificationShownOnce, false); SetDefault(Static.LastHoverSoundPlaybackTime, (double?)null); - SetDefault(Static.ReplayPlaybackSettingExpanded, true); - SetDefault(Static.ReplayVisualSettingsExpanded, false); SetDefault(Static.SeasonalBackgrounds, null); } @@ -44,8 +42,6 @@ namespace osu.Game.Configuration LoginOverlayDisplayed, MutedAudioNotificationShownOnce, LowBatteryNotificationShownOnce, - ReplayPlaybackSettingExpanded, - ReplayVisualSettingsExpanded, /// /// Info about seasonal backgrounds available fetched from API - see . diff --git a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs index c4f07f77cd..1edb227a75 100644 --- a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs +++ b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs @@ -3,15 +3,12 @@ #nullable disable -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; using osuTK; using osu.Game.Screens.Play.PlayerSettings; using osuTK.Input; -using osu.Game.Configuration; -using osu.Framework.Allocation; namespace osu.Game.Screens.Play.HUD { @@ -19,9 +16,6 @@ namespace osu.Game.Screens.Play.HUD { private const int fade_duration = 200; - private Bindable playbackMenuExpanded; - - private Bindable visualMenuExpanded; public bool ReplayLoaded; @@ -54,15 +48,6 @@ namespace osu.Game.Screens.Play.HUD }; } - [BackgroundDependencyLoader] - private void load(SessionStatics statics) - { - playbackMenuExpanded = statics.GetBindable(Static.ReplayPlaybackSettingExpanded); - visualMenuExpanded = statics.GetBindable(Static.ReplayVisualSettingsExpanded); - - PlaybackSettings.Expanded.BindTo(playbackMenuExpanded); - VisualSettings.Expanded.BindTo(visualMenuExpanded); - } protected override void PopIn() => this.FadeIn(fade_duration); protected override void PopOut() => this.FadeOut(fade_duration); From c3c1d77e8e8d0ccab211e461c84b73062c7aeece Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Fri, 13 Jan 2023 23:07:59 +0000 Subject: [PATCH 1505/2991] make `PlayerSettingsGroup` expand on hover --- .../Screens/Play/HUD/PlayerSettingsOverlay.cs | 6 ++--- .../PlayerSettings/PlayerSettingsGroup.cs | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs index 1edb227a75..019ba53a5e 100644 --- a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs +++ b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs @@ -16,7 +16,6 @@ namespace osu.Game.Screens.Play.HUD { private const int fade_duration = 200; - public bool ReplayLoaded; public readonly PlaybackSettings PlaybackSettings; @@ -42,13 +41,12 @@ namespace osu.Game.Screens.Play.HUD { //CollectionSettings = new CollectionSettings(), //DiscussionSettings = new DiscussionSettings(), - PlaybackSettings = new PlaybackSettings(), - VisualSettings = new VisualSettings() + PlaybackSettings = new PlaybackSettings { Expanded = { Value = false } }, + VisualSettings = new VisualSettings { Expanded = { Value = false } } } }; } - protected override void PopIn() => this.FadeIn(fade_duration); protected override void PopOut() => this.FadeOut(fade_duration); diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs index 6c6f62a8ac..63e081b2ea 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs @@ -4,6 +4,7 @@ #nullable disable using osu.Framework.Input.Events; +using osu.Framework.Threading; using osu.Game.Overlays; namespace osu.Game.Screens.Play.PlayerSettings @@ -15,12 +16,35 @@ namespace osu.Game.Screens.Play.PlayerSettings { } + private ScheduledDelegate hoverExpandEvent; + protected override bool OnHover(HoverEvent e) { + updateHoverExpansion(); base.OnHover(e); // Importantly, return true to correctly take focus away from PlayerLoader. return true; } + + protected override void OnHoverLost(HoverLostEvent e) + { + if (hoverExpandEvent == null) return; + + hoverExpandEvent?.Cancel(); + hoverExpandEvent = null; + + Expanded.Value = false; + + base.OnHoverLost(e); + } + + private void updateHoverExpansion() + { + hoverExpandEvent?.Cancel(); + + if (IsHovered && !Expanded.Value) + hoverExpandEvent = Scheduler.AddDelayed(() => Expanded.Value = true, 0); + } } } From 660bf748d59d2033f788de97cd3b23571d3be315 Mon Sep 17 00:00:00 2001 From: StanR Date: Sat, 14 Jan 2023 02:23:08 +0300 Subject: [PATCH 1506/2991] Fix `GroupBadge` crashing on `null` group colour --- osu.Game/Online/API/Requests/Responses/APIUserGroup.cs | 2 +- osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIUserGroup.cs b/osu.Game/Online/API/Requests/Responses/APIUserGroup.cs index 5f943e583e..89631d3d7a 100644 --- a/osu.Game/Online/API/Requests/Responses/APIUserGroup.cs +++ b/osu.Game/Online/API/Requests/Responses/APIUserGroup.cs @@ -8,7 +8,7 @@ namespace osu.Game.Online.API.Requests.Responses public class APIUserGroup { [JsonProperty(@"colour")] - public string Colour { get; set; } = null!; + public string? Colour { get; set; } [JsonProperty(@"has_listing")] public bool HasListings { get; set; } diff --git a/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs b/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs index ce56768a72..5a5c58dc93 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GroupBadge.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 System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; @@ -62,7 +63,7 @@ namespace osu.Game.Overlays.Profile.Header.Components new OsuSpriteText { Text = group.ShortName, - Colour = Color4Extensions.FromHex(group.Colour), + Colour = Color4Extensions.FromHex(group.Colour ?? Colour4.White.ToHex()), Shadow = false, Font = OsuFont.GetFont(size: TextSize, weight: FontWeight.Bold, italics: true) } From 78adaa9b03d5f73db721ebdd53bc477beb5b0d26 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 02:23:21 +0300 Subject: [PATCH 1507/2991] Enable nullability for timing screen --- .../Edit/Timing/ControlPointSettings.cs | 2 -- osu.Game/Screens/Edit/Timing/EffectSection.cs | 10 +++---- osu.Game/Screens/Edit/Timing/GroupSection.cs | 16 +++++------ .../IndeterminateSliderWithTextBoxInput.cs | 2 -- .../Edit/Timing/LabelledTimeSignature.cs | 4 +-- .../Screens/Edit/Timing/MetronomeDisplay.cs | 28 ++++++++----------- .../Edit/Timing/RepeatingButtonBehaviour.cs | 10 +++---- osu.Game/Screens/Edit/Timing/RowAttribute.cs | 6 ++-- .../RowAttributes/AttributeProgressBar.cs | 2 -- .../Timing/RowAttributes/AttributeText.cs | 2 -- .../RowAttributes/DifficultyRowAttribute.cs | 4 +-- .../RowAttributes/EffectRowAttribute.cs | 8 ++---- .../RowAttributes/SampleRowAttribute.cs | 6 ++-- .../RowAttributes/TimingRowAttribute.cs | 4 +-- osu.Game/Screens/Edit/Timing/Section.cs | 20 ++++++------- .../Edit/Timing/SliderWithTextBoxInput.cs | 2 -- osu.Game/Screens/Edit/Timing/TapButton.cs | 4 +-- .../Screens/Edit/Timing/TimingAdjustButton.cs | 16 +++++------ osu.Game/Screens/Edit/Timing/TimingSection.cs | 8 ++---- 19 files changed, 58 insertions(+), 96 deletions(-) diff --git a/osu.Game/Screens/Edit/Timing/ControlPointSettings.cs b/osu.Game/Screens/Edit/Timing/ControlPointSettings.cs index 97bd84b1b6..b76723378f 100644 --- a/osu.Game/Screens/Edit/Timing/ControlPointSettings.cs +++ b/osu.Game/Screens/Edit/Timing/ControlPointSettings.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Framework.Graphics; diff --git a/osu.Game/Screens/Edit/Timing/EffectSection.cs b/osu.Game/Screens/Edit/Timing/EffectSection.cs index 1f5400c03b..051ac97366 100644 --- a/osu.Game/Screens/Edit/Timing/EffectSection.cs +++ b/osu.Game/Screens/Edit/Timing/EffectSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -15,10 +13,10 @@ namespace osu.Game.Screens.Edit.Timing { internal partial class EffectSection : Section { - private LabelledSwitchButton kiai; - private LabelledSwitchButton omitBarLine; + private LabelledSwitchButton kiai = null!; + private LabelledSwitchButton omitBarLine = null!; - private SliderWithTextBoxInput scrollSpeedSlider; + private SliderWithTextBoxInput scrollSpeedSlider = null!; [BackgroundDependencyLoader] private void load() @@ -55,7 +53,7 @@ namespace osu.Game.Screens.Edit.Timing private bool isRebinding; - protected override void OnControlPointChanged(ValueChangedEvent point) + protected override void OnControlPointChanged(ValueChangedEvent point) { if (point.NewValue != null) { diff --git a/osu.Game/Screens/Edit/Timing/GroupSection.cs b/osu.Game/Screens/Edit/Timing/GroupSection.cs index f36989cf32..487a871881 100644 --- a/osu.Game/Screens/Edit/Timing/GroupSection.cs +++ b/osu.Game/Screens/Edit/Timing/GroupSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -17,21 +15,21 @@ namespace osu.Game.Screens.Edit.Timing { internal partial class GroupSection : CompositeDrawable { - private LabelledTextBox textBox; + private LabelledTextBox textBox = null!; - private OsuButton button; + private OsuButton button = null!; [Resolved] - protected Bindable SelectedGroup { get; private set; } + protected Bindable SelectedGroup { get; private set; } = null!; [Resolved] - protected EditorBeatmap Beatmap { get; private set; } + protected EditorBeatmap Beatmap { get; private set; } = null!; [Resolved] - private EditorClock clock { get; set; } + private EditorClock clock { get; set; } = null!; - [Resolved(canBeNull: true)] - private IEditorChangeHandler changeHandler { get; set; } + [Resolved] + private IEditorChangeHandler? changeHandler { get; set; } [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Screens/Edit/Timing/IndeterminateSliderWithTextBoxInput.cs b/osu.Game/Screens/Edit/Timing/IndeterminateSliderWithTextBoxInput.cs index 64713c7714..eabe9b9f64 100644 --- a/osu.Game/Screens/Edit/Timing/IndeterminateSliderWithTextBoxInput.cs +++ b/osu.Game/Screens/Edit/Timing/IndeterminateSliderWithTextBoxInput.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Globalization; using osu.Framework.Bindables; diff --git a/osu.Game/Screens/Edit/Timing/LabelledTimeSignature.cs b/osu.Game/Screens/Edit/Timing/LabelledTimeSignature.cs index 217aa46c3f..d0e1737f78 100644 --- a/osu.Game/Screens/Edit/Timing/LabelledTimeSignature.cs +++ b/osu.Game/Screens/Edit/Timing/LabelledTimeSignature.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -35,7 +33,7 @@ namespace osu.Game.Screens.Edit.Timing set => current.Current = value; } - private OsuNumberBox numeratorBox; + private OsuNumberBox numeratorBox = null!; [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Screens/Edit/Timing/MetronomeDisplay.cs b/osu.Game/Screens/Edit/Timing/MetronomeDisplay.cs index dfe2ec1f17..f4a39405a1 100644 --- a/osu.Game/Screens/Edit/Timing/MetronomeDisplay.cs +++ b/osu.Game/Screens/Edit/Timing/MetronomeDisplay.cs @@ -1,10 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; @@ -28,24 +25,23 @@ namespace osu.Game.Screens.Edit.Timing { public partial class MetronomeDisplay : BeatSyncedContainer { - private Container swing; + private Container swing = null!; - private OsuSpriteText bpmText; + private OsuSpriteText bpmText = null!; - private Drawable weight; - private Drawable stick; + private Drawable weight = null!; + private Drawable stick = null!; - private IAdjustableClock metronomeClock; + private IAdjustableClock metronomeClock = null!; - private Sample sampleTick; - private Sample sampleTickDownbeat; - private Sample sampleLatch; + private Sample? sampleTick; + private Sample? sampleTickDownbeat; + private Sample? sampleLatch; - [CanBeNull] - private ScheduledDelegate tickPlaybackDelegate; + private ScheduledDelegate? tickPlaybackDelegate; [Resolved] - private OverlayColourProvider overlayColourProvider { get; set; } + private OverlayColourProvider overlayColourProvider { get; set; } = null!; public bool EnableClicking { get; set; } = true; @@ -225,13 +221,13 @@ namespace osu.Game.Screens.Edit.Timing private double beatLength; - private TimingControlPoint timingPoint; + private TimingControlPoint timingPoint = null!; private bool isSwinging; private readonly BindableInt interpolatedBpm = new BindableInt(); - private ScheduledDelegate latchDelegate; + private ScheduledDelegate? latchDelegate; protected override void LoadComplete() { diff --git a/osu.Game/Screens/Edit/Timing/RepeatingButtonBehaviour.cs b/osu.Game/Screens/Edit/Timing/RepeatingButtonBehaviour.cs index 0b442fe5da..0437118f81 100644 --- a/osu.Game/Screens/Edit/Timing/RepeatingButtonBehaviour.cs +++ b/osu.Game/Screens/Edit/Timing/RepeatingButtonBehaviour.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Audio; @@ -23,10 +21,10 @@ namespace osu.Game.Screens.Edit.Timing private readonly Drawable button; - private Sample sample; + private Sample? sample; - public Action RepeatBegan; - public Action RepeatEnded; + public Action? RepeatBegan; + public Action? RepeatEnded; /// /// An additive modifier for the frequency of the sample played on next actuation. @@ -61,7 +59,7 @@ namespace osu.Game.Screens.Edit.Timing base.OnMouseUp(e); } - private ScheduledDelegate adjustDelegate; + private ScheduledDelegate? adjustDelegate; private double adjustDelay = initial_delay; private void beginRepeat() diff --git a/osu.Game/Screens/Edit/Timing/RowAttribute.cs b/osu.Game/Screens/Edit/Timing/RowAttribute.cs index 6f0553c771..71407701db 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttribute.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttribute.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -21,9 +19,9 @@ namespace osu.Game.Screens.Edit.Timing private readonly string label; - protected Drawable Background { get; private set; } + protected Drawable Background { get; private set; } = null!; - protected FillFlowContainer Content { get; private set; } + protected FillFlowContainer Content { get; private set; } = null!; public RowAttribute(ControlPoint point, string label) { diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeProgressBar.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeProgressBar.cs index 49791bd99a..4cae774078 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeProgressBar.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeProgressBar.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps.ControlPoints; diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeText.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeText.cs index c9d7aab5d8..d735c93523 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeText.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeText.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps.ControlPoints; diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/DifficultyRowAttribute.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/DifficultyRowAttribute.cs index 4d3704d44a..43f3739503 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/DifficultyRowAttribute.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/DifficultyRowAttribute.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -15,7 +13,7 @@ namespace osu.Game.Screens.Edit.Timing.RowAttributes { private readonly BindableNumber speedMultiplier; - private OsuSpriteText text; + private OsuSpriteText text = null!; public DifficultyRowAttribute(DifficultyControlPoint difficulty) : base(difficulty, "difficulty") diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/EffectRowAttribute.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/EffectRowAttribute.cs index 88943e5578..3b068699ca 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/EffectRowAttribute.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/EffectRowAttribute.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -16,9 +14,9 @@ namespace osu.Game.Screens.Edit.Timing.RowAttributes private readonly Bindable omitBarLine; private readonly BindableNumber scrollSpeed; - private AttributeText kiaiModeBubble; - private AttributeText omitBarLineBubble; - private AttributeText text; + private AttributeText kiaiModeBubble = null!; + private AttributeText omitBarLineBubble = null!; + private AttributeText text = null!; public EffectRowAttribute(EffectControlPoint effect) : base(effect, "effect") diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/SampleRowAttribute.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/SampleRowAttribute.cs index 915cf63baa..e86a991521 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/SampleRowAttribute.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/SampleRowAttribute.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -13,8 +11,8 @@ namespace osu.Game.Screens.Edit.Timing.RowAttributes { public partial class SampleRowAttribute : RowAttribute { - private AttributeText sampleText; - private OsuSpriteText volumeText; + private AttributeText sampleText = null!; + private OsuSpriteText volumeText = null!; private readonly Bindable sampleBank; private readonly BindableNumber volume; diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/TimingRowAttribute.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/TimingRowAttribute.cs index 3887282c6a..a6d3816bd4 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/TimingRowAttribute.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/TimingRowAttribute.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions; @@ -17,7 +15,7 @@ namespace osu.Game.Screens.Edit.Timing.RowAttributes { private readonly BindableNumber beatLength; private readonly Bindable timeSignature; - private OsuSpriteText text; + private OsuSpriteText text = null!; public TimingRowAttribute(TimingControlPoint timing) : base(timing, "timing") diff --git a/osu.Game/Screens/Edit/Timing/Section.cs b/osu.Game/Screens/Edit/Timing/Section.cs index ebba481099..ba3874dcee 100644 --- a/osu.Game/Screens/Edit/Timing/Section.cs +++ b/osu.Game/Screens/Edit/Timing/Section.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -19,23 +17,23 @@ namespace osu.Game.Screens.Edit.Timing internal abstract partial class Section : CompositeDrawable where T : ControlPoint { - private OsuCheckbox checkbox; - private Container content; + private OsuCheckbox checkbox = null!; + private Container content = null!; - protected FillFlowContainer Flow { get; private set; } + protected FillFlowContainer Flow { get; private set; } = null!; - protected Bindable ControlPoint { get; } = new Bindable(); + protected Bindable ControlPoint { get; } = new Bindable(); private const float header_height = 50; [Resolved] - protected EditorBeatmap Beatmap { get; private set; } + protected EditorBeatmap Beatmap { get; private set; } = null!; [Resolved] - protected Bindable SelectedGroup { get; private set; } + protected Bindable SelectedGroup { get; private set; } = null!; - [Resolved(canBeNull: true)] - protected IEditorChangeHandler ChangeHandler { get; private set; } + [Resolved] + protected IEditorChangeHandler? ChangeHandler { get; private set; } [BackgroundDependencyLoader] private void load(OverlayColourProvider colours) @@ -128,7 +126,7 @@ namespace osu.Game.Screens.Edit.Timing ControlPoint.BindValueChanged(OnControlPointChanged, true); } - protected abstract void OnControlPointChanged(ValueChangedEvent point); + protected abstract void OnControlPointChanged(ValueChangedEvent point); protected abstract T CreatePoint(); } diff --git a/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs b/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs index 65c5128438..1bf0e5299d 100644 --- a/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs +++ b/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Globalization; using osu.Framework.Bindables; diff --git a/osu.Game/Screens/Edit/Timing/TapButton.cs b/osu.Game/Screens/Edit/Timing/TapButton.cs index af5e6aa180..f28c6ccf0a 100644 --- a/osu.Game/Screens/Edit/Timing/TapButton.cs +++ b/osu.Game/Screens/Edit/Timing/TapButton.cs @@ -37,10 +37,10 @@ namespace osu.Game.Screens.Edit.Timing [Resolved] private OverlayColourProvider colourProvider { get; set; } = null!; - [Resolved(canBeNull: true)] + [Resolved] private Bindable? selectedGroup { get; set; } - [Resolved(canBeNull: true)] + [Resolved] private IBeatSyncProvider? beatSyncSource { get; set; } private Circle hoverLayer = null!; diff --git a/osu.Game/Screens/Edit/Timing/TimingAdjustButton.cs b/osu.Game/Screens/Edit/Timing/TimingAdjustButton.cs index 4018eff5d6..fac168c70c 100644 --- a/osu.Game/Screens/Edit/Timing/TimingAdjustButton.cs +++ b/osu.Game/Screens/Edit/Timing/TimingAdjustButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using osu.Framework.Allocation; @@ -22,7 +20,7 @@ namespace osu.Game.Screens.Edit.Timing /// public partial class TimingAdjustButton : CompositeDrawable { - public Action Action; + public Action? Action; private readonly double adjustAmount; @@ -44,10 +42,10 @@ namespace osu.Game.Screens.Edit.Timing private readonly RepeatingButtonBehaviour repeatBehaviour; [Resolved] - private OverlayColourProvider colourProvider { get; set; } + private OverlayColourProvider colourProvider { get; set; } = null!; [Resolved] - private EditorBeatmap editorBeatmap { get; set; } + private EditorBeatmap editorBeatmap { get; set; } = null!; public TimingAdjustButton(double adjustAmount) { @@ -104,7 +102,7 @@ namespace osu.Game.Screens.Edit.Timing if (hoveredBox == null) return false; - Action(adjustAmount * hoveredBox.Multiplier); + Action?.Invoke(adjustAmount * hoveredBox.Multiplier); hoveredBox.Flash(); @@ -119,6 +117,9 @@ namespace osu.Game.Screens.Edit.Timing private readonly Box box; private readonly OsuSpriteText text; + [Resolved] + private OverlayColourProvider colourProvider { get; set; } = null!; + public IncrementBox(int index, double amount) { Multiplier = Math.Sign(index) * convertMultiplier(index); @@ -156,9 +157,6 @@ namespace osu.Game.Screens.Edit.Timing }; } - [Resolved] - private OverlayColourProvider colourProvider { get; set; } - protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game/Screens/Edit/Timing/TimingSection.cs b/osu.Game/Screens/Edit/Timing/TimingSection.cs index 81abb266d4..d2d524ccbe 100644 --- a/osu.Game/Screens/Edit/Timing/TimingSection.cs +++ b/osu.Game/Screens/Edit/Timing/TimingSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -13,8 +11,8 @@ namespace osu.Game.Screens.Edit.Timing { internal partial class TimingSection : Section { - private LabelledTimeSignature timeSignature; - private BPMTextBox bpmTextEntry; + private LabelledTimeSignature timeSignature = null!; + private BPMTextBox bpmTextEntry = null!; [BackgroundDependencyLoader] private void load() @@ -45,7 +43,7 @@ namespace osu.Game.Screens.Edit.Timing private bool isRebinding; - protected override void OnControlPointChanged(ValueChangedEvent point) + protected override void OnControlPointChanged(ValueChangedEvent point) { if (point.NewValue != null) { From 4b42240fbabf6d542594b1691a4e2746947fecab Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 02:24:28 +0300 Subject: [PATCH 1508/2991] Enable nullability for setup screen --- osu.Game/Screens/Edit/Setup/ColoursSection.cs | 4 +--- osu.Game/Screens/Edit/Setup/DesignSection.cs | 18 ++++++++---------- .../Screens/Edit/Setup/DifficultySection.cs | 10 ++++------ .../Edit/Setup/LabelledRomanisedTextBox.cs | 2 -- .../Edit/Setup/LabelledTextBoxWithPopover.cs | 4 +--- osu.Game/Screens/Edit/Setup/MetadataSection.cs | 18 ++++++++---------- .../Screens/Edit/Setup/RulesetSetupSection.cs | 2 -- osu.Game/Screens/Edit/Setup/SetupScreen.cs | 2 -- .../Screens/Edit/Setup/SetupScreenHeader.cs | 8 +++----- .../Edit/Setup/SetupScreenHeaderBackground.cs | 6 ++---- osu.Game/Screens/Edit/Setup/SetupSection.cs | 8 +++----- 11 files changed, 30 insertions(+), 52 deletions(-) diff --git a/osu.Game/Screens/Edit/Setup/ColoursSection.cs b/osu.Game/Screens/Edit/Setup/ColoursSection.cs index 10ab272a87..8cd5c0f779 100644 --- a/osu.Game/Screens/Edit/Setup/ColoursSection.cs +++ b/osu.Game/Screens/Edit/Setup/ColoursSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; @@ -15,7 +13,7 @@ namespace osu.Game.Screens.Edit.Setup { public override LocalisableString Title => EditorSetupStrings.ColoursHeader; - private LabelledColourPalette comboColours; + private LabelledColourPalette comboColours = null!; [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Screens/Edit/Setup/DesignSection.cs b/osu.Game/Screens/Edit/Setup/DesignSection.cs index fd70b0c142..b05a073146 100644 --- a/osu.Game/Screens/Edit/Setup/DesignSection.cs +++ b/osu.Game/Screens/Edit/Setup/DesignSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Globalization; using System.Linq; @@ -19,16 +17,16 @@ namespace osu.Game.Screens.Edit.Setup { internal partial class DesignSection : SetupSection { - protected LabelledSwitchButton EnableCountdown; + protected LabelledSwitchButton EnableCountdown = null!; - protected FillFlowContainer CountdownSettings; - protected LabelledEnumDropdown CountdownSpeed; - protected LabelledNumberBox CountdownOffset; + protected FillFlowContainer CountdownSettings = null!; + protected LabelledEnumDropdown CountdownSpeed = null!; + protected LabelledNumberBox CountdownOffset = null!; - private LabelledSwitchButton widescreenSupport; - private LabelledSwitchButton epilepsyWarning; - private LabelledSwitchButton letterboxDuringBreaks; - private LabelledSwitchButton samplesMatchPlaybackRate; + private LabelledSwitchButton widescreenSupport = null!; + private LabelledSwitchButton epilepsyWarning = null!; + private LabelledSwitchButton letterboxDuringBreaks = null!; + private LabelledSwitchButton samplesMatchPlaybackRate = null!; public override LocalisableString Title => EditorSetupStrings.DesignHeader; diff --git a/osu.Game/Screens/Edit/Setup/DifficultySection.cs b/osu.Game/Screens/Edit/Setup/DifficultySection.cs index afe6b36cba..7026bde681 100644 --- a/osu.Game/Screens/Edit/Setup/DifficultySection.cs +++ b/osu.Game/Screens/Edit/Setup/DifficultySection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -17,10 +15,10 @@ namespace osu.Game.Screens.Edit.Setup { internal partial class DifficultySection : SetupSection { - private LabelledSliderBar circleSizeSlider; - private LabelledSliderBar healthDrainSlider; - private LabelledSliderBar approachRateSlider; - private LabelledSliderBar overallDifficultySlider; + private LabelledSliderBar circleSizeSlider = null!; + private LabelledSliderBar healthDrainSlider = null!; + private LabelledSliderBar approachRateSlider = null!; + private LabelledSliderBar overallDifficultySlider = null!; public override LocalisableString Title => EditorSetupStrings.DifficultyHeader; diff --git a/osu.Game/Screens/Edit/Setup/LabelledRomanisedTextBox.cs b/osu.Game/Screens/Edit/Setup/LabelledRomanisedTextBox.cs index 43c20b5e40..85c697bf14 100644 --- a/osu.Game/Screens/Edit/Setup/LabelledRomanisedTextBox.cs +++ b/osu.Game/Screens/Edit/Setup/LabelledRomanisedTextBox.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; diff --git a/osu.Game/Screens/Edit/Setup/LabelledTextBoxWithPopover.cs b/osu.Game/Screens/Edit/Setup/LabelledTextBoxWithPopover.cs index 05c8f88444..79288e2977 100644 --- a/osu.Game/Screens/Edit/Setup/LabelledTextBoxWithPopover.cs +++ b/osu.Game/Screens/Edit/Setup/LabelledTextBoxWithPopover.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Extensions; using osu.Framework.Graphics; @@ -30,7 +28,7 @@ namespace osu.Game.Screens.Edit.Setup internal partial class PopoverTextBox : OsuTextBox { - public Action OnFocused; + public Action? OnFocused; protected override bool OnDragStart(DragStartEvent e) { diff --git a/osu.Game/Screens/Edit/Setup/MetadataSection.cs b/osu.Game/Screens/Edit/Setup/MetadataSection.cs index c2c853f7b2..752f590308 100644 --- a/osu.Game/Screens/Edit/Setup/MetadataSection.cs +++ b/osu.Game/Screens/Edit/Setup/MetadataSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics.UserInterface; @@ -16,16 +14,16 @@ namespace osu.Game.Screens.Edit.Setup { public partial class MetadataSection : SetupSection { - protected LabelledTextBox ArtistTextBox; - protected LabelledTextBox RomanisedArtistTextBox; + protected LabelledTextBox ArtistTextBox = null!; + protected LabelledTextBox RomanisedArtistTextBox = null!; - protected LabelledTextBox TitleTextBox; - protected LabelledTextBox RomanisedTitleTextBox; + protected LabelledTextBox TitleTextBox = null!; + protected LabelledTextBox RomanisedTitleTextBox = null!; - private LabelledTextBox creatorTextBox; - private LabelledTextBox difficultyTextBox; - private LabelledTextBox sourceTextBox; - private LabelledTextBox tagsTextBox; + private LabelledTextBox creatorTextBox = null!; + private LabelledTextBox difficultyTextBox = null!; + private LabelledTextBox sourceTextBox = null!; + private LabelledTextBox tagsTextBox = null!; public override LocalisableString Title => EditorSetupStrings.MetadataHeader; diff --git a/osu.Game/Screens/Edit/Setup/RulesetSetupSection.cs b/osu.Game/Screens/Edit/Setup/RulesetSetupSection.cs index 0914bd47bc..af59868f29 100644 --- a/osu.Game/Screens/Edit/Setup/RulesetSetupSection.cs +++ b/osu.Game/Screens/Edit/Setup/RulesetSetupSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Localisation; using osu.Game.Rulesets; using osu.Game.Localisation; diff --git a/osu.Game/Screens/Edit/Setup/SetupScreen.cs b/osu.Game/Screens/Edit/Setup/SetupScreen.cs index cc705547de..ab4299a2f0 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreen.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreen.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; diff --git a/osu.Game/Screens/Edit/Setup/SetupScreenHeader.cs b/osu.Game/Screens/Edit/Setup/SetupScreenHeader.cs index 0a6643efeb..1d66830adf 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreenHeader.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreenHeader.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; @@ -18,12 +16,12 @@ namespace osu.Game.Screens.Edit.Setup { internal partial class SetupScreenHeader : OverlayHeader { - public SetupScreenHeaderBackground Background { get; private set; } + public SetupScreenHeaderBackground Background { get; private set; } = null!; [Resolved] - private SectionsContainer sections { get; set; } + private SectionsContainer sections { get; set; } = null!; - private SetupScreenTabControl tabControl; + private SetupScreenTabControl tabControl = null!; protected override OverlayTitle CreateTitle() => new SetupScreenTitle(); diff --git a/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs b/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs index 50743476bf..47a7512adf 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -18,10 +16,10 @@ namespace osu.Game.Screens.Edit.Setup public partial class SetupScreenHeaderBackground : CompositeDrawable { [Resolved] - private OsuColour colours { get; set; } + private OsuColour colours { get; set; } = null!; [Resolved] - private IBindable working { get; set; } + private IBindable working { get; set; } = null!; private readonly Container content; diff --git a/osu.Game/Screens/Edit/Setup/SetupSection.cs b/osu.Game/Screens/Edit/Setup/SetupSection.cs index c7690623ad..5f676798f1 100644 --- a/osu.Game/Screens/Edit/Setup/SetupSection.cs +++ b/osu.Game/Screens/Edit/Setup/SetupSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -16,7 +14,7 @@ namespace osu.Game.Screens.Edit.Setup { public abstract partial class SetupSection : Container { - private FillFlowContainer flow; + private FillFlowContainer flow = null!; /// /// Used to align some of the child s together to achieve a grid-like look. @@ -24,10 +22,10 @@ namespace osu.Game.Screens.Edit.Setup protected const float LABEL_WIDTH = 160; [Resolved] - protected OsuColour Colours { get; private set; } + protected OsuColour Colours { get; private set; } = null!; [Resolved] - protected EditorBeatmap Beatmap { get; private set; } + protected EditorBeatmap Beatmap { get; private set; } = null!; protected override Container Content => flow; From f70dedfd17768df2b2677fa293510fb767cd2ceb Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 02:24:48 +0300 Subject: [PATCH 1509/2991] Enable nullability for design screen --- osu.Game/Screens/Edit/Design/DesignScreen.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Design/DesignScreen.cs b/osu.Game/Screens/Edit/Design/DesignScreen.cs index 10b351ded1..c36afcdb6d 100644 --- a/osu.Game/Screens/Edit/Design/DesignScreen.cs +++ b/osu.Game/Screens/Edit/Design/DesignScreen.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Screens.Edit.Design { public partial class DesignScreen : EditorScreen From e2d6e31314253bb3dcfd1089ca082c2f0f80ad6b Mon Sep 17 00:00:00 2001 From: StanR Date: Sat, 14 Jan 2023 02:26:26 +0300 Subject: [PATCH 1510/2991] Using --- osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs b/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs index 5a5c58dc93..e62f1cebf0 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GroupBadge.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.Allocation; using osu.Framework.Extensions.Color4Extensions; From 77e8315ee28bbbdedb3d0182022ad3b3e6ec6bef Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 02:30:10 +0300 Subject: [PATCH 1511/2991] Adjust naming --- osu.Game/Localisation/NotificationsStrings.cs | 5 ++--- osu.Game/Screens/Play/HUDOverlay.cs | 2 +- osu.Game/Screens/Play/PlayerLoader.cs | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game/Localisation/NotificationsStrings.cs b/osu.Game/Localisation/NotificationsStrings.cs index f5c3589c60..a1c974c777 100644 --- a/osu.Game/Localisation/NotificationsStrings.cs +++ b/osu.Game/Localisation/NotificationsStrings.cs @@ -32,8 +32,7 @@ namespace osu.Game.Localisation /// /// "Your battery level is low! Charge your device to prevent interruptions during gameplay." /// - public static LocalisableString LowBatteryWarning => - new TranslatableString(getKey(@"low_battery_warning"), @"Your battery level is low! Charge your device to prevent interruptions during gameplay."); + public static LocalisableString BatteryLow => new TranslatableString(getKey(@"battery_low"), @"Your battery level is low! Charge your device to prevent interruptions during gameplay."); /// /// "Your game volume is too low to hear anything! Click here to restore it." @@ -54,7 +53,7 @@ namespace osu.Game.Localisation /// /// "The score overlay is currently disabled. You can toggle this by pressing {0}." /// - public static LocalisableString TheScoreOverlayIsDisabled(LocalisableString arg0) => new TranslatableString(getKey(@"the_score_overlay_is_disabled"), + public static LocalisableString ScoreOverlayDisabled(LocalisableString arg0) => new TranslatableString(getKey(@"score_overlay_disabled"), @"The score overlay is currently disabled. You can toggle this by pressing {0}.", arg0); private static string getKey(string key) => $@"{prefix}:{key}"; diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index ee198d0209..076d43c077 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -173,7 +173,7 @@ namespace osu.Game.Screens.Play notificationOverlay?.Post(new SimpleNotification { - Text = NotificationsStrings.TheScoreOverlayIsDisabled(config.LookupKeyBindings(GlobalAction.ToggleInGameInterface)) + Text = NotificationsStrings.ScoreOverlayDisabled(config.LookupKeyBindings(GlobalAction.ToggleInGameInterface)) }); } diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index de67642104..d9062da8aa 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -606,7 +606,7 @@ namespace osu.Game.Screens.Play public BatteryWarningNotification() { - Text = NotificationsStrings.LowBatteryWarning; + Text = NotificationsStrings.BatteryLow; } [BackgroundDependencyLoader] From cb4f32e7bd7fb2912e98ca0d70e1308cb646113d Mon Sep 17 00:00:00 2001 From: StanR Date: Sat, 14 Jan 2023 02:31:27 +0300 Subject: [PATCH 1512/2991] Use `StatusIcon` in `UserDropdown` --- osu.Game/Overlays/Login/UserDropdown.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Login/UserDropdown.cs b/osu.Game/Overlays/Login/UserDropdown.cs index dfc9d12977..f856f57c46 100644 --- a/osu.Game/Overlays/Login/UserDropdown.cs +++ b/osu.Game/Overlays/Login/UserDropdown.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; +using osu.Game.Users.Drawables; using osuTK; using osuTK.Graphics; @@ -78,7 +79,7 @@ namespace osu.Game.Overlays.Login { public const float LABEL_LEFT_MARGIN = 20; - private readonly SpriteIcon statusIcon; + private readonly StatusIcon statusIcon; public Color4 StatusColour { @@ -101,11 +102,10 @@ namespace osu.Game.Overlays.Login Icon.Size = new Vector2(14); Icon.Margin = new MarginPadding(0); - Foreground.Add(statusIcon = new SpriteIcon + Foreground.Add(statusIcon = new StatusIcon { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Icon = FontAwesome.Regular.Circle, Size = new Vector2(14), }); From 9e7ecbf4a14ebf97459677b128ef70528d0115e2 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 02:41:11 +0300 Subject: [PATCH 1513/2991] Adapt to changes in base class --- osu.Game/Overlays/Comments/CommentsContainer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 98c186b273..08542bbcea 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -429,15 +429,15 @@ namespace osu.Game.Overlays.Comments protected override void OnCommit(string text) { - CommitButton.IsLoadingSpinnerShown = true; + ShowLoadingSpinner = true; CommentPostRequest req = new CommentPostRequest(CommentableType.Value, CommentableId.Value, text); req.Failure += _ => Schedule(() => { - CommitButton.IsLoadingSpinnerShown = false; + ShowLoadingSpinner = false; }); req.Success += cb => Schedule(() => { - CommitButton.IsLoadingSpinnerShown = false; + ShowLoadingSpinner = false; Current.Value = string.Empty; OnPost?.Invoke(cb); }); From c95d8645f3afbd56ea71fc2be2093e9eab848b9a Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 02:42:04 +0300 Subject: [PATCH 1514/2991] Revert "Use existing string" This reverts commit f950b624ae4f0659f12f43148b2782aff60b98df. --- osu.Game/Localisation/NotificationsStrings.cs | 5 +++++ osu.Game/Overlays/NotificationOverlay.cs | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Localisation/NotificationsStrings.cs b/osu.Game/Localisation/NotificationsStrings.cs index a1c974c777..6a9793b20c 100644 --- a/osu.Game/Localisation/NotificationsStrings.cs +++ b/osu.Game/Localisation/NotificationsStrings.cs @@ -24,6 +24,11 @@ namespace osu.Game.Localisation /// public static LocalisableString RunningTasks => new TranslatableString(getKey(@"running_tasks"), @"Running Tasks"); + /// + /// "Clear All" + /// + public static LocalisableString ClearAll => new TranslatableString(getKey(@"clear_all"), @"Clear All"); + /// /// "Cancel All" /// diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index ed2a67cd6b..71a4c58afd 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -17,7 +17,6 @@ using osu.Game.Overlays.Notifications; using osu.Game.Resources.Localisation.Web; using osuTK; using NotificationsStrings = osu.Game.Localisation.NotificationsStrings; -using WebNotificationsStrings = osu.Game.Resources.Localisation.Web.NotificationsStrings; namespace osu.Game.Overlays { @@ -93,8 +92,7 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.X, Children = new[] { - new NotificationSection(AccountsStrings.NotificationsTitle, new[] { typeof(SimpleNotification) }, - WebNotificationsStrings.MarkRead(WebNotificationsStrings.FiltersDefault)), + new NotificationSection(AccountsStrings.NotificationsTitle, new[] { typeof(SimpleNotification) }, NotificationsStrings.ClearAll), new NotificationSection(NotificationsStrings.RunningTasks, new[] { typeof(ProgressNotification) }, NotificationsStrings.CancelAll), } } From bb8bcd7248153a5bf1ae2c96dcaf0e93bda0502e Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 02:50:30 +0300 Subject: [PATCH 1515/2991] Move avatar update bind to LoadComplete --- osu.Game/Overlays/Comments/CommentsContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 08542bbcea..9446857f5e 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -183,12 +183,12 @@ namespace osu.Game.Overlays.Comments }); User.BindTo(api.LocalUser); - User.BindValueChanged(e => avatar.User = e.NewValue); } protected override void LoadComplete() { User.BindValueChanged(_ => refetchComments()); + User.BindValueChanged(e => avatar.User = e.NewValue); Sort.BindValueChanged(_ => refetchComments(), true); base.LoadComplete(); } From e07c0c7c1fc215b24c16f82c4d015235ea2714f6 Mon Sep 17 00:00:00 2001 From: StanR Date: Sat, 14 Jan 2023 02:58:18 +0300 Subject: [PATCH 1516/2991] Using --- osu.Game/Overlays/Login/UserDropdown.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Login/UserDropdown.cs b/osu.Game/Overlays/Login/UserDropdown.cs index f856f57c46..0bdfa82517 100644 --- a/osu.Game/Overlays/Login/UserDropdown.cs +++ b/osu.Game/Overlays/Login/UserDropdown.cs @@ -7,7 +7,6 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Effects; -using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; From befb27551201a49cc11f6739dd0160afe718d7df Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 14 Jan 2023 14:34:22 +0300 Subject: [PATCH 1517/2991] Fix intermittent failure in GCC seeking test --- .../TestSceneMasterGameplayClockContainer.cs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneMasterGameplayClockContainer.cs b/osu.Game.Tests/Gameplay/TestSceneMasterGameplayClockContainer.cs index 3c6ec28da2..393217f371 100644 --- a/osu.Game.Tests/Gameplay/TestSceneMasterGameplayClockContainer.cs +++ b/osu.Game.Tests/Gameplay/TestSceneMasterGameplayClockContainer.cs @@ -73,16 +73,6 @@ namespace osu.Game.Tests.Gameplay } [Test] - [FlakyTest] - /* - * Fail rate around 0.15% - * - * TearDown : osu.Framework.Testing.Drawables.Steps.AssertButton+TracedException : gameplay clock time = 2500 - * --TearDown - * at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal() - * at osu.Framework.Threading.Scheduler.Update() - * at osu.Framework.Graphics.Drawable.UpdateSubTree() - */ public void TestSeekPerformsInGameplayTime( [Values(1.0, 0.5, 2.0)] double clockRate, [Values(0.0, 200.0, -200.0)] double userOffset, @@ -92,6 +82,9 @@ namespace osu.Game.Tests.Gameplay ClockBackedTestWorkingBeatmap working = null; GameplayClockContainer gameplayClockContainer = null; + // ReSharper disable once NotAccessedVariable + BindableDouble trackAdjustment = null; // keeping a reference for track adjustment + if (setAudioOffsetBeforeConstruction) AddStep($"preset audio offset to {userOffset}", () => localConfig.SetValue(OsuSetting.AudioOffset, userOffset)); @@ -103,16 +96,16 @@ namespace osu.Game.Tests.Gameplay gameplayClockContainer.Reset(startClock: !whileStopped); }); - AddStep($"set clock rate to {clockRate}", () => working.Track.AddAdjustment(AdjustableProperty.Frequency, new BindableDouble(clockRate))); + AddStep($"set clock rate to {clockRate}", () => working.Track.AddAdjustment(AdjustableProperty.Frequency, trackAdjustment = new BindableDouble(clockRate))); if (!setAudioOffsetBeforeConstruction) AddStep($"set audio offset to {userOffset}", () => localConfig.SetValue(OsuSetting.AudioOffset, userOffset)); AddStep("seek to 2500", () => gameplayClockContainer.Seek(2500)); - AddStep("gameplay clock time = 2500", () => Assert.AreEqual(gameplayClockContainer.CurrentTime, 2500, 10f)); + AddAssert("gameplay clock time = 2500", () => gameplayClockContainer.CurrentTime, () => Is.EqualTo(2500).Within(10f)); AddStep("seek to 10000", () => gameplayClockContainer.Seek(10000)); - AddStep("gameplay clock time = 10000", () => Assert.AreEqual(gameplayClockContainer.CurrentTime, 10000, 10f)); + AddAssert("gameplay clock time = 10000", () => gameplayClockContainer.CurrentTime, () => Is.EqualTo(10000).Within(10f)); } protected override void Dispose(bool isDisposing) From 2831db53f74088e1fb08e39cf51ded52cd5d76e9 Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Sat, 14 Jan 2023 14:19:02 +0000 Subject: [PATCH 1518/2991] fix wrong control flow on hover lost --- .../Play/PlayerSettings/PlayerSettingsGroup.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs index 63e081b2ea..f4769cd417 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs @@ -29,12 +29,13 @@ namespace osu.Game.Screens.Play.PlayerSettings protected override void OnHoverLost(HoverLostEvent e) { - if (hoverExpandEvent == null) return; + if (hoverExpandEvent != null) + { + hoverExpandEvent?.Cancel(); + hoverExpandEvent = null; - hoverExpandEvent?.Cancel(); - hoverExpandEvent = null; - - Expanded.Value = false; + Expanded.Value = false; + } base.OnHoverLost(e); } From 3fa81a52b4a6b1e99190c712f45adfd128b6ea2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 16:53:03 +0100 Subject: [PATCH 1519/2991] Add other profile sections to test scene --- .../Online/TestSceneUserProfileOverlay.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs index f209e8a8bb..f7e88e4437 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs @@ -86,12 +86,21 @@ namespace osu.Game.Tests.Visual.Online CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c1.jpg", JoinDate = DateTimeOffset.Now.AddDays(-1), LastVisit = DateTimeOffset.Now, - ProfileOrder = new[] { "me" }, Groups = new[] { new APIUserGroup { Colour = "#EB47D0", ShortName = "DEV", Name = "Developers" }, new APIUserGroup { Colour = "#A347EB", ShortName = "BN", Name = "Beatmap Nominators", Playmodes = new[] { "osu", "taiko" } } }, + ProfileOrder = new[] + { + @"me", + @"recent_activity", + @"beatmaps", + @"historical", + @"kudosu", + @"top_ranks", + @"medals" + }, Statistics = new UserStatistics { IsRanked = true, @@ -128,7 +137,12 @@ namespace osu.Game.Tests.Visual.Online Title = "osu!volunteer", Colour = "ff0000", Achievements = Array.Empty(), - PlayMode = "osu" + PlayMode = "osu", + Kudosu = new APIUser.KudosuCount + { + Available = 10, + Total = 50 + } }; } } From 49e08c06a626844eb32d880dcbf4a182325bc590 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 16:58:25 +0100 Subject: [PATCH 1520/2991] Adjust general appearance of user profile overlay --- .../Overlays/Profile/Header/MedalHeaderContainer.cs | 12 ++---------- osu.Game/Overlays/UserProfileOverlay.cs | 4 ++-- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index edb695a00e..2652550fb5 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -4,7 +4,6 @@ using System.Threading; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; @@ -12,7 +11,6 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile.Header.Components; using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header { @@ -43,14 +41,8 @@ namespace osu.Game.Overlays.Profile.Header Child = new Box { RelativeSizeAxes = Axes.Both, - Colour = new ColourInfo - { - TopLeft = Color4.Black.Opacity(0.2f), - TopRight = Color4.Black.Opacity(0.2f), - BottomLeft = Color4.Black.Opacity(0), - BottomRight = Color4.Black.Opacity(0) - } - }, + Colour = ColourInfo.GradientVertical(Colour4.Black.Opacity(0.2f), Colour4.Black.Opacity(0)) + } }, badgeFlowContainer = new FillFlowContainer { diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index cf7bb56cb8..b6ff78b09b 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -42,7 +42,7 @@ namespace osu.Game.Overlays [Resolved] private RulesetStore rulesets { get; set; } = null!; - public const float CONTENT_X_MARGIN = 70; + public const float CONTENT_X_MARGIN = 50; public UserProfileOverlay() : base(OverlayColourScheme.Pink) @@ -59,7 +59,7 @@ namespace osu.Game.Overlays protected override ProfileHeader CreateHeader() => new ProfileHeader(); - protected override Color4 BackgroundColour => ColourProvider.Background6; + protected override Color4 BackgroundColour => ColourProvider.Background5; public void ShowUser(IUser user, IRulesetInfo? ruleset = null) { From 3f81f173fb0b34ac5c2691be799f34b022b98840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 17:17:35 +0100 Subject: [PATCH 1521/2991] Adjust appearance of section navigation --- osu.Game/Overlays/UserProfileOverlay.cs | 80 +++++++++++++++++-------- 1 file changed, 54 insertions(+), 26 deletions(-) diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index b6ff78b09b..f9c6662ee3 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -12,7 +12,9 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Extensions; +using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Online; using osu.Game.Online.API.Requests; @@ -171,46 +173,72 @@ namespace osu.Game.Overlays loadingLayer.Hide(); } - private partial class ProfileSectionTabControl : OverlayTabControl + private partial class ProfileSectionTabControl : OsuTabControl { - private const float bar_height = 2; - public ProfileSectionTabControl() { - TabContainer.RelativeSizeAxes &= ~Axes.X; - TabContainer.AutoSizeAxes |= Axes.X; - TabContainer.Anchor |= Anchor.x1; - TabContainer.Origin |= Anchor.x1; - - Height = 36 + bar_height; - BarHeight = bar_height; + Height = 40; + Padding = new MarginPadding { Horizontal = CONTENT_X_MARGIN }; + TabContainer.Spacing = new Vector2(20); } - protected override TabItem CreateTabItem(ProfileSection value) => new ProfileSectionTabItem(value) - { - AccentColour = AccentColour, - }; - - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - AccentColour = colourProvider.Highlight1; - } + protected override TabItem CreateTabItem(ProfileSection value) => new ProfileSectionTabItem(value); protected override bool OnClick(ClickEvent e) => true; protected override bool OnHover(HoverEvent e) => true; - private partial class ProfileSectionTabItem : OverlayTabItem + private partial class ProfileSectionTabItem : TabItem { + private OsuSpriteText text = null!; + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } = null!; + public ProfileSectionTabItem(ProfileSection value) : base(value) { - Text.Text = value.Title; - Text.Font = Text.Font.With(size: 16); - Text.Margin = new MarginPadding { Bottom = 10 + bar_height }; - Bar.ExpandedSize = 10; - Bar.Margin = new MarginPadding { Bottom = bar_height }; + } + + [BackgroundDependencyLoader] + private void load() + { + AutoSizeAxes = Axes.Both; + Anchor = Anchor.CentreLeft; + Origin = Anchor.CentreLeft; + + InternalChild = text = new OsuSpriteText + { + Text = Value.Title + }; + + updateState(); + } + + protected override void OnActivated() => updateState(); + + protected override void OnDeactivated() => updateState(); + + protected override bool OnHover(HoverEvent e) + { + updateState(); + return true; + } + + protected override void OnHoverLost(HoverLostEvent e) => updateState(); + + private void updateState() + { + text.Font = OsuFont.Default.With(size: 14, weight: Active.Value ? FontWeight.SemiBold : FontWeight.Regular); + + Colour4 textColour; + + if (IsHovered) + textColour = colourProvider.Light1; + else + textColour = Active.Value ? colourProvider.Content1 : colourProvider.Light2; + + text.FadeColour(textColour, 300, Easing.OutQuint); } } } From 5b1111c6b1a0ba56aff0e7e4acf39558cd8362d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 17:32:20 +0100 Subject: [PATCH 1522/2991] Adjust appearance of user profile sections --- osu.Game/Overlays/Profile/ProfileSection.cs | 67 ++++++--------------- osu.Game/Overlays/UserProfileOverlay.cs | 4 +- 2 files changed, 22 insertions(+), 49 deletions(-) diff --git a/osu.Game/Overlays/Profile/ProfileSection.cs b/osu.Game/Overlays/Profile/ProfileSection.cs index edb3ec1733..03917b75a4 100644 --- a/osu.Game/Overlays/Profile/ProfileSection.cs +++ b/osu.Game/Overlays/Profile/ProfileSection.cs @@ -3,16 +3,15 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; using osu.Game.Graphics; -using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osuTK; namespace osu.Game.Overlays.Profile { @@ -30,22 +29,29 @@ namespace osu.Game.Overlays.Profile public readonly Bindable User = new Bindable(); + private const float outer_gutter_width = 10; + protected ProfileSection() { AutoSizeAxes = Axes.Y; RelativeSizeAxes = Axes.X; + Masking = true; + CornerRadius = 10; + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Offset = new Vector2(0, 1), + Radius = 3, + Colour = Colour4.Black.Opacity(0.25f) + }; + InternalChildren = new Drawable[] { background = new Box { RelativeSizeAxes = Axes.Both, }, - new SectionTriangles - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - }, new FillFlowContainer { Direction = FillDirection.Vertical, @@ -58,8 +64,8 @@ namespace osu.Game.Overlays.Profile AutoSizeAxes = Axes.Both, Margin = new MarginPadding { - Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, - Top = 15, + Horizontal = UserProfileOverlay.CONTENT_X_MARGIN - outer_gutter_width, + Top = 20, Bottom = 20, }, Children = new Drawable[] @@ -67,7 +73,7 @@ namespace osu.Game.Overlays.Profile new OsuSpriteText { Text = Title, - Font = OsuFont.GetFont(size: 20, weight: FontWeight.Bold), + Font = OsuFont.GetFont(size: 16, weight: FontWeight.Bold), }, underscore = new Box { @@ -88,7 +94,7 @@ namespace osu.Game.Overlays.Profile RelativeSizeAxes = Axes.X, Padding = new MarginPadding { - Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, + Horizontal = UserProfileOverlay.CONTENT_X_MARGIN - outer_gutter_width, Bottom = 20 } }, @@ -100,43 +106,8 @@ namespace osu.Game.Overlays.Profile [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - background.Colour = colourProvider.Background5; + background.Colour = colourProvider.Background4; underscore.Colour = colourProvider.Highlight1; } - - private partial class SectionTriangles : Container - { - private readonly Triangles triangles; - private readonly Box foreground; - - public SectionTriangles() - { - RelativeSizeAxes = Axes.X; - Height = 100; - Masking = true; - Children = new Drawable[] - { - triangles = new Triangles - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - RelativeSizeAxes = Axes.Both, - TriangleScale = 3, - }, - foreground = new Box - { - RelativeSizeAxes = Axes.Both, - } - }; - } - - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - triangles.ColourLight = colourProvider.Background4; - triangles.ColourDark = colourProvider.Background5.Darken(0.2f); - foreground.Colour = ColourInfo.GradientVertical(colourProvider.Background5, colourProvider.Background5.Opacity(0)); - } - } } } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index f9c6662ee3..8849c674dc 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -259,7 +259,9 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, - Spacing = new Vector2(0, 20), + Spacing = new Vector2(0, 10), + Padding = new MarginPadding { Horizontal = 10 }, + Margin = new MarginPadding { Bottom = 10 }, }; } } From e39eb089ce617ac0109d11858e56f2b030dacbde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 20:51:29 +0100 Subject: [PATCH 1523/2991] Update colouring of some profile section elements --- .../Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs | 4 ++-- osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs | 4 ++-- .../Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs b/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs index 53447a971b..8a05341783 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs @@ -112,8 +112,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - IdleColour = colourProvider.Background4; - HoverColour = colourProvider.Background3; + IdleColour = colourProvider.Background3; + HoverColour = colourProvider.Background2; } } diff --git a/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs index b30faee380..5e1b650bd3 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs @@ -65,8 +65,8 @@ namespace osu.Game.Overlays.Profile.Sections [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - IdleColour = colourProvider.Background3; - HoverColour = colourProvider.Background2; + IdleColour = colourProvider.Background2; + HoverColour = colourProvider.Background1; } protected override bool OnHover(HoverEvent e) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 0f3e0bc6b2..529e78a7cf 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -160,7 +160,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Both, Height = 0.5f, - Colour = colourProvider.Background4, + Colour = colourProvider.Background3, Shear = new Vector2(-performance_background_shear, 0), EdgeSmoothness = new Vector2(2, 0), }, @@ -172,7 +172,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks RelativePositionAxes = Axes.Y, Height = -0.5f, Position = new Vector2(0, 1), - Colour = colourProvider.Background4, + Colour = colourProvider.Background3, Shear = new Vector2(performance_background_shear, 0), EdgeSmoothness = new Vector2(2, 0), }, From f80dddbb5e1f45f366617208159fd21206b060c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 17:41:57 +0100 Subject: [PATCH 1524/2991] Rearrange and adjust header components where simple --- .../Profile/Header/CentreHeaderContainer.cs | 67 +------------------ .../Profile/Header/DetailHeaderContainer.cs | 29 +------- osu.Game/Overlays/Profile/ProfileHeader.cs | 6 +- 3 files changed, 6 insertions(+), 96 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index ecf78e7b92..7721342ba8 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -3,26 +3,18 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Localisation; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile.Header.Components; -using osu.Game.Resources.Localisation.Web; using osuTK; namespace osu.Game.Overlays.Profile.Header { public partial class CentreHeaderContainer : CompositeDrawable { - public readonly BindableBool DetailsVisible = new BindableBool(true); public readonly Bindable User = new Bindable(); - private OverlinedInfoContainer hiddenDetailGlobal = null!; - private OverlinedInfoContainer hiddenDetailCountry = null!; - public CentreHeaderContainer() { Height = 60; @@ -31,15 +23,12 @@ namespace osu.Game.Overlays.Profile.Header [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - Container hiddenDetailContainer; - Container expandedDetailContainer; - InternalChildren = new Drawable[] { new Box { RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background4 + Colour = colourProvider.Background3 }, new FillFlowContainer { @@ -66,20 +55,6 @@ namespace osu.Game.Overlays.Profile.Header } }, new Container - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - RelativeSizeAxes = Axes.Y, - Padding = new MarginPadding { Vertical = 10 }, - Width = UserProfileOverlay.CONTENT_X_MARGIN, - Child = new ExpandDetailsButton - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - DetailsVisible = { BindTarget = DetailsVisible } - }, - }, - new Container { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, @@ -94,7 +69,7 @@ namespace osu.Game.Overlays.Profile.Header Size = new Vector2(40), User = { BindTarget = User } }, - expandedDetailContainer = new Container + new Container { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, @@ -107,47 +82,9 @@ namespace osu.Game.Overlays.Profile.Header User = { BindTarget = User } } }, - hiddenDetailContainer = new FillFlowContainer - { - Direction = FillDirection.Horizontal, - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Width = 200, - AutoSizeAxes = Axes.Y, - Alpha = 0, - Spacing = new Vector2(10, 0), - Margin = new MarginPadding { Right = 50 }, - Children = new[] - { - hiddenDetailGlobal = new OverlinedInfoContainer - { - Title = UsersStrings.ShowRankGlobalSimple, - LineColour = colourProvider.Highlight1 - }, - hiddenDetailCountry = new OverlinedInfoContainer - { - Title = UsersStrings.ShowRankCountrySimple, - LineColour = colourProvider.Highlight1 - }, - } - } } } }; - - DetailsVisible.BindValueChanged(visible => - { - hiddenDetailContainer.FadeTo(visible.NewValue ? 0 : 1, 200, Easing.OutQuint); - expandedDetailContainer.FadeTo(visible.NewValue ? 1 : 0, 200, Easing.OutQuint); - }); - - User.BindValueChanged(user => updateDisplay(user.NewValue?.User)); - } - - private void updateDisplay(APIUser? user) - { - hiddenDetailGlobal.Content = user?.Statistics?.GlobalRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-"; - hiddenDetailCountry.Content = user?.Statistics?.CountryRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-"; } } } diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 3bab798caf..63473e007d 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -26,35 +26,10 @@ namespace osu.Game.Overlays.Profile.Header private OverlinedInfoContainer ppInfo = null!; private OverlinedInfoContainer detailGlobalRank = null!; private OverlinedInfoContainer detailCountryRank = null!; - private FillFlowContainer? fillFlow; private RankGraph rankGraph = null!; public readonly Bindable User = new Bindable(); - private bool expanded = true; - - public bool Expanded - { - set - { - if (expanded == value) return; - - expanded = value; - - if (fillFlow == null) return; - - fillFlow.ClearTransforms(); - - if (expanded) - fillFlow.AutoSizeAxes = Axes.Y; - else - { - fillFlow.AutoSizeAxes = Axes.None; - fillFlow.ResizeHeightTo(0, 200, Easing.OutQuint); - } - } - } - [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider, OsuColour colours) { @@ -69,10 +44,10 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background5, }, - fillFlow = new FillFlowContainer + new FillFlowContainer { RelativeSizeAxes = Axes.X, - AutoSizeAxes = expanded ? Axes.Y : Axes.None, + AutoSizeAxes = Axes.Y, AutoSizeDuration = 200, AutoSizeEasing = Easing.OutQuint, Masking = true, diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index bd12837343..c559a1c102 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -39,8 +39,6 @@ namespace osu.Game.Overlays.Profile // Haphazardly guaranteed by OverlayHeader constructor (see CreateBackground / CreateContent). Debug.Assert(centreHeaderContainer != null); Debug.Assert(detailHeaderContainer != null); - - centreHeaderContainer.DetailsVisible.BindValueChanged(visible => detailHeaderContainer.Expanded = visible.NewValue, true); } protected override Drawable CreateBackground() => @@ -75,7 +73,7 @@ namespace osu.Game.Overlays.Profile RelativeSizeAxes = Axes.X, User = { BindTarget = User }, }, - centreHeaderContainer = new CentreHeaderContainer + new MedalHeaderContainer { RelativeSizeAxes = Axes.X, User = { BindTarget = User }, @@ -85,7 +83,7 @@ namespace osu.Game.Overlays.Profile RelativeSizeAxes = Axes.X, User = { BindTarget = User }, }, - new MedalHeaderContainer + centreHeaderContainer = new CentreHeaderContainer { RelativeSizeAxes = Axes.X, User = { BindTarget = User }, From de077403e9b2a6259c74e6d8ba80221da249b3ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 17:51:58 +0100 Subject: [PATCH 1525/2991] Adjust visual appearance of profile value displays --- ...nfoContainer.cs => ProfileValueDisplay.cs} | 30 ++++++++----------- ...linedTotalPlayTime.cs => TotalPlayTime.cs} | 11 ++++--- .../Profile/Header/DetailHeaderContainer.cs | 30 ++++++++----------- 3 files changed, 30 insertions(+), 41 deletions(-) rename osu.Game/Overlays/Profile/Header/Components/{OverlinedInfoContainer.cs => ProfileValueDisplay.cs} (64%) rename osu.Game/Overlays/Profile/Header/Components/{OverlinedTotalPlayTime.cs => TotalPlayTime.cs} (83%) diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileValueDisplay.cs similarity index 64% rename from osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs rename to osu.Game/Overlays/Profile/Header/Components/ProfileValueDisplay.cs index 42b67865a0..4b1a0409a3 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileValueDisplay.cs @@ -1,19 +1,17 @@ // 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.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { - public partial class OverlinedInfoContainer : CompositeDrawable + public partial class ProfileValueDisplay : CompositeDrawable { - private readonly Circle line; private readonly OsuSpriteText title; private readonly OsuSpriteText content; @@ -27,12 +25,7 @@ namespace osu.Game.Overlays.Profile.Header.Components set => content.Text = value; } - public Color4 LineColour - { - set => line.Colour = value; - } - - public OverlinedInfoContainer(bool big = false, int minimumWidth = 60) + public ProfileValueDisplay(bool big = false, int minimumWidth = 60) { AutoSizeAxes = Axes.Both; InternalChild = new FillFlowContainer @@ -41,19 +34,13 @@ namespace osu.Game.Overlays.Profile.Header.Components AutoSizeAxes = Axes.Both, Children = new Drawable[] { - line = new Circle - { - RelativeSizeAxes = Axes.X, - Height = 2, - Margin = new MarginPadding { Bottom = 2 } - }, title = new OsuSpriteText { - Font = OsuFont.GetFont(size: big ? 14 : 12, weight: FontWeight.Bold) + Font = OsuFont.GetFont(size: 12) }, content = new OsuSpriteText { - Font = OsuFont.GetFont(size: big ? 40 : 18, weight: FontWeight.Light) + Font = OsuFont.GetFont(size: big ? 30 : 20, weight: FontWeight.Light) }, new Container // Add a minimum size to the FillFlowContainer { @@ -62,5 +49,12 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + title.Colour = colourProvider.Content1; + content.Colour = colourProvider.Content2; + } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/Components/TotalPlayTime.cs similarity index 83% rename from osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs rename to osu.Game/Overlays/Profile/Header/Components/TotalPlayTime.cs index 0396f42336..08ca59d89b 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs +++ b/osu.Game/Overlays/Profile/Header/Components/TotalPlayTime.cs @@ -11,15 +11,15 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Header.Components { - public partial class OverlinedTotalPlayTime : CompositeDrawable, IHasTooltip + public partial class TotalPlayTime : CompositeDrawable, IHasTooltip { public readonly Bindable User = new Bindable(); public LocalisableString TooltipText { get; set; } - private OverlinedInfoContainer info = null!; + private ProfileValueDisplay info = null!; - public OverlinedTotalPlayTime() + public TotalPlayTime() { AutoSizeAxes = Axes.Both; @@ -27,12 +27,11 @@ namespace osu.Game.Overlays.Profile.Header.Components } [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) + private void load() { - InternalChild = info = new OverlinedInfoContainer + InternalChild = info = new ProfileValueDisplay(minimumWidth: 140) { Title = UsersStrings.ShowStatsPlayTime, - LineColour = colourProvider.Highlight1, }; User.BindValueChanged(updateTime, true); diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 63473e007d..5e55521f21 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -22,16 +22,16 @@ namespace osu.Game.Overlays.Profile.Header public partial class DetailHeaderContainer : CompositeDrawable { private readonly Dictionary scoreRankInfos = new Dictionary(); - private OverlinedInfoContainer medalInfo = null!; - private OverlinedInfoContainer ppInfo = null!; - private OverlinedInfoContainer detailGlobalRank = null!; - private OverlinedInfoContainer detailCountryRank = null!; + private ProfileValueDisplay medalInfo = null!; + private ProfileValueDisplay ppInfo = null!; + private ProfileValueDisplay detailGlobalRank = null!; + private ProfileValueDisplay detailCountryRank = null!; private RankGraph rankGraph = null!; public readonly Bindable User = new Bindable(); [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider, OsuColour colours) + private void load(OverlayColourProvider colourProvider) { AutoSizeAxes = Axes.Y; @@ -71,19 +71,17 @@ namespace osu.Game.Overlays.Profile.Header Spacing = new Vector2(10, 0), Children = new Drawable[] { - new OverlinedTotalPlayTime - { - User = { BindTarget = User } - }, - medalInfo = new OverlinedInfoContainer + medalInfo = new ProfileValueDisplay { Title = UsersStrings.ShowStatsMedals, - LineColour = colours.GreenLight, }, - ppInfo = new OverlinedInfoContainer + ppInfo = new ProfileValueDisplay { Title = "pp", - LineColour = colours.Red, + }, + new TotalPlayTime + { + User = { BindTarget = User } }, } }, @@ -126,15 +124,13 @@ namespace osu.Game.Overlays.Profile.Header Spacing = new Vector2(0, 20), Children = new Drawable[] { - detailGlobalRank = new OverlinedInfoContainer(true, 110) + detailGlobalRank = new ProfileValueDisplay(true, 110) { Title = UsersStrings.ShowRankGlobalSimple, - LineColour = colourProvider.Highlight1, }, - detailCountryRank = new OverlinedInfoContainer(false, 110) + detailCountryRank = new ProfileValueDisplay(false, 110) { Title = UsersStrings.ShowRankCountrySimple, - LineColour = colourProvider.Highlight1, }, } } From 6a9d8426605333f260a702b75ead339f03213285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 18:02:05 +0100 Subject: [PATCH 1526/2991] Adjust user profile header detail appearance --- .../Profile/Header/DetailHeaderContainer.cs | 69 +++++++++---------- .../Profile/Header/MedalHeaderContainer.cs | 3 +- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 5e55521f21..890e6c4e04 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -53,9 +53,39 @@ namespace osu.Game.Overlays.Profile.Header Masking = true, Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), + Spacing = new Vector2(0, 15), Children = new Drawable[] { + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(20), + Children = new Drawable[] + { + detailGlobalRank = new ProfileValueDisplay(true) + { + Title = UsersStrings.ShowRankGlobalSimple, + }, + detailCountryRank = new ProfileValueDisplay(true) + { + Title = UsersStrings.ShowRankCountrySimple, + }, + } + }, + new Container + { + RelativeSizeAxes = Axes.X, + Height = 60, + Children = new Drawable[] + { + rankGraph = new RankGraph + { + RelativeSizeAxes = Axes.Both, + }, + } + }, new Container { RelativeSizeAxes = Axes.X, @@ -103,39 +133,6 @@ namespace osu.Game.Overlays.Profile.Header } } }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Right = 130 }, - Children = new Drawable[] - { - rankGraph = new RankGraph - { - RelativeSizeAxes = Axes.Both, - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - Width = 130, - Anchor = Anchor.TopRight, - Direction = FillDirection.Vertical, - Padding = new MarginPadding { Horizontal = 10 }, - Spacing = new Vector2(0, 20), - Children = new Drawable[] - { - detailGlobalRank = new ProfileValueDisplay(true, 110) - { - Title = UsersStrings.ShowRankGlobalSimple, - }, - detailCountryRank = new ProfileValueDisplay(false, 110) - { - Title = UsersStrings.ShowRankCountrySimple, - }, - } - } - } - }, } }, }; @@ -172,14 +169,14 @@ namespace osu.Game.Overlays.Profile.Header InternalChild = new FillFlowContainer { AutoSizeAxes = Axes.Y, - Width = 56, + Width = 44, Direction = FillDirection.Vertical, Children = new Drawable[] { new DrawableRank(rank) { RelativeSizeAxes = Axes.X, - Height = 30, + Height = 22, }, rankCount = new OsuSpriteText { diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index 2652550fb5..be160a6948 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -49,9 +49,8 @@ namespace osu.Game.Overlays.Profile.Header Direction = FillDirection.Full, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = 5 }, Spacing = new Vector2(10, 10), - Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Top = 10 }, } }; } From bfca75395be49e7257e10d24347e13cd577d8d24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 18:24:45 +0100 Subject: [PATCH 1527/2991] Adjust colour of top header container --- osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 33e24593e0..e04a8ad9ad 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -51,7 +51,7 @@ namespace osu.Game.Overlays.Profile.Header new Box { RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background5, + Colour = colourProvider.Background4, }, new FillFlowContainer { From 67a3ea2c5992527db7def7414566931c22747daa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 21:10:48 +0100 Subject: [PATCH 1528/2991] Fix wrong date colour of kudosu history items --- osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs | 9 ++++++--- .../Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs | 7 ++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs index 84497245db..25a56196eb 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs @@ -5,12 +5,12 @@ using osu.Game.Overlays.Profile.Sections.Kudosu; using System.Collections.Generic; using System; using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; using osu.Framework.Allocation; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics; using osu.Game.Online.API.Requests.Responses; using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Online { @@ -18,6 +18,9 @@ namespace osu.Game.Tests.Visual.Online { private readonly Box background; + [Cached] + private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink); + public TestSceneKudosuHistory() { FillFlowContainer content; @@ -42,9 +45,9 @@ namespace osu.Game.Tests.Visual.Online } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load() { - background.Colour = colours.GreySeaFoam; + background.Colour = colourProvider.Background4; } private readonly IEnumerable items = new[] diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index e7991acb89..161d5b6f64 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -17,9 +17,6 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { private const int height = 25; - [Resolved] - private OsuColour colours { get; set; } = null!; - private readonly APIKudosuHistory historyItem; private readonly LinkFlowContainer linkFlowContainer; private readonly DrawableDate date; @@ -48,9 +45,9 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu } [BackgroundDependencyLoader] - private void load() + private void load(OverlayColourProvider colourProvider) { - date.Colour = colours.GreySeaFoamLighter; + date.Colour = colourProvider.Foreground1; var formattedSource = MessageFormatter.FormatText(getString(historyItem)); linkFlowContainer.AddLinks(formattedSource.Text, formattedSource.Links); } From fbb674d8e9d809b9a5154525d96e36685e928fac Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 20:15:19 +0300 Subject: [PATCH 1529/2991] Rename parent comment id field --- osu.Game/Online/API/Requests/CommentPostRequest.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Online/API/Requests/CommentPostRequest.cs b/osu.Game/Online/API/Requests/CommentPostRequest.cs index 7012d479bd..45e5eb1a94 100644 --- a/osu.Game/Online/API/Requests/CommentPostRequest.cs +++ b/osu.Game/Online/API/Requests/CommentPostRequest.cs @@ -12,14 +12,14 @@ namespace osu.Game.Online.API.Requests public readonly CommentableType Commentable; public readonly long CommentableId; public readonly string Message; - public readonly long? ReplyTo; + public readonly long? ParentCommentId; - public CommentPostRequest(CommentableType commentable, long commentableId, string message, long? replyTo = null) + public CommentPostRequest(CommentableType commentable, long commentableId, string message, long? parentCommentId = null) { Commentable = commentable; CommentableId = commentableId; Message = message; - ReplyTo = replyTo; + ParentCommentId = parentCommentId; } protected override WebRequest CreateWebRequest() @@ -30,8 +30,8 @@ namespace osu.Game.Online.API.Requests req.AddParameter(@"comment[commentable_type]", Commentable.ToString().ToLowerInvariant()); req.AddParameter(@"comment[commentable_id]", $"{CommentableId}"); req.AddParameter(@"comment[message]", Message); - if (ReplyTo.HasValue) - req.AddParameter(@"comment[parent_id]", $"{ReplyTo}"); + if (ParentCommentId.HasValue) + req.AddParameter(@"comment[parent_id]", $"{ParentCommentId}"); return req; } From 3102044d00a85caaaafd059f77a08022dfd2d7aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 14 Jan 2023 18:46:14 +0100 Subject: [PATCH 1530/2991] Add failing test for new difficulty creation --- .../Editing/TestSceneEditorBeatmapCreation.cs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs index a40c7814e1..3f89bf9e9c 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs @@ -20,6 +20,8 @@ using osu.Game.Rulesets.Catch; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.UI; +using osu.Game.Rulesets.Taiko; +using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Setup; using osu.Game.Storyboards; @@ -395,5 +397,52 @@ namespace osu.Game.Tests.Visual.Editing return set != null && set.PerformRead(s => s.Beatmaps.Count == 2 && s.Files.Count == 2); }); } + + [Test] + public void TestCreateNewDifficultyForInconvertibleRuleset() + { + Guid setId = Guid.Empty; + + AddStep("retrieve set ID", () => setId = EditorBeatmap.BeatmapInfo.BeatmapSet!.ID); + AddStep("save beatmap", () => Editor.Save()); + AddStep("try to create new taiko difficulty", () => Editor.CreateNewDifficulty(new TaikoRuleset().RulesetInfo)); + + AddUntilStep("wait for created", () => + { + string? difficultyName = Editor.ChildrenOfType().SingleOrDefault()?.BeatmapInfo.DifficultyName; + return difficultyName != null && difficultyName == "New Difficulty"; + }); + AddAssert("new difficulty persisted", () => + { + var set = beatmapManager.QueryBeatmapSet(s => s.ID == setId); + return set != null && set.PerformRead(s => s.Beatmaps.Count == 2 && s.Files.Count == 2); + }); + + AddStep("add timing point", () => EditorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 })); + AddStep("add hitobjects", () => EditorBeatmap.AddRange(new[] + { + new Hit + { + StartTime = 0 + }, + new Hit + { + StartTime = 1000 + } + })); + AddStep("save beatmap", () => Editor.Save()); + AddStep("try to create new catch difficulty", () => Editor.CreateNewDifficulty(new CatchRuleset().RulesetInfo)); + + AddUntilStep("wait for created", () => + { + string? difficultyName = Editor.ChildrenOfType().SingleOrDefault()?.BeatmapInfo.DifficultyName; + return difficultyName != null && difficultyName == "New Difficulty (1)"; + }); + AddAssert("new difficulty persisted", () => + { + var set = beatmapManager.QueryBeatmapSet(s => s.ID == setId); + return set != null && set.PerformRead(s => s.Beatmaps.Count == 3 && s.Files.Count == 3); + }); + } } } From 88c3eef8e1b48e01827c50d10cacfca55bebad53 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 20:59:13 +0300 Subject: [PATCH 1531/2991] Add test case with no existing comments --- .../Online/TestSceneCommentsContainer.cs | 45 ++++++++++++++----- .../Overlays/Comments/CommentsContainer.cs | 2 +- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index e58423241b..4a41eca898 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -32,13 +32,18 @@ namespace osu.Game.Tests.Visual.Online private CommentsContainer commentsContainer; + private TextBox editorTextBox; + [SetUp] public void SetUp() => Schedule(() => + { Child = new BasicScrollContainer { RelativeSizeAxes = Axes.Both, Child = commentsContainer = new CommentsContainer() - }); + }; + editorTextBox = commentsContainer.ChildrenOfType().First(); + }); [Test] public void TestIdleState() @@ -129,21 +134,41 @@ namespace osu.Game.Tests.Visual.Online commentsContainer.ChildrenOfType().Count(d => d.Comment.Pinned == withPinned) == 1); } - [TestCase] + [Test] public void TestPost() + { + setUpCommentsResponse(new CommentBundle { Comments = new List() }); + AddStep("show comments", () => commentsContainer.ShowComments(CommentableType.Beatmapset, 123)); + AddAssert("no comments placeholder shown", () => commentsContainer.ChildrenOfType().Any()); + + setUpPostResponse(); + AddStep("enter text", () => editorTextBox.Current.Value = "comm"); + AddStep("submit", () => commentsContainer.ChildrenOfType().First().TriggerClick()); + + AddUntilStep("comment sent", () => + { + string writtenText = editorTextBox.Current.Value; + var comment = commentsContainer.ChildrenOfType().Last(); + return comment.ChildrenOfType().Any(y => y.Text == writtenText); + }); + AddAssert("no comments placeholder removed", () => !commentsContainer.ChildrenOfType().Any()); + } + + [Test] + public void TestPostWithExistingComments() { setUpCommentsResponse(getExampleComments()); AddStep("show comments", () => commentsContainer.ShowComments(CommentableType.Beatmapset, 123)); + setUpPostResponse(); - AddStep("Enter text", () => this.ChildrenOfType().Single().ChildrenOfType().Single().Current.Value = "comm"); - AddStep("Submit", () => this.ChildrenOfType().Single().ChildrenOfType().First().TriggerClick()); - AddUntilStep("Comment sent", () => + AddStep("enter text", () => editorTextBox.Current.Value = "comm"); + AddStep("submit", () => commentsContainer.ChildrenOfType().Single().ChildrenOfType().First().TriggerClick()); + + AddUntilStep("comment sent", () => { - string text = this.ChildrenOfType().Single().ChildrenOfType().Single().Current.Value; - return this.ChildrenOfType().Any(x => - { - return x.ChildrenOfType().Any(y => y.Text == text); - }); + string writtenText = editorTextBox.Current.Value; + var comment = commentsContainer.ChildrenOfType().Last(); + return comment.ChildrenOfType().Any(y => y.Text == writtenText); }); } diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 9446857f5e..a8939ffdc6 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -390,7 +390,7 @@ namespace osu.Game.Overlays.Comments base.Dispose(isDisposing); } - private partial class NoCommentsPlaceholder : CompositeDrawable + internal partial class NoCommentsPlaceholder : CompositeDrawable { [BackgroundDependencyLoader] private void load() From e7ab54379933937e8affbb008b0e3dacd3e3c92a Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Fri, 13 Jan 2023 16:08:34 -0800 Subject: [PATCH 1532/2991] Add ability to view converted beatmaps on beatmap set overlay --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 4 ++++ osu.Game/Online/API/Requests/Responses/APIBeatmap.cs | 3 +++ osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs | 3 +++ osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 5 +++-- osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs | 3 ++- 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 1665ec52fa..41db2399ac 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -13,6 +13,7 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets; using osuTK; using osuTK.Graphics; @@ -116,6 +117,9 @@ namespace osu.Game.Beatmaps.Drawables private Drawable getRulesetIcon() { + if ((beatmap as APIBeatmap)?.Convert == true) + return rulesets.GetRuleset(0)!.CreateInstance().CreateIcon(); + int? onlineID = ruleset.OnlineID; if (onlineID >= 0 && rulesets.GetRuleset(onlineID.Value)?.CreateInstance() is Ruleset rulesetInstance) diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs index 27ad2a746c..7d6740ee46 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -63,6 +63,9 @@ namespace osu.Game.Online.API.Requests.Responses set => Length = TimeSpan.FromSeconds(value).TotalMilliseconds; } + [JsonProperty(@"convert")] + public bool Convert { get; set; } + [JsonProperty(@"count_circles")] public int CircleCount { get; set; } diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index aeae3edde2..d39ed1e1ed 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -125,6 +125,9 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"beatmaps")] public APIBeatmap[] Beatmaps { get; set; } = Array.Empty(); + [JsonProperty(@"converts")] + public APIBeatmap[] Converts { get; set; } = Array.Empty(); + private BeatmapMetadata metadata => new BeatmapMetadata { Title = Title, diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 84d12f2611..51b6b14579 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -168,9 +168,10 @@ namespace osu.Game.Overlays.BeatmapSet if (BeatmapSet != null) { - Difficulties.ChildrenEnumerable = BeatmapSet.Beatmaps + Difficulties.ChildrenEnumerable = BeatmapSet.Beatmaps.Concat(BeatmapSet.Converts) .Where(b => b.Ruleset.MatchesOnlineID(ruleset.Value)) - .OrderBy(b => b.StarRating) + .OrderBy(b => !b.Convert) + .ThenBy(b => b.StarRating) .Select(b => new DifficultySelectorButton(b) { State = DifficultySelectorState.NotSelected, diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs b/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs index f802807c3c..76e2f256b0 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs @@ -68,11 +68,12 @@ namespace osu.Game.Overlays.BeatmapSet BeatmapSet.BindValueChanged(setInfo => { int beatmapsCount = setInfo.NewValue?.Beatmaps.Count(b => b.Ruleset.MatchesOnlineID(Value)) ?? 0; + int osuBeatmaps = setInfo.NewValue?.Beatmaps.Count(b => b.Ruleset.OnlineID == 0) ?? 0; count.Text = beatmapsCount.ToString(); countContainer.FadeTo(beatmapsCount > 0 ? 1 : 0); - Enabled.Value = beatmapsCount > 0; + Enabled.Value = beatmapsCount > 0 || osuBeatmaps > 0; }, true); } } From a9facc076f37fc6663bae5e0b64c5e124bf9e3b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 14 Jan 2023 19:39:30 +0100 Subject: [PATCH 1533/2991] Fix difficulty creation flow failing for some ruleset combinations In current `master`, the difficulty creation flow would retrieve a "reference beatmap" to copy metadata and timing points from using `GetPlayableBeatmap()`. But, importantly, it was calling that method using *the ruleset of the new difficulty* rather than the ruleset of the existing one. This would make the difficulty creation flow fail if the beatmap couldn't be converted between rulesets (like taiko to catch). Fixing to use the reference beatmap's actual ruleset would be trivial, but there's no real reason to do all of that work anyway when a `WorkingBeatmap` is available. Because getting a playable beatmap is not required to copy across metadata and timing points, remove the `GetPlayableBeatmap()` step entirely to fix the bug. Closes #22145. --- osu.Game/Beatmaps/BeatmapManager.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index eafd1e96e8..34637501fa 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -136,14 +136,12 @@ namespace osu.Game.Beatmaps /// The ruleset with which the new difficulty should be created. public virtual WorkingBeatmap CreateNewDifficulty(BeatmapSetInfo targetBeatmapSet, WorkingBeatmap referenceWorkingBeatmap, RulesetInfo rulesetInfo) { - var playableBeatmap = referenceWorkingBeatmap.GetPlayableBeatmap(rulesetInfo); - - var newBeatmapInfo = new BeatmapInfo(rulesetInfo, new BeatmapDifficulty(), playableBeatmap.Metadata.DeepClone()) + var newBeatmapInfo = new BeatmapInfo(rulesetInfo, new BeatmapDifficulty(), referenceWorkingBeatmap.Metadata.DeepClone()) { DifficultyName = NamingUtils.GetNextBestName(targetBeatmapSet.Beatmaps.Select(b => b.DifficultyName), "New Difficulty") }; var newBeatmap = new Beatmap { BeatmapInfo = newBeatmapInfo }; - foreach (var timingPoint in playableBeatmap.ControlPointInfo.TimingPoints) + foreach (var timingPoint in referenceWorkingBeatmap.Beatmap.ControlPointInfo.TimingPoints) newBeatmap.ControlPointInfo.Add(timingPoint.Time, timingPoint.DeepClone()); return addDifficultyToSet(targetBeatmapSet, newBeatmap, referenceWorkingBeatmap.Skin); From cdf3aafdddd4c987c2ad8b5aa4ece2a03703f174 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 22:37:05 +0300 Subject: [PATCH 1534/2991] Add check for any drawables in content before looking for placeholder --- osu.Game/Overlays/Comments/CommentsContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index a8939ffdc6..58f7a72ee5 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -342,7 +342,7 @@ namespace osu.Game.Overlays.Comments { LoadComponentsAsync(topLevelComments, loaded => { - if (content[0] is NoCommentsPlaceholder placeholder) + if (content.Count > 0 && content[0] is NoCommentsPlaceholder placeholder) content.Remove(placeholder, true); foreach (var comment in loaded) From c2bb0949f52404739cea5dd5d544b3068615efb8 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 22:57:23 +0300 Subject: [PATCH 1535/2991] Take type and id from container directly on submit --- .../Overlays/Comments/CommentsContainer.cs | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 58f7a72ee5..67db0714dc 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -29,13 +29,10 @@ namespace osu.Game.Overlays.Comments [Cached] public partial class CommentsContainer : CompositeDrawable { - private const string cid = "commentableId"; - - [Cached] private readonly Bindable type = new Bindable(); - - [Cached(name: cid)] private readonly BindableLong id = new BindableLong(); + public IBindable Type => type; + public IBindable Id => id; public readonly Bindable Sort = new Bindable(); public readonly BindableBool ShowDeleted = new BindableBool(); @@ -413,24 +410,23 @@ namespace osu.Game.Overlays.Comments private partial class NewCommentEditor : CommentEditor { [Resolved] - public Bindable CommentableType { get; set; } - - [Resolved(name: cid)] - public BindableLong CommentableId { get; set; } - - protected override LocalisableString FooterText => default; - protected override LocalisableString CommitButtonText => CommonStrings.ButtonsPost; - protected override LocalisableString TextBoxPlaceholder => CommentsStrings.PlaceholderNew; + private CommentsContainer commentsContainer { get; set; } [Resolved] private IAPIProvider api { get; set; } public Action OnPost; + protected override LocalisableString FooterText => default; + + protected override LocalisableString CommitButtonText => CommonStrings.ButtonsPost; + + protected override LocalisableString TextBoxPlaceholder => CommentsStrings.PlaceholderNew; + protected override void OnCommit(string text) { ShowLoadingSpinner = true; - CommentPostRequest req = new CommentPostRequest(CommentableType.Value, CommentableId.Value, text); + CommentPostRequest req = new CommentPostRequest(commentsContainer.Type.Value, commentsContainer.Id.Value, text); req.Failure += _ => Schedule(() => { ShowLoadingSpinner = false; From c36922dd2c630dfb621633e359de61b0636941e7 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 22:57:51 +0300 Subject: [PATCH 1536/2991] Use clock to obtain a position for comment insertion --- osu.Game/Overlays/Comments/CommentsContainer.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 67db0714dc..c626d1f26c 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -344,15 +344,7 @@ namespace osu.Game.Overlays.Comments foreach (var comment in loaded) { - int pos = -1; - - if (content.Count > 0) - { - var first = content.FlowingChildren.First(); - pos = (int)(content.GetLayoutPosition(first) - 1); - } - - content.Insert(pos, comment); + content.Insert((int)-Clock.CurrentTime, comment); } }, (loadCancellation = new CancellationTokenSource()).Token); } From 58406cae19851cf6910ffb5fbc04aea54af78e42 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 23:42:10 +0300 Subject: [PATCH 1537/2991] Make test wait for comment loading --- .../Visual/Online/TestSceneCommentsContainer.cs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 4a41eca898..3d8781d902 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -30,9 +28,9 @@ namespace osu.Game.Tests.Visual.Online private DummyAPIAccess dummyAPI => (DummyAPIAccess)API; - private CommentsContainer commentsContainer; + private CommentsContainer commentsContainer = null!; - private TextBox editorTextBox; + private TextBox editorTextBox = null!; [SetUp] public void SetUp() => Schedule(() => @@ -148,8 +146,8 @@ namespace osu.Game.Tests.Visual.Online AddUntilStep("comment sent", () => { string writtenText = editorTextBox.Current.Value; - var comment = commentsContainer.ChildrenOfType().Last(); - return comment.ChildrenOfType().Any(y => y.Text == writtenText); + var comment = commentsContainer.ChildrenOfType().LastOrDefault(); + return comment != null && comment.ChildrenOfType().Any(y => y.Text == writtenText); }); AddAssert("no comments placeholder removed", () => !commentsContainer.ChildrenOfType().Any()); } @@ -167,8 +165,8 @@ namespace osu.Game.Tests.Visual.Online AddUntilStep("comment sent", () => { string writtenText = editorTextBox.Current.Value; - var comment = commentsContainer.ChildrenOfType().Last(); - return comment.ChildrenOfType().Any(y => y.Text == writtenText); + var comment = commentsContainer.ChildrenOfType().LastOrDefault(); + return comment != null && comment.ChildrenOfType().Any(y => y.Text == writtenText); }); } From 1480c691ae8bbf2ca0fbe4b88acc5eb426f7ffc5 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 23:42:56 +0300 Subject: [PATCH 1538/2991] Explain empty string in editor's footer --- osu.Game/Overlays/Comments/CommentsContainer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index c626d1f26c..3639fe1835 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -409,6 +409,7 @@ namespace osu.Game.Overlays.Comments public Action OnPost; + //TODO should match web, left empty due to no multiline support protected override LocalisableString FooterText => default; protected override LocalisableString CommitButtonText => CommonStrings.ButtonsPost; From a68d4fe5d18da32ede6420f50520769e20739106 Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Sat, 14 Jan 2023 21:18:51 +0000 Subject: [PATCH 1539/2991] make expansion to not use scheduler --- .../PlayerSettings/PlayerSettingsGroup.cs | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs index f4769cd417..55cf69b0f2 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs @@ -4,7 +4,6 @@ #nullable disable using osu.Framework.Input.Events; -using osu.Framework.Threading; using osu.Game.Overlays; namespace osu.Game.Screens.Play.PlayerSettings @@ -16,11 +15,16 @@ namespace osu.Game.Screens.Play.PlayerSettings { } - private ScheduledDelegate hoverExpandEvent; + private bool expandedByDefault = true; protected override bool OnHover(HoverEvent e) { - updateHoverExpansion(); + if (IsHovered && !Expanded.Value) + { + Expanded.Value = true; + expandedByDefault = false; + } + base.OnHover(e); // Importantly, return true to correctly take focus away from PlayerLoader. @@ -29,23 +33,10 @@ namespace osu.Game.Screens.Play.PlayerSettings protected override void OnHoverLost(HoverLostEvent e) { - if (hoverExpandEvent != null) - { - hoverExpandEvent?.Cancel(); - hoverExpandEvent = null; - + if (!expandedByDefault) Expanded.Value = false; - } base.OnHoverLost(e); } - - private void updateHoverExpansion() - { - hoverExpandEvent?.Cancel(); - - if (IsHovered && !Expanded.Value) - hoverExpandEvent = Scheduler.AddDelayed(() => Expanded.Value = true, 0); - } } } From 76eefc7573a5267ddf3016517d77e0eea1adf272 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 01:46:11 +0300 Subject: [PATCH 1540/2991] Add support for localisation where it was missing --- osu.Game/Graphics/UserInterface/OsuMenuItem.cs | 6 ++---- osu.Game/Graphics/UserInterface/StatefulMenuItem.cs | 11 +++++------ osu.Game/Graphics/UserInterface/ToggleMenuItem.cs | 7 +++---- .../Screens/Edit/Components/Menus/EditorMenuItem.cs | 9 +++++---- .../Components/Menus/EditorScreenSwitcherControl.cs | 5 ----- 5 files changed, 15 insertions(+), 23 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuMenuItem.cs b/osu.Game/Graphics/UserInterface/OsuMenuItem.cs index 9d65d6b8b9..20461de08f 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenuItem.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenuItem.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; @@ -13,12 +11,12 @@ namespace osu.Game.Graphics.UserInterface { public readonly MenuItemType Type; - public OsuMenuItem(string text, MenuItemType type = MenuItemType.Standard) + public OsuMenuItem(LocalisableString text, MenuItemType type = MenuItemType.Standard) : this(text, type, null) { } - public OsuMenuItem(LocalisableString text, MenuItemType type, Action action) + public OsuMenuItem(LocalisableString text, MenuItemType type, Action? action) : base(text, action) { Type = type; diff --git a/osu.Game/Graphics/UserInterface/StatefulMenuItem.cs b/osu.Game/Graphics/UserInterface/StatefulMenuItem.cs index 17266e876c..85efd75a60 100644 --- a/osu.Game/Graphics/UserInterface/StatefulMenuItem.cs +++ b/osu.Game/Graphics/UserInterface/StatefulMenuItem.cs @@ -1,11 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; namespace osu.Game.Graphics.UserInterface { @@ -25,7 +24,7 @@ namespace osu.Game.Graphics.UserInterface /// The text to display. /// A function that mutates a state to another state after this is pressed. /// The type of action which this performs. - protected StatefulMenuItem(string text, Func changeStateFunc, MenuItemType type = MenuItemType.Standard) + protected StatefulMenuItem(LocalisableString text, Func changeStateFunc, MenuItemType type = MenuItemType.Standard) : this(text, changeStateFunc, type, null) { } @@ -37,7 +36,7 @@ namespace osu.Game.Graphics.UserInterface /// A function that mutates a state to another state after this is pressed. /// The type of action which this performs. /// A delegate to be invoked when this is pressed. - protected StatefulMenuItem(string text, Func changeStateFunc, MenuItemType type, Action action) + protected StatefulMenuItem(LocalisableString text, Func? changeStateFunc, MenuItemType type, Action? action) : base(text, type) { Action.Value = () => @@ -69,7 +68,7 @@ namespace osu.Game.Graphics.UserInterface /// The text to display. /// A function that mutates a state to another state after this is pressed. /// The type of action which this performs. - protected StatefulMenuItem(string text, Func changeStateFunc, MenuItemType type = MenuItemType.Standard) + protected StatefulMenuItem(LocalisableString text, Func? changeStateFunc, MenuItemType type = MenuItemType.Standard) : this(text, changeStateFunc, type, null) { } @@ -81,7 +80,7 @@ namespace osu.Game.Graphics.UserInterface /// A function that mutates a state to another state after this is pressed. /// The type of action which this performs. /// A delegate to be invoked when this is pressed. - protected StatefulMenuItem(string text, Func changeStateFunc, MenuItemType type, Action action) + protected StatefulMenuItem(LocalisableString text, Func? changeStateFunc, MenuItemType type, Action? action) : base(text, o => changeStateFunc?.Invoke((T)o) ?? o, type, o => action?.Invoke((T)o)) { base.State.BindValueChanged(state => diff --git a/osu.Game/Graphics/UserInterface/ToggleMenuItem.cs b/osu.Game/Graphics/UserInterface/ToggleMenuItem.cs index 6787e17113..51e1248bc1 100644 --- a/osu.Game/Graphics/UserInterface/ToggleMenuItem.cs +++ b/osu.Game/Graphics/UserInterface/ToggleMenuItem.cs @@ -1,10 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; namespace osu.Game.Graphics.UserInterface { @@ -18,7 +17,7 @@ namespace osu.Game.Graphics.UserInterface /// /// The text to display. /// The type of action which this performs. - public ToggleMenuItem(string text, MenuItemType type = MenuItemType.Standard) + public ToggleMenuItem(LocalisableString text, MenuItemType type = MenuItemType.Standard) : this(text, type, null) { } @@ -29,7 +28,7 @@ namespace osu.Game.Graphics.UserInterface /// The text to display. /// The type of action which this performs. /// A delegate to be invoked when this is pressed. - public ToggleMenuItem(string text, MenuItemType type, Action action) + public ToggleMenuItem(LocalisableString text, MenuItemType type, Action? action) : base(text, value => !value, type, action) { } diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs b/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs index 0a2c073dcd..1bd8979347 100644 --- a/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs +++ b/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; namespace osu.Game.Screens.Edit.Components.Menus @@ -10,13 +11,13 @@ namespace osu.Game.Screens.Edit.Components.Menus { private const int min_text_length = 40; - public EditorMenuItem(string text, MenuItemType type = MenuItemType.Standard) - : base(text.PadRight(min_text_length), type) + public EditorMenuItem(LocalisableString text, MenuItemType type = MenuItemType.Standard) + : base(LocalisableString.Interpolate($"{text,-min_text_length}"), type) { } - public EditorMenuItem(string text, MenuItemType type, Action action) - : base(text.PadRight(min_text_length), type, action) + public EditorMenuItem(LocalisableString text, MenuItemType type, Action action) + : base(LocalisableString.Interpolate($"{text,-min_text_length}"), type, action) { } } diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs b/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs index 3d51874082..1f6d61d0ad 100644 --- a/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs +++ b/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs @@ -56,11 +56,6 @@ namespace osu.Game.Screens.Edit.Components.Menus Bar.Expire(); } - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - } - protected override void OnActivated() { base.OnActivated(); From 24df23f42038d890ad645bc7430351baf3314afc Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 01:49:19 +0300 Subject: [PATCH 1541/2991] Localise background header --- osu.Game/Localisation/EditorSetupStrings.cs | 26 ++++++++++++++----- .../Edit/Setup/SetupScreenHeaderBackground.cs | 3 ++- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/osu.Game/Localisation/EditorSetupStrings.cs b/osu.Game/Localisation/EditorSetupStrings.cs index 0431b9cf76..4ddacf2c5b 100644 --- a/osu.Game/Localisation/EditorSetupStrings.cs +++ b/osu.Game/Localisation/EditorSetupStrings.cs @@ -42,7 +42,8 @@ namespace osu.Game.Localisation /// /// "If enabled, an "Are you ready? 3, 2, 1, GO!" countdown will be inserted at the beginning of the beatmap, assuming there is enough time to do so." /// - public static LocalisableString CountdownDescription => new TranslatableString(getKey(@"countdown_description"), @"If enabled, an ""Are you ready? 3, 2, 1, GO!"" countdown will be inserted at the beginning of the beatmap, assuming there is enough time to do so."); + public static LocalisableString CountdownDescription => new TranslatableString(getKey(@"countdown_description"), + @"If enabled, an ""Are you ready? 3, 2, 1, GO!"" countdown will be inserted at the beginning of the beatmap, assuming there is enough time to do so."); /// /// "Countdown speed" @@ -52,7 +53,8 @@ namespace osu.Game.Localisation /// /// "If the countdown sounds off-time, use this to make it appear one or more beats early." /// - public static LocalisableString CountdownOffsetDescription => new TranslatableString(getKey(@"countdown_offset_description"), @"If the countdown sounds off-time, use this to make it appear one or more beats early."); + public static LocalisableString CountdownOffsetDescription => + new TranslatableString(getKey(@"countdown_offset_description"), @"If the countdown sounds off-time, use this to make it appear one or more beats early."); /// /// "Countdown offset" @@ -67,7 +69,8 @@ namespace osu.Game.Localisation /// /// "Allows storyboards to use the full screen space, rather than be confined to a 4:3 area." /// - public static LocalisableString WidescreenSupportDescription => new TranslatableString(getKey(@"widescreen_support_description"), @"Allows storyboards to use the full screen space, rather than be confined to a 4:3 area."); + public static LocalisableString WidescreenSupportDescription => + new TranslatableString(getKey(@"widescreen_support_description"), @"Allows storyboards to use the full screen space, rather than be confined to a 4:3 area."); /// /// "Epilepsy warning" @@ -77,7 +80,8 @@ namespace osu.Game.Localisation /// /// "Recommended if the storyboard or video contain scenes with rapidly flashing colours." /// - public static LocalisableString EpilepsyWarningDescription => new TranslatableString(getKey(@"epilepsy_warning_description"), @"Recommended if the storyboard or video contain scenes with rapidly flashing colours."); + public static LocalisableString EpilepsyWarningDescription => + new TranslatableString(getKey(@"epilepsy_warning_description"), @"Recommended if the storyboard or video contain scenes with rapidly flashing colours."); /// /// "Letterbox during breaks" @@ -87,7 +91,8 @@ namespace osu.Game.Localisation /// /// "Adds horizontal letterboxing to give a cinematic look during breaks." /// - public static LocalisableString LetterboxDuringBreaksDescription => new TranslatableString(getKey(@"letterbox_during_breaks_description"), @"Adds horizontal letterboxing to give a cinematic look during breaks."); + public static LocalisableString LetterboxDuringBreaksDescription => + new TranslatableString(getKey(@"letterbox_during_breaks_description"), @"Adds horizontal letterboxing to give a cinematic look during breaks."); /// /// "Samples match playback rate" @@ -97,7 +102,8 @@ namespace osu.Game.Localisation /// /// "When enabled, all samples will speed up or slow down when rate-changing mods are enabled." /// - public static LocalisableString SamplesMatchPlaybackRateDescription => new TranslatableString(getKey(@"samples_match_playback_rate_description"), @"When enabled, all samples will speed up or slow down when rate-changing mods are enabled."); + public static LocalisableString SamplesMatchPlaybackRateDescription => new TranslatableString(getKey(@"samples_match_playback_rate_description"), + @"When enabled, all samples will speed up or slow down when rate-changing mods are enabled."); /// /// "The size of all hit objects" @@ -117,7 +123,8 @@ namespace osu.Game.Localisation /// /// "The harshness of hit windows and difficulty of special objects (ie. spinners)" /// - public static LocalisableString OverallDifficultyDescription => new TranslatableString(getKey(@"overall_difficulty_description"), @"The harshness of hit windows and difficulty of special objects (ie. spinners)"); + public static LocalisableString OverallDifficultyDescription => + new TranslatableString(getKey(@"overall_difficulty_description"), @"The harshness of hit windows and difficulty of special objects (ie. spinners)"); /// /// "Metadata" @@ -199,6 +206,11 @@ namespace osu.Game.Localisation /// public static LocalisableString DifficultyHeader => new TranslatableString(getKey(@"difficulty_header"), @"Difficulty"); + /// + /// "Drag image here to set beatmap background!" + /// + public static LocalisableString DragToSetBackground => new TranslatableString(getKey(@"drag_to_set_background"), @"Drag image here to set beatmap background!"); + private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs b/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs index 47a7512adf..033e5361bb 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs @@ -10,6 +10,7 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Localisation; namespace osu.Game.Screens.Edit.Setup { @@ -61,7 +62,7 @@ namespace osu.Game.Screens.Edit.Setup }, new OsuTextFlowContainer(t => t.Font = OsuFont.Default.With(size: 24)) { - Text = "Drag image here to set beatmap background!", + Text = EditorSetupStrings.DragToSetBackground, Anchor = Anchor.Centre, Origin = Anchor.Centre, AutoSizeAxes = Axes.Both From 78e562903df18bf7c24d31bc640636b4fe029d78 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 01:50:41 +0300 Subject: [PATCH 1542/2991] Localise part of editor --- osu.Game/Localisation/EditorStrings.cs | 164 ++++++++++++++++++ .../Screens/Edit/BackgroundDimMenuItem.cs | 13 +- .../Edit/Components/PlaybackControl.cs | 3 +- .../Timelines/Summary/TestGameplayButton.cs | 3 +- .../Components/Timeline/TimelineArea.cs | 7 +- osu.Game/Screens/Edit/Editor.cs | 39 ++--- osu.Game/Screens/Edit/EditorScreenMode.cs | 15 +- .../Screens/Edit/WaveformOpacityMenuItem.cs | 3 +- 8 files changed, 207 insertions(+), 40 deletions(-) create mode 100644 osu.Game/Localisation/EditorStrings.cs diff --git a/osu.Game/Localisation/EditorStrings.cs b/osu.Game/Localisation/EditorStrings.cs new file mode 100644 index 0000000000..32078468c9 --- /dev/null +++ b/osu.Game/Localisation/EditorStrings.cs @@ -0,0 +1,164 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class EditorStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.Editor"; + + /// + /// "File" + /// + public static LocalisableString File => new TranslatableString(getKey(@"file"), @"File"); + + /// + /// "Edit" + /// + public static LocalisableString Edit => new TranslatableString(getKey(@"edit"), @"Edit"); + + /// + /// "Undo" + /// + public static LocalisableString Undo => new TranslatableString(getKey(@"undo"), @"Undo"); + + /// + /// "Redo" + /// + public static LocalisableString Redo => new TranslatableString(getKey(@"redo"), @"Redo"); + + /// + /// "Cut" + /// + public static LocalisableString Cut => new TranslatableString(getKey(@"cut"), @"Cut"); + + /// + /// "Copy" + /// + public static LocalisableString Copy => new TranslatableString(getKey(@"copy"), @"Copy"); + + /// + /// "Paste" + /// + public static LocalisableString Paste => new TranslatableString(getKey(@"paste"), @"Paste"); + + /// + /// "Clone" + /// + public static LocalisableString Clone => new TranslatableString(getKey(@"clone"), @"Clone"); + + /// + /// "View" + /// + public static LocalisableString View => new TranslatableString(getKey(@"view"), @"View"); + + /// + /// "Background dim" + /// + public static LocalisableString BackgroundDim => new TranslatableString(getKey(@"background_dim"), @"Background dim"); + + /// + /// "Waveform opacity" + /// + public static LocalisableString WaveformOpacity => new TranslatableString(getKey(@"waveform_opacity"), @"Waveform opacity"); + + /// + /// "Show hit markers" + /// + public static LocalisableString ShowHitMarkers => new TranslatableString(getKey(@"show_hit_markers"), @"Show hit markers"); + + /// + /// "Timing" + /// + public static LocalisableString Timing => new TranslatableString(getKey(@"timing"), @"Timing"); + + /// + /// "Set preview point to current time" + /// + public static LocalisableString SetPreviewPointToCurrent => new TranslatableString(getKey(@"set_preview_point_to_current"), @"Set preview point to current time"); + + /// + /// "Save" + /// + public static LocalisableString Save => new TranslatableString(getKey(@"save"), @"Save"); + + /// + /// "Export package" + /// + public static LocalisableString ExportPackage => new TranslatableString(getKey(@"export_package"), @"Export package"); + + /// + /// "Create new difficulty" + /// + public static LocalisableString CreateNewDifficulty => new TranslatableString(getKey(@"create_new_difficulty"), @"Create new difficulty"); + + /// + /// "Change difficulty" + /// + public static LocalisableString ChangeDifficulty => new TranslatableString(getKey(@"change_difficulty"), @"Change difficulty"); + + /// + /// "Delete difficulty" + /// + public static LocalisableString DeleteDifficulty => new TranslatableString(getKey(@"delete_difficulty"), @"Delete difficulty"); + + /// + /// "Exit" + /// + public static LocalisableString Exit => new TranslatableString(getKey(@"exit"), @"Exit"); + + /// + /// "setup" + /// + public static LocalisableString SetupScreen => new TranslatableString(getKey(@"setup_screen"), @"setup"); + + /// + /// "compose" + /// + public static LocalisableString ComposeScreen => new TranslatableString(getKey(@"compose_screen"), @"compose"); + + /// + /// "design" + /// + public static LocalisableString DesignScreen => new TranslatableString(getKey(@"design_screen"), @"design"); + + /// + /// "timing" + /// + public static LocalisableString TimingScreen => new TranslatableString(getKey(@"timing_screen"), @"timing"); + + /// + /// "verify" + /// + public static LocalisableString VerifyScreen => new TranslatableString(getKey(@"verify_screen"), @"verify"); + + /// + /// "Playback speed" + /// + public static LocalisableString PlaybackSpeed => new TranslatableString(getKey(@"playback_speed"), @"Playback speed"); + + /// + /// "Test!" + /// + public static LocalisableString TestBeatmap => new TranslatableString(getKey(@"test_beatmap"), @"Test!"); + + /// + /// "Waveform" + /// + public static LocalisableString TimelineWaveform => new TranslatableString(getKey(@"timeline_waveform"), @"Waveform"); + + /// + /// "Ticks" + /// + public static LocalisableString TimelineTicks => new TranslatableString(getKey(@"timeline_ticks"), @"Ticks"); + + /// + /// "BPM" + /// + public static LocalisableString TimelineBpm => new TranslatableString(getKey(@"timeline_bpm"), @"BPM"); + + private static string getKey(string key) => $@"{prefix}:{key}"; + } +} diff --git a/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs b/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs index b5a33f06e7..bff01385bb 100644 --- a/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs +++ b/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs @@ -5,17 +5,18 @@ using System.Collections.Generic; using osu.Framework.Bindables; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; namespace osu.Game.Screens.Edit { internal class BackgroundDimMenuItem : MenuItem { - private readonly Bindable backgroudDim; + private readonly Bindable backgroundDim; private readonly Dictionary menuItemLookup = new Dictionary(); - public BackgroundDimMenuItem(Bindable backgroudDim) - : base("Background dim") + public BackgroundDimMenuItem(Bindable backgroundDim) + : base(EditorStrings.BackgroundDim) { Items = new[] { @@ -25,8 +26,8 @@ namespace osu.Game.Screens.Edit createMenuItem(0.75f), }; - this.backgroudDim = backgroudDim; - backgroudDim.BindValueChanged(dim => + this.backgroundDim = backgroundDim; + backgroundDim.BindValueChanged(dim => { foreach (var kvp in menuItemLookup) kvp.Value.State.Value = kvp.Key == dim.NewValue ? TernaryState.True : TernaryState.False; @@ -40,6 +41,6 @@ namespace osu.Game.Screens.Edit return item; } - private void updateOpacity(float dim) => backgroudDim.Value = dim; + private void updateOpacity(float dim) => backgroundDim.Value = dim; } } diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs index 87cbcb8aff..72c299f443 100644 --- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs +++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs @@ -16,6 +16,7 @@ using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Overlays; using osuTK.Input; @@ -47,7 +48,7 @@ namespace osu.Game.Screens.Edit.Components new OsuSpriteText { Origin = Anchor.BottomLeft, - Text = "Playback speed", + Text = EditorStrings.PlaybackSpeed, RelativePositionAxes = Axes.Y, Y = 0.5f, Padding = new MarginPadding { Left = 45 } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs index 9b45464e81..169e72fe3f 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Overlays; namespace osu.Game.Screens.Edit.Components.Timelines.Summary @@ -30,7 +31,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary Content.CornerRadius = 0; - Text = "Test!"; + Text = EditorStrings.TestBeatmap; } } } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs index 615925ff91..f11c7b1d00 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Overlays; using osuTK; @@ -75,17 +76,17 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { waveformCheckbox = new OsuCheckbox { - LabelText = "Waveform", + LabelText = EditorStrings.TimelineWaveform, Current = { Value = true }, }, ticksCheckbox = new OsuCheckbox { - LabelText = "Ticks", + LabelText = EditorStrings.TimelineTicks, Current = { Value = true }, }, controlPointsCheckbox = new OsuCheckbox { - LabelText = "BPM", + LabelText = EditorStrings.TimelineBpm, Current = { Value = true }, }, } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index be4e2f9628..c440cc8285 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -51,7 +51,6 @@ using osu.Game.Screens.Edit.Verify; using osu.Game.Screens.Play; using osu.Game.Users; using osuTK.Input; -using CommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings; namespace osu.Game.Screens.Edit { @@ -294,40 +293,40 @@ namespace osu.Game.Screens.Edit RelativeSizeAxes = Axes.Both, Items = new[] { - new MenuItem("File") + new MenuItem(EditorStrings.File) { Items = createFileMenuItems() }, - new MenuItem(CommonStrings.ButtonsEdit) + new MenuItem(EditorStrings.Edit) { Items = new[] { - undoMenuItem = new EditorMenuItem("Undo", MenuItemType.Standard, Undo), - redoMenuItem = new EditorMenuItem("Redo", MenuItemType.Standard, Redo), + undoMenuItem = new EditorMenuItem(EditorStrings.Undo, MenuItemType.Standard, Undo), + redoMenuItem = new EditorMenuItem(EditorStrings.Redo, MenuItemType.Standard, Redo), new EditorMenuItemSpacer(), - cutMenuItem = new EditorMenuItem("Cut", MenuItemType.Standard, Cut), - copyMenuItem = new EditorMenuItem("Copy", MenuItemType.Standard, Copy), - pasteMenuItem = new EditorMenuItem("Paste", MenuItemType.Standard, Paste), - cloneMenuItem = new EditorMenuItem("Clone", MenuItemType.Standard, Clone), + cutMenuItem = new EditorMenuItem(EditorStrings.Cut, MenuItemType.Standard, Cut), + copyMenuItem = new EditorMenuItem(EditorStrings.Copy, MenuItemType.Standard, Copy), + pasteMenuItem = new EditorMenuItem(EditorStrings.Paste, MenuItemType.Standard, Paste), + cloneMenuItem = new EditorMenuItem(EditorStrings.Clone, MenuItemType.Standard, Clone), } }, - new MenuItem("View") + new MenuItem(EditorStrings.View) { Items = new MenuItem[] { new WaveformOpacityMenuItem(config.GetBindable(OsuSetting.EditorWaveformOpacity)), new BackgroundDimMenuItem(editorBackgroundDim), - new ToggleMenuItem("Show hit markers") + new ToggleMenuItem(EditorStrings.ShowHitMarkers) { State = { BindTarget = editorHitMarkers }, } } }, - new MenuItem("Timing") + new MenuItem(EditorStrings.Timing) { Items = new MenuItem[] { - new EditorMenuItem("Set preview point to current time", MenuItemType.Standard, SetPreviewPointToCurrentTime) + new EditorMenuItem(EditorStrings.SetPreviewPointToCurrent, MenuItemType.Standard, SetPreviewPointToCurrentTime) } } } @@ -716,7 +715,7 @@ namespace osu.Game.Screens.Edit if (!(refetchedBeatmap is DummyWorkingBeatmap)) { - Logger.Log("Editor providing re-fetched beatmap post edit session"); + Logger.Log(@"Editor providing re-fetched beatmap post edit session"); Beatmap.Value = refetchedBeatmap; } } @@ -952,15 +951,15 @@ namespace osu.Game.Screens.Edit private List createFileMenuItems() => new List { - new EditorMenuItem("Save", MenuItemType.Standard, () => Save()), - new EditorMenuItem("Export package", MenuItemType.Standard, exportBeatmap) { Action = { Disabled = !RuntimeInfo.IsDesktop } }, + new EditorMenuItem(EditorStrings.Save, MenuItemType.Standard, () => Save()), + new EditorMenuItem(EditorStrings.ExportPackage, MenuItemType.Standard, exportBeatmap) { Action = { Disabled = !RuntimeInfo.IsDesktop } }, new EditorMenuItemSpacer(), createDifficultyCreationMenu(), createDifficultySwitchMenu(), new EditorMenuItemSpacer(), - new EditorMenuItem("Delete difficulty", MenuItemType.Standard, deleteDifficulty) { Action = { Disabled = Beatmap.Value.BeatmapSetInfo.Beatmaps.Count < 2 } }, + new EditorMenuItem(EditorStrings.DeleteDifficulty, MenuItemType.Standard, deleteDifficulty) { Action = { Disabled = Beatmap.Value.BeatmapSetInfo.Beatmaps.Count < 2 } }, new EditorMenuItemSpacer(), - new EditorMenuItem("Exit", MenuItemType.Standard, this.Exit) + new EditorMenuItem(EditorStrings.Exit, MenuItemType.Standard, this.Exit) }; private void exportBeatmap() @@ -1009,7 +1008,7 @@ namespace osu.Game.Screens.Edit foreach (var ruleset in rulesets.AvailableRulesets) rulesetItems.Add(new EditorMenuItem(ruleset.Name, MenuItemType.Standard, () => CreateNewDifficulty(ruleset))); - return new EditorMenuItem("Create new difficulty") { Items = rulesetItems }; + return new EditorMenuItem(EditorStrings.CreateNewDifficulty) { Items = rulesetItems }; } protected void CreateNewDifficulty(RulesetInfo rulesetInfo) @@ -1045,7 +1044,7 @@ namespace osu.Game.Screens.Edit } } - return new EditorMenuItem("Change difficulty") { Items = difficultyItems }; + return new EditorMenuItem(EditorStrings.ChangeDifficulty) { Items = difficultyItems }; } protected void SwitchToDifficulty(BeatmapInfo nextBeatmap) => loader?.ScheduleSwitchToExistingDifficulty(nextBeatmap, GetState(nextBeatmap.Ruleset)); diff --git a/osu.Game/Screens/Edit/EditorScreenMode.cs b/osu.Game/Screens/Edit/EditorScreenMode.cs index 81fcf23cdf..f787fee1e0 100644 --- a/osu.Game/Screens/Edit/EditorScreenMode.cs +++ b/osu.Game/Screens/Edit/EditorScreenMode.cs @@ -1,27 +1,26 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using System.ComponentModel; +using osu.Framework.Localisation; +using osu.Game.Localisation; namespace osu.Game.Screens.Edit { public enum EditorScreenMode { - [Description("setup")] + [LocalisableDescription(typeof(EditorStrings), nameof(EditorStrings.SetupScreen))] SongSetup, - [Description("compose")] + [LocalisableDescription(typeof(EditorStrings), nameof(EditorStrings.ComposeScreen))] Compose, - [Description("design")] + [LocalisableDescription(typeof(EditorStrings), nameof(EditorStrings.DesignScreen))] Design, - [Description("timing")] + [LocalisableDescription(typeof(EditorStrings), nameof(EditorStrings.TimingScreen))] Timing, - [Description("verify")] + [LocalisableDescription(typeof(EditorStrings), nameof(EditorStrings.VerifyScreen))] Verify, } } diff --git a/osu.Game/Screens/Edit/WaveformOpacityMenuItem.cs b/osu.Game/Screens/Edit/WaveformOpacityMenuItem.cs index 3d3f67e70e..5b1d7142e4 100644 --- a/osu.Game/Screens/Edit/WaveformOpacityMenuItem.cs +++ b/osu.Game/Screens/Edit/WaveformOpacityMenuItem.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using osu.Framework.Bindables; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; namespace osu.Game.Screens.Edit { @@ -17,7 +18,7 @@ namespace osu.Game.Screens.Edit private readonly Dictionary menuItemLookup = new Dictionary(); public WaveformOpacityMenuItem(Bindable waveformOpacity) - : base("Waveform opacity") + : base(EditorStrings.WaveformOpacity) { Items = new[] { From 87650044bbecc58bcdd74ee4920b3a21603a6f9d Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 01:49:54 +0300 Subject: [PATCH 1543/2991] Localise create/save dialog --- osu.Game/Localisation/EditorDialogsStrings.cs | 54 +++++++++++++++++++ .../Screens/Edit/CreateNewDifficultyDialog.cs | 11 ++-- osu.Game/Screens/Edit/PromptForSaveDialog.cs | 11 ++-- 3 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 osu.Game/Localisation/EditorDialogsStrings.cs diff --git a/osu.Game/Localisation/EditorDialogsStrings.cs b/osu.Game/Localisation/EditorDialogsStrings.cs new file mode 100644 index 0000000000..fc4c2b7f2a --- /dev/null +++ b/osu.Game/Localisation/EditorDialogsStrings.cs @@ -0,0 +1,54 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class EditorDialogsStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.EditorDialogs"; + + /// + /// "Would you like to create a blank difficulty?" + /// + public static LocalisableString NewDifficultyDialogHeader => new TranslatableString(getKey(@"new_difficulty_dialog_header"), @"Would you like to create a blank difficulty?"); + + /// + /// "Yeah, let's start from scratch!" + /// + public static LocalisableString CreateNew => new TranslatableString(getKey(@"create_new"), @"Yeah, let's start from scratch!"); + + /// + /// "No, create an exact copy of this difficulty" + /// + public static LocalisableString CreateCopy => new TranslatableString(getKey(@"create_copy"), @"No, create an exact copy of this difficulty"); + + /// + /// "I changed my mind, I want to keep editing this difficulty" + /// + public static LocalisableString KeepEditing => new TranslatableString(getKey(@"keep_editing"), @"I changed my mind, I want to keep editing this difficulty"); + + /// + /// "Did you want to save your changes?" + /// + public static LocalisableString SaveDialogHeader => new TranslatableString(getKey(@"save_dialog_header"), @"Did you want to save your changes?"); + + /// + /// "Save my masterpiece!" + /// + public static LocalisableString Save => new TranslatableString(getKey(@"save"), @"Save my masterpiece!"); + + /// + /// "Forget all changes" + /// + public static LocalisableString ForgetAllChanges => new TranslatableString(getKey(@"forget_all_changes"), @"Forget all changes"); + + /// + /// "Oops, continue editing" + /// + public static LocalisableString ContinueEditing => new TranslatableString(getKey(@"continue_editing"), @"Oops, continue editing"); + + private static string getKey(string key) => $@"{prefix}:{key}"; + } +} diff --git a/osu.Game/Screens/Edit/CreateNewDifficultyDialog.cs b/osu.Game/Screens/Edit/CreateNewDifficultyDialog.cs index 85466c5056..811da5236e 100644 --- a/osu.Game/Screens/Edit/CreateNewDifficultyDialog.cs +++ b/osu.Game/Screens/Edit/CreateNewDifficultyDialog.cs @@ -1,10 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics.Sprites; using osu.Game.Overlays.Dialog; +using osu.Game.Localisation; namespace osu.Game.Screens.Edit { @@ -20,7 +19,7 @@ namespace osu.Game.Screens.Edit public CreateNewDifficultyDialog(CreateNewDifficulty createNewDifficulty) { - HeaderText = "Would you like to create a blank difficulty?"; + HeaderText = EditorDialogsStrings.NewDifficultyDialogHeader; Icon = FontAwesome.Regular.Clone; @@ -28,17 +27,17 @@ namespace osu.Game.Screens.Edit { new PopupDialogOkButton { - Text = "Yeah, let's start from scratch!", + Text = EditorDialogsStrings.CreateNew, Action = () => createNewDifficulty.Invoke(false) }, new PopupDialogCancelButton { - Text = "No, create an exact copy of this difficulty", + Text = EditorDialogsStrings.CreateCopy, Action = () => createNewDifficulty.Invoke(true) }, new PopupDialogCancelButton { - Text = "I changed my mind, I want to keep editing this difficulty", + Text = EditorDialogsStrings.KeepEditing, Action = () => { } } }; diff --git a/osu.Game/Screens/Edit/PromptForSaveDialog.cs b/osu.Game/Screens/Edit/PromptForSaveDialog.cs index 2a2cd019ea..7d78465e6c 100644 --- a/osu.Game/Screens/Edit/PromptForSaveDialog.cs +++ b/osu.Game/Screens/Edit/PromptForSaveDialog.cs @@ -1,11 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Graphics.Sprites; using osu.Game.Overlays.Dialog; +using osu.Game.Localisation; namespace osu.Game.Screens.Edit { @@ -13,7 +12,7 @@ namespace osu.Game.Screens.Edit { public PromptForSaveDialog(Action exit, Action saveAndExit, Action cancel) { - HeaderText = "Did you want to save your changes?"; + HeaderText = EditorDialogsStrings.SaveDialogHeader; Icon = FontAwesome.Regular.Save; @@ -21,17 +20,17 @@ namespace osu.Game.Screens.Edit { new PopupDialogOkButton { - Text = @"Save my masterpiece!", + Text = EditorDialogsStrings.Save, Action = saveAndExit }, new PopupDialogDangerousButton { - Text = @"Forget all changes", + Text = EditorDialogsStrings.ForgetAllChanges, Action = exit }, new PopupDialogCancelButton { - Text = @"Oops, continue editing", + Text = EditorDialogsStrings.ContinueEditing, Action = cancel }, }; From 627d1725c37b2cdfeaaab2ae2f158f767a2e3d67 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 14 Jan 2023 19:23:25 -0800 Subject: [PATCH 1544/2991] Fix kudosu wiki link from user profile not linking to in-game overlay --- osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs index 5e0227de5b..d2f01ef9f7 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs @@ -14,6 +14,7 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.LocalisationExtensions; using osu.Game.Resources.Localisation.Web; using osu.Framework.Localisation; +using osu.Game.Online.Chat; namespace osu.Game.Overlays.Profile.Sections.Kudosu { @@ -42,7 +43,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu : base(UsersStrings.ShowExtraKudosuTotal) { DescriptionText.AddText("Based on how much of a contribution the user has made to beatmap moderation. See "); - DescriptionText.AddLink("this page", "https://osu.ppy.sh/wiki/Kudosu"); + DescriptionText.AddLink("this page", LinkAction.OpenWiki, @"Modding/Kudosu"); DescriptionText.AddText(" for more information."); } } From a75fc5108a35bdea5b01439e058b216f5d38c1d9 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 16:00:34 +0900 Subject: [PATCH 1545/2991] Remove #nullable disable from Catch.Edit namespace --- .../Edit/BananaShowerCompositionTool.cs | 2 -- .../Blueprints/BananaShowerPlacementBlueprint.cs | 2 -- .../Blueprints/BananaShowerSelectionBlueprint.cs | 2 -- .../Edit/Blueprints/CatchPlacementBlueprint.cs | 4 +--- .../Edit/Blueprints/CatchSelectionBlueprint.cs | 4 +--- .../Edit/Blueprints/Components/EditablePath.cs | 6 +----- .../Edit/Blueprints/Components/FruitOutline.cs | 2 -- .../Components/NestedOutlineContainer.cs | 2 -- .../Components/PlacementEditablePath.cs | 2 -- .../Edit/Blueprints/Components/ScrollingPath.cs | 2 -- .../Components/SelectionEditablePath.cs | 6 +----- .../Edit/Blueprints/Components/TimeSpanOutline.cs | 2 -- .../Edit/Blueprints/Components/VertexPiece.cs | 4 +--- .../Edit/Blueprints/FruitPlacementBlueprint.cs | 2 -- .../Edit/Blueprints/FruitSelectionBlueprint.cs | 2 -- .../Blueprints/JuiceStreamPlacementBlueprint.cs | 4 +--- .../Blueprints/JuiceStreamSelectionBlueprint.cs | 6 +----- .../Edit/CatchBeatmapVerifier.cs | 2 -- .../Edit/CatchBlueprintContainer.cs | 4 +--- .../Edit/CatchDistanceSnapGrid.cs | 8 ++------ .../Edit/CatchEditorPlayfield.cs | 2 -- .../Edit/CatchHitObjectComposer.cs | 15 +++++---------- .../Edit/CatchHitObjectUtils.cs | 2 -- .../Edit/CatchSelectionHandler.cs | 4 +--- .../Edit/DrawableCatchEditorRuleset.cs | 4 +--- .../Edit/FruitCompositionTool.cs | 2 -- .../Edit/JuiceStreamCompositionTool.cs | 2 -- 27 files changed, 17 insertions(+), 82 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/BananaShowerCompositionTool.cs b/osu.Game.Rulesets.Catch/Edit/BananaShowerCompositionTool.cs index e64a51f03a..31075db7d1 100644 --- a/osu.Game.Rulesets.Catch/Edit/BananaShowerCompositionTool.cs +++ b/osu.Game.Rulesets.Catch/Edit/BananaShowerCompositionTool.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Edit.Blueprints; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerPlacementBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerPlacementBlueprint.cs index 166fa44303..5f22ef5c12 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerPlacementBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Input.Events; using osu.Game.Rulesets.Catch.Edit.Blueprints.Components; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerSelectionBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerSelectionBlueprint.cs index 2c545e8f0e..f6dd67889e 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerSelectionBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Objects; namespace osu.Game.Rulesets.Catch.Edit.Blueprints diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchPlacementBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchPlacementBlueprint.cs index 94373147d2..d2d605a6fe 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchPlacementBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Edit; @@ -20,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints protected ScrollingHitObjectContainer HitObjectContainer => (ScrollingHitObjectContainer)playfield.HitObjectContainer; [Resolved] - private Playfield playfield { get; set; } + private Playfield playfield { get; set; } = null!; public CatchPlacementBlueprint() : base(new THitObject()) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchSelectionBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchSelectionBlueprint.cs index 87c33a9cb8..8220fb88b4 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchSelectionBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Edit; @@ -31,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints protected ScrollingHitObjectContainer HitObjectContainer => (ScrollingHitObjectContainer)playfield.HitObjectContainer; [Resolved] - private Playfield playfield { get; set; } + private Playfield playfield { get; set; } = null!; protected CatchSelectionBlueprint(THitObject hitObject) : base(hitObject) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs index 006ea6e9cf..c2a426de66 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs @@ -1,13 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -43,8 +40,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components private readonly List previousVertexStates = new List(); [Resolved(CanBeNull = true)] - [CanBeNull] - private IBeatSnapProvider beatSnapProvider { get; set; } + private IBeatSnapProvider? beatSnapProvider { get; set; } protected EditablePath(Func positionToTime) { diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/FruitOutline.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/FruitOutline.cs index dc2b038e01..c7805544ea 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/FruitOutline.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/FruitOutline.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/NestedOutlineContainer.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/NestedOutlineContainer.cs index ac0c850bca..c1f46539fa 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/NestedOutlineContainer.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/NestedOutlineContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/PlacementEditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/PlacementEditablePath.cs index ba2f5ed0eb..3a7d6d87f2 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/PlacementEditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/PlacementEditablePath.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Game.Rulesets.Catch.Objects; using osuTK; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/ScrollingPath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/ScrollingPath.cs index 6deb5a174f..a22abcb76d 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/ScrollingPath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/ScrollingPath.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs index 3a44f7ac8a..95b17a197f 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.UserInterface; @@ -26,8 +23,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components private Vector2 dragStartPosition; [Resolved(CanBeNull = true)] - [CanBeNull] - private IEditorChangeHandler changeHandler { get; set; } + private IEditorChangeHandler? changeHandler { get; set; } public SelectionEditablePath(Func positionToTime) : base(positionToTime) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/TimeSpanOutline.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/TimeSpanOutline.cs index a1d5d7ae3e..9d450cd355 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/TimeSpanOutline.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/TimeSpanOutline.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/VertexPiece.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/VertexPiece.cs index 49570d3735..07d7c72698 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/VertexPiece.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/VertexPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -15,7 +13,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components public partial class VertexPiece : Circle { [Resolved] - private OsuColour osuColour { get; set; } + private OsuColour osuColour { get; set; } = null!; public VertexPiece() { diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitPlacementBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitPlacementBlueprint.cs index af75023e68..72592891fb 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitPlacementBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Input.Events; using osu.Game.Rulesets.Catch.Edit.Blueprints.Components; using osu.Game.Rulesets.Catch.Objects; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitSelectionBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitSelectionBlueprint.cs index 319b1b5e20..2737b283ef 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitSelectionBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Edit.Blueprints.Components; using osu.Game.Rulesets.Catch.Objects; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamPlacementBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamPlacementBlueprint.cs index 0e2ee334ff..03ec674abb 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamPlacementBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Input; using osu.Framework.Input.Events; @@ -24,7 +22,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints private int lastEditablePathId = -1; - private InputManager inputManager; + private InputManager inputManager = null!; public JuiceStreamPlacementBlueprint() { diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs index 99ec5e2b0c..1be5148d76 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs @@ -1,11 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Caching; using osu.Framework.Graphics; @@ -54,8 +51,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints private Vector2 rightMouseDownPosition; [Resolved(CanBeNull = true)] - [CanBeNull] - private EditorBeatmap editorBeatmap { get; set; } + private EditorBeatmap? editorBeatmap { get; set; } public JuiceStreamSelectionBlueprint(JuiceStream hitObject) : base(hitObject) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchBeatmapVerifier.cs b/osu.Game.Rulesets.Catch/Edit/CatchBeatmapVerifier.cs index 6570a19a92..c7a41a4e22 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchBeatmapVerifier.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchBeatmapVerifier.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Game.Rulesets.Catch.Edit.Checks; diff --git a/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs b/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs index 9408a9f95c..3979d30616 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Edit.Blueprints; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Edit; @@ -20,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Edit protected override SelectionHandler CreateSelectionHandler() => new CatchSelectionHandler(); - public override HitObjectSelectionBlueprint CreateHitObjectBlueprintFor(HitObject hitObject) + public override HitObjectSelectionBlueprint? CreateHitObjectBlueprintFor(HitObject hitObject) { switch (hitObject) { diff --git a/osu.Game.Rulesets.Catch/Edit/CatchDistanceSnapGrid.cs b/osu.Game.Rulesets.Catch/Edit/CatchDistanceSnapGrid.cs index 43918bda57..cf6ddc66ed 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchDistanceSnapGrid.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchDistanceSnapGrid.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -39,7 +36,7 @@ namespace osu.Game.Rulesets.Catch.Edit private readonly List verticalLineVertices = new List(); [Resolved] - private Playfield playfield { get; set; } + private Playfield playfield { get; set; } = null!; private ScrollingHitObjectContainer hitObjectContainer => (ScrollingHitObjectContainer)playfield.HitObjectContainer; @@ -106,8 +103,7 @@ namespace osu.Game.Rulesets.Catch.Edit } } - [CanBeNull] - public SnapResult GetSnappedPosition(Vector2 screenSpacePosition) + public SnapResult? GetSnappedPosition(Vector2 screenSpacePosition) { double time = hitObjectContainer.TimeAtScreenSpacePosition(screenSpacePosition); diff --git a/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs b/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs index bca89c6024..c9481c2757 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.UI; diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index cdf0ccfae9..ea5f54a775 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.EnumExtensions; @@ -32,9 +29,9 @@ namespace osu.Game.Rulesets.Catch.Edit { private const float distance_snap_radius = 50; - private CatchDistanceSnapGrid distanceSnapGrid; + private CatchDistanceSnapGrid distanceSnapGrid = null!; - private InputManager inputManager; + private InputManager inputManager = null!; private readonly BindableDouble timeRangeMultiplier = new BindableDouble(1) { @@ -117,7 +114,7 @@ namespace osu.Game.Rulesets.Catch.Edit return base.OnPressed(e); } - protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) => + protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList? mods = null) => new DrawableCatchEditorRuleset(ruleset, beatmap, mods) { TimeRangeMultiplier = { BindTarget = timeRangeMultiplier, } @@ -150,8 +147,7 @@ namespace osu.Game.Rulesets.Catch.Edit protected override ComposeBlueprintContainer CreateBlueprintContainer() => new CatchBlueprintContainer(this); - [CanBeNull] - private PalpableCatchHitObject getLastSnappableHitObject(double time) + private PalpableCatchHitObject? getLastSnappableHitObject(double time) { var hitObject = EditorBeatmap.HitObjects.OfType().LastOrDefault(h => h.GetEndTime() < time && !(h is BananaShower)); @@ -168,8 +164,7 @@ namespace osu.Game.Rulesets.Catch.Edit } } - [CanBeNull] - private PalpableCatchHitObject getDistanceSnapGridSourceHitObject() + private PalpableCatchHitObject? getDistanceSnapGridSourceHitObject() { switch (BlueprintContainer.CurrentTool) { diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectUtils.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectUtils.cs index 889d3909bd..bd33080109 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectUtils.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectUtils.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Game.Rulesets.Catch.Objects; diff --git a/osu.Game.Rulesets.Catch/Edit/CatchSelectionHandler.cs b/osu.Game.Rulesets.Catch/Edit/CatchSelectionHandler.cs index d9d7047920..418351e2f3 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchSelectionHandler.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchSelectionHandler.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -23,7 +21,7 @@ namespace osu.Game.Rulesets.Catch.Edit protected ScrollingHitObjectContainer HitObjectContainer => (ScrollingHitObjectContainer)playfield.HitObjectContainer; [Resolved] - private Playfield playfield { get; set; } + private Playfield playfield { get; set; } = null!; public override bool HandleMovement(MoveSelectionEvent moveEvent) { diff --git a/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs b/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs index 0a50ad1df4..7ad2106ab9 100644 --- a/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs +++ b/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Framework.Bindables; using osu.Game.Beatmaps; @@ -16,7 +14,7 @@ namespace osu.Game.Rulesets.Catch.Edit { public readonly BindableDouble TimeRangeMultiplier = new BindableDouble(1); - public DrawableCatchEditorRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) + public DrawableCatchEditorRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList? mods = null) : base(ruleset, beatmap, mods) { } diff --git a/osu.Game.Rulesets.Catch/Edit/FruitCompositionTool.cs b/osu.Game.Rulesets.Catch/Edit/FruitCompositionTool.cs index 5c13692b51..f776fe39c1 100644 --- a/osu.Game.Rulesets.Catch/Edit/FruitCompositionTool.cs +++ b/osu.Game.Rulesets.Catch/Edit/FruitCompositionTool.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Edit.Blueprints; diff --git a/osu.Game.Rulesets.Catch/Edit/JuiceStreamCompositionTool.cs b/osu.Game.Rulesets.Catch/Edit/JuiceStreamCompositionTool.cs index 85cf89f700..cb66e2952e 100644 --- a/osu.Game.Rulesets.Catch/Edit/JuiceStreamCompositionTool.cs +++ b/osu.Game.Rulesets.Catch/Edit/JuiceStreamCompositionTool.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Edit.Blueprints; From b049244b75d578f964a4d6b5b41d494ccc652fc3 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 16:21:56 +0900 Subject: [PATCH 1546/2991] Remove #nullable disable from Catch.Beatmaps --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs | 2 -- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs | 2 -- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs | 2 -- 3 files changed, 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs index ac39b91f00..f009c10a9c 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Game.Beatmaps; diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index 9f5d007114..7774a7da09 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using System.Collections.Generic; diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 835f7c2d27..ab61b14ac4 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; From 3ab3f556ae3044dd0689ae77c7f5911d49c86280 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 16:22:21 +0900 Subject: [PATCH 1547/2991] Remove #nullable disable from Catch.Difficulty --- .../Difficulty/CatchDifficultyCalculator.cs | 4 +--- .../Difficulty/CatchPerformanceAttributes.cs | 2 -- .../Difficulty/CatchPerformanceCalculator.cs | 2 -- .../Difficulty/Preprocessing/CatchDifficultyHitObject.cs | 2 -- osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs | 2 -- 5 files changed, 1 insertion(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs index f37479f84a..42cfde268e 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -51,7 +49,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty protected override IEnumerable CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) { - CatchHitObject lastObject = null; + CatchHitObject? lastObject = null; List objects = new List(); diff --git a/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceAttributes.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceAttributes.cs index ccdfd30200..1335fc2d23 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceAttributes.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceAttributes.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Difficulty; namespace osu.Game.Rulesets.Catch.Difficulty diff --git a/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs index 2a07b8019e..b30b85be2d 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; diff --git a/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs b/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs index c44480776f..3bcfce3a56 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using osu.Game.Rulesets.Catch.Objects; diff --git a/osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs b/osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs index 827c28f7de..cfb3fe40be 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Game.Rulesets.Catch.Difficulty.Preprocessing; using osu.Game.Rulesets.Difficulty.Preprocessing; From 2468911f4b2b1b8afaab986faf61b743c7b3687c Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 16:22:49 +0900 Subject: [PATCH 1548/2991] Remove #nullable disable from Catch.Judgements --- osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs | 2 -- osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs | 2 -- osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs | 2 -- osu.Game.Rulesets.Catch/Judgements/CatchJudgementResult.cs | 5 +---- .../Judgements/CatchTinyDropletJudgement.cs | 2 -- 5 files changed, 1 insertion(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs index 15f6e4a64d..b919102215 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs index 90aa6f41a1..8fd7b93e4c 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Judgements diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs index e5d6429660..ccafe0abc4 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Scoring; diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchJudgementResult.cs b/osu.Game.Rulesets.Catch/Judgements/CatchJudgementResult.cs index 6cc79f9619..4cec61d016 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchJudgementResult.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchJudgementResult.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; @@ -22,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.Judgements /// public bool CatcherHyperDash; - public CatchJudgementResult([NotNull] HitObject hitObject, [NotNull] Judgement judgement) + public CatchJudgementResult(HitObject hitObject, Judgement judgement) : base(hitObject, judgement) { } diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs index c9052e3c39..d957d4171b 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Judgements From 56fb315f32f6a15f000bf7aa38f2b3f54e03211e Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 16:23:45 +0900 Subject: [PATCH 1549/2991] Remove #nullable disable from Catch.Objects --- osu.Game.Rulesets.Catch/Objects/BananaShower.cs | 2 -- osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs | 2 -- osu.Game.Rulesets.Catch/Objects/Droplet.cs | 2 -- osu.Game.Rulesets.Catch/Objects/Fruit.cs | 2 -- .../Objects/FruitVisualRepresentation.cs | 2 -- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 11 ++--------- .../Objects/PalpableCatchHitObject.cs | 6 ++---- osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs | 2 -- 8 files changed, 4 insertions(+), 25 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs index e5541e49c1..b45f95a8e6 100644 --- a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Threading; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Types; diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index cd2b8348e2..f4bd515995 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using Newtonsoft.Json; using osu.Framework.Bindables; diff --git a/osu.Game.Rulesets.Catch/Objects/Droplet.cs b/osu.Game.Rulesets.Catch/Objects/Droplet.cs index ecaa4bfaf4..9c1004a04b 100644 --- a/osu.Game.Rulesets.Catch/Objects/Droplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Droplet.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Judgements; diff --git a/osu.Game.Rulesets.Catch/Objects/Fruit.cs b/osu.Game.Rulesets.Catch/Objects/Fruit.cs index bdf8b3f28d..4818fe2cad 100644 --- a/osu.Game.Rulesets.Catch/Objects/Fruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Fruit.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Judgements; diff --git a/osu.Game.Rulesets.Catch/Objects/FruitVisualRepresentation.cs b/osu.Game.Rulesets.Catch/Objects/FruitVisualRepresentation.cs index e5d013dafc..7ec7050245 100644 --- a/osu.Game.Rulesets.Catch/Objects/FruitVisualRepresentation.cs +++ b/osu.Game.Rulesets.Catch/Objects/FruitVisualRepresentation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Catch.Objects { public enum FruitVisualRepresentation diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 015457e84f..96e2d5c4e5 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -142,13 +140,8 @@ namespace osu.Game.Rulesets.Catch.Objects set { path.ControlPoints.Clear(); - path.ExpectedDistance.Value = null; - - if (value != null) - { - path.ControlPoints.AddRange(value.ControlPoints.Select(c => new PathControlPoint(c.Position, c.Type))); - path.ExpectedDistance.Value = value.ExpectedDistance.Value; - } + path.ControlPoints.AddRange(value.ControlPoints.Select(c => new PathControlPoint(c.Position, c.Type))); + path.ExpectedDistance.Value = value.ExpectedDistance.Value; } } diff --git a/osu.Game.Rulesets.Catch/Objects/PalpableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/PalpableCatchHitObject.cs index c9bc9ca2ac..197029aeeb 100644 --- a/osu.Game.Rulesets.Catch/Objects/PalpableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/PalpableCatchHitObject.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using Newtonsoft.Json; using osu.Framework.Bindables; using osu.Game.Rulesets.Objects; @@ -34,13 +32,13 @@ namespace osu.Game.Rulesets.Catch.Objects /// public bool HyperDash => hyperDash.Value; - private CatchHitObject hyperDashTarget; + private CatchHitObject? hyperDashTarget; /// /// The target fruit if we are to initiate a hyperdash. /// [JsonIgnore] - public CatchHitObject HyperDashTarget + public CatchHitObject? HyperDashTarget { get => hyperDashTarget; set diff --git a/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs index 6bd5f0ac2a..1bf160b5a6 100644 --- a/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Judgements; From b08a1e3a0b4b0b85f0403c02c2deb57520531fb1 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 16:25:08 +0900 Subject: [PATCH 1550/2991] Remove #nullable disable from misc Catch files --- osu.Game.Rulesets.Catch/Properties/AssemblyInfo.cs | 2 -- osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs | 2 -- 2 files changed, 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Properties/AssemblyInfo.cs b/osu.Game.Rulesets.Catch/Properties/AssemblyInfo.cs index 6c7f0478a7..26f20b223a 100644 --- a/osu.Game.Rulesets.Catch/Properties/AssemblyInfo.cs +++ b/osu.Game.Rulesets.Catch/Properties/AssemblyInfo.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Runtime.CompilerServices; // We publish our internal attributes to other sub-projects of the framework. diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index b784fc4c19..b6a42407da 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Scoring From b88091262db0b4ebf4d9405ab8e6eb1ee53914fb Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 16:26:11 +0900 Subject: [PATCH 1551/2991] Remove #nullable disable from Catch.UI --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 6 ++---- .../UI/CatchPlayfieldAdjustmentContainer.cs | 2 -- osu.Game.Rulesets.Catch/UI/CatchReplayRecorder.cs | 2 -- osu.Game.Rulesets.Catch/UI/Catcher.cs | 14 ++++++-------- .../UI/CatcherAnimationState.cs | 2 -- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 4 +--- osu.Game.Rulesets.Catch/UI/CatcherTrail.cs | 2 -- .../UI/CatcherTrailAnimation.cs | 2 -- osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs | 7 +++---- osu.Game.Rulesets.Catch/UI/CatcherTrailEntry.cs | 2 -- osu.Game.Rulesets.Catch/UI/Direction.cs | 2 -- osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs | 6 ++---- .../UI/DroppedObjectContainer.cs | 2 -- .../UI/HitExplosionContainer.cs | 2 -- osu.Game.Rulesets.Catch/UI/ICatchComboCounter.cs | 2 -- osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs | 2 -- 16 files changed, 14 insertions(+), 45 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 6167ee53f6..c33d021876 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps; @@ -39,9 +37,9 @@ namespace osu.Game.Rulesets.Catch.UI // only check the X position; handle all vertical space. base.ReceivePositionalInputAt(new Vector2(screenSpacePos.X, ScreenSpaceDrawQuad.Centre.Y)); - internal Catcher Catcher { get; private set; } + internal Catcher Catcher { get; private set; } = null!; - internal CatcherArea CatcherArea { get; private set; } + internal CatcherArea CatcherArea { get; private set; } = null!; private readonly IBeatmapDifficultyInfo difficulty; diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs index c03179dc50..74cbc665c0 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.UI; diff --git a/osu.Game.Rulesets.Catch/UI/CatchReplayRecorder.cs b/osu.Game.Rulesets.Catch/UI/CatchReplayRecorder.cs index 9ea150a2cf..32ede8f205 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchReplayRecorder.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchReplayRecorder.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Replays; diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 086b4ff285..411330f6fc 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -1,11 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; +using System.Diagnostics; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -123,7 +121,7 @@ namespace osu.Game.Rulesets.Catch.UI private double hyperDashModifier = 1; private int hyperDashDirection; private float hyperDashTargetPosition; - private Bindable hitLighting; + private Bindable hitLighting = null!; private readonly HitExplosionContainer hitExplosionContainer; @@ -131,7 +129,7 @@ namespace osu.Game.Rulesets.Catch.UI private readonly DrawablePool caughtBananaPool; private readonly DrawablePool caughtDropletPool; - public Catcher([NotNull] DroppedObjectContainer droppedObjectTarget, IBeatmapDifficultyInfo difficulty = null) + public Catcher(DroppedObjectContainer droppedObjectTarget, IBeatmapDifficultyInfo? difficulty = null) { this.droppedObjectTarget = droppedObjectTarget; @@ -231,9 +229,8 @@ namespace osu.Game.Rulesets.Catch.UI // droplet doesn't affect the catcher state if (hitObject is TinyDroplet) return; - if (result.IsHit && hitObject.HyperDash) + if (result.IsHit && hitObject.HyperDashTarget is CatchHitObject target) { - var target = hitObject.HyperDashTarget; double timeDifference = target.StartTime - hitObject.StartTime; double positionDifference = target.EffectiveX - X; double velocity = positionDifference / Math.Max(1.0, timeDifference - 1000.0 / 60.0); @@ -385,7 +382,7 @@ namespace osu.Game.Rulesets.Catch.UI private void addLighting(JudgementResult judgementResult, Color4 colour, float x) => hitExplosionContainer.Add(new HitExplosionEntry(Time.Current, judgementResult, colour, x)); - private CaughtObject getCaughtObject(PalpableCatchHitObject source) + private CaughtObject? getCaughtObject(PalpableCatchHitObject source) { switch (source) { @@ -406,6 +403,7 @@ namespace osu.Game.Rulesets.Catch.UI private CaughtObject getDroppedObject(CaughtObject caughtObject) { var droppedObject = getCaughtObject(caughtObject.HitObject); + Debug.Assert(droppedObject != null); droppedObject.CopyStateFrom(caughtObject); droppedObject.Anchor = Anchor.TopLeft; diff --git a/osu.Game.Rulesets.Catch/UI/CatcherAnimationState.cs b/osu.Game.Rulesets.Catch/UI/CatcherAnimationState.cs index 82591eb47f..566e9d1911 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherAnimationState.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherAnimationState.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Catch.UI { public enum CatcherAnimationState diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index d0da05bc44..4f7535d13a 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -35,7 +33,7 @@ namespace osu.Game.Rulesets.Catch.UI private readonly CatcherTrailDisplay catcherTrails; - private Catcher catcher; + private Catcher catcher = null!; /// /// -1 when only left button is pressed. diff --git a/osu.Game.Rulesets.Catch/UI/CatcherTrail.cs b/osu.Game.Rulesets.Catch/UI/CatcherTrail.cs index f486633e12..762f95828a 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherTrail.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherTrail.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Timing; using osu.Game.Rulesets.Objects.Pooling; diff --git a/osu.Game.Rulesets.Catch/UI/CatcherTrailAnimation.cs b/osu.Game.Rulesets.Catch/UI/CatcherTrailAnimation.cs index 02bc5be863..0a5281cd10 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherTrailAnimation.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherTrailAnimation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Catch.UI { public enum CatcherTrailAnimation diff --git a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs index e982be53d8..e3e01c1b39 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs @@ -1,10 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Pooling; @@ -41,7 +40,7 @@ namespace osu.Game.Rulesets.Catch.UI private readonly Container hyperDashAfterImages; [Resolved] - private ISkinSource skin { get; set; } + private ISkinSource skin { get; set; } = null!; public CatcherTrailDisplay() { @@ -130,7 +129,7 @@ namespace osu.Game.Rulesets.Catch.UI { base.Dispose(isDisposing); - if (skin != null) + if (skin.IsNotNull()) skin.SourceChanged -= skinSourceChanged; } } diff --git a/osu.Game.Rulesets.Catch/UI/CatcherTrailEntry.cs b/osu.Game.Rulesets.Catch/UI/CatcherTrailEntry.cs index 78d6979b78..3a40ab26cc 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherTrailEntry.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherTrailEntry.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics.Performance; using osuTK; diff --git a/osu.Game.Rulesets.Catch/UI/Direction.cs b/osu.Game.Rulesets.Catch/UI/Direction.cs index 15e4aed86b..65f064b7fb 100644 --- a/osu.Game.Rulesets.Catch/UI/Direction.cs +++ b/osu.Game.Rulesets.Catch/UI/Direction.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Catch.UI { public enum Direction diff --git a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs index 0be271b236..7930a07551 100644 --- a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; @@ -27,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.UI protected override bool UserScrollSpeedAdjustment => false; - public DrawableCatchRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) + public DrawableCatchRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList? mods = null) : base(ruleset, beatmap, mods) { Direction.Value = ScrollingDirection.Down; @@ -54,6 +52,6 @@ namespace osu.Game.Rulesets.Catch.UI protected override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo); - public override DrawableHitObject CreateDrawableRepresentation(CatchHitObject h) => null; + public override DrawableHitObject? CreateDrawableRepresentation(CatchHitObject h) => null; } } diff --git a/osu.Game.Rulesets.Catch/UI/DroppedObjectContainer.cs b/osu.Game.Rulesets.Catch/UI/DroppedObjectContainer.cs index cb2d8498cc..df1e932ad5 100644 --- a/osu.Game.Rulesets.Catch/UI/DroppedObjectContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/DroppedObjectContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Catch.Objects.Drawables; diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs b/osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs index e1dd665bf2..1e2d94433c 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Pooling; using osu.Game.Rulesets.Objects.Pooling; diff --git a/osu.Game.Rulesets.Catch/UI/ICatchComboCounter.cs b/osu.Game.Rulesets.Catch/UI/ICatchComboCounter.cs index 5d027edbaa..cfb6879067 100644 --- a/osu.Game.Rulesets.Catch/UI/ICatchComboCounter.cs +++ b/osu.Game.Rulesets.Catch/UI/ICatchComboCounter.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osuTK.Graphics; diff --git a/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs b/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs index 78a71f26a2..bcc59a5e4f 100644 --- a/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs +++ b/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; From 086604cd14eb48308b5b5ec43b97533ea180339b Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 16:27:49 +0900 Subject: [PATCH 1552/2991] Remove #nullable disable from Catch.Objects.Drawables Except DrawableCatchHitObject, it complains in base(hitObject) call. --- osu.Game.Rulesets.Catch/Objects/Drawables/CaughtBanana.cs | 2 -- osu.Game.Rulesets.Catch/Objects/Drawables/CaughtDroplet.cs | 2 -- osu.Game.Rulesets.Catch/Objects/Drawables/CaughtFruit.cs | 2 -- osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs | 5 +---- .../Objects/Drawables/DrawableBananaShower.cs | 5 +---- .../Objects/Drawables/DrawableCatchHitObject.cs | 1 + .../Objects/Drawables/DrawableDroplet.cs | 5 +---- osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs | 5 +---- .../Objects/Drawables/DrawableJuiceStream.cs | 5 +---- .../Objects/Drawables/DrawablePalpableCatchHitObject.cs | 5 +---- .../Objects/Drawables/DrawableTinyDroplet.cs | 6 +----- .../Objects/Drawables/IHasCatchObjectState.cs | 2 -- 12 files changed, 8 insertions(+), 37 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtBanana.cs index 65d91bffe2..bfeb37b1b7 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtBanana.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Skinning.Default; namespace osu.Game.Rulesets.Catch.Objects.Drawables diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtDroplet.cs index ed8bf17747..d228c629c0 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtDroplet.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Skinning.Default; namespace osu.Game.Rulesets.Catch.Objects.Drawables diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtFruit.cs index d296052220..99dcac5268 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtFruit.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Skinning.Default; namespace osu.Game.Rulesets.Catch.Objects.Drawables diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs index 51addaebd5..26e304cf3f 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Skinning.Default; @@ -18,7 +15,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { } - public DrawableBanana([CanBeNull] Banana h) + public DrawableBanana(Banana? h) : base(h) { } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBananaShower.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBananaShower.cs index c5ae1b5526..03adbce885 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBananaShower.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; @@ -19,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { } - public DrawableBananaShower([CanBeNull] BananaShower s) + public DrawableBananaShower(BananaShower? s) : base(s) { RelativeSizeAxes = Axes.X; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs index c25bc7d076..7f8c17861d 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs @@ -53,6 +53,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables XOffsetBindable.UnbindFrom(HitObject.XOffsetBindable); } + [CanBeNull] public Func CheckPosition; protected override JudgementResult CreateResult(Judgement judgement) => new CatchJudgementResult(HitObject, judgement); diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs index e8b0c4a9fb..8f32cdcc31 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Skinning.Default; @@ -18,7 +15,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { } - public DrawableDroplet([CanBeNull] CatchHitObject h) + public DrawableDroplet(CatchHitObject? h) : base(h) { } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs index 4347c77383..52c53523e6 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Skinning.Default; @@ -18,7 +15,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { } - public DrawableFruit([CanBeNull] Fruit h) + public DrawableFruit(Fruit? h) : base(h) { } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs index 1ad1664122..41ecf59276 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; @@ -19,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { } - public DrawableJuiceStream([CanBeNull] JuiceStream s) + public DrawableJuiceStream(JuiceStream? s) : base(s) { RelativeSizeAxes = Axes.X; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs index 8468cc0a6a..4a9661f108 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -42,7 +39,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables public float DisplayRotation => ScalingContainer.Rotation; - protected DrawablePalpableCatchHitObject([CanBeNull] CatchHitObject h) + protected DrawablePalpableCatchHitObject(CatchHitObject? h) : base(h) { Origin = Anchor.Centre; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableTinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableTinyDroplet.cs index 8e98efdbda..f820ccdc62 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableTinyDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableTinyDroplet.cs @@ -1,10 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; - namespace osu.Game.Rulesets.Catch.Objects.Drawables { public partial class DrawableTinyDroplet : DrawableDroplet @@ -16,7 +12,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { } - public DrawableTinyDroplet([CanBeNull] TinyDroplet h) + public DrawableTinyDroplet(TinyDroplet? h) : base(h) { } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/IHasCatchObjectState.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/IHasCatchObjectState.cs index f30ef0831a..18fc0db6e3 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/IHasCatchObjectState.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/IHasCatchObjectState.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osuTK; using osuTK.Graphics; From 8777d5349bd9e816d9ceff9b0891bc51ca0014ea Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 14:39:34 +0300 Subject: [PATCH 1553/2991] Use existing strings --- osu.Game/Localisation/EditorStrings.cs | 15 --------------- osu.Game/Screens/Edit/BackgroundDimMenuItem.cs | 2 +- .../Compose/Components/Timeline/TimelineArea.cs | 3 ++- osu.Game/Screens/Edit/Editor.cs | 3 ++- 4 files changed, 5 insertions(+), 18 deletions(-) diff --git a/osu.Game/Localisation/EditorStrings.cs b/osu.Game/Localisation/EditorStrings.cs index 32078468c9..6b16e43bd3 100644 --- a/osu.Game/Localisation/EditorStrings.cs +++ b/osu.Game/Localisation/EditorStrings.cs @@ -54,11 +54,6 @@ namespace osu.Game.Localisation /// public static LocalisableString View => new TranslatableString(getKey(@"view"), @"View"); - /// - /// "Background dim" - /// - public static LocalisableString BackgroundDim => new TranslatableString(getKey(@"background_dim"), @"Background dim"); - /// /// "Waveform opacity" /// @@ -79,11 +74,6 @@ namespace osu.Game.Localisation /// public static LocalisableString SetPreviewPointToCurrent => new TranslatableString(getKey(@"set_preview_point_to_current"), @"Set preview point to current time"); - /// - /// "Save" - /// - public static LocalisableString Save => new TranslatableString(getKey(@"save"), @"Save"); - /// /// "Export package" /// @@ -154,11 +144,6 @@ namespace osu.Game.Localisation /// public static LocalisableString TimelineTicks => new TranslatableString(getKey(@"timeline_ticks"), @"Ticks"); - /// - /// "BPM" - /// - public static LocalisableString TimelineBpm => new TranslatableString(getKey(@"timeline_bpm"), @"BPM"); - private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs b/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs index bff01385bb..2a1159eb27 100644 --- a/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs +++ b/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs @@ -16,7 +16,7 @@ namespace osu.Game.Screens.Edit private readonly Dictionary menuItemLookup = new Dictionary(); public BackgroundDimMenuItem(Bindable backgroundDim) - : base(EditorStrings.BackgroundDim) + : base(GameplaySettingsStrings.BackgroundDim) { Items = new[] { diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs index f11c7b1d00..0b83258f8b 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Localisation; using osu.Game.Overlays; +using osu.Game.Resources.Localisation.Web; using osuTK; namespace osu.Game.Screens.Edit.Compose.Components.Timeline @@ -86,7 +87,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline }, controlPointsCheckbox = new OsuCheckbox { - LabelText = EditorStrings.TimelineBpm, + LabelText = BeatmapsetsStrings.ShowStatsBpm, Current = { Value = true }, }, } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index c440cc8285..29be1a3881 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -51,6 +51,7 @@ using osu.Game.Screens.Edit.Verify; using osu.Game.Screens.Play; using osu.Game.Users; using osuTK.Input; +using CommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings; namespace osu.Game.Screens.Edit { @@ -951,7 +952,7 @@ namespace osu.Game.Screens.Edit private List createFileMenuItems() => new List { - new EditorMenuItem(EditorStrings.Save, MenuItemType.Standard, () => Save()), + new EditorMenuItem(CommonStrings.ButtonsSave, MenuItemType.Standard, () => Save()), new EditorMenuItem(EditorStrings.ExportPackage, MenuItemType.Standard, exportBeatmap) { Action = { Disabled = !RuntimeInfo.IsDesktop } }, new EditorMenuItemSpacer(), createDifficultyCreationMenu(), From 5d2e09137cfed291d842458972c4c8c2e64073be Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 14:40:53 +0300 Subject: [PATCH 1554/2991] Remove text padding in editor menu for now --- osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs b/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs index 1bd8979347..368fe40977 100644 --- a/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs +++ b/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs @@ -9,15 +9,13 @@ namespace osu.Game.Screens.Edit.Components.Menus { public class EditorMenuItem : OsuMenuItem { - private const int min_text_length = 40; - public EditorMenuItem(LocalisableString text, MenuItemType type = MenuItemType.Standard) - : base(LocalisableString.Interpolate($"{text,-min_text_length}"), type) + : base(text, type) { } public EditorMenuItem(LocalisableString text, MenuItemType type, Action action) - : base(LocalisableString.Interpolate($"{text,-min_text_length}"), type, action) + : base(text, type, action) { } } From 13c1b8f5a49b1ba009ee687e824008b403f3e6e8 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 15 Jan 2023 15:51:18 +0300 Subject: [PATCH 1555/2991] Fix intermittent failure in tests with restarting player instances --- .../Visual/Navigation/TestSceneScreenNavigation.cs | 8 +++++++- osu.Game/Online/Spectator/SpectatorClient.cs | 2 +- osu.Game/OsuGameBase.cs | 6 +++--- osu.Game/Tests/Visual/OsuGameTestScene.cs | 3 +++ osu.Game/Tests/Visual/TestPlayer.cs | 14 ++++++++++++++ 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 66c4cf8686..7bde2e747d 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -195,11 +195,17 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for player", () => { DismissAnyNotifications(); - return (player = Game.ScreenStack.CurrentScreen as Player) != null; + player = Game.ScreenStack.CurrentScreen as Player; + return player?.IsLoaded == true; }); AddAssert("retry count is 0", () => player.RestartCount == 0); + // todo: see https://github.com/ppy/osu/issues/22220 + // tests are supposed to be immune to this edge case by the logic in TestPlayer, + // but we're running a full game instance here, so we have to work around it manually. + AddStep("end spectator before retry", () => Game.SpectatorClient.EndPlaying(player.GameplayState)); + AddStep("attempt to retry", () => player.ChildrenOfType().First().Action()); AddUntilStep("wait for old player gone", () => Game.ScreenStack.CurrentScreen != player); diff --git a/osu.Game/Online/Spectator/SpectatorClient.cs b/osu.Game/Online/Spectator/SpectatorClient.cs index b60cef2835..55ec75f4ce 100644 --- a/osu.Game/Online/Spectator/SpectatorClient.cs +++ b/osu.Game/Online/Spectator/SpectatorClient.cs @@ -47,7 +47,7 @@ namespace osu.Game.Online.Spectator /// /// Whether the local user is playing. /// - protected bool IsPlaying { get; private set; } + protected internal bool IsPlaying { get; private set; } /// /// Called whenever new frames arrive from the server. diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 33d33fe181..b27be37591 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -189,7 +189,7 @@ namespace osu.Game private RulesetConfigCache rulesetConfigCache; - private SpectatorClient spectatorClient; + protected SpectatorClient SpectatorClient { get; private set; } protected MultiplayerClient MultiplayerClient { get; private set; } @@ -300,7 +300,7 @@ namespace osu.Game // TODO: OsuGame or OsuGameBase? dependencies.CacheAs(beatmapUpdater = new BeatmapUpdater(BeatmapManager, difficultyCache, API, Storage)); - dependencies.CacheAs(spectatorClient = new OnlineSpectatorClient(endpoints)); + dependencies.CacheAs(SpectatorClient = new OnlineSpectatorClient(endpoints)); dependencies.CacheAs(MultiplayerClient = new OnlineMultiplayerClient(endpoints)); dependencies.CacheAs(metadataClient = new OnlineMetadataClient(endpoints)); dependencies.CacheAs(soloStatisticsWatcher = new SoloStatisticsWatcher()); @@ -346,7 +346,7 @@ namespace osu.Game if (API is APIAccess apiAccess) base.Content.Add(apiAccess); - base.Content.Add(spectatorClient); + base.Content.Add(SpectatorClient); base.Content.Add(MultiplayerClient); base.Content.Add(metadataClient); base.Content.Add(soloStatisticsWatcher); diff --git a/osu.Game/Tests/Visual/OsuGameTestScene.cs b/osu.Game/Tests/Visual/OsuGameTestScene.cs index 1bf1fbf6ab..94be4a375d 100644 --- a/osu.Game/Tests/Visual/OsuGameTestScene.cs +++ b/osu.Game/Tests/Visual/OsuGameTestScene.cs @@ -20,6 +20,7 @@ using osu.Game.Database; using osu.Game.Graphics.Cursor; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; +using osu.Game.Online.Spectator; using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -148,6 +149,8 @@ namespace osu.Game.Tests.Visual public new Bindable> SelectedMods => base.SelectedMods; + public new SpectatorClient SpectatorClient => base.SpectatorClient; + // if we don't apply these changes, when running under nUnit the version that gets populated is that of nUnit. public override Version AssemblyVersion => new Version(0, 0); public override string Version => "test game"; diff --git a/osu.Game/Tests/Visual/TestPlayer.cs b/osu.Game/Tests/Visual/TestPlayer.cs index 81195ebed9..d9cae6b03b 100644 --- a/osu.Game/Tests/Visual/TestPlayer.cs +++ b/osu.Game/Tests/Visual/TestPlayer.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Screens; using osu.Game.Online.API; using osu.Game.Online.Rooms; using osu.Game.Online.Spectator; @@ -103,6 +104,19 @@ namespace osu.Game.Tests.Visual ScoreProcessor.NewJudgement += r => Results.Add(r); } + public override bool OnExiting(ScreenExitEvent e) + { + bool exiting = base.OnExiting(e); + + // SubmittingPlayer performs EndPlaying on a fire-and-forget async task, which allows for the chance of BeginPlaying to be called before EndPlaying is called here. + // Until this is handled properly at game-side, ensure EndPlaying is called before exiting player. + // see: https://github.com/ppy/osu/issues/22220 + if (LoadedBeatmapSuccessfully) + spectatorClient?.EndPlaying(GameplayState); + + return exiting; + } + protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); From f7af5a8115d5566a623a9ba8d3b6a5679bc13d29 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 15 Jan 2023 22:35:44 +0900 Subject: [PATCH 1556/2991] Revert some formatting changes --- osu.Game/Screens/Select/SongSelect.cs | 54 +++++++++++++-------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index ef5827fad7..0e108d3db0 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -314,17 +314,16 @@ namespace osu.Game.Screens.Select /// Creates the buttons to be displayed in the footer. /// /// A set of and an optional which the button opens when pressed. - protected virtual IEnumerable<(FooterButton, OverlayContainer?)> CreateFooterButtons() => - new (FooterButton, OverlayContainer?)[] + protected virtual IEnumerable<(FooterButton, OverlayContainer?)> CreateFooterButtons() => new (FooterButton, OverlayContainer?)[] + { + (new FooterButtonMods { Current = Mods }, ModSelect), + (new FooterButtonRandom { - (new FooterButtonMods { Current = Mods }, ModSelect), - (new FooterButtonRandom - { - NextRandom = () => Carousel.SelectNextRandom(), - PreviousRandom = Carousel.SelectPreviousRandom - }, null), - (beatmapOptionsButton = new FooterButtonOptions(), BeatmapOptions) - }; + NextRandom = () => Carousel.SelectNextRandom(), + PreviousRandom = Carousel.SelectPreviousRandom + }, null), + (beatmapOptionsButton = new FooterButtonOptions(), BeatmapOptions) + }; protected virtual ModSelectOverlay CreateModSelectOverlay() => new SoloModSelectOverlay(); @@ -425,25 +424,26 @@ namespace osu.Game.Screens.Select Logger.Log($"Song select working beatmap updated to {beatmap}"); - if (Carousel.SelectBeatmap(beatmap.BeatmapInfo, false)) return; - - // A selection may not have been possible with filters applied. - - // There was possibly a ruleset mismatch. This is a case we can help things along by updating the game-wide ruleset to match. - if (!beatmap.BeatmapInfo.Ruleset.Equals(decoupledRuleset.Value)) + if (!Carousel.SelectBeatmap(beatmap.BeatmapInfo, false)) { - Ruleset.Value = beatmap.BeatmapInfo.Ruleset; - transferRulesetValue(); + // A selection may not have been possible with filters applied. + + // There was possibly a ruleset mismatch. This is a case we can help things along by updating the game-wide ruleset to match. + if (!beatmap.BeatmapInfo.Ruleset.Equals(decoupledRuleset.Value)) + { + Ruleset.Value = beatmap.BeatmapInfo.Ruleset; + transferRulesetValue(); + } + + // Even if a ruleset mismatch was not the cause (ie. a text filter is applied), + // we still want to temporarily show the new beatmap, bypassing filters. + // This will be undone the next time the user changes the filter. + var criteria = FilterControl.CreateCriteria(); + criteria.SelectedBeatmapSet = beatmap.BeatmapInfo.BeatmapSet; + Carousel.Filter(criteria); + + Carousel.SelectBeatmap(beatmap.BeatmapInfo); } - - // Even if a ruleset mismatch was not the cause (ie. a text filter is applied), - // we still want to temporarily show the new beatmap, bypassing filters. - // This will be undone the next time the user changes the filter. - var criteria = FilterControl.CreateCriteria(); - criteria.SelectedBeatmapSet = beatmap.BeatmapInfo.BeatmapSet; - Carousel.Filter(criteria); - - Carousel.SelectBeatmap(beatmap.BeatmapInfo); } // We need to keep track of the last selected beatmap ignoring debounce to play the correct selection sounds. From 4cf4a6685802831dee21b6d0cc0047c453ec608b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 15 Jan 2023 22:43:30 +0900 Subject: [PATCH 1557/2991] Make `MusicController` a required dependency of `SongSelect` --- osu.Game/Screens/Select/SongSelect.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 0e108d3db0..d7c1dbf543 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -34,6 +34,7 @@ using osu.Framework.Input.Bindings; using osu.Game.Collections; using osu.Game.Graphics.UserInterface; using System.Diagnostics; +using osu.Framework.Extensions.ObjectExtensions; using osu.Game.Screens.Play; using osu.Game.Skinning; @@ -118,7 +119,7 @@ namespace osu.Game.Screens.Select private IDisposable? modSelectOverlayRegistration; [Resolved] - private MusicController? music { get; set; } + private MusicController music { get; set; } = null!; [Resolved] internal IOverlayManager? OverlayManager { get; private set; } @@ -616,7 +617,6 @@ namespace osu.Game.Screens.Select { // restart playback on returning to song select, regardless. // not sure this should be a permanent thing (we may want to leave a user pause paused even on returning) - Debug.Assert(music != null); music.ResetTrackAdjustments(); music.Play(requestedByUser: true); } @@ -692,7 +692,6 @@ namespace osu.Game.Screens.Select ensureTrackLooping(Beatmap.Value, TrackChangeDirection.None); - Debug.Assert(music != null); music.TrackChanged += ensureTrackLooping; } @@ -702,7 +701,6 @@ namespace osu.Game.Screens.Select if (!isHandlingLooping) return; - Debug.Assert(music != null); music.CurrentTrack.Looping = isHandlingLooping = false; music.TrackChanged -= ensureTrackLooping; @@ -728,7 +726,7 @@ namespace osu.Game.Screens.Select decoupledRuleset.UnbindAll(); - if (music != null) + if (music.IsNotNull()) music.TrackChanged -= ensureTrackLooping; modSelectOverlayRegistration?.Dispose(); @@ -774,7 +772,6 @@ namespace osu.Game.Screens.Select if (!ControlGlobalMusic) return; - Debug.Assert(music != null); ITrack track = music.CurrentTrack; bool isNewTrack = !lastTrack.TryGetTarget(out var last) || last != track; From d664a66a375cb649c04783c1d2936bffb521f33f Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 23:11:59 +0900 Subject: [PATCH 1558/2991] Remove redundant `canBeNull: true` --- .../Edit/Blueprints/Components/EditablePath.cs | 2 +- .../Edit/Blueprints/Components/SelectionEditablePath.cs | 2 +- .../Edit/Blueprints/JuiceStreamSelectionBlueprint.cs | 2 +- osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs index c2a426de66..74d6565600 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components private readonly List previousVertexStates = new List(); - [Resolved(CanBeNull = true)] + [Resolved] private IBeatSnapProvider? beatSnapProvider { get; set; } protected EditablePath(Func positionToTime) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs index 95b17a197f..c7a26ca15a 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components // To handle when the editor is scrolled while dragging. private Vector2 dragStartPosition; - [Resolved(CanBeNull = true)] + [Resolved] private IEditorChangeHandler? changeHandler { get; set; } public SelectionEditablePath(Func positionToTime) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs index 1be5148d76..49d778ad08 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs @@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints private Vector2 rightMouseDownPosition; - [Resolved(CanBeNull = true)] + [Resolved] private EditorBeatmap? editorBeatmap { get; set; } public JuiceStreamSelectionBlueprint(JuiceStream hitObject) diff --git a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs index ffdc5299d0..dbbe905879 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.UI { } - [Resolved(canBeNull: true)] + [Resolved] private Player? player { get; set; } protected override void LoadComplete() From 1f8b7b8f034bbcc0bfe1284d1b973135cd1d3e79 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 23:21:38 +0900 Subject: [PATCH 1559/2991] Remove #nullable disable from CaughtObject --- osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs index 436edf6367..0c26c52171 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -19,7 +17,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables [Cached(typeof(IHasCatchObjectState))] public abstract partial class CaughtObject : SkinnableDrawable, IHasCatchObjectState { - public PalpableCatchHitObject HitObject { get; private set; } + public PalpableCatchHitObject HitObject { get; private set; } = null!; public Bindable AccentColour { get; } = new Bindable(); public Bindable HyperDash { get; } = new Bindable(); public Bindable IndexInBeatmap { get; } = new Bindable(); From 9a29c9ae26a94f35d1a3cc4aff6678ab388847e7 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 15 Jan 2023 15:32:53 +0100 Subject: [PATCH 1560/2991] remove hacky method to check if carousel is null --- osu.Game/Screens/Select/SongSelect.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index d7c1dbf543..d4d75d0ad6 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -128,7 +128,7 @@ namespace osu.Game.Screens.Select private void load(AudioManager audio, OsuColour colours, ManageCollectionsDialog? manageCollectionsDialog, DifficultyRecommender? recommender) { // initial value transfer is required for FilterControl (it uses our re-cached bindables in its async load for the initial filter). - transferRulesetValue(false); + transferRulesetValue(); LoadComponentAsync(Carousel = new BeatmapCarousel { @@ -852,7 +852,7 @@ namespace osu.Game.Screens.Select /// Will immediately run filter operations if required. /// /// Whether a transfer occurred. - private bool transferRulesetValue(bool carouselLoaded = true) + private bool transferRulesetValue() { if (decoupledRuleset.Value?.Equals(Ruleset.Value) == true) return false; @@ -860,8 +860,8 @@ namespace osu.Game.Screens.Select Logger.Log($"decoupled ruleset transferred (\"{decoupledRuleset.Value}\" -> \"{Ruleset.Value}\")"); rulesetNoDebounce = decoupledRuleset.Value = Ruleset.Value; - // We don't want to declare the carousel as nullable, so this check allows us to avoid running the carousel flush during the loading process - if (!carouselLoaded) return true; + // We want to check for null since this method gets called before the loading of the carousel. + if (Carousel.IsNull()) return true; // if we have a pending filter operation, we want to run it now. // it could change selection (ie. if the ruleset has been changed). From 00acea59fca4254630d4a21555be1ab8ffc9fccb Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 19:37:40 +0300 Subject: [PATCH 1561/2991] Move some strings to common --- osu.Game/Localisation/CommonStrings.cs | 50 ++++++++++++++++++++++++++ osu.Game/Localisation/EditorStrings.cs | 50 -------------------------- osu.Game/Screens/Edit/Editor.cs | 25 +++++++------ 3 files changed, 62 insertions(+), 63 deletions(-) diff --git a/osu.Game/Localisation/CommonStrings.cs b/osu.Game/Localisation/CommonStrings.cs index 385ebd0593..10178915a2 100644 --- a/osu.Game/Localisation/CommonStrings.cs +++ b/osu.Game/Localisation/CommonStrings.cs @@ -104,6 +104,56 @@ namespace osu.Game.Localisation /// public static LocalisableString Description => new TranslatableString(getKey(@"description"), @"Description"); + /// + /// "File" + /// + public static LocalisableString MenuBarFile => new TranslatableString(getKey(@"menu_bar_file"), @"File"); + + /// + /// "Edit" + /// + public static LocalisableString MenuBarEdit => new TranslatableString(getKey(@"menu_bar_edit"), @"Edit"); + + /// + /// "View" + /// + public static LocalisableString MenuBarView => new TranslatableString(getKey(@"menu_bar_view"), @"View"); + + /// + /// "Undo" + /// + public static LocalisableString Undo => new TranslatableString(getKey(@"undo"), @"Undo"); + + /// + /// "Redo" + /// + public static LocalisableString Redo => new TranslatableString(getKey(@"redo"), @"Redo"); + + /// + /// "Cut" + /// + public static LocalisableString Cut => new TranslatableString(getKey(@"cut"), @"Cut"); + + /// + /// "Copy" + /// + public static LocalisableString Copy => new TranslatableString(getKey(@"copy"), @"Copy"); + + /// + /// "Paste" + /// + public static LocalisableString Paste => new TranslatableString(getKey(@"paste"), @"Paste"); + + /// + /// "Clone" + /// + public static LocalisableString Clone => new TranslatableString(getKey(@"clone"), @"Clone"); + + /// + /// "Exit" + /// + public static LocalisableString Exit => new TranslatableString(getKey(@"exit"), @"Exit"); + private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Localisation/EditorStrings.cs b/osu.Game/Localisation/EditorStrings.cs index 6b16e43bd3..96c08aa6f8 100644 --- a/osu.Game/Localisation/EditorStrings.cs +++ b/osu.Game/Localisation/EditorStrings.cs @@ -9,51 +9,6 @@ namespace osu.Game.Localisation { private const string prefix = @"osu.Game.Resources.Localisation.Editor"; - /// - /// "File" - /// - public static LocalisableString File => new TranslatableString(getKey(@"file"), @"File"); - - /// - /// "Edit" - /// - public static LocalisableString Edit => new TranslatableString(getKey(@"edit"), @"Edit"); - - /// - /// "Undo" - /// - public static LocalisableString Undo => new TranslatableString(getKey(@"undo"), @"Undo"); - - /// - /// "Redo" - /// - public static LocalisableString Redo => new TranslatableString(getKey(@"redo"), @"Redo"); - - /// - /// "Cut" - /// - public static LocalisableString Cut => new TranslatableString(getKey(@"cut"), @"Cut"); - - /// - /// "Copy" - /// - public static LocalisableString Copy => new TranslatableString(getKey(@"copy"), @"Copy"); - - /// - /// "Paste" - /// - public static LocalisableString Paste => new TranslatableString(getKey(@"paste"), @"Paste"); - - /// - /// "Clone" - /// - public static LocalisableString Clone => new TranslatableString(getKey(@"clone"), @"Clone"); - - /// - /// "View" - /// - public static LocalisableString View => new TranslatableString(getKey(@"view"), @"View"); - /// /// "Waveform opacity" /// @@ -94,11 +49,6 @@ namespace osu.Game.Localisation /// public static LocalisableString DeleteDifficulty => new TranslatableString(getKey(@"delete_difficulty"), @"Delete difficulty"); - /// - /// "Exit" - /// - public static LocalisableString Exit => new TranslatableString(getKey(@"exit"), @"Exit"); - /// /// "setup" /// diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 29be1a3881..74ea933255 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -51,7 +51,7 @@ using osu.Game.Screens.Edit.Verify; using osu.Game.Screens.Play; using osu.Game.Users; using osuTK.Input; -using CommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings; +using WebCommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings; namespace osu.Game.Screens.Edit { @@ -294,24 +294,24 @@ namespace osu.Game.Screens.Edit RelativeSizeAxes = Axes.Both, Items = new[] { - new MenuItem(EditorStrings.File) + new MenuItem(CommonStrings.MenuBarFile) { Items = createFileMenuItems() }, - new MenuItem(EditorStrings.Edit) + new MenuItem(CommonStrings.MenuBarEdit) { Items = new[] { - undoMenuItem = new EditorMenuItem(EditorStrings.Undo, MenuItemType.Standard, Undo), - redoMenuItem = new EditorMenuItem(EditorStrings.Redo, MenuItemType.Standard, Redo), + undoMenuItem = new EditorMenuItem(CommonStrings.Undo, MenuItemType.Standard, Undo), + redoMenuItem = new EditorMenuItem(CommonStrings.Redo, MenuItemType.Standard, Redo), new EditorMenuItemSpacer(), - cutMenuItem = new EditorMenuItem(EditorStrings.Cut, MenuItemType.Standard, Cut), - copyMenuItem = new EditorMenuItem(EditorStrings.Copy, MenuItemType.Standard, Copy), - pasteMenuItem = new EditorMenuItem(EditorStrings.Paste, MenuItemType.Standard, Paste), - cloneMenuItem = new EditorMenuItem(EditorStrings.Clone, MenuItemType.Standard, Clone), + cutMenuItem = new EditorMenuItem(CommonStrings.Cut, MenuItemType.Standard, Cut), + copyMenuItem = new EditorMenuItem(CommonStrings.Copy, MenuItemType.Standard, Copy), + pasteMenuItem = new EditorMenuItem(CommonStrings.Paste, MenuItemType.Standard, Paste), + cloneMenuItem = new EditorMenuItem(CommonStrings.Clone, MenuItemType.Standard, Clone), } }, - new MenuItem(EditorStrings.View) + new MenuItem(CommonStrings.MenuBarView) { Items = new MenuItem[] { @@ -344,7 +344,6 @@ namespace osu.Game.Screens.Edit bottomBar = new BottomBar(), } }); - changeHandler?.CanUndo.BindValueChanged(v => undoMenuItem.Action.Disabled = !v.NewValue, true); changeHandler?.CanRedo.BindValueChanged(v => redoMenuItem.Action.Disabled = !v.NewValue, true); @@ -952,7 +951,7 @@ namespace osu.Game.Screens.Edit private List createFileMenuItems() => new List { - new EditorMenuItem(CommonStrings.ButtonsSave, MenuItemType.Standard, () => Save()), + new EditorMenuItem(WebCommonStrings.ButtonsSave, MenuItemType.Standard, () => Save()), new EditorMenuItem(EditorStrings.ExportPackage, MenuItemType.Standard, exportBeatmap) { Action = { Disabled = !RuntimeInfo.IsDesktop } }, new EditorMenuItemSpacer(), createDifficultyCreationMenu(), @@ -960,7 +959,7 @@ namespace osu.Game.Screens.Edit new EditorMenuItemSpacer(), new EditorMenuItem(EditorStrings.DeleteDifficulty, MenuItemType.Standard, deleteDifficulty) { Action = { Disabled = Beatmap.Value.BeatmapSetInfo.Beatmaps.Count < 2 } }, new EditorMenuItemSpacer(), - new EditorMenuItem(EditorStrings.Exit, MenuItemType.Standard, this.Exit) + new EditorMenuItem(CommonStrings.Exit, MenuItemType.Standard, this.Exit) }; private void exportBeatmap() From 9ce7c51b149401e3988eafbbe8461de7a86f1993 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 23:29:58 +0300 Subject: [PATCH 1562/2991] Localise osu! settings --- .../UI/OsuSettingsSubsection.cs | 11 +++++----- .../Localisation/RulesetSettingsStrings.cs | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs index f711a0fc31..64c4e7eef6 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs @@ -1,11 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; +using osu.Game.Localisation; using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Rulesets.UI; @@ -30,23 +29,23 @@ namespace osu.Game.Rulesets.Osu.UI { new SettingsCheckbox { - LabelText = "Snaking in sliders", + LabelText = RulesetSettingsStrings.SnakingInSliders, Current = config.GetBindable(OsuRulesetSetting.SnakingInSliders) }, new SettingsCheckbox { ClassicDefault = false, - LabelText = "Snaking out sliders", + LabelText = RulesetSettingsStrings.SnakingOutSliders, Current = config.GetBindable(OsuRulesetSetting.SnakingOutSliders) }, new SettingsCheckbox { - LabelText = "Cursor trail", + LabelText = RulesetSettingsStrings.CursorTrail, Current = config.GetBindable(OsuRulesetSetting.ShowCursorTrail) }, new SettingsEnumDropdown { - LabelText = "Playfield border style", + LabelText = RulesetSettingsStrings.PlayfieldBorderStyle, Current = config.GetBindable(OsuRulesetSetting.PlayfieldBorderStyle), }, }; diff --git a/osu.Game/Localisation/RulesetSettingsStrings.cs b/osu.Game/Localisation/RulesetSettingsStrings.cs index bc4be56c80..dd2b7b0040 100644 --- a/osu.Game/Localisation/RulesetSettingsStrings.cs +++ b/osu.Game/Localisation/RulesetSettingsStrings.cs @@ -14,6 +14,26 @@ namespace osu.Game.Localisation /// public static LocalisableString Rulesets => new TranslatableString(getKey(@"rulesets"), @"Rulesets"); + /// + /// "Snaking in sliders" + /// + public static LocalisableString SnakingInSliders => new TranslatableString(getKey(@"snaking_in_sliders"), @"Snaking in sliders"); + + /// + /// "Snaking out sliders" + /// + public static LocalisableString SnakingOutSliders => new TranslatableString(getKey(@"snaking_out_sliders"), @"Snaking out sliders"); + + /// + /// "Cursor trail" + /// + public static LocalisableString CursorTrail => new TranslatableString(getKey(@"cursor_trail"), @"Cursor trail"); + + /// + /// "Playfield border style" + /// + public static LocalisableString PlayfieldBorderStyle => new TranslatableString(getKey(@"playfield_border_style"), @"Playfield border style"); + /// /// "None" /// From 6f84641596871a0f64c2a82e702c21f2e32aef8e Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 23:30:11 +0300 Subject: [PATCH 1563/2991] Localise osu!mania settings --- .../ManiaSettingsSubsection.cs | 9 +++--- .../UI/ManiaScrollingDirection.cs | 7 +++-- .../Localisation/RulesetSettingsStrings.cs | 30 +++++++++++++++++++ 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs b/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs index 9ed555da51..f5a5771386 100644 --- a/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs +++ b/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Mania.Configuration; using osu.Game.Rulesets.Mania.UI; @@ -30,18 +31,18 @@ namespace osu.Game.Rulesets.Mania { new SettingsEnumDropdown { - LabelText = "Scrolling direction", + LabelText = RulesetSettingsStrings.ScrollingDirection, Current = config.GetBindable(ManiaRulesetSetting.ScrollDirection) }, new SettingsSlider { - LabelText = "Scroll speed", + LabelText = RulesetSettingsStrings.ScrollSpeed, Current = config.GetBindable(ManiaRulesetSetting.ScrollTime), KeyboardStep = 5 }, new SettingsCheckbox { - LabelText = "Timing-based note colouring", + LabelText = RulesetSettingsStrings.TimingBasedColouring, Current = config.GetBindable(ManiaRulesetSetting.TimingBasedNoteColouring), } }; @@ -49,7 +50,7 @@ namespace osu.Game.Rulesets.Mania private partial class ManiaScrollSlider : OsuSliderBar { - public override LocalisableString TooltipText => $"{Current.Value}ms (speed {(int)Math.Round(DrawableManiaRuleset.MAX_TIME_RANGE / Current.Value)})"; + public override LocalisableString TooltipText => RulesetSettingsStrings.ScrollSpeedTooltip(Current.Value, (int)Math.Round(DrawableManiaRuleset.MAX_TIME_RANGE / Current.Value)); } } } diff --git a/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs b/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs index 44fe4b1b30..d36e6057bb 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs @@ -1,15 +1,18 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - +using osu.Framework.Localisation; +using osu.Game.Localisation; using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Mania.UI { public enum ManiaScrollingDirection { + [LocalisableDescription(typeof(RulesetSettingsStrings), nameof(RulesetSettingsStrings.Up))] Up = ScrollingDirection.Up, + + [LocalisableDescription(typeof(RulesetSettingsStrings), nameof(RulesetSettingsStrings.Down))] Down = ScrollingDirection.Down } } diff --git a/osu.Game/Localisation/RulesetSettingsStrings.cs b/osu.Game/Localisation/RulesetSettingsStrings.cs index dd2b7b0040..0374f81cee 100644 --- a/osu.Game/Localisation/RulesetSettingsStrings.cs +++ b/osu.Game/Localisation/RulesetSettingsStrings.cs @@ -49,6 +49,36 @@ namespace osu.Game.Localisation /// public static LocalisableString BorderFull => new TranslatableString(getKey(@"full_borders"), @"Full"); + /// + /// "Scrolling direction" + /// + public static LocalisableString ScrollingDirection => new TranslatableString(getKey(@"scrolling_direction"), @"Scrolling direction"); + + /// + /// "Up" + /// + public static LocalisableString Up => new TranslatableString(getKey(@"scrolling_up"), @"Up"); + + /// + /// "Down" + /// + public static LocalisableString Down => new TranslatableString(getKey(@"scrolling_down"), @"Down"); + + /// + /// "Scroll speed" + /// + public static LocalisableString ScrollSpeed => new TranslatableString(getKey(@"scroll_speed"), @"Scroll speed"); + + /// + /// "Timing-based note colouring" + /// + public static LocalisableString TimingBasedColouring => new TranslatableString(getKey(@"Timing_based_colouring"), @"Timing-based note colouring"); + + /// + /// "{0}ms (speed {1})" + /// + public static LocalisableString ScrollSpeedTooltip(double arg0, int arg1) => new TranslatableString(getKey(@"ruleset"), @"{0}ms (speed {1})", arg0, arg1); + private static string getKey(string key) => $@"{prefix}:{key}"; } } From 85c1932851bf71202805c9cbcfe133d32ee3088b Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 15 Jan 2023 12:46:41 -0800 Subject: [PATCH 1564/2991] Mark `Converts` as nullable --- osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs | 2 +- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index d39ed1e1ed..d98715a42d 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -126,7 +126,7 @@ namespace osu.Game.Online.API.Requests.Responses public APIBeatmap[] Beatmaps { get; set; } = Array.Empty(); [JsonProperty(@"converts")] - public APIBeatmap[] Converts { get; set; } = Array.Empty(); + public APIBeatmap[]? Converts { get; set; } private BeatmapMetadata metadata => new BeatmapMetadata { diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 51b6b14579..0ee7dfc9bd 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -168,7 +168,7 @@ namespace osu.Game.Overlays.BeatmapSet if (BeatmapSet != null) { - Difficulties.ChildrenEnumerable = BeatmapSet.Beatmaps.Concat(BeatmapSet.Converts) + Difficulties.ChildrenEnumerable = BeatmapSet.Beatmaps.Concat(BeatmapSet.Converts ?? Array.Empty()) .Where(b => b.Ruleset.MatchesOnlineID(ruleset.Value)) .OrderBy(b => !b.Convert) .ThenBy(b => b.StarRating) From b733f46c6fed49d930da4e0cf20d5949c5914ddd Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 15 Jan 2023 14:15:36 -0800 Subject: [PATCH 1565/2991] Apply NRT to `BeatmapPicker` --- .../TestSceneStartupBeatmapDisplay.cs | 4 +--- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 22 +++++++++---------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneStartupBeatmapDisplay.cs b/osu.Game.Tests/Visual/Navigation/TestSceneStartupBeatmapDisplay.cs index 0c165bc40e..25cef8440a 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneStartupBeatmapDisplay.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneStartupBeatmapDisplay.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using NUnit.Framework; using osu.Framework.Graphics.Containers; @@ -50,7 +48,7 @@ namespace osu.Game.Tests.Visual.Navigation public void TestBeatmapLink() { AddUntilStep("Beatmap overlay displayed", () => Game.ChildrenOfType().FirstOrDefault()?.State.Value == Visibility.Visible); - AddUntilStep("Beatmap overlay showing content", () => Game.ChildrenOfType().FirstOrDefault()?.Beatmap.Value.OnlineID == requested_beatmap_id); + AddUntilStep("Beatmap overlay showing content", () => Game.ChildrenOfType().FirstOrDefault()?.Beatmap.Value?.OnlineID == requested_beatmap_id); } } } diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 0ee7dfc9bd..76fc1bbf53 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using osu.Framework; @@ -38,10 +36,10 @@ namespace osu.Game.Overlays.BeatmapSet public readonly DifficultiesContainer Difficulties; - public readonly Bindable Beatmap = new Bindable(); - private APIBeatmapSet beatmapSet; + public readonly Bindable Beatmap = new Bindable(); + private APIBeatmapSet? beatmapSet; - public APIBeatmapSet BeatmapSet + public APIBeatmapSet? BeatmapSet { get => beatmapSet; set @@ -142,7 +140,7 @@ namespace osu.Game.Overlays.BeatmapSet } [Resolved] - private IBindable ruleset { get; set; } + private IBindable ruleset { get; set; } = null!; [BackgroundDependencyLoader] private void load(OsuColour colours) @@ -200,9 +198,9 @@ namespace osu.Game.Overlays.BeatmapSet updateDifficultyButtons(); } - private void showBeatmap(IBeatmapInfo beatmapInfo) + private void showBeatmap(IBeatmapInfo? beatmapInfo) { - version.Text = beatmapInfo?.DifficultyName; + version.Text = beatmapInfo?.DifficultyName ?? string.Empty; } private void updateDifficultyButtons() @@ -212,7 +210,7 @@ namespace osu.Game.Overlays.BeatmapSet public partial class DifficultiesContainer : FillFlowContainer { - public Action OnLostHover; + public Action? OnLostHover; protected override void OnHoverLost(HoverLostEvent e) { @@ -233,9 +231,9 @@ namespace osu.Game.Overlays.BeatmapSet public readonly APIBeatmap Beatmap; - public Action OnHovered; - public Action OnClicked; - public event Action StateChanged; + public Action? OnHovered; + public Action? OnClicked; + public event Action? StateChanged; private DifficultySelectorState state; From ae49e724e43ebe449f1229c1efbed7157d00ba23 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 15 Jan 2023 14:17:46 -0800 Subject: [PATCH 1566/2991] Move converted beatmap icons logic locally --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 4 ---- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 41db2399ac..1665ec52fa 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -13,7 +13,6 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Graphics.Containers; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets; using osuTK; using osuTK.Graphics; @@ -117,9 +116,6 @@ namespace osu.Game.Beatmaps.Drawables private Drawable getRulesetIcon() { - if ((beatmap as APIBeatmap)?.Convert == true) - return rulesets.GetRuleset(0)!.CreateInstance().CreateIcon(); - int? onlineID = ruleset.OnlineID; if (onlineID >= 0 && rulesets.GetRuleset(onlineID.Value)?.CreateInstance() is Ruleset rulesetInstance) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 76fc1bbf53..585e0dd1a2 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -170,7 +170,7 @@ namespace osu.Game.Overlays.BeatmapSet .Where(b => b.Ruleset.MatchesOnlineID(ruleset.Value)) .OrderBy(b => !b.Convert) .ThenBy(b => b.StarRating) - .Select(b => new DifficultySelectorButton(b) + .Select(b => new DifficultySelectorButton(b, b.Convert ? new RulesetInfo { OnlineID = 0 } : null) { State = DifficultySelectorState.NotSelected, OnHovered = beatmap => @@ -254,7 +254,7 @@ namespace osu.Game.Overlays.BeatmapSet } } - public DifficultySelectorButton(APIBeatmap beatmapInfo) + public DifficultySelectorButton(APIBeatmap beatmapInfo, IRulesetInfo? ruleset) { Beatmap = beatmapInfo; Size = new Vector2(size); @@ -273,7 +273,7 @@ namespace osu.Game.Overlays.BeatmapSet Alpha = 0.5f } }, - icon = new DifficultyIcon(beatmapInfo) + icon = new DifficultyIcon(beatmapInfo, ruleset) { ShowTooltip = false, Current = { Value = new StarDifficulty(beatmapInfo.StarRating, 0) }, From 87ee9ab813e023d0d51bea755ba3f5db16356353 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 12 Oct 2022 19:04:45 +0200 Subject: [PATCH 1567/2991] Added custom menu items in DrawableCarouselBeatmap --- .../Carousel/DrawableCarouselBeatmap.cs | 19 ++++++++----------- osu.Game/Screens/Select/PlaySongSelect.cs | 12 ++++++++++++ osu.Game/Screens/Select/SongSelect.cs | 3 +++ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index 4e10961e55..4c8f986563 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -49,8 +49,9 @@ namespace osu.Game.Screens.Select.Carousel private Sprite background; - private Action startRequested; - private Action editRequested; + private MenuItem[] customMenuItems; + + private Action selectRequested; private Action hideRequested; private Triangles triangles; @@ -86,9 +87,8 @@ namespace osu.Game.Screens.Select.Carousel if (songSelect != null) { - startRequested = b => songSelect.FinaliseSelection(b); - if (songSelect.AllowEditing) - editRequested = songSelect.Edit; + customMenuItems = songSelect.CustomMenuItems.Select(f => f.Invoke(beatmapInfo)).ToArray(); + selectRequested = b => songSelect.FinaliseSelection(b); } if (manager != null) @@ -195,7 +195,7 @@ namespace osu.Game.Screens.Select.Carousel protected override bool OnClick(ClickEvent e) { if (Item.State.Value == CarouselItemState.Selected) - startRequested?.Invoke(beatmapInfo); + selectRequested?.Invoke(beatmapInfo); return base.OnClick(e); } @@ -229,11 +229,8 @@ namespace osu.Game.Screens.Select.Carousel { List items = new List(); - if (startRequested != null) - items.Add(new OsuMenuItem("Play", MenuItemType.Highlighted, () => startRequested(beatmapInfo))); - - if (editRequested != null) - items.Add(new OsuMenuItem(CommonStrings.ButtonsEdit, MenuItemType.Standard, () => editRequested(beatmapInfo))); + if (customMenuItems != null) + items.AddRange(customMenuItems); if (beatmapInfo.OnlineID > 0 && beatmapOverlay != null) items.Add(new OsuMenuItem("Details...", MenuItemType.Standard, () => beatmapOverlay.FetchAndShowBeatmap(beatmapInfo.OnlineID))); diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index f73cfe8d55..15356baf44 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -1,15 +1,20 @@ // 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 osu.Framework.Allocation; using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Framework.Screens; +using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; +using osu.Game.Resources.Localisation.Web; using osu.Game.Rulesets.Mods; using osu.Game.Scoring; using osu.Game.Screens.Play; @@ -29,6 +34,13 @@ namespace osu.Game.Screens.Select public override bool AllowExternalScreenChange => true; + public override Func[] CustomMenuItems => + new Func[] + { + b => new OsuMenuItem("Play", MenuItemType.Highlighted, () => FinaliseSelection(b)), + b => new OsuMenuItem(CommonStrings.ButtonsEdit, MenuItemType.Standard, () => Edit(b)) + }; + protected override UserActivity InitialActivity => new UserActivity.ChoosingBeatmap(); private PlayBeatmapDetailArea playBeatmapDetailArea = null!; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index f4804c6a6c..38f4b8ef40 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -37,6 +37,7 @@ using osu.Game.Collections; using osu.Game.Graphics.UserInterface; using System.Diagnostics; using JetBrains.Annotations; +using osu.Framework.Graphics.UserInterface; using osu.Game.Screens.Play; using osu.Game.Skinning; @@ -84,6 +85,8 @@ namespace osu.Game.Screens.Select public bool BeatmapSetsLoaded => IsLoaded && Carousel?.BeatmapSetsLoaded == true; + public virtual Func[] CustomMenuItems => new Func[] { b => new OsuMenuItem(@"Select", MenuItemType.Highlighted, () => FinaliseSelection(b)) }; + [Resolved] private Bindable> selectedMods { get; set; } From 1c0a6505756ef2ace70ae5d24dbddca14ef961e1 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Mon, 16 Jan 2023 00:17:26 +0100 Subject: [PATCH 1568/2991] Fix typo --- osu.Game/Screens/Select/PlaySongSelect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 15356baf44..92a23048c7 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -101,7 +101,7 @@ namespace osu.Game.Screens.Select { notifications?.Post(new SimpleNotification { - Text = "The current ruleset doesn't have an autoplay mod avalaible!" + Text = "The current ruleset doesn't have an autoplay mod available!" }); return false; } From 0ff143d4c86d7e6ae19f703201046cab5592c01a Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 15 Jan 2023 15:19:06 -0800 Subject: [PATCH 1569/2991] Add argument for play some ruleset string --- osu.Game/Localisation/ToolbarStrings.cs | 5 ++--- osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Localisation/ToolbarStrings.cs b/osu.Game/Localisation/ToolbarStrings.cs index b76c643332..02a68a6bdc 100644 --- a/osu.Game/Localisation/ToolbarStrings.cs +++ b/osu.Game/Localisation/ToolbarStrings.cs @@ -30,10 +30,9 @@ namespace osu.Game.Localisation public static LocalisableString HomeHeaderDescription => new TranslatableString(getKey(@"header_description"), @"return to the main menu"); /// - /// "play some" + /// "play some {0}" /// - - public static LocalisableString RulesetHeaderDescription => new TranslatableString(getKey(@"header_description"), @"play some"); + public static LocalisableString PlaySomeRuleset(string arg0) => new TranslatableString(getKey(@"play_some_ruleset"), @"play some {0}", arg0); private static string getKey(string key) => $@"{prefix}:{key}"; } diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs index d603863888..07f7d52545 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; -using osu.Framework.Localisation; using osu.Game.Localisation; using osu.Game.Rulesets; using osuTK.Graphics; @@ -31,7 +30,7 @@ namespace osu.Game.Overlays.Toolbar var rInstance = value.CreateInstance(); ruleset.TooltipMain = rInstance.Description; - ruleset.TooltipSub = LocalisableString.Format("{0} {1}", ToolbarStrings.RulesetHeaderDescription, ($"{rInstance.Description}")); + ruleset.TooltipSub = ToolbarStrings.PlaySomeRuleset(rInstance.Description); ruleset.SetIcon(rInstance.CreateIcon()); } From 6a847faea9ad82990e7aa2ab94eb10eb2767112b Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 15 Jan 2023 15:19:47 -0800 Subject: [PATCH 1570/2991] Make home string keys more specific --- osu.Game/Localisation/ToolbarStrings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Localisation/ToolbarStrings.cs b/osu.Game/Localisation/ToolbarStrings.cs index 02a68a6bdc..e71a3fff9b 100644 --- a/osu.Game/Localisation/ToolbarStrings.cs +++ b/osu.Game/Localisation/ToolbarStrings.cs @@ -22,12 +22,12 @@ namespace osu.Game.Localisation /// /// "home" /// - public static LocalisableString HomeHeaderTitle => new TranslatableString(getKey(@"header_title"), @"home"); + public static LocalisableString HomeHeaderTitle => new TranslatableString(getKey(@"home_header_title"), @"home"); /// /// "return to the main menu" /// - public static LocalisableString HomeHeaderDescription => new TranslatableString(getKey(@"header_description"), @"return to the main menu"); + public static LocalisableString HomeHeaderDescription => new TranslatableString(getKey(@"home_header_description"), @"return to the main menu"); /// /// "play some {0}" From 832d033777eeeffff5e419343416a876d4deb43a Mon Sep 17 00:00:00 2001 From: OliBomby Date: Mon, 16 Jan 2023 01:09:04 +0100 Subject: [PATCH 1571/2991] Fix merge issues --- .../Screens/Select/Carousel/DrawableCarouselBeatmap.cs | 8 ++++---- osu.Game/Screens/Select/PlaySongSelect.cs | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index 75c367acba..a831271bb4 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -47,10 +47,10 @@ namespace osu.Game.Screens.Select.Carousel private Sprite background = null!; - private MenuItem[] customMenuItems; + private MenuItem[]? customMenuItems; - private Action selectRequested; - private Action hideRequested; + private Action? selectRequested; + private Action? hideRequested; private Triangles triangles = null!; @@ -192,7 +192,7 @@ namespace osu.Game.Screens.Select.Carousel protected override bool OnClick(ClickEvent e) { - if (Item.State.Value == CarouselItemState.Selected) + if (Item?.State.Value == CarouselItemState.Selected) selectRequested?.Invoke(beatmapInfo); return base.OnClick(e); diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index aebdfb8a04..c6c2b69fd8 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -15,7 +15,6 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Localisation; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; -using osu.Game.Resources.Localisation.Web; using osu.Game.Rulesets.Mods; using osu.Game.Scoring; using osu.Game.Screens.Play; @@ -39,7 +38,7 @@ namespace osu.Game.Screens.Select new Func[] { b => new OsuMenuItem("Play", MenuItemType.Highlighted, () => FinaliseSelection(b)), - b => new OsuMenuItem(CommonStrings.ButtonsEdit, MenuItemType.Standard, () => Edit(b)) + b => new OsuMenuItem(Resources.Localisation.Web.CommonStrings.ButtonsEdit, MenuItemType.Standard, () => Edit(b)) }; protected override UserActivity InitialActivity => new UserActivity.ChoosingBeatmap(); From d19b35bd5fc225434a7f7288392b2c409ec2db8c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Jan 2023 13:18:49 +0900 Subject: [PATCH 1572/2991] Rename ambiguous translation keys --- osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs | 4 ++-- osu.Game/Localisation/RulesetSettingsStrings.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs b/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs index d36e6057bb..4a8843c999 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs @@ -9,10 +9,10 @@ namespace osu.Game.Rulesets.Mania.UI { public enum ManiaScrollingDirection { - [LocalisableDescription(typeof(RulesetSettingsStrings), nameof(RulesetSettingsStrings.Up))] + [LocalisableDescription(typeof(RulesetSettingsStrings), nameof(RulesetSettingsStrings.ScrollingDirectionUp))] Up = ScrollingDirection.Up, - [LocalisableDescription(typeof(RulesetSettingsStrings), nameof(RulesetSettingsStrings.Down))] + [LocalisableDescription(typeof(RulesetSettingsStrings), nameof(RulesetSettingsStrings.ScrollingDirectionDown))] Down = ScrollingDirection.Down } } diff --git a/osu.Game/Localisation/RulesetSettingsStrings.cs b/osu.Game/Localisation/RulesetSettingsStrings.cs index 0374f81cee..1b0df6ecf6 100644 --- a/osu.Game/Localisation/RulesetSettingsStrings.cs +++ b/osu.Game/Localisation/RulesetSettingsStrings.cs @@ -57,12 +57,12 @@ namespace osu.Game.Localisation /// /// "Up" /// - public static LocalisableString Up => new TranslatableString(getKey(@"scrolling_up"), @"Up"); + public static LocalisableString ScrollingDirectionUp => new TranslatableString(getKey(@"scrolling_up"), @"Up"); /// /// "Down" /// - public static LocalisableString Down => new TranslatableString(getKey(@"scrolling_down"), @"Down"); + public static LocalisableString ScrollingDirectionDown => new TranslatableString(getKey(@"scrolling_down"), @"Down"); /// /// "Scroll speed" From eb0f30c6414b84f73b22d56aaae543546cd2e111 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Jan 2023 13:28:45 +0900 Subject: [PATCH 1573/2991] Use scroll speed localisation in one more usage --- .../Configuration/ManiaRulesetConfigManager.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs b/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs index d367c82ed8..99a80ef28d 100644 --- a/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs +++ b/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs @@ -4,6 +4,7 @@ using System; using osu.Framework.Configuration.Tracking; using osu.Game.Configuration; +using osu.Game.Localisation; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Mania.UI; @@ -30,8 +31,8 @@ namespace osu.Game.Rulesets.Mania.Configuration new TrackedSetting(ManiaRulesetSetting.ScrollTime, scrollTime => new SettingDescription( rawValue: scrollTime, - name: "Scroll Speed", - value: $"{scrollTime}ms (speed {(int)Math.Round(DrawableManiaRuleset.MAX_TIME_RANGE / scrollTime)})" + name: RulesetSettingsStrings.ScrollSpeed, + value: RulesetSettingsStrings.ScrollSpeedTooltip(scrollTime, (int)Math.Round(DrawableManiaRuleset.MAX_TIME_RANGE / scrollTime)) ) ) }; From 1552726150f2c6481f81a3d4b4f83022079aded2 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 16 Jan 2023 14:03:09 +0300 Subject: [PATCH 1574/2991] Fix intermittent failure in beatmap options state test --- osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index cfee02dfb8..a61171abad 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -1064,6 +1064,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("options enabled", () => songSelect.ChildrenOfType().Single().Enabled.Value); AddStep("delete all beatmaps", () => manager.Delete()); + AddWaitStep("wait for debounce", 1); AddAssert("options disabled", () => !songSelect.ChildrenOfType().Single().Enabled.Value); } From fd5fac507e2fd3c07ffd4285a56ab1d4498662c7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Jan 2023 19:34:59 +0900 Subject: [PATCH 1575/2991] Add test coverage of expected touch to action handling --- .../TestSceneTouchInput.cs | 217 ++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs new file mode 100644 index 0000000000..b1edafa4f8 --- /dev/null +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs @@ -0,0 +1,217 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Input; +using osu.Framework.Input.Bindings; +using osu.Framework.Input.Events; +using osu.Framework.Testing; +using osu.Game.Screens.Play; +using osu.Game.Tests.Visual; +using osuTK; + +namespace osu.Game.Rulesets.Osu.Tests +{ + [TestFixture] + public partial class TestSceneTouchInput : OsuManualInputManagerTestScene + { + private TestActionKeyCounter leftKeyCounter = null!; + + private TestActionKeyCounter rightKeyCounter = null!; + + private OsuInputManager osuInputManager = null!; + + [SetUpSteps] + public void SetUpSteps() + { + releaseAllTouches(); + + AddStep("Create tests", () => + { + Child = osuInputManager = new OsuInputManager(new OsuRuleset().RulesetInfo) + { + Child = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Children = new Drawable[] + { + leftKeyCounter = new TestActionKeyCounter(OsuAction.LeftButton), + rightKeyCounter = new TestActionKeyCounter(OsuAction.RightButton) { Margin = new MarginPadding { Left = 150 } } + }, + } + }; + }); + } + + [Test] + public void TestSimpleInput() + { + beginTouch(TouchSource.Touch1); + + assertKeyCounter(1, 0); + expectPressedCurrently(OsuAction.LeftButton); + + beginTouch(TouchSource.Touch2); + + assertKeyCounter(1, 1); + expectPressedCurrently(OsuAction.LeftButton); + expectPressedCurrently(OsuAction.RightButton); + + // Subsequent touches should be ignored. + beginTouch(TouchSource.Touch3); + beginTouch(TouchSource.Touch4); + + assertKeyCounter(1, 1); + + expectPressedCurrently(OsuAction.LeftButton); + expectPressedCurrently(OsuAction.RightButton); + + assertKeyCounter(1, 1); + } + + [Test] + public void TestAlternatingInput() + { + beginTouch(TouchSource.Touch1); + + assertKeyCounter(1, 0); + expectPressedCurrently(OsuAction.LeftButton); + + beginTouch(TouchSource.Touch2); + + assertKeyCounter(1, 1); + expectPressedCurrently(OsuAction.LeftButton); + expectPressedCurrently(OsuAction.RightButton); + + endTouch(TouchSource.Touch1); + + assertKeyCounter(1, 1); + expectPressedCurrently(OsuAction.RightButton); + + beginTouch(TouchSource.Touch1); + + assertKeyCounter(2, 1); + expectPressedCurrently(OsuAction.LeftButton); + expectPressedCurrently(OsuAction.RightButton); + + endTouch(TouchSource.Touch2); + + assertKeyCounter(2, 1); + expectPressedCurrently(OsuAction.LeftButton); + + beginTouch(TouchSource.Touch2); + + assertKeyCounter(2, 2); + expectPressedCurrently(OsuAction.LeftButton); + expectPressedCurrently(OsuAction.RightButton); + } + + [Test] + public void TestPressReleaseOrder() + { + beginTouch(TouchSource.Touch1); + beginTouch(TouchSource.Touch2); + beginTouch(TouchSource.Touch3); + + assertKeyCounter(1, 1); + expectPressedCurrently(OsuAction.LeftButton); + expectPressedCurrently(OsuAction.RightButton); + + // Touch 3 was ignored, but let's ensure that if 1 or 2 are released, 3 will be handled a second attempt. + endTouch(TouchSource.Touch1); + + assertKeyCounter(1, 1); + expectPressedCurrently(OsuAction.RightButton); + + endTouch(TouchSource.Touch3); + + assertKeyCounter(1, 1); + expectPressedCurrently(OsuAction.RightButton); + + beginTouch(TouchSource.Touch3); + + assertKeyCounter(2, 1); + expectPressedCurrently(OsuAction.LeftButton); + expectPressedCurrently(OsuAction.RightButton); + } + + [Test] + public void TestWithDisallowedUserCursor() + { + beginTouch(TouchSource.Touch1); + + assertKeyCounter(1, 0); + expectPressedCurrently(OsuAction.LeftButton); + + beginTouch(TouchSource.Touch2); + + assertKeyCounter(1, 1); + expectPressedCurrently(OsuAction.RightButton); + + // Subsequent touches should be ignored. + beginTouch(TouchSource.Touch3); + beginTouch(TouchSource.Touch4); + + assertKeyCounter(1, 1); + + expectPressedCurrently(OsuAction.LeftButton); + expectPressedCurrently(OsuAction.RightButton); + + assertKeyCounter(1, 1); + } + + private void beginTouch(TouchSource source, Vector2? screenSpacePosition = null) => + AddStep($"Begin touch for {source}", () => InputManager.BeginTouch(new Touch(source, screenSpacePosition ?? osuInputManager.ScreenSpaceDrawQuad.Centre))); + + private void endTouch(TouchSource source) => + AddStep($"Release touch for {source}", () => InputManager.EndTouch(new Touch(source, osuInputManager.ScreenSpaceDrawQuad.Centre))); + + private void assertKeyCounter(int left, int right) + { + AddAssert($"The left key was pressed {left} times", () => leftKeyCounter.CountPresses, () => Is.EqualTo(left)); + AddAssert($"The right key was pressed {right} times", () => rightKeyCounter.CountPresses, () => Is.EqualTo(right)); + } + + private void releaseAllTouches() + { + AddStep("Release all touches", () => + { + foreach (TouchSource source in InputManager.CurrentState.Touch.ActiveSources) + InputManager.EndTouch(new Touch(source, osuInputManager.ScreenSpaceDrawQuad.Centre)); + }); + } + + private void expectPressedCurrently(OsuAction action) => AddAssert($"Is pressing {action}", () => osuInputManager.PressedActions.Contains(action)); + + public partial class TestActionKeyCounter : KeyCounter, IKeyBindingHandler + { + public OsuAction Action { get; } + + public TestActionKeyCounter(OsuAction action) + : base(action.ToString()) + { + Action = action; + } + + public bool OnPressed(KeyBindingPressEvent e) + { + if (e.Action == Action) + { + IsLit = true; + Increment(); + } + + return false; + } + + public void OnReleased(KeyBindingReleaseEvent e) + { + if (e.Action == Action) IsLit = false; + } + } + } +} From b265888f182935035a372d5f6558f8895b90b2c5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Jan 2023 19:35:55 +0900 Subject: [PATCH 1576/2991] Add bare minimum touch support to osu! ruleset --- osu.Game.Rulesets.Osu/OsuInputManager.cs | 11 ++- .../UI/OsuTouchInputMapper.cs | 76 +++++++++++++++++++ 2 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index 7dede9e283..28b4f70c10 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -1,16 +1,17 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.ComponentModel; using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Input.StateChanges.Events; using osu.Game.Input.Bindings; +using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu @@ -45,6 +46,12 @@ namespace osu.Game.Rulesets.Osu { } + [BackgroundDependencyLoader] + private void load() + { + Add(new OsuTouchInputMapper(this) { RelativeSizeAxes = Axes.Both }); + } + protected override bool Handle(UIEvent e) { if ((e is MouseMoveEvent || e is TouchMoveEvent) && !AllowUserCursorMovement) return false; diff --git a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs new file mode 100644 index 0000000000..f4ed70f790 --- /dev/null +++ b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs @@ -0,0 +1,76 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Graphics; +using osu.Framework.Input; +using osu.Framework.Input.Events; + +namespace osu.Game.Rulesets.Osu.UI +{ + public partial class OsuTouchInputMapper : Drawable + { + /// + /// This is our parent . + /// + private readonly OsuInputManager osuInputManager; + + /// + /// All the active s and the that it triggered (if any). + /// Ordered from oldest to newest touch chronologically. + /// + private readonly List trackedTouches = new List(); + + public OsuTouchInputMapper(OsuInputManager inputManager) + { + osuInputManager = inputManager; + } + + private OsuAction? lastAction; + + protected override bool OnTouchDown(TouchDownEvent e) + { + OsuAction action = lastAction == OsuAction.LeftButton && trackedTouches.Count > 0 ? OsuAction.RightButton : OsuAction.LeftButton; + + if (trackedTouches.All(t => t.Action != action)) + { + trackedTouches.Add(new TrackedTouch(e.Touch, action)); + osuInputManager.KeyBindingContainer.TriggerPressed(action); + lastAction = action; + } + else + { + // Ignore any taps which trigger an action which is already handled. But track them for potential positional input in the future. + trackedTouches.Add(new TrackedTouch(e.Touch, null)); + } + + return true; + } + + protected override void OnTouchUp(TouchUpEvent e) + { + var tracked = trackedTouches.First(t => t.Touch.Source == e.Touch.Source); + + if (tracked.Action is OsuAction action) + osuInputManager.KeyBindingContainer.TriggerReleased(action); + + trackedTouches.Remove(tracked); + + base.OnTouchUp(e); + } + + private class TrackedTouch + { + public readonly Touch Touch; + + public readonly OsuAction? Action; + + public TrackedTouch(Touch touch, OsuAction? action) + { + Touch = touch; + Action = action; + } + } + } +} From 355bec2058217ae28cc683d2a1edd030dade305e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Jan 2023 20:11:59 +0900 Subject: [PATCH 1577/2991] Handle movement locally as we are blocking events from touch->mouse mapping --- .../UI/OsuTouchInputMapper.cs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs index f4ed70f790..a57953f8d3 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs @@ -6,6 +6,7 @@ using System.Linq; using osu.Framework.Graphics; using osu.Framework.Input; using osu.Framework.Input.Events; +using osu.Framework.Input.StateChanges; namespace osu.Game.Rulesets.Osu.UI { @@ -27,17 +28,24 @@ namespace osu.Game.Rulesets.Osu.UI osuInputManager = inputManager; } - private OsuAction? lastAction; + protected override void OnTouchMove(TouchMoveEvent e) + { + base.OnTouchMove(e); + handleTouchMovement(e); + } protected override bool OnTouchDown(TouchDownEvent e) { - OsuAction action = lastAction == OsuAction.LeftButton && trackedTouches.Count > 0 ? OsuAction.RightButton : OsuAction.LeftButton; + OsuAction action = trackedTouches.Any(t => t.Action == OsuAction.LeftButton) + ? OsuAction.RightButton + : OsuAction.LeftButton; + + handleTouchMovement(e); if (trackedTouches.All(t => t.Action != action)) { trackedTouches.Add(new TrackedTouch(e.Touch, action)); osuInputManager.KeyBindingContainer.TriggerPressed(action); - lastAction = action; } else { @@ -48,6 +56,11 @@ namespace osu.Game.Rulesets.Osu.UI return true; } + private void handleTouchMovement(TouchEvent touchEvent) + { + new MousePositionAbsoluteInput { Position = touchEvent.ScreenSpaceTouch.Position }.Apply(osuInputManager.CurrentState, osuInputManager); + } + protected override void OnTouchUp(TouchUpEvent e) { var tracked = trackedTouches.First(t => t.Touch.Source == e.Touch.Source); From 606e374d94782738f3d6946da59692796aeb36f3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Jan 2023 20:13:31 +0900 Subject: [PATCH 1578/2991] Don't handle touch down events if "mouse" buttons are disabled Maintains compatibility with existing logic. --- osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs index a57953f8d3..16283d3baa 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs @@ -3,10 +3,13 @@ using System.Collections.Generic; using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Input; using osu.Framework.Input.Events; using osu.Framework.Input.StateChanges; +using osu.Game.Configuration; namespace osu.Game.Rulesets.Osu.UI { @@ -23,11 +26,19 @@ namespace osu.Game.Rulesets.Osu.UI /// private readonly List trackedTouches = new List(); + private Bindable mouseDisabled = null!; + public OsuTouchInputMapper(OsuInputManager inputManager) { osuInputManager = inputManager; } + [BackgroundDependencyLoader(true)] + private void load(OsuConfigManager config) + { + mouseDisabled = config.GetBindable(OsuSetting.MouseDisableButtons); + } + protected override void OnTouchMove(TouchMoveEvent e) { base.OnTouchMove(e); @@ -42,7 +53,7 @@ namespace osu.Game.Rulesets.Osu.UI handleTouchMovement(e); - if (trackedTouches.All(t => t.Action != action)) + if (!mouseDisabled.Value && trackedTouches.All(t => t.Action != action)) { trackedTouches.Add(new TrackedTouch(e.Touch, action)); osuInputManager.KeyBindingContainer.TriggerPressed(action); From b1c9505ab6216c667e276c33b691ef54af8ba14d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Jan 2023 20:45:04 +0900 Subject: [PATCH 1579/2991] Add touch visualisation to test --- .../TestSceneTouchInput.cs | 123 ++++++++++++++++-- 1 file changed, 111 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs index b1edafa4f8..fc39c6493d 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs @@ -1,17 +1,21 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Diagnostics; using System.Linq; using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; +using osu.Framework.Input.States; using osu.Framework.Testing; using osu.Game.Screens.Play; using osu.Game.Tests.Visual; using osuTK; +using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Tests { @@ -31,18 +35,32 @@ namespace osu.Game.Rulesets.Osu.Tests AddStep("Create tests", () => { - Child = osuInputManager = new OsuInputManager(new OsuRuleset().RulesetInfo) + Children = new Drawable[] { - Child = new Container + osuInputManager = new OsuInputManager(new OsuRuleset().RulesetInfo) { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Children = new Drawable[] + Child = new Container { - leftKeyCounter = new TestActionKeyCounter(OsuAction.LeftButton), - rightKeyCounter = new TestActionKeyCounter(OsuAction.RightButton) { Margin = new MarginPadding { Left = 150 } } - }, - } + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Children = new Drawable[] + { + leftKeyCounter = new TestActionKeyCounter(OsuAction.LeftButton) + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreRight, + X = -100, + }, + rightKeyCounter = new TestActionKeyCounter(OsuAction.RightButton) + { + Anchor = Anchor.Centre, + Origin = Anchor.CentreLeft, + X = 100, + } + }, + } + }, + new TouchVisualiser(), }; }); } @@ -165,10 +183,18 @@ namespace osu.Game.Rulesets.Osu.Tests } private void beginTouch(TouchSource source, Vector2? screenSpacePosition = null) => - AddStep($"Begin touch for {source}", () => InputManager.BeginTouch(new Touch(source, screenSpacePosition ?? osuInputManager.ScreenSpaceDrawQuad.Centre))); + AddStep($"Begin touch for {source}", () => InputManager.BeginTouch(new Touch(source, screenSpacePosition ??= getSanePositionForSource(source)))); - private void endTouch(TouchSource source) => - AddStep($"Release touch for {source}", () => InputManager.EndTouch(new Touch(source, osuInputManager.ScreenSpaceDrawQuad.Centre))); + private void endTouch(TouchSource source, Vector2? screenSpacePosition = null) => + AddStep($"Release touch for {source}", () => InputManager.EndTouch(new Touch(source, screenSpacePosition ??= getSanePositionForSource(source)))); + + private Vector2 getSanePositionForSource(TouchSource source) + { + return new Vector2( + osuInputManager.ScreenSpaceDrawQuad.Centre.X + osuInputManager.ScreenSpaceDrawQuad.Width * (-1 + (int)source) / 8, + osuInputManager.ScreenSpaceDrawQuad.Centre.Y - 100 + ); + } private void assertKeyCounter(int left, int right) { @@ -213,5 +239,78 @@ namespace osu.Game.Rulesets.Osu.Tests if (e.Action == Action) IsLit = false; } } + + public partial class TouchVisualiser : CompositeDrawable + { + private readonly Drawable?[] drawableTouches = new Drawable?[10]; + + public TouchVisualiser() + { + RelativeSizeAxes = Axes.Both; + } + + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; + + protected override bool OnTouchDown(TouchDownEvent e) + { + if (IsDisposed) + return false; + + var circle = new Circle + { + Alpha = 0.5f, + Origin = Anchor.Centre, + Size = new Vector2(20), + Position = e.Touch.Position, + Colour = colourFor(e.Touch.Source), + }; + + AddInternal(circle); + drawableTouches[(int)e.Touch.Source] = circle; + return false; + } + + protected override void OnTouchMove(TouchMoveEvent e) + { + if (IsDisposed) + return; + + var circle = drawableTouches[(int)e.Touch.Source]; + + Debug.Assert(circle != null); + + AddInternal(new FadingCircle(circle)); + circle.Position = e.Touch.Position; + } + + protected override void OnTouchUp(TouchUpEvent e) + { + var circle = drawableTouches[(int)e.Touch.Source]; + circle.FadeOut(200, Easing.OutQuint).Expire(); + drawableTouches[(int)e.Touch.Source] = null; + } + + private Color4 colourFor(TouchSource source) + { + return Color4.FromHsv(new Vector4((float)source / TouchState.MAX_TOUCH_COUNT, 1f, 1f, 1f)); + } + + private partial class FadingCircle : Circle + { + public FadingCircle(Drawable source) + { + Origin = Anchor.Centre; + Size = source.Size; + Position = source.Position; + Colour = source.Colour; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + this.FadeOut(200).Expire(); + } + } + } } } From 9c5789848f0976c5ac7232abd7ebea04c12dd44c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Jan 2023 20:55:53 +0900 Subject: [PATCH 1580/2991] Add further coverage of alternating Covers a real failure I discovered. --- .../TestSceneTouchInput.cs | 68 ++++++++++--------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs index fc39c6493d..9860026b49 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs @@ -71,13 +71,13 @@ namespace osu.Game.Rulesets.Osu.Tests beginTouch(TouchSource.Touch1); assertKeyCounter(1, 0); - expectPressedCurrently(OsuAction.LeftButton); + checkPressed(OsuAction.LeftButton); beginTouch(TouchSource.Touch2); assertKeyCounter(1, 1); - expectPressedCurrently(OsuAction.LeftButton); - expectPressedCurrently(OsuAction.RightButton); + checkPressed(OsuAction.LeftButton); + checkPressed(OsuAction.RightButton); // Subsequent touches should be ignored. beginTouch(TouchSource.Touch3); @@ -85,8 +85,8 @@ namespace osu.Game.Rulesets.Osu.Tests assertKeyCounter(1, 1); - expectPressedCurrently(OsuAction.LeftButton); - expectPressedCurrently(OsuAction.RightButton); + checkPressed(OsuAction.LeftButton); + checkPressed(OsuAction.RightButton); assertKeyCounter(1, 1); } @@ -97,35 +97,36 @@ namespace osu.Game.Rulesets.Osu.Tests beginTouch(TouchSource.Touch1); assertKeyCounter(1, 0); - expectPressedCurrently(OsuAction.LeftButton); + checkPressed(OsuAction.LeftButton); beginTouch(TouchSource.Touch2); assertKeyCounter(1, 1); - expectPressedCurrently(OsuAction.LeftButton); - expectPressedCurrently(OsuAction.RightButton); + checkPressed(OsuAction.LeftButton); + checkPressed(OsuAction.RightButton); - endTouch(TouchSource.Touch1); + for (int i = 0; i < 2; i++) + { + endTouch(TouchSource.Touch1); - assertKeyCounter(1, 1); - expectPressedCurrently(OsuAction.RightButton); + checkPressed(OsuAction.RightButton); + checkNotPressed(OsuAction.LeftButton); - beginTouch(TouchSource.Touch1); + beginTouch(TouchSource.Touch1); - assertKeyCounter(2, 1); - expectPressedCurrently(OsuAction.LeftButton); - expectPressedCurrently(OsuAction.RightButton); + checkPressed(OsuAction.LeftButton); + checkPressed(OsuAction.RightButton); - endTouch(TouchSource.Touch2); + endTouch(TouchSource.Touch2); - assertKeyCounter(2, 1); - expectPressedCurrently(OsuAction.LeftButton); + checkPressed(OsuAction.LeftButton); + checkNotPressed(OsuAction.RightButton); - beginTouch(TouchSource.Touch2); + beginTouch(TouchSource.Touch2); - assertKeyCounter(2, 2); - expectPressedCurrently(OsuAction.LeftButton); - expectPressedCurrently(OsuAction.RightButton); + checkPressed(OsuAction.LeftButton); + checkPressed(OsuAction.RightButton); + } } [Test] @@ -136,25 +137,25 @@ namespace osu.Game.Rulesets.Osu.Tests beginTouch(TouchSource.Touch3); assertKeyCounter(1, 1); - expectPressedCurrently(OsuAction.LeftButton); - expectPressedCurrently(OsuAction.RightButton); + checkPressed(OsuAction.LeftButton); + checkPressed(OsuAction.RightButton); // Touch 3 was ignored, but let's ensure that if 1 or 2 are released, 3 will be handled a second attempt. endTouch(TouchSource.Touch1); assertKeyCounter(1, 1); - expectPressedCurrently(OsuAction.RightButton); + checkPressed(OsuAction.RightButton); endTouch(TouchSource.Touch3); assertKeyCounter(1, 1); - expectPressedCurrently(OsuAction.RightButton); + checkPressed(OsuAction.RightButton); beginTouch(TouchSource.Touch3); assertKeyCounter(2, 1); - expectPressedCurrently(OsuAction.LeftButton); - expectPressedCurrently(OsuAction.RightButton); + checkPressed(OsuAction.LeftButton); + checkPressed(OsuAction.RightButton); } [Test] @@ -163,12 +164,12 @@ namespace osu.Game.Rulesets.Osu.Tests beginTouch(TouchSource.Touch1); assertKeyCounter(1, 0); - expectPressedCurrently(OsuAction.LeftButton); + checkPressed(OsuAction.LeftButton); beginTouch(TouchSource.Touch2); assertKeyCounter(1, 1); - expectPressedCurrently(OsuAction.RightButton); + checkPressed(OsuAction.RightButton); // Subsequent touches should be ignored. beginTouch(TouchSource.Touch3); @@ -176,8 +177,8 @@ namespace osu.Game.Rulesets.Osu.Tests assertKeyCounter(1, 1); - expectPressedCurrently(OsuAction.LeftButton); - expectPressedCurrently(OsuAction.RightButton); + checkPressed(OsuAction.LeftButton); + checkPressed(OsuAction.RightButton); assertKeyCounter(1, 1); } @@ -211,7 +212,8 @@ namespace osu.Game.Rulesets.Osu.Tests }); } - private void expectPressedCurrently(OsuAction action) => AddAssert($"Is pressing {action}", () => osuInputManager.PressedActions.Contains(action)); + private void checkNotPressed(OsuAction action) => AddAssert($"Not pressing {action}", () => !osuInputManager.PressedActions.Contains(action)); + private void checkPressed(OsuAction action) => AddAssert($"Is pressing {action}", () => osuInputManager.PressedActions.Contains(action)); public partial class TestActionKeyCounter : KeyCounter, IKeyBindingHandler { From eaaab2e76dcda4ca24b1ba5b42b6b58e76f025b0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Jan 2023 20:58:24 +0900 Subject: [PATCH 1581/2991] Add test coverage of disabled mouse buttons --- .../TestSceneTouchInput.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs index 9860026b49..01b54d97a7 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -12,6 +13,7 @@ using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Input.States; using osu.Framework.Testing; +using osu.Game.Configuration; using osu.Game.Screens.Play; using osu.Game.Tests.Visual; using osuTK; @@ -22,6 +24,9 @@ namespace osu.Game.Rulesets.Osu.Tests [TestFixture] public partial class TestSceneTouchInput : OsuManualInputManagerTestScene { + [Resolved] + private OsuConfigManager config { get; set; } = null!; + private TestActionKeyCounter leftKeyCounter = null!; private TestActionKeyCounter rightKeyCounter = null!; @@ -91,6 +96,23 @@ namespace osu.Game.Rulesets.Osu.Tests assertKeyCounter(1, 1); } + [Test] + public void TestSimpleInputButtonsDisabled() + { + AddStep("Disable mouse buttons", () => config.SetValue(OsuSetting.MouseDisableButtons, true)); + + beginTouch(TouchSource.Touch1); + + assertKeyCounter(0, 0); + checkNotPressed(OsuAction.LeftButton); + + beginTouch(TouchSource.Touch2); + + assertKeyCounter(0, 0); + checkNotPressed(OsuAction.LeftButton); + checkNotPressed(OsuAction.RightButton); + } + [Test] public void TestAlternatingInput() { @@ -207,6 +229,7 @@ namespace osu.Game.Rulesets.Osu.Tests { AddStep("Release all touches", () => { + config.SetValue(OsuSetting.MouseDisableButtons, false); foreach (TouchSource source in InputManager.CurrentState.Touch.ActiveSources) InputManager.EndTouch(new Touch(source, osuInputManager.ScreenSpaceDrawQuad.Centre)); }); From ab3d63211211d79e37a05a19b955dfcc00912f3e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Jan 2023 21:02:37 +0900 Subject: [PATCH 1582/2991] Also add test coverage of positional updates --- osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs index 01b54d97a7..0f27579975 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs @@ -77,16 +77,21 @@ namespace osu.Game.Rulesets.Osu.Tests assertKeyCounter(1, 0); checkPressed(OsuAction.LeftButton); + checkPosition(TouchSource.Touch1); beginTouch(TouchSource.Touch2); assertKeyCounter(1, 1); checkPressed(OsuAction.LeftButton); checkPressed(OsuAction.RightButton); + checkPosition(TouchSource.Touch2); - // Subsequent touches should be ignored. + // Subsequent touches should be ignored (except position). beginTouch(TouchSource.Touch3); + checkPosition(TouchSource.Touch3); + beginTouch(TouchSource.Touch4); + checkPosition(TouchSource.Touch4); assertKeyCounter(1, 1); @@ -105,12 +110,14 @@ namespace osu.Game.Rulesets.Osu.Tests assertKeyCounter(0, 0); checkNotPressed(OsuAction.LeftButton); + checkPosition(TouchSource.Touch1); beginTouch(TouchSource.Touch2); assertKeyCounter(0, 0); checkNotPressed(OsuAction.LeftButton); checkNotPressed(OsuAction.RightButton); + checkPosition(TouchSource.Touch2); } [Test] @@ -219,6 +226,9 @@ namespace osu.Game.Rulesets.Osu.Tests ); } + private void checkPosition(TouchSource touchSource) => + AddAssert("Cursor position is correct", () => osuInputManager.CurrentState.Mouse.Position, () => Is.EqualTo(getSanePositionForSource(touchSource))); + private void assertKeyCounter(int left, int right) { AddAssert($"The left key was pressed {left} times", () => leftKeyCounter.CountPresses, () => Is.EqualTo(left)); From 6b16d3ee6191370551f87c1e1bac9a6f6872cae3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Jan 2023 21:07:19 +0900 Subject: [PATCH 1583/2991] Add test expectation for how positional input should be handled --- .../TestSceneTouchInput.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs index 0f27579975..5452405bf0 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs @@ -101,6 +101,26 @@ namespace osu.Game.Rulesets.Osu.Tests assertKeyCounter(1, 1); } + [Test] + public void TestPositionalInputUpdatesOnlyFromMostRecentTouch() + { + beginTouch(TouchSource.Touch1); + checkPosition(TouchSource.Touch1); + + beginTouch(TouchSource.Touch2); + checkPosition(TouchSource.Touch2); + + beginTouch(TouchSource.Touch1, Vector2.One); + checkPosition(TouchSource.Touch2); + + endTouch(TouchSource.Touch2); + checkPosition(TouchSource.Touch2); + + // note that touch1 was never ended, but becomes active for tracking again. + beginTouch(TouchSource.Touch1); + checkPosition(TouchSource.Touch1); + } + [Test] public void TestSimpleInputButtonsDisabled() { From b3860c6d52682d331fc34f6ecf4ab959dffe79cd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Jan 2023 21:07:28 +0900 Subject: [PATCH 1584/2991] Only use positional input from most recent touch --- .../UI/OsuTouchInputMapper.cs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs index 16283d3baa..38dbde99b9 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs @@ -51,24 +51,26 @@ namespace osu.Game.Rulesets.Osu.UI ? OsuAction.RightButton : OsuAction.LeftButton; + // Ignore any taps which trigger an action which is already handled. But track them for potential positional input in the future. + bool shouldResultInAction = !mouseDisabled.Value && trackedTouches.All(t => t.Action != action); + + trackedTouches.Add(new TrackedTouch(e.Touch, shouldResultInAction ? action : null)); + + // Important to update position before triggering the pressed action. handleTouchMovement(e); - if (!mouseDisabled.Value && trackedTouches.All(t => t.Action != action)) - { - trackedTouches.Add(new TrackedTouch(e.Touch, action)); + if (shouldResultInAction) osuInputManager.KeyBindingContainer.TriggerPressed(action); - } - else - { - // Ignore any taps which trigger an action which is already handled. But track them for potential positional input in the future. - trackedTouches.Add(new TrackedTouch(e.Touch, null)); - } return true; } private void handleTouchMovement(TouchEvent touchEvent) { + // Movement should only be tracked for the most recent touch. + if (touchEvent.Touch != trackedTouches.Last().Touch) + return; + new MousePositionAbsoluteInput { Position = touchEvent.ScreenSpaceTouch.Position }.Apply(osuInputManager.CurrentState, osuInputManager); } From 26f3b1dbfee45ed20d9bc62f003832f8bfca92c8 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 16 Jan 2023 19:37:47 +0300 Subject: [PATCH 1585/2991] Localise "revert to default" tooltip --- osu.Game/Localisation/CommonStrings.cs | 5 +++++ osu.Game/Overlays/RestoreDefaultValueButton.cs | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Localisation/CommonStrings.cs b/osu.Game/Localisation/CommonStrings.cs index 10178915a2..fed7b6cab7 100644 --- a/osu.Game/Localisation/CommonStrings.cs +++ b/osu.Game/Localisation/CommonStrings.cs @@ -154,6 +154,11 @@ namespace osu.Game.Localisation /// public static LocalisableString Exit => new TranslatableString(getKey(@"exit"), @"Exit"); + /// + /// "Revert to default" + /// + public static LocalisableString RevertToDefault => new TranslatableString(getKey(@"revert_to_default"), @"Revert to default"); + private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Overlays/RestoreDefaultValueButton.cs b/osu.Game/Overlays/RestoreDefaultValueButton.cs index 9d5e5db6e6..97c66fdf02 100644 --- a/osu.Game/Overlays/RestoreDefaultValueButton.cs +++ b/osu.Game/Overlays/RestoreDefaultValueButton.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; @@ -17,6 +18,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osuTK; +using osu.Game.Localisation; namespace osu.Game.Overlays { @@ -96,7 +98,7 @@ namespace osu.Game.Overlays FinishTransforms(true); } - public override LocalisableString TooltipText => "revert to default"; + public override LocalisableString TooltipText => CommonStrings.RevertToDefault.ToLower(); protected override bool OnHover(HoverEvent e) { From 6eb5508404c5841fc0dc007bc9224efc8df0c55b Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 16 Jan 2023 19:39:50 +0300 Subject: [PATCH 1586/2991] Localise menu bar --- osu.Game/Skinning/Editor/SkinEditor.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Skinning/Editor/SkinEditor.cs b/osu.Game/Skinning/Editor/SkinEditor.cs index 0ed4e5afd2..5fe92b33aa 100644 --- a/osu.Game/Skinning/Editor/SkinEditor.cs +++ b/osu.Game/Skinning/Editor/SkinEditor.cs @@ -122,14 +122,14 @@ namespace osu.Game.Skinning.Editor RelativeSizeAxes = Axes.Both, Items = new[] { - new MenuItem("File") + new MenuItem(CommonStrings.MenuBarFile) { Items = new[] { - new EditorMenuItem("Save", MenuItemType.Standard, Save), - new EditorMenuItem("Revert to default", MenuItemType.Destructive, revert), + new EditorMenuItem(Resources.Localisation.Web.CommonStrings.ButtonsSave, MenuItemType.Standard, Save), + new EditorMenuItem(CommonStrings.RevertToDefault, MenuItemType.Destructive, revert), new EditorMenuItemSpacer(), - new EditorMenuItem("Exit", MenuItemType.Standard, () => skinEditorOverlay?.Hide()), + new EditorMenuItem(CommonStrings.Exit, MenuItemType.Standard, () => skinEditorOverlay?.Hide()), }, }, } From 17aeb0ec192b13e158233d2f299fabe759d61794 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 16 Jan 2023 19:55:28 +0300 Subject: [PATCH 1587/2991] Localise editor's UI --- osu.Game/Localisation/SkinEditorStrings.cs | 49 +++++++++++++++++++ .../Skinning/Editor/SkinComponentToolbox.cs | 3 +- osu.Game/Skinning/Editor/SkinEditor.cs | 9 ++-- .../Skinning/Editor/SkinEditorSceneLibrary.cs | 9 ++-- .../Skinning/Editor/SkinSettingsToolbox.cs | 5 +- 5 files changed, 62 insertions(+), 13 deletions(-) create mode 100644 osu.Game/Localisation/SkinEditorStrings.cs diff --git a/osu.Game/Localisation/SkinEditorStrings.cs b/osu.Game/Localisation/SkinEditorStrings.cs new file mode 100644 index 0000000000..605b7d6a9d --- /dev/null +++ b/osu.Game/Localisation/SkinEditorStrings.cs @@ -0,0 +1,49 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class SkinEditorStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.SkinEditor"; + + /// + /// "Skin editor" + /// + public static LocalisableString SkinEditor => new TranslatableString(getKey(@"skin_editor"), @"Skin editor"); + + /// + /// "Currently editing" + /// + public static LocalisableString CurrentlyEditing => new TranslatableString(getKey(@"currently_editing"), @"Currently editing"); + + /// + /// "Components" + /// + public static LocalisableString Components => new TranslatableString(getKey(@"components"), @"Components"); + + /// + /// "Scene library" + /// + public static LocalisableString SceneLibrary => new TranslatableString(getKey(@"scene_library"), @"Scene library"); + + /// + /// "Song Select" + /// + public static LocalisableString SongSelect => new TranslatableString(getKey(@"song_select"), @"Song Select"); + + /// + /// "Gameplay" + /// + public static LocalisableString Gameplay => new TranslatableString(getKey(@"gameplay"), @"Gameplay"); + + /// + /// "Settings ({0})" + /// + public static LocalisableString Settings(string arg0) => new TranslatableString(getKey(@"settings"), @"Settings ({0})", arg0); + + private static string getKey(string key) => $@"{prefix}:{key}"; + } +} diff --git a/osu.Game/Skinning/Editor/SkinComponentToolbox.cs b/osu.Game/Skinning/Editor/SkinComponentToolbox.cs index 053119557f..9985b81059 100644 --- a/osu.Game/Skinning/Editor/SkinComponentToolbox.cs +++ b/osu.Game/Skinning/Editor/SkinComponentToolbox.cs @@ -10,6 +10,7 @@ using osu.Framework.Logging; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Overlays; using osu.Game.Screens.Edit.Components; using osu.Game.Screens.Play.HUD; @@ -26,7 +27,7 @@ namespace osu.Game.Skinning.Editor private FillFlowContainer fill = null!; public SkinComponentToolbox(CompositeDrawable? target = null) - : base("Components") + : base(SkinEditorStrings.Components) { this.target = target; } diff --git a/osu.Game/Skinning/Editor/SkinEditor.cs b/osu.Game/Skinning/Editor/SkinEditor.cs index 5fe92b33aa..74391e5269 100644 --- a/osu.Game/Skinning/Editor/SkinEditor.cs +++ b/osu.Game/Skinning/Editor/SkinEditor.cs @@ -109,7 +109,7 @@ namespace osu.Game.Skinning.Editor { new Container { - Name = "Menu container", + Name = @"Menu container", RelativeSizeAxes = Axes.X, Depth = float.MinValue, Height = MENU_HEIGHT, @@ -234,7 +234,6 @@ namespace osu.Game.Skinning.Editor // Immediately clear the previous blueprint container to ensure it doesn't try to interact with the old target. content?.Clear(); - Scheduler.AddOnce(loadBlueprintContainer); Scheduler.AddOnce(populateSettings); @@ -253,15 +252,15 @@ namespace osu.Game.Skinning.Editor { headerText.Clear(); - headerText.AddParagraph("Skin editor", cp => cp.Font = OsuFont.Default.With(size: 16)); + headerText.AddParagraph(SkinEditorStrings.SkinEditor, cp => cp.Font = OsuFont.Default.With(size: 16)); headerText.NewParagraph(); - headerText.AddText("Currently editing ", cp => + headerText.AddText(SkinEditorStrings.CurrentlyEditing, cp => { cp.Font = OsuFont.Default.With(size: 12); cp.Colour = colours.Yellow; }); - headerText.AddText($"{currentSkin.Value.SkinInfo}", cp => + headerText.AddText($" {currentSkin.Value.SkinInfo}", cp => { cp.Font = OsuFont.Default.With(size: 12, weight: FontWeight.Bold); cp.Colour = colours.Yellow; diff --git a/osu.Game/Skinning/Editor/SkinEditorSceneLibrary.cs b/osu.Game/Skinning/Editor/SkinEditorSceneLibrary.cs index c3907ea60d..44045e8916 100644 --- a/osu.Game/Skinning/Editor/SkinEditorSceneLibrary.cs +++ b/osu.Game/Skinning/Editor/SkinEditorSceneLibrary.cs @@ -16,6 +16,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -66,7 +67,7 @@ namespace osu.Game.Skinning.Editor { new FillFlowContainer { - Name = "Scene library", + Name = @"Scene library", AutoSizeAxes = Axes.X, RelativeSizeAxes = Axes.Y, Spacing = new Vector2(padding), @@ -76,14 +77,14 @@ namespace osu.Game.Skinning.Editor { new OsuSpriteText { - Text = "Scene library", + Text = SkinEditorStrings.SceneLibrary, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Margin = new MarginPadding(10), }, new SceneButton { - Text = "Song Select", + Text = SkinEditorStrings.SongSelect, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Action = () => performer?.PerformFromScreen(screen => @@ -96,7 +97,7 @@ namespace osu.Game.Skinning.Editor }, new SceneButton { - Text = "Gameplay", + Text = SkinEditorStrings.Gameplay, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Action = () => performer?.PerformFromScreen(screen => diff --git a/osu.Game/Skinning/Editor/SkinSettingsToolbox.cs b/osu.Game/Skinning/Editor/SkinSettingsToolbox.cs index 8c08f40b70..6afe92c6b2 100644 --- a/osu.Game/Skinning/Editor/SkinSettingsToolbox.cs +++ b/osu.Game/Skinning/Editor/SkinSettingsToolbox.cs @@ -1,12 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Configuration; +using osu.Game.Localisation; using osu.Game.Screens.Edit.Components; using osuTK; @@ -17,7 +16,7 @@ namespace osu.Game.Skinning.Editor protected override Container Content { get; } public SkinSettingsToolbox(Drawable component) - : base($"Settings ({component.GetType().Name})") + : base(SkinEditorStrings.Settings(component.GetType().Name)) { base.Content.Add(Content = new FillFlowContainer { From 1a776eb546119761f1f1283956c65a5b4fae1347 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Jan 2023 14:36:56 +0300 Subject: [PATCH 1588/2991] Mark item-mutating queue mode tests with `FlakyTest` attribute --- .../TestSceneAllPlayersQueueMode.cs | 33 ++++++--- .../Multiplayer/TestSceneHostOnlyQueueMode.cs | 71 +++++++++++-------- 2 files changed, 64 insertions(+), 40 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneAllPlayersQueueMode.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneAllPlayersQueueMode.cs index 7b1abd104f..6da9d37648 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneAllPlayersQueueMode.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneAllPlayersQueueMode.cs @@ -34,6 +34,24 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + public void TestSingleItemExpiredAfterGameplay() + { + RunGameplay(); + + AddUntilStep("playlist has only one item", () => MultiplayerClient.ClientAPIRoom?.Playlist.Count == 1); + AddUntilStep("playlist item is expired", () => MultiplayerClient.ClientAPIRoom?.Playlist[0].Expired == true); + AddUntilStep("last item selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[0].ID); + } + + [Test] + [FlakyTest] + /* + * TearDown : System.TimeoutException : "wait for ongoing operation to complete" timed out + * --TearDown + * at osu.Framework.Testing.Drawables.Steps.UntilStepButton.<>c__DisplayClass11_0.<.ctor>b__0() + * at osu.Framework.Testing.Drawables.Steps.StepButton.PerformStep(Boolean userTriggered) + * at osu.Framework.Testing.TestScene.runNextStep(Action onCompletion, Action`1 onError, Func`2 stopCondition) + */ public void TestItemAddedToTheEndOfQueue() { addItem(() => OtherBeatmap); @@ -46,16 +64,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] - public void TestSingleItemExpiredAfterGameplay() - { - RunGameplay(); - - AddUntilStep("playlist has only one item", () => MultiplayerClient.ClientAPIRoom?.Playlist.Count == 1); - AddUntilStep("playlist item is expired", () => MultiplayerClient.ClientAPIRoom?.Playlist[0].Expired == true); - AddUntilStep("last item selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[0].ID); - } - - [Test] + [FlakyTest] // See above public void TestNextItemSelectedAfterGameplayFinish() { addItem(() => OtherBeatmap); @@ -73,6 +82,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestItemsNotClearedWhenSwitchToHostOnlyMode() { addItem(() => OtherBeatmap); @@ -88,6 +98,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestCorrectItemSelectedAfterNewItemAdded() { addItem(() => OtherBeatmap); @@ -95,6 +106,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestCorrectRulesetSelectedAfterNewItemAdded() { addItem(() => OtherBeatmap, new CatchRuleset().RulesetInfo); @@ -112,6 +124,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestCorrectModsSelectedAfterNewItemAdded() { addItem(() => OtherBeatmap, mods: new Mod[] { new OsuModDoubleTime() }); diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneHostOnlyQueueMode.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneHostOnlyQueueMode.cs index 145c655c0a..dc36f539e3 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneHostOnlyQueueMode.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneHostOnlyQueueMode.cs @@ -27,22 +27,6 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("first item selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[0].ID); } - [Test] - public void TestItemStillSelectedAfterChangeToSameBeatmap() - { - selectNewItem(() => InitialBeatmap); - - AddUntilStep("playlist item still selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[0].ID); - } - - [Test] - public void TestItemStillSelectedAfterChangeToOtherBeatmap() - { - selectNewItem(() => OtherBeatmap); - - AddUntilStep("playlist item still selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[0].ID); - } - [Test] public void TestNewItemCreatedAfterGameplayFinished() { @@ -54,20 +38,6 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("second playlist item selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[1].ID); } - [Test] - public void TestOnlyLastItemChangedAfterGameplayFinished() - { - RunGameplay(); - - IBeatmapInfo firstBeatmap = null; - AddStep("get first playlist item beatmap", () => firstBeatmap = MultiplayerClient.ServerAPIRoom?.Playlist[0].Beatmap); - - selectNewItem(() => OtherBeatmap); - - AddUntilStep("first playlist item hasn't changed", () => MultiplayerClient.ServerAPIRoom?.Playlist[0].Beatmap == firstBeatmap); - AddUntilStep("second playlist item changed", () => MultiplayerClient.ClientAPIRoom?.Playlist[1].Beatmap != firstBeatmap); - } - [Test] public void TestSettingsUpdatedWhenChangingQueueMode() { @@ -80,6 +50,47 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] + /* + * TearDown : System.TimeoutException : "wait for ongoing operation to complete" timed out + * --TearDown + * at osu.Framework.Testing.Drawables.Steps.UntilStepButton.<>c__DisplayClass11_0.<.ctor>b__0() + * at osu.Framework.Testing.Drawables.Steps.StepButton.PerformStep(Boolean userTriggered) + * at osu.Framework.Testing.TestScene.runNextStep(Action onCompletion, Action`1 onError, Func`2 stopCondition) + */ + public void TestItemStillSelectedAfterChangeToSameBeatmap() + { + selectNewItem(() => InitialBeatmap); + + AddUntilStep("playlist item still selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[0].ID); + } + + [Test] + [FlakyTest] // See above + public void TestItemStillSelectedAfterChangeToOtherBeatmap() + { + selectNewItem(() => OtherBeatmap); + + AddUntilStep("playlist item still selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[0].ID); + } + + [Test] + [FlakyTest] // See above + public void TestOnlyLastItemChangedAfterGameplayFinished() + { + RunGameplay(); + + IBeatmapInfo firstBeatmap = null; + AddStep("get first playlist item beatmap", () => firstBeatmap = MultiplayerClient.ServerAPIRoom?.Playlist[0].Beatmap); + + selectNewItem(() => OtherBeatmap); + + AddUntilStep("first playlist item hasn't changed", () => MultiplayerClient.ServerAPIRoom?.Playlist[0].Beatmap == firstBeatmap); + AddUntilStep("second playlist item changed", () => MultiplayerClient.ClientAPIRoom?.Playlist[1].Beatmap != firstBeatmap); + } + + [Test] + [FlakyTest] // See above public void TestAddItemsAsHost() { addItem(() => OtherBeatmap); From f63de55a20a92f2669d6faae73cc5716c273a72d Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 16 Jan 2023 22:34:29 +0300 Subject: [PATCH 1589/2991] Mark ready-button-pressing multiplayer tests with `FlakyTest` attribute --- .../Multiplayer/TestSceneMultiplayer.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs index 5033347b15..d747d23229 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs @@ -377,6 +377,17 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] + /* + * On a slight investigation, this is occurring due to the ready button + * not receiving the click input generated by the manual input manager. + * + * TearDown : System.TimeoutException : "wait for ready button to be enabled" timed out + * --TearDown + * at osu.Framework.Testing.Drawables.Steps.UntilStepButton.<>c__DisplayClass11_0.<.ctor>b__0() + * at osu.Framework.Testing.Drawables.Steps.StepButton.PerformStep(Boolean userTriggered) + * at osu.Framework.Testing.TestScene.runNextStep(Action onCompletion, Action`1 onError, Func`2 stopCondition) + */ public void TestUserSetToIdleWhenBeatmapDeleted() { createRoom(() => new Room @@ -398,6 +409,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestPlayStartsWithCorrectBeatmapWhileAtSongSelect() { PlaylistItem? item = null; @@ -438,6 +450,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestPlayStartsWithCorrectRulesetWhileAtSongSelect() { PlaylistItem? item = null; @@ -478,6 +491,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestPlayStartsWithCorrectModsWhileAtSongSelect() { PlaylistItem? item = null; @@ -651,6 +665,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestGameplayFlow() { createRoom(() => new Room @@ -678,6 +693,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestGameplayExitFlow() { Bindable? holdDelay = null; @@ -715,6 +731,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestGameplayDoesntStartWithNonLoadedUser() { createRoom(() => new Room @@ -796,6 +813,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestSpectatingStateResetOnBackButtonDuringGameplay() { createRoom(() => new Room @@ -831,6 +849,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestSpectatingStateNotResetOnBackButtonOutsideOfGameplay() { createRoom(() => new Room @@ -869,6 +888,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestItemAddedByOtherUserDuringGameplay() { createRoom(() => new Room @@ -899,6 +919,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestItemAddedAndDeletedByOtherUserDuringGameplay() { createRoom(() => new Room From 0ec608ec5d67dc341ea768ac7e3460cacbd96937 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 16 Jan 2023 22:46:57 +0300 Subject: [PATCH 1590/2991] Select button using its index in test --- .../Visual/Navigation/TestSceneSkinEditorNavigation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs index e0b61794e4..3b49161dd6 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs @@ -219,7 +219,7 @@ namespace osu.Game.Tests.Visual.Navigation AddStep("Click gameplay scene button", () => { - InputManager.MoveMouseTo(skinEditor.ChildrenOfType().First(b => b.Text == "Gameplay")); + InputManager.MoveMouseTo(skinEditor.ChildrenOfType().Skip(1).First()); InputManager.Click(MouseButton.Left); }); From 133b9b79d768c41711429ff8c329729577c05dcf Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 16 Jan 2023 22:52:17 +0300 Subject: [PATCH 1591/2991] Do not touch "currently editing" line --- osu.Game/Localisation/SkinEditorStrings.cs | 5 ----- osu.Game/Skinning/Editor/SkinEditor.cs | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/osu.Game/Localisation/SkinEditorStrings.cs b/osu.Game/Localisation/SkinEditorStrings.cs index 605b7d6a9d..b2e5f3aeb6 100644 --- a/osu.Game/Localisation/SkinEditorStrings.cs +++ b/osu.Game/Localisation/SkinEditorStrings.cs @@ -14,11 +14,6 @@ namespace osu.Game.Localisation /// public static LocalisableString SkinEditor => new TranslatableString(getKey(@"skin_editor"), @"Skin editor"); - /// - /// "Currently editing" - /// - public static LocalisableString CurrentlyEditing => new TranslatableString(getKey(@"currently_editing"), @"Currently editing"); - /// /// "Components" /// diff --git a/osu.Game/Skinning/Editor/SkinEditor.cs b/osu.Game/Skinning/Editor/SkinEditor.cs index 74391e5269..98b4e960dd 100644 --- a/osu.Game/Skinning/Editor/SkinEditor.cs +++ b/osu.Game/Skinning/Editor/SkinEditor.cs @@ -254,13 +254,13 @@ namespace osu.Game.Skinning.Editor headerText.AddParagraph(SkinEditorStrings.SkinEditor, cp => cp.Font = OsuFont.Default.With(size: 16)); headerText.NewParagraph(); - headerText.AddText(SkinEditorStrings.CurrentlyEditing, cp => + headerText.AddText("Currently editing ", cp => { cp.Font = OsuFont.Default.With(size: 12); cp.Colour = colours.Yellow; }); - headerText.AddText($" {currentSkin.Value.SkinInfo}", cp => + headerText.AddText($"{currentSkin.Value.SkinInfo}", cp => { cp.Font = OsuFont.Default.With(size: 12, weight: FontWeight.Bold); cp.Colour = colours.Yellow; From 6207a96a29f93733fbd1569d26f0ce02b78ae8f5 Mon Sep 17 00:00:00 2001 From: StanR Date: Mon, 16 Jan 2023 23:24:09 +0300 Subject: [PATCH 1592/2991] Refactor `LevelBadge` to use `LevelInfo` --- .../Profile/Header/CentreHeaderContainer.cs | 15 ++++++++++++--- .../Profile/Header/Components/LevelBadge.cs | 10 +++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 7721342ba8..fbd8f1e0c6 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -6,6 +6,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile.Header.Components; using osuTK; @@ -15,6 +16,8 @@ namespace osu.Game.Overlays.Profile.Header { public readonly Bindable User = new Bindable(); + private LevelBadge levelBadge = null!; + public CentreHeaderContainer() { Height = 60; @@ -62,12 +65,11 @@ namespace osu.Game.Overlays.Profile.Header Margin = new MarginPadding { Right = UserProfileOverlay.CONTENT_X_MARGIN }, Children = new Drawable[] { - new LevelBadge + levelBadge = new LevelBadge { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - Size = new Vector2(40), - User = { BindTarget = User } + Size = new Vector2(40) }, new Container { @@ -85,6 +87,13 @@ namespace osu.Game.Overlays.Profile.Header } } }; + + User.BindValueChanged(user => updateDisplay(user.NewValue?.User)); + } + + private void updateDisplay(APIUser? user) + { + levelBadge.LevelInfo.Value = user?.Statistics?.Level; } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index 78c5231736..a0c17ccf93 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -11,14 +11,14 @@ using osu.Framework.Graphics.Textures; using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Resources.Localisation.Web; +using osu.Game.Users; namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelBadge : CompositeDrawable, IHasTooltip { - public readonly Bindable User = new Bindable(); + public readonly Bindable LevelInfo = new Bindable(); public LocalisableString TooltipText { get; private set; } @@ -48,12 +48,12 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; - User.BindValueChanged(user => updateLevel(user.NewValue?.User)); + LevelInfo.BindValueChanged(user => updateLevel(user.NewValue)); } - private void updateLevel(APIUser? user) + private void updateLevel(UserStatistics.LevelInfo? levelInfo) { - string level = user?.Statistics?.Level.Current.ToString() ?? "0"; + string level = levelInfo?.Current.ToString() ?? "0"; levelText.Text = level; TooltipText = UsersStrings.ShowStatsLevel(level); } From c5d09c0e2c82ff4ae5c7259d6459994972ff3ca2 Mon Sep 17 00:00:00 2001 From: StanR Date: Mon, 16 Jan 2023 23:36:50 +0300 Subject: [PATCH 1593/2991] Rename variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index a0c17ccf93..251cd1bae5 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -48,7 +48,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; - LevelInfo.BindValueChanged(user => updateLevel(user.NewValue)); + LevelInfo.BindValueChanged(level => updateLevel(level.NewValue)); } private void updateLevel(UserStatistics.LevelInfo? levelInfo) From 3f75506552e9285534cfa47b69aa81cb41633df0 Mon Sep 17 00:00:00 2001 From: StanR Date: Mon, 16 Jan 2023 23:42:07 +0300 Subject: [PATCH 1594/2991] Move binding to `LoadComplete` --- osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index 251cd1bae5..b75ffcaf98 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -47,8 +47,11 @@ namespace osu.Game.Overlays.Profile.Header.Components Font = OsuFont.GetFont(size: 20) } }; + } - LevelInfo.BindValueChanged(level => updateLevel(level.NewValue)); + protected override void LoadComplete() + { + LevelInfo.BindValueChanged(level => updateLevel(level.NewValue), true); } private void updateLevel(UserStatistics.LevelInfo? levelInfo) From f79037cefb206f9e57a3dd450d51ec6f7af0c343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 16 Jan 2023 21:47:31 +0100 Subject: [PATCH 1595/2991] Move to `LoadComplete()` better --- osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs | 7 ++++++- osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index fbd8f1e0c6..0dab4d582d 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -87,8 +87,13 @@ namespace osu.Game.Overlays.Profile.Header } } }; + } - User.BindValueChanged(user => updateDisplay(user.NewValue?.User)); + protected override void LoadComplete() + { + base.LoadComplete(); + + User.BindValueChanged(user => updateDisplay(user.NewValue?.User), true); } private void updateDisplay(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index b75ffcaf98..00bb8cbc75 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -51,6 +51,8 @@ namespace osu.Game.Overlays.Profile.Header.Components protected override void LoadComplete() { + base.LoadComplete(); + LevelInfo.BindValueChanged(level => updateLevel(level.NewValue), true); } From 4cf448ec11898985fc56ea2f1178ef765aa412eb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 11:51:17 +0900 Subject: [PATCH 1596/2991] Use `ToString()` for test instead of linq skip --- .../Visual/Navigation/TestSceneSkinEditorNavigation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs index 3b49161dd6..845cfdd6df 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs @@ -219,7 +219,7 @@ namespace osu.Game.Tests.Visual.Navigation AddStep("Click gameplay scene button", () => { - InputManager.MoveMouseTo(skinEditor.ChildrenOfType().Skip(1).First()); + InputManager.MoveMouseTo(skinEditor.ChildrenOfType().First(b => b.Text.ToString() == "Gameplay")); InputManager.Click(MouseButton.Left); }); From a02556d2fa93e7ca6242ba614af42ab37cc05a53 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 14:43:22 +0900 Subject: [PATCH 1597/2991] Move hover logic to `SettingsToolboxGroup` to avoid expanded state clash --- osu.Game/Overlays/SettingsToolboxGroup.cs | 4 +++- .../Play/PlayerSettings/PlayerSettingsGroup.cs | 18 ------------------ 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/osu.Game/Overlays/SettingsToolboxGroup.cs b/osu.Game/Overlays/SettingsToolboxGroup.cs index 86964e7ed4..c0948c1eab 100644 --- a/osu.Game/Overlays/SettingsToolboxGroup.cs +++ b/osu.Game/Overlays/SettingsToolboxGroup.cs @@ -135,12 +135,14 @@ namespace osu.Game.Overlays protected override bool OnHover(HoverEvent e) { updateFadeState(); + updateExpandedState(true); return false; } protected override void OnHoverLost(HoverLostEvent e) { updateFadeState(); + updateExpandedState(true); base.OnHoverLost(e); } @@ -168,7 +170,7 @@ namespace osu.Game.Overlays // potentially continuing to get processed while content has changed to autosize. content.ClearTransforms(); - if (Expanded.Value) + if (Expanded.Value || IsHovered) { content.AutoSizeAxes = Axes.Y; content.AutoSizeDuration = animate ? transition_duration : 0; diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs index ea4d983343..838106e198 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Input.Events; using osu.Game.Overlays; @@ -15,28 +13,12 @@ namespace osu.Game.Screens.Play.PlayerSettings { } - private bool expandedByDefault = true; - protected override bool OnHover(HoverEvent e) { - if (IsHovered && !Expanded.Value) - { - Expanded.Value = true; - expandedByDefault = false; - } - base.OnHover(e); // Importantly, return true to correctly take focus away from PlayerLoader. return true; } - - protected override void OnHoverLost(HoverLostEvent e) - { - if (!expandedByDefault) - Expanded.Value = false; - - base.OnHoverLost(e); - } } } From c6d33df147809ec02b3525371c1aa0db1df68ca0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 14:51:45 +0900 Subject: [PATCH 1598/2991] Only track `TouchSource` for now --- osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs index 38dbde99b9..c5fc464839 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs @@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Osu.UI // Ignore any taps which trigger an action which is already handled. But track them for potential positional input in the future. bool shouldResultInAction = !mouseDisabled.Value && trackedTouches.All(t => t.Action != action); - trackedTouches.Add(new TrackedTouch(e.Touch, shouldResultInAction ? action : null)); + trackedTouches.Add(new TrackedTouch(e.Touch.Source, shouldResultInAction ? action : null)); // Important to update position before triggering the pressed action. handleTouchMovement(e); @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Osu.UI private void handleTouchMovement(TouchEvent touchEvent) { // Movement should only be tracked for the most recent touch. - if (touchEvent.Touch != trackedTouches.Last().Touch) + if (touchEvent.Touch.Source != trackedTouches.Last().Source) return; new MousePositionAbsoluteInput { Position = touchEvent.ScreenSpaceTouch.Position }.Apply(osuInputManager.CurrentState, osuInputManager); @@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Osu.UI protected override void OnTouchUp(TouchUpEvent e) { - var tracked = trackedTouches.First(t => t.Touch.Source == e.Touch.Source); + var tracked = trackedTouches.First(t => t.Source == e.Touch.Source); if (tracked.Action is OsuAction action) osuInputManager.KeyBindingContainer.TriggerReleased(action); @@ -88,13 +88,13 @@ namespace osu.Game.Rulesets.Osu.UI private class TrackedTouch { - public readonly Touch Touch; + public readonly TouchSource Source; public readonly OsuAction? Action; - public TrackedTouch(Touch touch, OsuAction? action) + public TrackedTouch(TouchSource source, OsuAction? action) { - Touch = touch; + Source = source; Action = action; } } From 9b5d6b391bfc70f3d290aea7bceaaf9fc5cb5876 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 14:52:15 +0900 Subject: [PATCH 1599/2991] Remove nullability allowance from `BackgroundDependencyLoader` --- osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs index c5fc464839..34a303c098 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.UI osuInputManager = inputManager; } - [BackgroundDependencyLoader(true)] + [BackgroundDependencyLoader] private void load(OsuConfigManager config) { mouseDisabled = config.GetBindable(OsuSetting.MouseDisableButtons); From 34120b61317364e26e88db21b47fcfd418bfd7da Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 14:52:45 +0900 Subject: [PATCH 1600/2991] Use linq `Single` instead of `First` for guaranteed singular match --- osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs index 34a303c098..6bc1dfd280 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs @@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Osu.UI protected override void OnTouchUp(TouchUpEvent e) { - var tracked = trackedTouches.First(t => t.Source == e.Touch.Source); + var tracked = trackedTouches.Single(t => t.Source == e.Touch.Source); if (tracked.Action is OsuAction action) osuInputManager.KeyBindingContainer.TriggerReleased(action); From 45b34f5306d70355077a27ccc83816891f15a919 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 14:53:24 +0900 Subject: [PATCH 1601/2991] Remove pointless xmldoc --- osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs index 6bc1dfd280..e1759da0da 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs @@ -15,17 +15,14 @@ namespace osu.Game.Rulesets.Osu.UI { public partial class OsuTouchInputMapper : Drawable { - /// - /// This is our parent . - /// - private readonly OsuInputManager osuInputManager; - /// /// All the active s and the that it triggered (if any). /// Ordered from oldest to newest touch chronologically. /// private readonly List trackedTouches = new List(); + private readonly OsuInputManager osuInputManager; + private Bindable mouseDisabled = null!; public OsuTouchInputMapper(OsuInputManager inputManager) From 3b95691d53fd8bfb4bc16954d628ae59b4da3371 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 14:54:52 +0900 Subject: [PATCH 1602/2991] Add note about mouse button disable tracking --- osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs index e1759da0da..0e8dba3ab0 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs @@ -33,6 +33,8 @@ namespace osu.Game.Rulesets.Osu.UI [BackgroundDependencyLoader] private void load(OsuConfigManager config) { + // The mouse button disable setting affects touch. It's a bit weird. + // This is mostly just doing the same as what is done in RulesetInputManager to match behaviour. mouseDisabled = config.GetBindable(OsuSetting.MouseDisableButtons); } From f387a6af57844dc3b022e167a549f12e07263263 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 14:56:07 +0900 Subject: [PATCH 1603/2991] Apply review feedback to touch test scene --- osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs index 5452405bf0..870a03b118 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs @@ -297,7 +297,7 @@ namespace osu.Game.Rulesets.Osu.Tests public partial class TouchVisualiser : CompositeDrawable { - private readonly Drawable?[] drawableTouches = new Drawable?[10]; + private readonly Drawable?[] drawableTouches = new Drawable?[TouchState.MAX_TOUCH_COUNT]; public TouchVisualiser() { @@ -341,6 +341,9 @@ namespace osu.Game.Rulesets.Osu.Tests protected override void OnTouchUp(TouchUpEvent e) { var circle = drawableTouches[(int)e.Touch.Source]; + + Debug.Assert(circle != null); + circle.FadeOut(200, Easing.OutQuint).Expire(); drawableTouches[(int)e.Touch.Source] = null; } From 490f539c43d104ce4bb0efd6b4727b35c2aab3cf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 15:07:03 +0900 Subject: [PATCH 1604/2991] Add failing test coverage of relax/autopilot scenarios --- .../TestSceneTouchInput.cs | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs index 870a03b118..10d0143351 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneTouchInput.cs @@ -122,7 +122,38 @@ namespace osu.Game.Rulesets.Osu.Tests } [Test] - public void TestSimpleInputButtonsDisabled() + public void TestMovementWhileDisallowed() + { + // aka "autopilot" mod + + AddStep("Disallow gameplay cursor movement", () => osuInputManager.AllowUserCursorMovement = false); + + Vector2? positionBefore = null; + + AddStep("Store cursor position", () => positionBefore = osuInputManager.CurrentState.Mouse.Position); + beginTouch(TouchSource.Touch1); + + assertKeyCounter(1, 0); + checkPressed(OsuAction.LeftButton); + AddAssert("Cursor position unchanged", () => osuInputManager.CurrentState.Mouse.Position, () => Is.EqualTo(positionBefore)); + } + + [Test] + public void TestActionWhileDisallowed() + { + // aka "relax" mod + + AddStep("Disallow gameplay actions", () => osuInputManager.AllowGameplayInputs = false); + + beginTouch(TouchSource.Touch1); + + assertKeyCounter(0, 0); + checkNotPressed(OsuAction.LeftButton); + checkPosition(TouchSource.Touch1); + } + + [Test] + public void TestInputWhileMouseButtonsDisabled() { AddStep("Disable mouse buttons", () => config.SetValue(OsuSetting.MouseDisableButtons, true)); From 24a626a9cdc2b4fc17b81badf297f1aacf692d34 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 15:01:01 +0900 Subject: [PATCH 1605/2991] Fix incorrect touch handling in autopilot and relax mods --- osu.Game.Rulesets.Osu/OsuInputManager.cs | 1 + osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index 28b4f70c10..6f69fbef43 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -29,6 +29,7 @@ namespace osu.Game.Rulesets.Osu /// public bool AllowGameplayInputs { + get => ((OsuKeyBindingContainer)KeyBindingContainer).AllowGameplayInputs; set => ((OsuKeyBindingContainer)KeyBindingContainer).AllowGameplayInputs = value; } diff --git a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs index 0e8dba3ab0..c75e179443 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs @@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Osu.UI : OsuAction.LeftButton; // Ignore any taps which trigger an action which is already handled. But track them for potential positional input in the future. - bool shouldResultInAction = !mouseDisabled.Value && trackedTouches.All(t => t.Action != action); + bool shouldResultInAction = osuInputManager.AllowGameplayInputs && !mouseDisabled.Value && trackedTouches.All(t => t.Action != action); trackedTouches.Add(new TrackedTouch(e.Touch.Source, shouldResultInAction ? action : null)); @@ -70,6 +70,9 @@ namespace osu.Game.Rulesets.Osu.UI if (touchEvent.Touch.Source != trackedTouches.Last().Source) return; + if (!osuInputManager.AllowUserCursorMovement) + return; + new MousePositionAbsoluteInput { Position = touchEvent.ScreenSpaceTouch.Position }.Apply(osuInputManager.CurrentState, osuInputManager); } From ef354938646837725471a384172021f95a8ed51b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 15:27:19 +0900 Subject: [PATCH 1606/2991] Avoid need for weird null check by reordering initialisation process --- osu.Game/Screens/Select/SongSelect.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index d4d75d0ad6..64deb59026 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -127,9 +127,6 @@ namespace osu.Game.Screens.Select [BackgroundDependencyLoader(true)] private void load(AudioManager audio, OsuColour colours, ManageCollectionsDialog? manageCollectionsDialog, DifficultyRecommender? recommender) { - // initial value transfer is required for FilterControl (it uses our re-cached bindables in its async load for the initial filter). - transferRulesetValue(); - LoadComponentAsync(Carousel = new BeatmapCarousel { AllowSelection = false, // delay any selection until our bindables are ready to make a good choice. @@ -143,6 +140,9 @@ namespace osu.Game.Screens.Select GetRecommendedBeatmap = s => recommender?.GetRecommendedBeatmap(s), }, c => carouselContainer.Child = c); + // initial value transfer is required for FilterControl (it uses our re-cached bindables in its async load for the initial filter). + transferRulesetValue(); + AddRangeInternal(new Drawable[] { new ResetScrollContainer(() => Carousel.ScrollToSelected()) @@ -860,9 +860,6 @@ namespace osu.Game.Screens.Select Logger.Log($"decoupled ruleset transferred (\"{decoupledRuleset.Value}\" -> \"{Ruleset.Value}\")"); rulesetNoDebounce = decoupledRuleset.Value = Ruleset.Value; - // We want to check for null since this method gets called before the loading of the carousel. - if (Carousel.IsNull()) return true; - // if we have a pending filter operation, we want to run it now. // it could change selection (ie. if the ruleset has been changed). Carousel.FlushPendingFilterOperations(); From 08c570849f15c77e2f8fc7ab6800c5db742f5155 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 16 Jan 2023 23:24:47 -0800 Subject: [PATCH 1607/2991] Simplify container logic --- osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs b/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs index 8e0ee896a5..a5e0bddc6b 100644 --- a/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs +++ b/osu.Game/Tests/Visual/OsuManualInputManagerTestScene.cs @@ -46,8 +46,6 @@ namespace osu.Game.Tests.Visual { var mainContent = content = new Container { RelativeSizeAxes = Axes.Both }; - var inputContainer = new Container { RelativeSizeAxes = Axes.Both }; - if (DisplayCursorForManualInput) { var cursorDisplay = new GlobalCursorDisplay { RelativeSizeAxes = Axes.Both }; @@ -57,12 +55,11 @@ namespace osu.Game.Tests.Visual RelativeSizeAxes = Axes.Both, }); - inputContainer.Add(cursorDisplay); - mainContent = inputContainer; + mainContent.Add(cursorDisplay); } if (CreateNestedActionContainer) - inputContainer.Add(new GlobalActionContainer(null)); + mainContent.Add(new GlobalActionContainer(null)); base.Content.AddRange(new Drawable[] { From 8f7cb18217187084ccdecebe9328cbbcc98f3324 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 16 Jan 2023 23:36:28 -0800 Subject: [PATCH 1608/2991] Use `TriggerClick()` instead of calling `BackButton` action for pause gameplay --- osu.Game/Screens/Play/PauseOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/PauseOverlay.cs b/osu.Game/Screens/Play/PauseOverlay.cs index db2b87dae6..dc4c4fdc5a 100644 --- a/osu.Game/Screens/Play/PauseOverlay.cs +++ b/osu.Game/Screens/Play/PauseOverlay.cs @@ -64,7 +64,7 @@ namespace osu.Game.Screens.Play switch (e.Action) { case GlobalAction.PauseGameplay: - BackAction.Invoke(); + InternalButtons.Children.First().TriggerClick(); return true; } From 92fc439f8240d9bf2c384711dafa2c90c402b671 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 16:35:45 +0900 Subject: [PATCH 1609/2991] Add test coverage of carousel sort expectations This covers the fail case of removing and adding items (see https://github.com/ppy/osu/issues/21926) but also covers the proposed forward implementation, which now considers `DateAdded` and `OnlineID`. --- .../SongSelect/TestSceneBeatmapCarousel.cs | 100 +++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index ea9508ecff..e658d87497 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -580,7 +580,44 @@ namespace osu.Game.Tests.Visual.SongSelect /// Ensures stability is maintained on different sort modes for items with equal properties. /// [Test] - public void TestSortingStability() + public void TestSortingStabilityDateAdded() + { + var sets = new List(); + + AddStep("Populuate beatmap sets", () => + { + sets.Clear(); + + for (int i = 0; i < 10; i++) + { + var set = TestResources.CreateTestBeatmapSetInfo(); + + set.DateAdded = DateTimeOffset.FromUnixTimeSeconds(i); + + // only need to set the first as they are a shared reference. + var beatmap = set.Beatmaps.First(); + + beatmap.Metadata.Artist = "a"; + beatmap.Metadata.Title = "b"; + + sets.Add(set); + } + }); + + loadBeatmaps(sets); + + AddStep("Sort by title", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Title }, false)); + AddAssert("Items remain in descending added order", () => carousel.BeatmapSets.Select(s => s.DateAdded), () => Is.Ordered.Descending); + + AddStep("Sort by artist", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Artist }, false)); + AddAssert("Items remain in descending added order", () => carousel.BeatmapSets.Select(s => s.DateAdded), () => Is.Ordered.Descending); + } + + /// + /// Ensures stability is maintained on different sort modes for items with equal properties. + /// + [Test] + public void TestSortingStabilityOnlineID() { var sets = new List(); int idOffset = 0; @@ -599,6 +636,9 @@ namespace osu.Game.Tests.Visual.SongSelect beatmap.Metadata.Artist = $"artist {i / 2}"; beatmap.Metadata.Title = $"title {9 - i}"; + // testing the case where DateAdded happens to equal (quite rare). + set.DateAdded = DateTimeOffset.UnixEpoch; + sets.Add(set); } @@ -617,6 +657,58 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("Items reset to original order", () => carousel.BeatmapSets.Select((set, index) => set.OnlineID == idOffset + index).All(b => b)); } + /// + /// Ensures stability is maintained on different sort modes while a new item is added to the carousel. + /// + [Test] + public void TestSortingStabilityWithRemovedAndReaddedItem() + { + List sets = new List(); + int idOffset = 0; + + AddStep("Populuate beatmap sets", () => + { + sets.Clear(); + + for (int i = 0; i < 3; i++) + { + var set = TestResources.CreateTestBeatmapSetInfo(3); + + // only need to set the first as they are a shared reference. + var beatmap = set.Beatmaps.First(); + + beatmap.Metadata.Artist = "same artist"; + beatmap.Metadata.Title = "same title"; + + // testing the case where DateAdded happens to equal (quite rare). + set.DateAdded = DateTimeOffset.UnixEpoch; + + sets.Add(set); + } + + idOffset = sets.First().OnlineID; + }); + + loadBeatmaps(sets); + + AddStep("Sort by artist", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Artist }, false)); + assertOriginalOrderMaintained(); + + AddStep("Remove item", () => carousel.RemoveBeatmapSet(sets[1])); + AddStep("Re-add item", () => carousel.UpdateBeatmapSet(sets[1])); + + assertOriginalOrderMaintained(); + + AddStep("Sort by title", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Title }, false)); + assertOriginalOrderMaintained(); + + void assertOriginalOrderMaintained() + { + AddAssert("Items remain in original order", + () => carousel.BeatmapSets.Select(s => s.OnlineID), () => Is.EqualTo(carousel.BeatmapSets.Select((set, index) => idOffset + index))); + } + } + /// /// Ensures stability is maintained on different sort modes while a new item is added to the carousel. /// @@ -640,6 +732,9 @@ namespace osu.Game.Tests.Visual.SongSelect beatmap.Metadata.Artist = "same artist"; beatmap.Metadata.Title = "same title"; + // testing the case where DateAdded happens to equal (quite rare). + set.DateAdded = DateTimeOffset.UnixEpoch; + sets.Add(set); } @@ -661,6 +756,9 @@ namespace osu.Game.Tests.Visual.SongSelect beatmap.Metadata.Artist = "same artist"; beatmap.Metadata.Title = "same title"; + // testing the case where DateAdded happens to equal (quite rare). + set.DateAdded = DateTimeOffset.UnixEpoch; + carousel.UpdateBeatmapSet(set); }); From a9ac28b504357becf852dbf863cb121778b5781d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 16:36:47 +0900 Subject: [PATCH 1610/2991] Add fallback sorts to `CarouselBeatmapSet` to ensure stable sorting --- .../Select/Carousel/CarouselBeatmapSet.cs | 55 ++++++++++++++----- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index a360ddabc7..7c919d3586 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -61,50 +61,79 @@ namespace osu.Game.Screens.Select.Carousel if (!(other is CarouselBeatmapSet otherSet)) return base.CompareTo(criteria, other); + int comparison = 0; + switch (criteria.Sort) { default: case SortMode.Artist: - return string.Compare(BeatmapSet.Metadata.Artist, otherSet.BeatmapSet.Metadata.Artist, StringComparison.OrdinalIgnoreCase); + comparison = string.Compare(BeatmapSet.Metadata.Artist, otherSet.BeatmapSet.Metadata.Artist, StringComparison.OrdinalIgnoreCase); + break; case SortMode.Title: - return string.Compare(BeatmapSet.Metadata.Title, otherSet.BeatmapSet.Metadata.Title, StringComparison.OrdinalIgnoreCase); + comparison = string.Compare(BeatmapSet.Metadata.Title, otherSet.BeatmapSet.Metadata.Title, StringComparison.OrdinalIgnoreCase); + break; case SortMode.Author: - return string.Compare(BeatmapSet.Metadata.Author.Username, otherSet.BeatmapSet.Metadata.Author.Username, StringComparison.OrdinalIgnoreCase); + comparison = string.Compare(BeatmapSet.Metadata.Author.Username, otherSet.BeatmapSet.Metadata.Author.Username, StringComparison.OrdinalIgnoreCase); + break; case SortMode.Source: - return string.Compare(BeatmapSet.Metadata.Source, otherSet.BeatmapSet.Metadata.Source, StringComparison.OrdinalIgnoreCase); + comparison = string.Compare(BeatmapSet.Metadata.Source, otherSet.BeatmapSet.Metadata.Source, StringComparison.OrdinalIgnoreCase); + break; case SortMode.DateAdded: - return otherSet.BeatmapSet.DateAdded.CompareTo(BeatmapSet.DateAdded); + comparison = otherSet.BeatmapSet.DateAdded.CompareTo(BeatmapSet.DateAdded); + break; case SortMode.DateRanked: // Beatmaps which have no ranked date should already be filtered away in this mode. if (BeatmapSet.DateRanked == null || otherSet.BeatmapSet.DateRanked == null) - return 0; + break; - return otherSet.BeatmapSet.DateRanked.Value.CompareTo(BeatmapSet.DateRanked.Value); + comparison = otherSet.BeatmapSet.DateRanked.Value.CompareTo(BeatmapSet.DateRanked.Value); + break; case SortMode.LastPlayed: - return -compareUsingAggregateMax(otherSet, b => (b.LastPlayed ?? DateTimeOffset.MinValue).ToUnixTimeSeconds()); + comparison = -compareUsingAggregateMax(otherSet, b => (b.LastPlayed ?? DateTimeOffset.MinValue).ToUnixTimeSeconds()); + break; case SortMode.BPM: - return compareUsingAggregateMax(otherSet, b => b.BPM); + comparison = compareUsingAggregateMax(otherSet, b => b.BPM); + break; case SortMode.Length: - return compareUsingAggregateMax(otherSet, b => b.Length); + comparison = compareUsingAggregateMax(otherSet, b => b.Length); + break; case SortMode.Difficulty: - return compareUsingAggregateMax(otherSet, b => b.StarRating); + comparison = compareUsingAggregateMax(otherSet, b => b.StarRating); + break; case SortMode.DateSubmitted: // Beatmaps which have no submitted date should already be filtered away in this mode. if (BeatmapSet.DateSubmitted == null || otherSet.BeatmapSet.DateSubmitted == null) - return 0; + break; - return otherSet.BeatmapSet.DateSubmitted.Value.CompareTo(BeatmapSet.DateSubmitted.Value); + comparison = otherSet.BeatmapSet.DateSubmitted.Value.CompareTo(BeatmapSet.DateSubmitted.Value); + break; } + + if (comparison != 0) return comparison; + + // If the initial sort could not differentiate, attempt to use DateAdded and OnlineID to order sets in a stable fashion. + // This directionality is a touch arbitrary as while DateAdded puts newer beatmaps first, the OnlineID fallback puts lower IDs first. + // Can potentially be changed in the future if users actually notice / have preference, but keeping it this way matches historical tests. + + comparison = otherSet.BeatmapSet.DateAdded.CompareTo(BeatmapSet.DateAdded); + if (comparison != 0) return comparison; + + comparison = BeatmapSet.OnlineID.CompareTo(otherSet.BeatmapSet.OnlineID); + if (comparison != 0) return comparison; + + // If no online ID is available, fallback to our internal GUID for stability. + // This basically means it's a stable random sort. + return otherSet.BeatmapSet.ID.CompareTo(BeatmapSet.ID); } /// From 23ea77cb74034f2e19071a4758329efc8fad4ba0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 17:03:04 +0900 Subject: [PATCH 1611/2991] Use `ScoreProcessor` to fetch accuracy rather than calculating manually --- .../Rulesets/Mods/ModAccuracyChallenge.cs | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs index 74a9a205a0..732f54e356 100644 --- a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs +++ b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs @@ -5,23 +5,32 @@ using System; using System.Globalization; using System.Linq; using osu.Framework.Bindables; +using osu.Framework.Localisation; using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Judgements; +using osu.Game.Scoring; namespace osu.Game.Rulesets.Mods { - public class ModAccuracyChallenge : ModFailCondition + public class ModAccuracyChallenge : ModFailCondition, IApplicableToScoreProcessor { public override string Name => "Accuracy Challenge"; + public override string Acronym => "AC"; - public override string Description => "Fail the map if you don't maintain a certain accuracy."; + + public override LocalisableString Description => "Fail if your accuracy drops too low!"; + public override ModType Type => ModType.DifficultyIncrease; + public override double ScoreMultiplier => 1.0; + public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(ModEasyWithExtraLives), typeof(ModPerfect) }).ToArray(); + public override bool RequiresConfiguration => false; + public override string SettingDescription => base.SettingDescription.Replace(MinimumAccuracy.ToString(), MinimumAccuracy.Value.ToString("##%", NumberFormatInfo.InvariantInfo)); [SettingSource("Minimum accuracy", "Trigger a failure if your accuracy goes below this value.", SettingControlType = typeof(SettingsSlider))] @@ -34,9 +43,14 @@ namespace osu.Game.Rulesets.Mods Value = 0.9, }; - private double baseScore; - private double maxBaseScore; - private double accuracy => maxBaseScore > 0 ? baseScore / maxBaseScore : 1; + private ScoreProcessor scoreProcessor = null!; + + public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) + { + this.scoreProcessor = scoreProcessor; + } + + public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank; protected override bool FailCondition(HealthProcessor healthProcessor, JudgementResult result) { @@ -44,14 +58,11 @@ namespace osu.Game.Rulesets.Mods if (!result.Type.IsScorable() || result.Type.IsBonus()) return false; - baseScore += result.Type.IsHit() ? result.Judgement.NumericResultFor(result) : 0; - maxBaseScore += result.Judgement.MaxNumericResult; - - return accuracy < MinimumAccuracy.Value; + return scoreProcessor.Accuracy.Value < MinimumAccuracy.Value; } } - public class PercentSlider : OsuSliderBar + public partial class PercentSlider : OsuSliderBar { public PercentSlider() { From da0eb9b0cbe7ef101063085d244102fe7db389b4 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 17 Jan 2023 00:34:52 -0800 Subject: [PATCH 1612/2991] Simplify `TriggerClick`s in gameplay menu overlays --- osu.Game/Screens/Play/GameplayMenuOverlay.cs | 2 +- osu.Game/Screens/Play/PauseOverlay.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/GameplayMenuOverlay.cs b/osu.Game/Screens/Play/GameplayMenuOverlay.cs index 13f32d3b6a..81146a4ea6 100644 --- a/osu.Game/Screens/Play/GameplayMenuOverlay.cs +++ b/osu.Game/Screens/Play/GameplayMenuOverlay.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Play /// /// Action that is invoked when is triggered. /// - protected virtual Action BackAction => () => InternalButtons.Children.LastOrDefault()?.TriggerClick(); + protected virtual Action BackAction => () => InternalButtons.LastOrDefault()?.TriggerClick(); /// /// Action that is invoked when is triggered. diff --git a/osu.Game/Screens/Play/PauseOverlay.cs b/osu.Game/Screens/Play/PauseOverlay.cs index dc4c4fdc5a..d9c60519ad 100644 --- a/osu.Game/Screens/Play/PauseOverlay.cs +++ b/osu.Game/Screens/Play/PauseOverlay.cs @@ -28,7 +28,7 @@ namespace osu.Game.Screens.Play private SkinnableSound pauseLoop; - protected override Action BackAction => () => InternalButtons.Children.First().TriggerClick(); + protected override Action BackAction => () => InternalButtons.First().TriggerClick(); [BackgroundDependencyLoader] private void load(OsuColour colours) @@ -64,7 +64,7 @@ namespace osu.Game.Screens.Play switch (e.Action) { case GlobalAction.PauseGameplay: - InternalButtons.Children.First().TriggerClick(); + InternalButtons.First().TriggerClick(); return true; } From b62b5714e89199159341757688bd5abe01b008ea Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:07:11 +0900 Subject: [PATCH 1613/2991] Fix `TierColours` assignment --- osu.Game/Graphics/UserInterface/SegmentedGraph.cs | 9 +++------ osu.Game/Screens/Play/HUD/ArgonSongProgressGraph.cs | 8 +++++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index 8ccba710b8..dab7ec0559 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -48,17 +48,14 @@ namespace osu.Game.Graphics.UserInterface } } - private Colour4[] tierColours; + private IReadOnlyList tierColours; - public Colour4[] TierColours + public IReadOnlyList TierColours { get => tierColours; set { - if (value.Length == 0 || value == tierColours) - return; - - tierCount = value.Length; + tierCount = value.Count; tierColours = value; graphNeedsUpdate = true; diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgressGraph.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgressGraph.cs index 2c82faf7b2..577d79886c 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgressGraph.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgressGraph.cs @@ -53,10 +53,12 @@ namespace osu.Game.Screens.Play.HUD public ArgonSongProgressGraph() : base(5) { + var colours = new List(); + for (int i = 0; i < 5; i++) - { - TierColours[i] = Colour4.White.Opacity(1 / 5f * 0.85f); - } + colours.Add(Colour4.White.Opacity(1 / 5f * 0.85f)); + + TierColours = colours; } } } From 0a7d6948ca5f6947e5f1f49cf464672bb33c54d3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:16:46 +0900 Subject: [PATCH 1614/2991] Nest model class --- .../HUD/JudgementCounter/JudgementCounter.cs | 4 ++-- .../JudgementCounter/JudgementCounterDisplay.cs | 2 +- .../JudgementCounter/JudgementCounterInfo.cs | 15 --------------- .../Play/HUD/JudgementCounter/JudgementTally.cs | 17 ++++++++++++++--- 4 files changed, 17 insertions(+), 21 deletions(-) delete mode 100644 osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs index ea6e9997e3..635b9220f4 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -18,9 +18,9 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter public BindableBool ShowName = new BindableBool(); public Bindable Direction = new Bindable(); - public readonly JudgementCounterInfo Result; + public readonly JudgementTally.JudgementCount Result; - public JudgementCounter(JudgementCounterInfo result) => Result = result; + public JudgementCounter(JudgementTally.JudgementCount result) => Result = result; public OsuSpriteText ResultName = null!; private FillFlowContainer flowContainer = null!; diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 4e2b2a10cd..7dd28b29b9 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -124,7 +124,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter All } - private JudgementCounter createCounter(JudgementCounterInfo info) + private JudgementCounter createCounter(JudgementTally.JudgementCount info) { JudgementCounter counter = new JudgementCounter(info) { diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs deleted file mode 100644 index 0237981db1..0000000000 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterInfo.cs +++ /dev/null @@ -1,15 +0,0 @@ -// 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.Bindables; -using osu.Game.Rulesets.Scoring; - -namespace osu.Game.Screens.Play.HUD.JudgementCounter -{ - public struct JudgementCounterInfo - { - public HitResult Type { get; set; } - - public BindableInt ResultCount { get; set; } - } -} diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs index d8eac309aa..e9e3fde92a 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementTally.cs @@ -12,19 +12,23 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.HUD.JudgementCounter { + /// + /// Keeps track of judgements for a current play session, exposing bindable counts which can + /// be used for display purposes. + /// public partial class JudgementTally : CompositeDrawable { [Resolved] private ScoreProcessor scoreProcessor { get; set; } = null!; - public List Results = new List(); + public List Results = new List(); [BackgroundDependencyLoader] private void load(IBindable ruleset) { foreach (var result in ruleset.Value.CreateInstance().GetHitResults()) { - Results.Add(new JudgementCounterInfo + Results.Add(new JudgementCount { Type = result.result, ResultCount = new BindableInt() @@ -42,8 +46,15 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter private void updateCount(JudgementResult judgement, bool revert) { - foreach (JudgementCounterInfo result in Results.Where(result => result.Type == judgement.Type)) + foreach (JudgementCount result in Results.Where(result => result.Type == judgement.Type)) result.ResultCount.Value = revert ? result.ResultCount.Value - 1 : result.ResultCount.Value + 1; } + + public struct JudgementCount + { + public HitResult Type { get; set; } + + public BindableInt ResultCount { get; set; } + } } } From f923dc500937e4628c26a1917db63db296fe239d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:21:30 +0900 Subject: [PATCH 1615/2991] Use framework `Direction` instead of local enum It should be stable enough to use. --- .../Gameplay/TestSceneJudgementCounter.cs | 4 +-- .../JudgementCounterDisplay.cs | 35 ++++++++----------- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index a8d9f203ae..abd66d85ae 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -94,8 +94,8 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestChangeFlowDirection() { - AddStep("Set direction vertical", () => counterDisplay.FlowDirection.Value = JudgementCounterDisplay.Flow.Vertical); - AddStep("Set direction horizontal", () => counterDisplay.FlowDirection.Value = JudgementCounterDisplay.Flow.Horizontal); + AddStep("Set direction vertical", () => counterDisplay.FlowDirection.Value = Direction.Vertical); + AddStep("Set direction horizontal", () => counterDisplay.FlowDirection.Value = Direction.Horizontal); } [Test] diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 7dd28b29b9..6aa956943b 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -23,7 +23,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter public Bindable Mode { get; set; } = new Bindable(); [SettingSource("Counter direction")] - public Bindable FlowDirection { get; set; } = new Bindable(); + public Bindable FlowDirection { get; set; } = new Bindable(); [SettingSource("Show judgement names")] public BindableBool ShowName { get; set; } = new BindableBool(true); @@ -42,7 +42,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter AutoSizeAxes = Axes.Both; InternalChild = JudgementContainer = new FillFlowContainer { - Direction = getFlow(FlowDirection.Value), + Direction = getFillDirection(FlowDirection.Value), Spacing = new Vector2(10), AutoSizeAxes = Axes.Both }; @@ -57,11 +57,11 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter FlowDirection.BindValueChanged(direction => { - JudgementContainer.Direction = getFlow(direction.NewValue); + JudgementContainer.Direction = getFillDirection(direction.NewValue); //Can't pass directly due to Enum conversion foreach (var counter in JudgementContainer.Children.OfType()) - counter.Direction.Value = getFlow(direction.NewValue); + counter.Direction.Value = getFillDirection(direction.NewValue); }, true); Mode.BindValueChanged(_ => updateMode(), true); ShowMax.BindValueChanged(value => @@ -95,14 +95,14 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter } } - private FillDirection getFlow(Flow flow) + private FillDirection getFillDirection(Direction flow) { switch (flow) { - case Flow.Horizontal: + case Direction.Horizontal: return FillDirection.Horizontal; - case Flow.Vertical: + case Direction.Vertical: return FillDirection.Vertical; default: @@ -110,20 +110,6 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter } } - //Used to hide default full option in FillDirection - public enum Flow - { - Horizontal, - Vertical - } - - public enum DisplayMode - { - Simple, - Normal, - All - } - private JudgementCounter createCounter(JudgementTally.JudgementCount info) { JudgementCounter counter = new JudgementCounter(info) @@ -133,5 +119,12 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter }; return counter; } + + public enum DisplayMode + { + Simple, + Normal, + All + } } } From 09c7ab3af628d71e9f860cea3dddd1fa281ca3d6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:24:55 +0900 Subject: [PATCH 1616/2991] Rename exposed settings to make more sense --- .../Visual/Gameplay/TestSceneJudgementCounter.cs | 8 ++++---- .../Play/HUD/JudgementCounter/JudgementCounterDisplay.cs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index abd66d85ae..f387f1e055 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -101,10 +101,10 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestToggleJudgementNames() { - AddStep("Hide judgement names", () => counterDisplay.ShowName.Value = false); + AddStep("Hide judgement names", () => counterDisplay.ShowJudgementNames.Value = false); AddWaitStep("wait some", 2); AddAssert("Assert hidden", () => counterDisplay.JudgementContainer.Children.OfType().First().ResultName.Alpha == 0); - AddStep("Hide judgement names", () => counterDisplay.ShowName.Value = true); + AddStep("Hide judgement names", () => counterDisplay.ShowJudgementNames.Value = true); AddWaitStep("wait some", 2); AddAssert("Assert shown", () => counterDisplay.JudgementContainer.Children.OfType().First().ResultName.Alpha == 1); } @@ -112,10 +112,10 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestHideMaxValue() { - AddStep("Hide max judgement", () => counterDisplay.ShowMax.Value = false); + AddStep("Hide max judgement", () => counterDisplay.ShowMaxJudgement.Value = false); AddWaitStep("wait some", 2); AddAssert("Check max hidden", () => counterDisplay.JudgementContainer.ChildrenOfType().First().Alpha == 0); - AddStep("Show max judgement", () => counterDisplay.ShowMax.Value = true); + AddStep("Show max judgement", () => counterDisplay.ShowMaxJudgement.Value = true); } [Test] diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 6aa956943b..f4a732e68e 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -26,10 +26,10 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter public Bindable FlowDirection { get; set; } = new Bindable(); [SettingSource("Show judgement names")] - public BindableBool ShowName { get; set; } = new BindableBool(true); + public BindableBool ShowJudgementNames { get; set; } = new BindableBool(true); [SettingSource("Show max judgement")] - public BindableBool ShowMax { get; set; } = new BindableBool(true); + public BindableBool ShowMaxJudgement { get; set; } = new BindableBool(true); [Resolved] private JudgementTally tally { get; set; } = null!; @@ -64,7 +64,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter counter.Direction.Value = getFillDirection(direction.NewValue); }, true); Mode.BindValueChanged(_ => updateMode(), true); - ShowMax.BindValueChanged(value => + ShowMaxJudgement.BindValueChanged(value => { var firstChild = JudgementContainer.Children.FirstOrDefault(); firstChild.FadeTo(value.NewValue ? 1 : 0, TRANSFORM_DURATION, Easing.OutQuint); @@ -115,7 +115,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter JudgementCounter counter = new JudgementCounter(info) { State = { Value = Visibility.Visible }, - ShowName = { BindTarget = ShowName } + ShowName = { BindTarget = ShowJudgementNames } }; return counter; } From 35ad66eef94e6a9ec9202b29772e4643e1bf895a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:27:33 +0900 Subject: [PATCH 1617/2991] Give flow container a type to avoid locally casting in every location --- .../Visual/Gameplay/TestSceneJudgementCounter.cs | 8 ++++---- .../JudgementCounter/JudgementCounterDisplay.cs | 15 ++++++--------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index f387f1e055..0a501c55c7 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -103,10 +103,10 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("Hide judgement names", () => counterDisplay.ShowJudgementNames.Value = false); AddWaitStep("wait some", 2); - AddAssert("Assert hidden", () => counterDisplay.JudgementContainer.Children.OfType().First().ResultName.Alpha == 0); + AddAssert("Assert hidden", () => counterDisplay.JudgementContainer.Children.First().ResultName.Alpha == 0); AddStep("Hide judgement names", () => counterDisplay.ShowJudgementNames.Value = true); AddWaitStep("wait some", 2); - AddAssert("Assert shown", () => counterDisplay.JudgementContainer.Children.OfType().First().ResultName.Alpha == 1); + AddAssert("Assert shown", () => counterDisplay.JudgementContainer.Children.First().ResultName.Alpha == 1); } [Test] @@ -132,13 +132,13 @@ namespace osu.Game.Tests.Visual.Gameplay private int hiddenCount() { - var num = counterDisplay.JudgementContainer.Children.OfType().First(child => child.Result.Type == HitResult.LargeTickHit); + var num = counterDisplay.JudgementContainer.Children.First(child => child.Result.Type == HitResult.LargeTickHit); return num.Result.ResultCount.Value; } private partial class TestJudgementCounterDisplay : JudgementCounterDisplay { - public new FillFlowContainer JudgementContainer => base.JudgementContainer; + public new FillFlowContainer JudgementContainer => base.JudgementContainer; } } } diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index f4a732e68e..d3efbc9871 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -34,13 +34,13 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter [Resolved] private JudgementTally tally { get; set; } = null!; - protected FillFlowContainer JudgementContainer = null!; + protected FillFlowContainer JudgementContainer = null!; [BackgroundDependencyLoader] private void load() { AutoSizeAxes = Axes.Both; - InternalChild = JudgementContainer = new FillFlowContainer + InternalChild = JudgementContainer = new FillFlowContainer { Direction = getFillDirection(FlowDirection.Value), Spacing = new Vector2(10), @@ -60,7 +60,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter JudgementContainer.Direction = getFillDirection(direction.NewValue); //Can't pass directly due to Enum conversion - foreach (var counter in JudgementContainer.Children.OfType()) + foreach (var counter in JudgementContainer.Children) counter.Direction.Value = getFillDirection(direction.NewValue); }, true); Mode.BindValueChanged(_ => updateMode(), true); @@ -73,7 +73,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter private void updateMode() { - foreach (var counter in JudgementContainer.Children.OfType().Where(counter => !counter.Result.Type.IsBasic())) + foreach (var counter in JudgementContainer.Children.Where(counter => !counter.Result.Type.IsBasic())) { switch (Mode.Value) { @@ -110,15 +110,12 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter } } - private JudgementCounter createCounter(JudgementTally.JudgementCount info) - { - JudgementCounter counter = new JudgementCounter(info) + private JudgementCounter createCounter(JudgementTally.JudgementCount info) => + new JudgementCounter(info) { State = { Value = Visibility.Visible }, ShowName = { BindTarget = ShowJudgementNames } }; - return counter; - } public enum DisplayMode { From 181473c5fc9c9c0d784d4ad834ec82a3d242eaca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:28:08 +0900 Subject: [PATCH 1618/2991] Rename flow to better match its purpose --- .../Visual/Gameplay/TestSceneJudgementCounter.cs | 14 +++++++------- .../JudgementCounter/JudgementCounterDisplay.cs | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index 0a501c55c7..d104e25df0 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -103,10 +103,10 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("Hide judgement names", () => counterDisplay.ShowJudgementNames.Value = false); AddWaitStep("wait some", 2); - AddAssert("Assert hidden", () => counterDisplay.JudgementContainer.Children.First().ResultName.Alpha == 0); + AddAssert("Assert hidden", () => counterDisplay.CounterFlow.Children.First().ResultName.Alpha == 0); AddStep("Hide judgement names", () => counterDisplay.ShowJudgementNames.Value = true); AddWaitStep("wait some", 2); - AddAssert("Assert shown", () => counterDisplay.JudgementContainer.Children.First().ResultName.Alpha == 1); + AddAssert("Assert shown", () => counterDisplay.CounterFlow.Children.First().ResultName.Alpha == 1); } [Test] @@ -114,7 +114,7 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("Hide max judgement", () => counterDisplay.ShowMaxJudgement.Value = false); AddWaitStep("wait some", 2); - AddAssert("Check max hidden", () => counterDisplay.JudgementContainer.ChildrenOfType().First().Alpha == 0); + AddAssert("Check max hidden", () => counterDisplay.CounterFlow.ChildrenOfType().First().Alpha == 0); AddStep("Show max judgement", () => counterDisplay.ShowMaxJudgement.Value = true); } @@ -123,22 +123,22 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("Show basic judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.Simple); AddWaitStep("wait some", 2); - AddAssert("Check only basic", () => counterDisplay.JudgementContainer.ChildrenOfType().Last().Alpha == 0); + AddAssert("Check only basic", () => counterDisplay.CounterFlow.ChildrenOfType().Last().Alpha == 0); AddStep("Show normal judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.Normal); AddStep("Show all judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.All); AddWaitStep("wait some", 2); - AddAssert("Check all visible", () => counterDisplay.JudgementContainer.ChildrenOfType().Last().Alpha == 1); + AddAssert("Check all visible", () => counterDisplay.CounterFlow.ChildrenOfType().Last().Alpha == 1); } private int hiddenCount() { - var num = counterDisplay.JudgementContainer.Children.First(child => child.Result.Type == HitResult.LargeTickHit); + var num = counterDisplay.CounterFlow.Children.First(child => child.Result.Type == HitResult.LargeTickHit); return num.Result.ResultCount.Value; } private partial class TestJudgementCounterDisplay : JudgementCounterDisplay { - public new FillFlowContainer JudgementContainer => base.JudgementContainer; + public new FillFlowContainer CounterFlow => base.CounterFlow; } } } diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index d3efbc9871..a29335ff50 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -34,13 +34,13 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter [Resolved] private JudgementTally tally { get; set; } = null!; - protected FillFlowContainer JudgementContainer = null!; + protected FillFlowContainer CounterFlow = null!; [BackgroundDependencyLoader] private void load() { AutoSizeAxes = Axes.Both; - InternalChild = JudgementContainer = new FillFlowContainer + InternalChild = CounterFlow = new FillFlowContainer { Direction = getFillDirection(FlowDirection.Value), Spacing = new Vector2(10), @@ -48,7 +48,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter }; foreach (var result in tally.Results) - JudgementContainer.Add(createCounter(result)); + CounterFlow.Add(createCounter(result)); } protected override void LoadComplete() @@ -57,23 +57,23 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter FlowDirection.BindValueChanged(direction => { - JudgementContainer.Direction = getFillDirection(direction.NewValue); + CounterFlow.Direction = getFillDirection(direction.NewValue); //Can't pass directly due to Enum conversion - foreach (var counter in JudgementContainer.Children) + foreach (var counter in CounterFlow.Children) counter.Direction.Value = getFillDirection(direction.NewValue); }, true); Mode.BindValueChanged(_ => updateMode(), true); ShowMaxJudgement.BindValueChanged(value => { - var firstChild = JudgementContainer.Children.FirstOrDefault(); + var firstChild = CounterFlow.Children.FirstOrDefault(); firstChild.FadeTo(value.NewValue ? 1 : 0, TRANSFORM_DURATION, Easing.OutQuint); }, true); } private void updateMode() { - foreach (var counter in JudgementContainer.Children.Where(counter => !counter.Result.Type.IsBasic())) + foreach (var counter in CounterFlow.Children.Where(counter => !counter.Result.Type.IsBasic())) { switch (Mode.Value) { From ca1799376952d97a77e97ce0ca88cd31bbdd2beb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:30:50 +0900 Subject: [PATCH 1619/2991] Don't use `OverlayContainer` (what) --- osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs index 635b9220f4..0630b73376 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -13,7 +13,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Screens.Play.HUD.JudgementCounter { - public partial class JudgementCounter : OverlayContainer + public partial class JudgementCounter : VisibilityContainer { public BindableBool ShowName = new BindableBool(); public Bindable Direction = new Bindable(); @@ -30,6 +30,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter private void load(OsuColour colours, IBindable ruleset) { AutoSizeAxes = Axes.Both; + InternalChild = flowContainer = new FillFlowContainer { AutoSizeAxes = Axes.Both, From 448abf897a5824c115d0071a2f15f876e48572a6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:31:08 +0900 Subject: [PATCH 1620/2991] Tidy up direction assignment --- .../Play/HUD/JudgementCounter/JudgementCounterDisplay.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index a29335ff50..0899870005 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -57,13 +57,16 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter FlowDirection.BindValueChanged(direction => { - CounterFlow.Direction = getFillDirection(direction.NewValue); + var convertedDirection = getFillDirection(direction.NewValue); + + CounterFlow.Direction = convertedDirection; - //Can't pass directly due to Enum conversion foreach (var counter in CounterFlow.Children) - counter.Direction.Value = getFillDirection(direction.NewValue); + counter.Direction.Value = convertedDirection; }, true); + Mode.BindValueChanged(_ => updateMode(), true); + ShowMaxJudgement.BindValueChanged(value => { var firstChild = CounterFlow.Children.FirstOrDefault(); From 7d1fd24ab4e8387703829fd67ca187bc0a61f374 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:31:25 +0900 Subject: [PATCH 1621/2991] Start all counters hidden to fix pop out animation when some portions are hidden --- .../HUD/JudgementCounter/JudgementCounterDisplay.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 0899870005..a9a3ca2cf6 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -76,8 +76,14 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter private void updateMode() { - foreach (var counter in CounterFlow.Children.Where(counter => !counter.Result.Type.IsBasic())) + foreach (var counter in CounterFlow.Children) { + if (counter.Result.Type.IsBasic()) + { + counter.Show(); + continue; + } + switch (Mode.Value) { case DisplayMode.Simple: @@ -116,7 +122,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter private JudgementCounter createCounter(JudgementTally.JudgementCount info) => new JudgementCounter(info) { - State = { Value = Visibility.Visible }, + State = { Value = Visibility.Hidden }, ShowName = { BindTarget = ShowJudgementNames } }; From 48959c0212ddbbdf8e0fd98a2ba879efbb1d9eef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:35:19 +0900 Subject: [PATCH 1622/2991] Start name not visible to avoid pop out when hidden on startup --- osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs index 0630b73376..7675d0cc4f 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounter.cs @@ -42,6 +42,7 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter }, ResultName = new OsuSpriteText { + Alpha = 0, Font = OsuFont.Numeric.With(size: 8), Text = ruleset.Value.CreateInstance().GetDisplayNameForHitResult(Result.Type) } From 81aa7feeb5299d18d6cb02e47cce53c0b6c7e45d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:35:30 +0900 Subject: [PATCH 1623/2991] Fix using `FadeTo` on a visibility container --- .../JudgementCounterDisplay.cs | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index a9a3ca2cf6..1d82fa5397 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -78,25 +78,27 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { foreach (var counter in CounterFlow.Children) { - if (counter.Result.Type.IsBasic()) - { + if (shouldShow(counter)) counter.Show(); - continue; - } + else + counter.Hide(); + } + + bool shouldShow(JudgementCounter counter) + { + if (counter.Result.Type.IsBasic()) + return true; switch (Mode.Value) { case DisplayMode.Simple: - counter.Hide(); - break; + return false; case DisplayMode.Normal: - counter.FadeTo(counter.Result.Type.IsBonus() ? 0 : 1); - break; + return !counter.Result.Type.IsBonus(); case DisplayMode.All: - counter.Show(); - break; + return true; default: throw new ArgumentOutOfRangeException(); From 14649160e15f4bfd7c3bef56d26126efc7b8fd5a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:38:29 +0900 Subject: [PATCH 1624/2991] Adjust transform delay to make things feel more snappy --- .../Play/HUD/JudgementCounter/JudgementCounterDisplay.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 1d82fa5397..4ec90edeb0 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -16,7 +16,8 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter { public partial class JudgementCounterDisplay : CompositeDrawable, ISkinnableDrawable { - public const int TRANSFORM_DURATION = 500; + public const int TRANSFORM_DURATION = 250; + public bool UsesFixedAnchor { get; set; } [SettingSource("Display mode")] From 26cd70f2bfde476c3fe08df4ef363b6bfc10512b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:44:42 +0900 Subject: [PATCH 1625/2991] Always use production (non-experimental) endpoints for tournament client --- osu.Game.Tournament/TournamentGameBase.cs | 9 +++++++++ .../ExperimentalEndpointConfiguration.cs | 19 +++++++++++++++++++ .../Online/ProductionEndpointConfiguration.cs | 5 +---- osu.Game/OsuGameBase.cs | 4 ++-- 4 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 osu.Game/Online/ExperimentalEndpointConfiguration.cs diff --git a/osu.Game.Tournament/TournamentGameBase.cs b/osu.Game.Tournament/TournamentGameBase.cs index 08f21cb556..c61ee0d3e8 100644 --- a/osu.Game.Tournament/TournamentGameBase.cs +++ b/osu.Game.Tournament/TournamentGameBase.cs @@ -16,6 +16,7 @@ using osu.Framework.IO.Stores; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Graphics; +using osu.Game.Online; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Tournament.IO; @@ -44,6 +45,14 @@ namespace osu.Game.Tournament return dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); } + public override EndpointConfiguration CreateEndpoints() + { + if (UseDevelopmentServer) + return base.CreateEndpoints(); + + return new ProductionEndpointConfiguration(); + } + private TournamentSpriteText initialisationText; [BackgroundDependencyLoader] diff --git a/osu.Game/Online/ExperimentalEndpointConfiguration.cs b/osu.Game/Online/ExperimentalEndpointConfiguration.cs new file mode 100644 index 0000000000..c3d0014c8b --- /dev/null +++ b/osu.Game/Online/ExperimentalEndpointConfiguration.cs @@ -0,0 +1,19 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Online +{ + public class ExperimentalEndpointConfiguration : EndpointConfiguration + { + public ExperimentalEndpointConfiguration() + { + WebsiteRootUrl = @"https://osu.ppy.sh"; + APIEndpointUrl = @"https://lazer.ppy.sh"; + APIClientSecret = @"FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk"; + APIClientID = "5"; + SpectatorEndpointUrl = "https://spectator.ppy.sh/spectator"; + MultiplayerEndpointUrl = "https://spectator.ppy.sh/multiplayer"; + MetadataEndpointUrl = "https://spectator.ppy.sh/metadata"; + } + } +} diff --git a/osu.Game/Online/ProductionEndpointConfiguration.cs b/osu.Game/Online/ProductionEndpointConfiguration.cs index 003ec50afd..0244761b65 100644 --- a/osu.Game/Online/ProductionEndpointConfiguration.cs +++ b/osu.Game/Online/ProductionEndpointConfiguration.cs @@ -1,16 +1,13 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Online { public class ProductionEndpointConfiguration : EndpointConfiguration { public ProductionEndpointConfiguration() { - WebsiteRootUrl = @"https://osu.ppy.sh"; - APIEndpointUrl = @"https://lazer.ppy.sh"; + WebsiteRootUrl = APIEndpointUrl = @"https://osu.ppy.sh"; APIClientSecret = @"FGc9GAtyHzeQDshWP5Ah7dega8hJACAJpQtw6OXk"; APIClientID = "5"; SpectatorEndpointUrl = "https://spectator.ppy.sh/spectator"; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index b27be37591..1c50349941 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -98,8 +98,8 @@ namespace osu.Game public virtual bool UseDevelopmentServer => DebugUtils.IsDebugBuild; - internal EndpointConfiguration CreateEndpoints() => - UseDevelopmentServer ? new DevelopmentEndpointConfiguration() : new ProductionEndpointConfiguration(); + public virtual EndpointConfiguration CreateEndpoints() => + UseDevelopmentServer ? new DevelopmentEndpointConfiguration() : new ExperimentalEndpointConfiguration(); public virtual Version AssemblyVersion => Assembly.GetEntryAssembly()?.GetName().Version ?? new Version(); From 68636aeaaa339d9a2dc82402d46d68bbb6004b90 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:56:15 +0900 Subject: [PATCH 1626/2991] Fix tournament client not saving changes after populating new data --- osu.Game.Tournament/TournamentGameBase.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tournament/TournamentGameBase.cs b/osu.Game.Tournament/TournamentGameBase.cs index 08f21cb556..e4fe922a51 100644 --- a/osu.Game.Tournament/TournamentGameBase.cs +++ b/osu.Game.Tournament/TournamentGameBase.cs @@ -156,7 +156,7 @@ namespace osu.Game.Tournament addedInfo |= addSeedingBeatmaps(); if (addedInfo) - SaveChanges(); + saveChanges(); ladder.CurrentMatch.Value = ladder.Matches.FirstOrDefault(p => p.Current.Value); } @@ -306,6 +306,11 @@ namespace osu.Game.Tournament return; } + saveChanges(); + } + + private void saveChanges() + { foreach (var r in ladder.Rounds) r.Matches = ladder.Matches.Where(p => p.Round.Value == r).Select(p => p.ID).ToList(); From 74bb44e05d668b70a53d08d1d1289e9ae9084cdd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 18:59:43 +0900 Subject: [PATCH 1627/2991] Fix player rank data not being re-fetched after a tournament's ruleset is changed --- osu.Game.Tournament/Screens/Setup/SetupScreen.cs | 2 +- osu.Game.Tournament/TournamentGameBase.cs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tournament/Screens/Setup/SetupScreen.cs b/osu.Game.Tournament/Screens/Setup/SetupScreen.cs index b86513eb49..ceddd4d1a1 100644 --- a/osu.Game.Tournament/Screens/Setup/SetupScreen.cs +++ b/osu.Game.Tournament/Screens/Setup/SetupScreen.cs @@ -113,7 +113,7 @@ namespace osu.Game.Tournament.Screens.Setup new LabelledDropdown { Label = "Ruleset", - Description = "Decides what stats are displayed and which ranks are retrieved for players.", + Description = "Decides what stats are displayed and which ranks are retrieved for players. This requires a restart to reload data for an existing bracket.", Items = rulesets.AvailableRulesets, Current = LadderInfo.Ruleset, }, diff --git a/osu.Game.Tournament/TournamentGameBase.cs b/osu.Game.Tournament/TournamentGameBase.cs index 08f21cb556..ed766c69df 100644 --- a/osu.Game.Tournament/TournamentGameBase.cs +++ b/osu.Game.Tournament/TournamentGameBase.cs @@ -159,6 +159,18 @@ namespace osu.Game.Tournament SaveChanges(); ladder.CurrentMatch.Value = ladder.Matches.FirstOrDefault(p => p.Current.Value); + + ladder.Ruleset.BindValueChanged(r => + { + // Refetch player rank data on next startup as the ruleset has changed. + foreach (var team in ladder.Teams) + { + foreach (var player in team.Players) + player.Rank = null; + } + + SaveChanges(); + }); } catch (Exception e) { From 00996c9f470ab5007da1e753f41c79be858ae95f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 19:11:22 +0900 Subject: [PATCH 1628/2991] Remove unnecessary touch interception from `OsuInputManager` --- osu.Game.Rulesets.Osu/OsuInputManager.cs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index 6f69fbef43..d5eae4b391 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -60,19 +60,6 @@ namespace osu.Game.Rulesets.Osu return base.Handle(e); } - protected override bool HandleMouseTouchStateChange(TouchStateChangeEvent e) - { - if (!AllowUserCursorMovement) - { - // Still allow for forwarding of the "touch" part, but replace the positional data with that of the mouse. - // Primarily relied upon by the "autopilot" osu! mod. - var touch = new Touch(e.Touch.Source, CurrentState.Mouse.Position); - e = new TouchStateChangeEvent(e.State, e.Input, touch, e.IsActive, null); - } - - return base.HandleMouseTouchStateChange(e); - } - private partial class OsuKeyBindingContainer : RulesetKeyBindingContainer { private bool allowGameplayInputs = true; From 905dec913a716ae4272b8d780dad2a851446c736 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Tue, 17 Jan 2023 12:37:30 +0100 Subject: [PATCH 1629/2991] update skin deserialisation --- .../Archives/modified-default-20230111.osk | Bin 1685 -> 0 bytes .../Archives/modified-default-20230117.osk | Bin 0 -> 1686 bytes osu.Game.Tests/Skins/SkinDeserialisationTest.cs | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 osu.Game.Tests/Resources/Archives/modified-default-20230111.osk create mode 100644 osu.Game.Tests/Resources/Archives/modified-default-20230117.osk diff --git a/osu.Game.Tests/Resources/Archives/modified-default-20230111.osk b/osu.Game.Tests/Resources/Archives/modified-default-20230111.osk deleted file mode 100644 index 53dda9744edacb6fa6bb4f1ec5a5dbb3e2fe9317..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1685 zcmWIWW@Zs#U|`^2SRJVyrrnWvYTm-%#pVHcC5fa_;F*O{6x z&iOPeq`A$`-6GxTn0YlLx%}#-;Ij{In%z*YWEC|uF%Uk>b?^D-c-jB|R&(tu=UIDf zMePLLoRFTQ3y$+`n4z|1!$ArD1{a?Vb`52z3?ZLX1r%tg$H=jzfa z7S2h|PKWuo|4Dh+Q}}e>xz3+kGcqg}Fztl?Zxw18LVI4+{A1kKV5c;=7MF3n>IETePff23O=ZN{8+^D>6)fq8mdt@@0rgK z3CcB6{Z=ozI((yE#N3*QyX#CQ)nC~DUQ^ANv((Ao*7E=6=f}?r*U3%f$b2yUPfBjq z3Ffdp_fVaFRMl)UHxmQHD?tVZF`(0Z6EpKXLS3Bma|`nGQu9iR!G3r<{e1py1(DFpBiq9J&s4Mh+D)-^lICapXoQ^Pgx5T2Tpx@#kS)7 zl4r-xZPT_`b3BWG+rvQqpAyNhw!ONyO2y&F#=o0q{_~Z(=CeLl{z&LKFAKvPW#-HF z%v)+aF@NbQ>qTxqS5+L$KJBR-lX*e@2lJZ#Wb-vwE>y85@6afDyTf!=UggfP0O_6k zW}2M)H|4k1bgs5XebqBKfxr~T)e zZ0(N2JESMieBNrNWhlAN;_qz7nRou6rTj*z`V-ZR3=9u|nVcV(e1h}y(t}fTQj<%- z>E>u~Y&J0M*M1LAseR{k>&xjzey!Vb$7Y<#(|_c=w%lxn+EPzP!T-O5a?Q1x4b3GL z`M;}JJ}>fnx2FBVxtx|Y710f)%{nW!YUV#_Se~uMBCKsQtx}PdW9*{uQF#K90v|~&1wXM$+UkS~>U~F7)>v7wKEAi6r zC)pS53%zt~$E~{&VVP|uY#OPlryOG=WxvL&f6>1zG)rHmC9phV5rg%!_0{RmTsFLC z&y%RQcXETw!w*f5KS@T#eQ=TYx!?n|z!vYdvU?|Sc%+t%v%X~V)u#3r2!1c48>rBlT z=X{zK(%fd}ZjtVE%)FYBTz>UZ@Yx49&2A`HvWgm-7zm%`y7&BZyzKvftGV`-^Q=9# zqIQCAPDszu1;_a|%uw61;h+S6gNx4wyN0qMv}6uc_wCS?c6(Yx#fk^W*1*>*OYKWImYwCnY!Q z1asJ)d#FzLYu|i=hlzpVxgZ0B7|`jyiJ5sGp)St(xdr)osd**EU_ZQ_em?uQfynXq zKec_%t(&0x^SVO&wVPtwrp{b;cj=b}R{DJ_ltn$;W^MdmTa?WH=*@+xSM}Z+*uBtx zY5TF#|I+2JM+)n1-7j1={j05yy+!a!?JqNP8FhXEa_WoNh#V>6rt9o3eu2&p(XyUqa1o!aOL{>?$fMGb0-u&)Nh!YX8iouy)vG8 zADEw1UsAXG#;EK%Q8QBG!Y|!VY7Yau+LZ<43qA*Gt~_^8PFrfOVd;WBuD|5oUB0jV z|E2x(e`P7HjY=dQp%b zA$a*hy}R{e9cy`=-@@`2TaG+22xRU_n*T$e?=OG&!H5g{Lsm0wQ}F5j=OMA`&-XtZ zN9Tzj**iVFLrI@&(saI)7lR+fyQLI;mPSoKjZ*a|su>v=9sqMWKQR3S=jWvdr{<(4 zmw*$_(csu@VB)X+9-dPB&gs^d(~bOEx8;t_IFqOU$a!tK*$lO%o{ob5e+T87Yc(61 zODghzSFwCv$A=PmZ!`aq|)Ay?DZ22cO$|w+e+9pQd3Vk#zxA1jaUDoe_3djzD!GCdBh?H>u2k$)1SF) zc+Z|EQE~6&2APK+njU|WjEei^&G`@!Ff){k?TG5LZgw|!i1cSYxK{o?Ec_GYr#*C5J0=!w-KnhrZ L@Dq^kV+HX5+q}g^ literal 0 HcmV?d00001 diff --git a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs index f7744cb9c6..5c4f59ba2c 100644 --- a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs +++ b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs @@ -46,7 +46,7 @@ namespace osu.Game.Tests.Skins // Covers BPM counter. "Archives/modified-default-20221205.osk", // Covers judgement counter. - "Archives/modified-default-20230111.osk" + "Archives/modified-default-20230117.osk" }; /// From e65108533ab3f42a0d6a6fdfc0926d2cf02f96a0 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Tue, 17 Jan 2023 22:12:06 +0900 Subject: [PATCH 1630/2991] Reduce number of tested value combination 121 combinations took 2min+ --- .../TestSceneSliderFollowCircleInput.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs index 0af0ff5604..369c3d6168 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs @@ -31,9 +31,9 @@ namespace osu.Game.Rulesets.Osu.Tests [Test] public void TestMaximumDistanceTrackingWithoutMovement( - [Values(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)] + [Values(0, 5, 10)] float circleSize, - [Values(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)] + [Values(0, 5, 10)] double velocity) { const double time_slider_start = 1000; From 66441d4421ac3a1a6cf4a4748424aa72bf3558af Mon Sep 17 00:00:00 2001 From: tsrk Date: Tue, 17 Jan 2023 13:16:11 +0000 Subject: [PATCH 1631/2991] test: remove test for ArgonSongProgressGraph --- .../TestSceneArgonSongProgressGraph.cs | 69 ------------------- 1 file changed, 69 deletions(-) delete mode 100644 osu.Game.Tests/Visual/Gameplay/TestSceneArgonSongProgressGraph.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneArgonSongProgressGraph.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneArgonSongProgressGraph.cs deleted file mode 100644 index e7feadc72b..0000000000 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneArgonSongProgressGraph.cs +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Collections.Generic; -using System.Diagnostics; -using NUnit.Framework; -using osu.Framework.Graphics; -using osu.Framework.Testing; -using osu.Framework.Utils; -using osu.Game.Rulesets.Objects; -using osu.Game.Screens.Play.HUD; - -namespace osu.Game.Tests.Visual.Gameplay -{ - [TestFixture] - public partial class TestSceneArgonSongProgressGraph : OsuTestScene - { - private TestArgonSongProgressGraph? graph; - - [SetUpSteps] - public void SetupSteps() - { - AddStep("add new big graph", () => - { - if (graph != null) - { - graph.Expire(); - graph = null; - } - - Add(graph = new TestArgonSongProgressGraph - { - RelativeSizeAxes = Axes.X, - Height = 200, - Anchor = Anchor.TopLeft, - Origin = Anchor.TopLeft, - }); - }); - } - - [Test] - public void Test() - { - AddAssert("ensure not created", () => graph!.CreationCount == 0); - AddStep("display values", displayRandomValues); - } - - private void displayRandomValues() - { - Debug.Assert(graph != null); - var objects = new List(); - for (double i = 0; i < 5000; i += RNG.NextDouble() * 10 + i / 1000) - objects.Add(new HitObject { StartTime = i }); - - graph.Objects = objects; - } - - private partial class TestArgonSongProgressGraph : ArgonSongProgressGraph - { - public int CreationCount { get; private set; } - - protected override void RecreateGraph() - { - base.RecreateGraph(); - CreationCount++; - } - } - } -} From d91aa341e511285d00e682ea8781ac31a1dfc16b Mon Sep 17 00:00:00 2001 From: tsrk Date: Tue, 17 Jan 2023 13:16:47 +0000 Subject: [PATCH 1632/2991] refactor(ArgonSongProgress): reorder layering and make density graph visible for past time --- .../Screens/Play/HUD/ArgonSongProgress.cs | 29 +++++++++++++------ .../Screens/Play/HUD/ArgonSongProgressBar.cs | 19 ++++++++++-- .../Play/HUD/ArgonSongProgressGraph.cs | 4 +-- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs index e5ee42e72a..8446abecd2 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Timing; using osu.Game.Configuration; using osu.Game.Graphics; @@ -18,6 +19,7 @@ namespace osu.Game.Screens.Play.HUD private readonly SongProgressInfo info; private readonly ArgonSongProgressGraph graph; private readonly ArgonSongProgressBar bar; + private readonly Container graphContainer; private const float bar_height = 10; @@ -38,6 +40,8 @@ namespace osu.Game.Screens.Play.HUD { Anchor = Anchor.BottomCentre; Origin = Anchor.BottomCentre; + Masking = true; + CornerRadius = 5; Children = new Drawable[] { info = new SongProgressInfo @@ -48,20 +52,27 @@ namespace osu.Game.Screens.Play.HUD RelativeSizeAxes = Axes.X, ShowProgress = false }, - graph = new ArgonSongProgressGraph - { - Name = "Difficulty graph", - Origin = Anchor.BottomLeft, - Anchor = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, - }, bar = new ArgonSongProgressBar(bar_height) { Name = "Seek bar", Origin = Anchor.BottomLeft, Anchor = Anchor.BottomLeft, OnSeek = time => player?.Seek(time), - } + }, + graphContainer = new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Masking = true, + CornerRadius = 5, + Child = graph = new ArgonSongProgressGraph + { + Name = "Difficulty graph", + RelativeSizeAxes = Axes.Both, + Blending = BlendingParameters.Additive + }, + RelativeSizeAxes = Axes.X, + }, }; RelativeSizeAxes = Axes.X; } @@ -111,7 +122,7 @@ namespace osu.Game.Screens.Play.HUD { base.Update(); Height = bar.Height + bar_height + info.Height; - graph.Height = bar.Height; + graphContainer.Height = bar.Height; } protected override void PopIn() diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs index 3ac7223f1d..d87359397e 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs @@ -4,6 +4,7 @@ using System; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; @@ -30,12 +31,19 @@ namespace osu.Game.Screens.Play.HUD private readonly BindableBool showBackground = new BindableBool(); + private readonly ColourInfo mainColour; + private readonly ColourInfo mainColourDarkened; + private ColourInfo altColour; + private ColourInfo altColourDarkened; + public bool ShowBackground { get => showBackground.Value; set => showBackground.Value = value; } + public BindableBool Darken = new BindableBool(); + private const float alpha_threshold = 2500; public Action? OnSeek { get; set; } @@ -91,6 +99,7 @@ namespace osu.Game.Screens.Play.HUD { RelativeSizeAxes = Axes.Both, Alpha = 0, + Colour = Colour4.White.Darken(1 + 1 / 4f) }, catchupBar = new RoundedBar { @@ -107,11 +116,12 @@ namespace osu.Game.Screens.Play.HUD Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, CornerRadius = 5, - AccentColour = Color4.White, + AccentColour = mainColour = Color4.White, RelativeSizeAxes = Axes.Both }, }; catchupBaseDepth = catchupBar.Depth; + mainColourDarkened = Colour4.White.Darken(1 / 3f); } private void setupAlternateValue() @@ -135,13 +145,16 @@ namespace osu.Game.Screens.Play.HUD [BackgroundDependencyLoader] private void load(OsuColour colours) { - catchupBar.AccentColour = colours.BlueLight; + catchupBar.AccentColour = altColour = colours.BlueLight; + altColourDarkened = colours.BlueLight.Darken(1 / 3f); showBackground.BindValueChanged(_ => updateBackground(), true); } private void updateBackground() { - background.FadeTo(showBackground.Value ? 1 : 0, 200, Easing.In); + background.FadeTo(showBackground.Value ? 1 / 4f : 0, 200, Easing.In); + catchupBar.TransformTo(nameof(catchupBar.AccentColour), ShowBackground ? altColour : altColourDarkened, 200, Easing.In); + playfieldBar.TransformTo(nameof(playfieldBar.AccentColour), ShowBackground ? mainColour : mainColourDarkened, 200, Easing.In); } protected override bool OnHover(HoverEvent e) diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgressGraph.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgressGraph.cs index 577d79886c..0899476ed4 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgressGraph.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgressGraph.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.Play.HUD { objects = value; - const int granularity = 300; + const int granularity = 200; int[] values = new int[granularity]; if (!objects.Any()) @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Play.HUD var colours = new List(); for (int i = 0; i < 5; i++) - colours.Add(Colour4.White.Opacity(1 / 5f * 0.85f)); + colours.Add(Colour4.White.Darken(1 + 1 / 5f).Opacity(1 / 5f)); TierColours = colours; } From dfbbc4002c0fccf6ecdedea8a609972efa0fdd45 Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Tue, 17 Jan 2023 10:22:58 -0500 Subject: [PATCH 1633/2991] address test failure --- .../Mods/OsuModAccuracyChallenge.cs | 14 ++++++++++++++ osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModAccuracyChallenge.cs diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAccuracyChallenge.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAccuracyChallenge.cs new file mode 100644 index 0000000000..5b79753632 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModAccuracyChallenge.cs @@ -0,0 +1,14 @@ +// 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.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModAccuracyChallenge : ModAccuracyChallenge + { + public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModAutopilot)).ToArray(); + } +} diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 6417b557f4..48056a49de 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -165,7 +165,7 @@ namespace osu.Game.Rulesets.Osu new OsuModHidden(), new MultiMod(new OsuModFlashlight(), new OsuModBlinds()), new OsuModStrictTracking(), - new ModAccuracyChallenge(), + new OsuModAccuracyChallenge(), }; case ModType.Conversion: From 0b1e5c0f53f4470ab9ead7d1b99c35d5fca2c790 Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Tue, 17 Jan 2023 10:23:57 -0500 Subject: [PATCH 1634/2991] lambdaify function --- osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs index 732f54e356..78e6acf23a 100644 --- a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs +++ b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs @@ -45,10 +45,7 @@ namespace osu.Game.Rulesets.Mods private ScoreProcessor scoreProcessor = null!; - public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) - { - this.scoreProcessor = scoreProcessor; - } + public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) => this.scoreProcessor = scoreProcessor; public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank; From 8e1002b7448e1045f12cea690ed50c2e3361c6ed Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 01:56:12 +0900 Subject: [PATCH 1635/2991] Fix song select potentially operating on `Carousel` before it is fully loaded Should fix test failures like https://github.com/ppy/osu/actions/runs/3939620830/jobs/6739690253. --- osu.Game/Screens/Select/SongSelect.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 64deb59026..db4d326991 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -860,9 +860,13 @@ namespace osu.Game.Screens.Select Logger.Log($"decoupled ruleset transferred (\"{decoupledRuleset.Value}\" -> \"{Ruleset.Value}\")"); rulesetNoDebounce = decoupledRuleset.Value = Ruleset.Value; - // if we have a pending filter operation, we want to run it now. - // it could change selection (ie. if the ruleset has been changed). - Carousel.FlushPendingFilterOperations(); + if (Carousel.IsLoaded) + { + // if we have a pending filter operation, we want to run it now. + // it could change selection (ie. if the ruleset has been changed). + Carousel.FlushPendingFilterOperations(); + } + return true; } From 452bf9255023fe6a7ac9c62e6856af7d721b4b3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 17 Jan 2023 18:02:06 +0100 Subject: [PATCH 1636/2991] Fix code quality inspection --- .../TestSceneSliderFollowCircleInput.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs index 369c3d6168..a32f0a13b8 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs @@ -31,10 +31,8 @@ namespace osu.Game.Rulesets.Osu.Tests [Test] public void TestMaximumDistanceTrackingWithoutMovement( - [Values(0, 5, 10)] - float circleSize, - [Values(0, 5, 10)] - double velocity) + [Values(0, 5, 10)] float circleSize, + [Values(0, 5, 10)] double velocity) { const double time_slider_start = 1000; From f1989ba24d93717eac9843dfd8eb9984941a65dc Mon Sep 17 00:00:00 2001 From: tsrk Date: Tue, 17 Jan 2023 17:26:05 +0000 Subject: [PATCH 1637/2991] quality: remove unused `Darken` bindable boolean --- osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs index d87359397e..ff999aa6a3 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs @@ -42,8 +42,6 @@ namespace osu.Game.Screens.Play.HUD set => showBackground.Value = value; } - public BindableBool Darken = new BindableBool(); - private const float alpha_threshold = 2500; public Action? OnSeek { get; set; } From 97bd76efc6638c4994c06442c3bcd28057bd9672 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 17 Jan 2023 09:47:42 -0800 Subject: [PATCH 1638/2991] Add ability to easily mention users in chat by right clicking username --- osu.Game/Localisation/ChatStrings.cs | 5 +++++ osu.Game/Online/Chat/StandAloneChatDisplay.cs | 1 + osu.Game/Overlays/Chat/DrawableUsername.cs | 13 +++++++++++++ 3 files changed, 19 insertions(+) diff --git a/osu.Game/Localisation/ChatStrings.cs b/osu.Game/Localisation/ChatStrings.cs index 7bd284a94e..6b0a6bd8e1 100644 --- a/osu.Game/Localisation/ChatStrings.cs +++ b/osu.Game/Localisation/ChatStrings.cs @@ -19,6 +19,11 @@ namespace osu.Game.Localisation /// public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"join the real-time discussion"); + /// + /// "Mention" + /// + public static LocalisableString MentionUser => new TranslatableString(getKey(@"mention_user"), @"Mention"); + private static string getKey(string key) => $"{prefix}:{key}"; } } diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs index 0a5434822b..e3b5037367 100644 --- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs +++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs @@ -25,6 +25,7 @@ namespace osu.Game.Online.Chat /// public partial class StandAloneChatDisplay : CompositeDrawable { + [Cached] public readonly Bindable Channel = new Bindable(); protected readonly ChatTextBox TextBox; diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs index 8cd16047f3..73eb335e99 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -24,6 +25,7 @@ using osu.Game.Online.Chat; using osu.Game.Resources.Localisation.Web; using osuTK; using osuTK.Graphics; +using ChatStrings = osu.Game.Localisation.ChatStrings; namespace osu.Game.Overlays.Chat { @@ -65,6 +67,9 @@ namespace osu.Game.Overlays.Chat [Resolved(canBeNull: true)] private UserProfileOverlay? profileOverlay { get; set; } + [Resolved] + private Bindable? currentChannel { get; set; } + private readonly APIUser user; private readonly OsuSpriteText drawableText; @@ -156,6 +161,14 @@ namespace osu.Game.Overlays.Chat if (!user.Equals(api.LocalUser.Value)) items.Add(new OsuMenuItem(UsersStrings.CardSendMessage, MenuItemType.Standard, openUserChannel)); + if (currentChannel != null) + { + items.Add(new OsuMenuItem(ChatStrings.MentionUser, MenuItemType.Standard, () => + { + currentChannel.Value.TextBoxMessage.Value += $"@{user.Username}"; + })); + } + return items.ToArray(); } } From b8e6a2d87b86c88f243bd67ee6379d572ca1c5b3 Mon Sep 17 00:00:00 2001 From: Wleter Date: Tue, 17 Jan 2023 20:41:49 +0100 Subject: [PATCH 1639/2991] filter currentEndPointPositions --- .../Compose/Components/BlueprintContainer.cs | 64 ++++++++++--------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 826a16b83b..07cfd9fe0a 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -440,7 +440,7 @@ namespace osu.Game.Screens.Edit.Compose.Components #region Selection Movement private Vector2[] movementBlueprintOriginalPositions; - private Vector2[] movementBlueprintEndPositions; + private Vector2[] movementBlueprintOriginalEndPositions; private SelectionBlueprint[] movementBlueprints; private bool isDraggingBlueprint; @@ -462,7 +462,7 @@ namespace osu.Game.Screens.Edit.Compose.Components movementBlueprints = SortForMovement(SelectionHandler.SelectedBlueprints).ToArray(); movementBlueprintOriginalPositions = movementBlueprints.Select(m => m.ScreenSpaceSelectionPoint) .ToArray(); - movementBlueprintEndPositions = movementBlueprints.Where(m => m.ScreenSpaceSelectionPoint != m.ScreenSpaceEndPoint) + movementBlueprintOriginalEndPositions = movementBlueprints.Where(m => m.ScreenSpaceSelectionPoint != m.ScreenSpaceEndPoint) .Select(m => m.ScreenSpaceEndPoint) .ToArray(); @@ -476,33 +476,6 @@ namespace osu.Game.Screens.Edit.Compose.Components /// Sorted blueprints. protected virtual IEnumerable> SortForMovement(IReadOnlyList> blueprints) => blueprints; - /// - /// Check for positional snap for every given positions. - /// - /// Distance traveled since start of dragging action. - /// The positions to check for snapping before start of dragging action. - /// The positions to check for snapping at the current time. - /// Whether found object to snap to. - private bool checkSnappingForNearbyObjects(Vector2 distanceTraveled, Vector2[] originalPositions, Vector2[] currentPositions) - { - for (int i = 0; i < originalPositions.Length; i++) - { - Vector2 originalPosition = originalPositions[i]; - var testPosition = originalPosition + distanceTraveled; - - var positionalResult = snapProvider.FindSnappedPositionAndTime(testPosition, SnapType.NearbyObjects); - - if (positionalResult.ScreenSpacePosition == testPosition) continue; - - var delta = positionalResult.ScreenSpacePosition - currentPositions[i]; - - // attempt to move the objects, and abort any time based snapping if we can. - if (SelectionHandler.HandleMovement(new MoveSelectionEvent(movementBlueprints[i], delta))) - return true; - } - return false; - } - /// /// Moves the current selected blueprints. /// @@ -523,8 +496,10 @@ namespace osu.Game.Screens.Edit.Compose.Components if (checkSnappingForNearbyObjects(distanceTraveled, movementBlueprintOriginalPositions, currentSelectionPointPositions)) return true; - var currentEndPointPositions = movementBlueprints.Select(m => m.ScreenSpaceEndPoint).ToArray(); - if (checkSnappingForNearbyObjects(distanceTraveled, movementBlueprintEndPositions, currentEndPointPositions)) + var currentEndPointPositions = movementBlueprints.Where(m => m.ScreenSpaceSelectionPoint != m.ScreenSpaceEndPoint) + .Select(m => m.ScreenSpaceEndPoint) + .ToArray(); + if (checkSnappingForNearbyObjects(distanceTraveled, movementBlueprintOriginalEndPositions, currentEndPointPositions)) return true; } @@ -545,6 +520,33 @@ namespace osu.Game.Screens.Edit.Compose.Components return ApplySnapResult(movementBlueprints, result); } + /// + /// Check for positional snap for every given positions. + /// + /// Distance traveled since start of dragging action. + /// The position of objects before start of dragging action. + /// The positions of object at the current time. + /// Whether found object to snap to. + private bool checkSnappingForNearbyObjects(Vector2 distanceTraveled, Vector2[] originalPositions, Vector2[] currentPositions) + { + for (int i = 0; i < originalPositions.Length; i++) + { + Vector2 originalPosition = originalPositions[i]; + var testPosition = originalPosition + distanceTraveled; + + var positionalResult = snapProvider.FindSnappedPositionAndTime(testPosition, SnapType.NearbyObjects); + + if (positionalResult.ScreenSpacePosition == testPosition) continue; + + var delta = positionalResult.ScreenSpacePosition - currentPositions[i]; + + // attempt to move the objects, and abort any time based snapping if we can. + if (SelectionHandler.HandleMovement(new MoveSelectionEvent(movementBlueprints[i], delta))) + return true; + } + return false; + } + protected virtual bool ApplySnapResult(SelectionBlueprint[] blueprints, SnapResult result) => SelectionHandler.HandleMovement(new MoveSelectionEvent(blueprints.First(), result.ScreenSpacePosition - blueprints.First().ScreenSpaceSelectionPoint)); From 00f15d19f969d1977b9834a75ff781b8a4d0dc19 Mon Sep 17 00:00:00 2001 From: Wleter Date: Tue, 17 Jan 2023 21:11:21 +0100 Subject: [PATCH 1640/2991] fix double newlines --- .../Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs | 1 + .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 1 - osu.Game.Rulesets.Osu/Skinning/SliderBody.cs | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs index c44bbbfa03..4ff38cd1f8 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs @@ -26,6 +26,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components /// Offset in absolute (local) coordinates from the end of the curve. /// public Vector2 PathEndLocation => body.PathEndOffset; + public SliderBodyPiece() { InternalChild = body = new ManualSliderBody diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 3737a44ad2..90c97e2752 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -409,7 +409,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders public override Vector2 ScreenSpaceSelectionPoint => DrawableObject.SliderBody?.ToScreenSpace(DrawableObject.SliderBody.PathOffset) ?? BodyPiece.ToScreenSpace(BodyPiece.PathStartLocation); - public override Vector2 ScreenSpaceEndPoint => DrawableObject.SliderBody?.ToScreenSpace(DrawableObject.SliderBody.PathEndOffset) ?? BodyPiece.ToScreenSpace(BodyPiece.PathEndLocation); diff --git a/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs index 8a54723a8e..e7885e65de 100644 --- a/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs @@ -35,7 +35,6 @@ namespace osu.Game.Rulesets.Osu.Skinning /// Offset in absolute coordinates from the end of the curve. /// public virtual Vector2 PathEndOffset => path.PositionInBoundingBox(path.Vertices[^1]); - /// /// Used to colour the path. From 788033e1b89997142f9d74089b19bd7821b08119 Mon Sep 17 00:00:00 2001 From: Wleter Date: Tue, 17 Jan 2023 21:13:54 +0100 Subject: [PATCH 1641/2991] fix unnecessary newline --- .../Screens/Edit/Compose/Components/BlueprintContainer.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 07cfd9fe0a..113dffbcb0 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -460,11 +460,9 @@ namespace osu.Game.Screens.Edit.Compose.Components // Movement is tracked from the blueprint of the earliest item, since it only makes sense to distance snap from that item movementBlueprints = SortForMovement(SelectionHandler.SelectedBlueprints).ToArray(); - movementBlueprintOriginalPositions = movementBlueprints.Select(m => m.ScreenSpaceSelectionPoint) - .ToArray(); + movementBlueprintOriginalPositions = movementBlueprints.Select(m => m.ScreenSpaceSelectionPoint).ToArray(); movementBlueprintOriginalEndPositions = movementBlueprints.Where(m => m.ScreenSpaceSelectionPoint != m.ScreenSpaceEndPoint) - .Select(m => m.ScreenSpaceEndPoint) - .ToArray(); + .Select(m => m.ScreenSpaceEndPoint).ToArray(); return true; } From 364034280563cfd683136e9c005e91801fc3a678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 17 Jan 2023 21:30:46 +0100 Subject: [PATCH 1642/2991] Add logging on comment post failure --- osu.Game/Overlays/Comments/CommentsContainer.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 3639fe1835..a334fac215 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -19,6 +19,7 @@ using osu.Framework.Threading; using System.Collections.Generic; using JetBrains.Annotations; using osu.Framework.Localisation; +using osu.Framework.Logging; using osu.Game.Graphics.Sprites; using osu.Game.Resources.Localisation.Web; using osu.Game.Users.Drawables; @@ -420,9 +421,10 @@ namespace osu.Game.Overlays.Comments { ShowLoadingSpinner = true; CommentPostRequest req = new CommentPostRequest(commentsContainer.Type.Value, commentsContainer.Id.Value, text); - req.Failure += _ => Schedule(() => + req.Failure += e => Schedule(() => { ShowLoadingSpinner = false; + Logger.Error(e, "Posting comment failed."); }); req.Success += cb => Schedule(() => { From 92a755c5da93c4077ace0342b784539e21072941 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Tue, 17 Jan 2023 22:16:59 +0100 Subject: [PATCH 1643/2991] adjust colourbar to position itself in a more simple fashion --- .../Screens/Select/FooterV2/FooterButtonV2.cs | 47 ++++++++----------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs index 342f5d1bd7..33bf062abb 100644 --- a/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs +++ b/osu.Game/Screens/Select/FooterV2/FooterButtonV2.cs @@ -117,21 +117,22 @@ namespace osu.Game.Screens.Select.FooterV2 Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre }, - new Container - { - // The X offset has to multiplied as such to account for the fact that we only want to offset by the distance from the CenterLeft point of the container - // not the whole shear width - Position = new Vector2(-SHEAR.X * (button_height / 2 - 10), -10), - Anchor = Anchor.BottomCentre, - Origin = Anchor.Centre, - Size = new Vector2(120, 6), - Masking = true, - CornerRadius = 3, - Child = bar = new Box - { - RelativeSizeAxes = Axes.Both, - } - } + } + }, + new Container + { + // The X offset has to multiplied as such to account for the fact that we only want to offset by the distance from the CenterLeft point of the container + // not the whole shear width + Shear = -SHEAR, + Anchor = Anchor.BottomCentre, + Origin = Anchor.Centre, + Y = -10, + Size = new Vector2(120, 6), + Masking = true, + CornerRadius = 3, + Child = bar = new Box + { + RelativeSizeAxes = Axes.Both, } } }; @@ -153,20 +154,10 @@ namespace osu.Game.Screens.Select.FooterV2 return true; } - protected override void OnHoverLost(HoverLostEvent e) - { - updateDisplay(); - } + protected override void OnHoverLost(HoverLostEvent e) => updateDisplay(); - protected override bool OnMouseDown(MouseDownEvent e) - { - return !Enabled.Value || base.OnMouseDown(e); - } - - protected override bool OnClick(ClickEvent e) - { - return !Enabled.Value || base.OnClick(e); - } + protected override bool OnMouseDown(MouseDownEvent e) => !Enabled.Value || base.OnMouseDown(e); + protected override bool OnClick(ClickEvent e) => !Enabled.Value || base.OnClick(e); public virtual bool OnPressed(KeyBindingPressEvent e) { From 350cce1315d050b8d466edd3549ad309517fe8d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 18:39:36 +0100 Subject: [PATCH 1644/2991] Move contents of detail header to separate component --- .../Profile/Header/Components/MainDetails.cs | 187 ++++++++++++++++++ .../Profile/Header/DetailHeaderContainer.cs | 161 +-------------- 2 files changed, 190 insertions(+), 158 deletions(-) create mode 100644 osu.Game/Overlays/Profile/Header/Components/MainDetails.cs diff --git a/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs b/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs new file mode 100644 index 0000000000..930ba29c7f --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs @@ -0,0 +1,187 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Extensions.LocalisationExtensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Localisation; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Online.Leaderboards; +using osu.Game.Resources.Localisation.Web; +using osu.Game.Scoring; +using osuTK; + +namespace osu.Game.Overlays.Profile.Header.Components +{ + public partial class MainDetails : CompositeDrawable + { + private readonly Dictionary scoreRankInfos = new Dictionary(); + private ProfileValueDisplay medalInfo = null!; + private ProfileValueDisplay ppInfo = null!; + private ProfileValueDisplay detailGlobalRank = null!; + private ProfileValueDisplay detailCountryRank = null!; + private RankGraph rankGraph = null!; + + public readonly Bindable User = new Bindable(); + + [BackgroundDependencyLoader] + private void load() + { + AutoSizeAxes = Axes.Y; + + InternalChild = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + AutoSizeDuration = 200, + AutoSizeEasing = Easing.OutQuint, + Masking = true, + Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 15), + Children = new Drawable[] + { + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(20), + Children = new Drawable[] + { + detailGlobalRank = new ProfileValueDisplay(true) + { + Title = UsersStrings.ShowRankGlobalSimple, + }, + detailCountryRank = new ProfileValueDisplay(true) + { + Title = UsersStrings.ShowRankCountrySimple, + }, + } + }, + new Container + { + RelativeSizeAxes = Axes.X, + Height = 60, + Children = new Drawable[] + { + rankGraph = new RankGraph + { + RelativeSizeAxes = Axes.Both, + }, + } + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] + { + medalInfo = new ProfileValueDisplay + { + Title = UsersStrings.ShowStatsMedals, + }, + ppInfo = new ProfileValueDisplay + { + Title = "pp", + }, + new TotalPlayTime + { + User = { BindTarget = User } + }, + } + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5), + Children = new[] + { + scoreRankInfos[ScoreRank.XH] = new ScoreRankInfo(ScoreRank.XH), + scoreRankInfos[ScoreRank.X] = new ScoreRankInfo(ScoreRank.X), + scoreRankInfos[ScoreRank.SH] = new ScoreRankInfo(ScoreRank.SH), + scoreRankInfos[ScoreRank.S] = new ScoreRankInfo(ScoreRank.S), + scoreRankInfos[ScoreRank.A] = new ScoreRankInfo(ScoreRank.A), + } + } + } + }, + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + User.BindValueChanged(e => updateDisplay(e.NewValue), true); + } + + private void updateDisplay(UserProfileData? data) + { + var user = data?.User; + + medalInfo.Content = user?.Achievements?.Length.ToString() ?? "0"; + ppInfo.Content = user?.Statistics?.PP?.ToLocalisableString("#,##0") ?? (LocalisableString)"0"; + + foreach (var scoreRankInfo in scoreRankInfos) + scoreRankInfo.Value.RankCount = user?.Statistics?.GradesCount[scoreRankInfo.Key] ?? 0; + + detailGlobalRank.Content = user?.Statistics?.GlobalRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-"; + detailCountryRank.Content = user?.Statistics?.CountryRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-"; + + rankGraph.Statistics.Value = user?.Statistics; + } + + private partial class ScoreRankInfo : CompositeDrawable + { + private readonly OsuSpriteText rankCount; + + public int RankCount + { + set => rankCount.Text = value.ToLocalisableString("#,##0"); + } + + public ScoreRankInfo(ScoreRank rank) + { + AutoSizeAxes = Axes.Both; + InternalChild = new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + Width = 44, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new DrawableRank(rank) + { + RelativeSizeAxes = Axes.X, + Height = 22, + }, + rankCount = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre + } + } + }; + } + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 890e6c4e04..17de8b8ba0 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -1,33 +1,17 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Localisation; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Online.Leaderboards; using osu.Game.Overlays.Profile.Header.Components; -using osu.Game.Resources.Localisation.Web; -using osu.Game.Scoring; -using osuTK; namespace osu.Game.Overlays.Profile.Header { public partial class DetailHeaderContainer : CompositeDrawable { - private readonly Dictionary scoreRankInfos = new Dictionary(); - private ProfileValueDisplay medalInfo = null!; - private ProfileValueDisplay ppInfo = null!; - private ProfileValueDisplay detailGlobalRank = null!; - private ProfileValueDisplay detailCountryRank = null!; - private RankGraph rankGraph = null!; - public readonly Bindable User = new Bindable(); [BackgroundDependencyLoader] @@ -35,8 +19,6 @@ namespace osu.Game.Overlays.Profile.Header { AutoSizeAxes = Axes.Y; - User.ValueChanged += e => updateDisplay(e.NewValue); - InternalChildren = new Drawable[] { new Box @@ -44,149 +26,12 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background5, }, - new FillFlowContainer + new MainDetails { RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - AutoSizeDuration = 200, - AutoSizeEasing = Easing.OutQuint, - Masking = true, - Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 15), - Children = new Drawable[] - { - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(20), - Children = new Drawable[] - { - detailGlobalRank = new ProfileValueDisplay(true) - { - Title = UsersStrings.ShowRankGlobalSimple, - }, - detailCountryRank = new ProfileValueDisplay(true) - { - Title = UsersStrings.ShowRankCountrySimple, - }, - } - }, - new Container - { - RelativeSizeAxes = Axes.X, - Height = 60, - Children = new Drawable[] - { - rankGraph = new RankGraph - { - RelativeSizeAxes = Axes.Both, - }, - } - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - Children = new Drawable[] - { - medalInfo = new ProfileValueDisplay - { - Title = UsersStrings.ShowStatsMedals, - }, - ppInfo = new ProfileValueDisplay - { - Title = "pp", - }, - new TotalPlayTime - { - User = { BindTarget = User } - }, - } - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5), - Children = new[] - { - scoreRankInfos[ScoreRank.XH] = new ScoreRankInfo(ScoreRank.XH), - scoreRankInfos[ScoreRank.X] = new ScoreRankInfo(ScoreRank.X), - scoreRankInfos[ScoreRank.SH] = new ScoreRankInfo(ScoreRank.SH), - scoreRankInfos[ScoreRank.S] = new ScoreRankInfo(ScoreRank.S), - scoreRankInfos[ScoreRank.A] = new ScoreRankInfo(ScoreRank.A), - } - } - } - }, - } - }, + User = { BindTarget = User } + } }; } - - private void updateDisplay(UserProfileData? data) - { - var user = data?.User; - - medalInfo.Content = user?.Achievements?.Length.ToString() ?? "0"; - ppInfo.Content = user?.Statistics?.PP?.ToLocalisableString("#,##0") ?? (LocalisableString)"0"; - - foreach (var scoreRankInfo in scoreRankInfos) - scoreRankInfo.Value.RankCount = user?.Statistics?.GradesCount[scoreRankInfo.Key] ?? 0; - - detailGlobalRank.Content = user?.Statistics?.GlobalRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-"; - detailCountryRank.Content = user?.Statistics?.CountryRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-"; - - rankGraph.Statistics.Value = user?.Statistics; - } - - private partial class ScoreRankInfo : CompositeDrawable - { - private readonly OsuSpriteText rankCount; - - public int RankCount - { - set => rankCount.Text = value.ToLocalisableString("#,##0"); - } - - public ScoreRankInfo(ScoreRank rank) - { - AutoSizeAxes = Axes.Both; - InternalChild = new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - Width = 44, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - new DrawableRank(rank) - { - RelativeSizeAxes = Axes.X, - Height = 22, - }, - rankCount = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre - } - } - }; - } - } } } From 7a475d9cf8b160ad9ce77ba283c8b4696298c2aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 18:55:27 +0100 Subject: [PATCH 1645/2991] Move out stats from top header container --- .../Header/Components/ExtendedDetails.cs | 108 ++++++++++++++++++ .../Profile/Header/TopHeaderContainer.cs | 51 --------- 2 files changed, 108 insertions(+), 51 deletions(-) create mode 100644 osu.Game/Overlays/Profile/Header/Components/ExtendedDetails.cs diff --git a/osu.Game/Overlays/Profile/Header/Components/ExtendedDetails.cs b/osu.Game/Overlays/Profile/Header/Components/ExtendedDetails.cs new file mode 100644 index 0000000000..b50b0041d0 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/Components/ExtendedDetails.cs @@ -0,0 +1,108 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Extensions.LocalisationExtensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Resources.Localisation.Web; +using osu.Game.Users; +using osuTK; + +namespace osu.Game.Overlays.Profile.Header.Components +{ + public partial class ExtendedDetails : CompositeDrawable + { + public Bindable UserProfile { get; } = new Bindable(); + + private SpriteText rankedScore = null!; + private SpriteText hitAccuracy = null!; + private SpriteText playCount = null!; + private SpriteText totalScore = null!; + private SpriteText totalHits = null!; + private SpriteText maximumCombo = null!; + private SpriteText replaysWatched = null!; + + [BackgroundDependencyLoader] + private void load() + { + var font = OsuFont.Default.With(size: 12); + const float vertical_spacing = 4; + + AutoSizeAxes = Axes.Both; + + // this should really be a grid, but trying to avoid one to avoid the performance hit. + InternalChild = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(20, 0), + Children = new[] + { + new FillFlowContainer + { + Name = @"Labels", + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, vertical_spacing), + Children = new Drawable[] + { + new OsuSpriteText { Font = font, Text = UsersStrings.ShowStatsRankedScore }, + new OsuSpriteText { Font = font, Text = UsersStrings.ShowStatsHitAccuracy }, + new OsuSpriteText { Font = font, Text = UsersStrings.ShowStatsPlayCount }, + new OsuSpriteText { Font = font, Text = UsersStrings.ShowStatsTotalScore }, + new OsuSpriteText { Font = font, Text = UsersStrings.ShowStatsTotalHits }, + new OsuSpriteText { Font = font, Text = UsersStrings.ShowStatsMaximumCombo }, + new OsuSpriteText { Font = font, Text = UsersStrings.ShowStatsReplaysWatchedByOthers }, + } + }, + new FillFlowContainer + { + Name = @"Values", + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, vertical_spacing), + Children = new Drawable[] + { + rankedScore = new OsuSpriteText { Font = font }, + hitAccuracy = new OsuSpriteText { Font = font }, + playCount = new OsuSpriteText { Font = font }, + totalScore = new OsuSpriteText { Font = font }, + totalHits = new OsuSpriteText { Font = font }, + maximumCombo = new OsuSpriteText { Font = font }, + replaysWatched = new OsuSpriteText { Font = font }, + } + }, + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + UserProfile.BindValueChanged(userProfile => updateStatistics(userProfile.NewValue?.User.Statistics), true); + } + + private void updateStatistics(UserStatistics? statistics) + { + if (statistics == null) + { + Alpha = 0; + return; + } + + Alpha = 1; + + rankedScore.Text = statistics.RankedScore.ToLocalisableString(@"N0"); + hitAccuracy.Text = statistics.DisplayAccuracy; + playCount.Text = statistics.PlayCount.ToLocalisableString(@"N0"); + totalScore.Text = statistics.TotalScore.ToLocalisableString(@"N0"); + totalHits.Text = statistics.TotalHits.ToLocalisableString(@"N0"); + maximumCombo.Text = statistics.MaxCombo.ToLocalisableString(@"N0"); + replaysWatched.Text = statistics.ReplaysWatched.ToLocalisableString(@"N0"); + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index e04a8ad9ad..1fe39cb570 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -5,18 +5,15 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Cursor; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Overlays.Profile.Header.Components; -using osu.Game.Resources.Localisation.Web; using osu.Game.Users.Drawables; using osuTK; @@ -38,7 +35,6 @@ namespace osu.Game.Overlays.Profile.Header private OsuSpriteText titleText = null!; private UpdateableFlag userFlag = null!; private OsuSpriteText userCountryText = null!; - private FillFlowContainer userStats = null!; private GroupBadgeFlow groupBadgeFlow = null!; [BackgroundDependencyLoader] @@ -164,16 +160,6 @@ namespace osu.Game.Overlays.Profile.Header } } }, - userStats = new FillFlowContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Y, - Width = 300, - Margin = new MarginPadding { Right = UserProfileOverlay.CONTENT_X_MARGIN }, - Padding = new MarginPadding { Vertical = 15 }, - Spacing = new Vector2(0, 2) - } }; User.BindValueChanged(user => updateUser(user.NewValue)); @@ -192,43 +178,6 @@ namespace osu.Game.Overlays.Profile.Header titleText.Text = user?.Title ?? string.Empty; titleText.Colour = Color4Extensions.FromHex(user?.Colour ?? "fff"); groupBadgeFlow.User.Value = user; - - userStats.Clear(); - - if (user?.Statistics != null) - { - userStats.Add(new UserStatsLine(UsersStrings.ShowStatsRankedScore, user.Statistics.RankedScore.ToLocalisableString("#,##0"))); - userStats.Add(new UserStatsLine(UsersStrings.ShowStatsHitAccuracy, user.Statistics.DisplayAccuracy)); - userStats.Add(new UserStatsLine(UsersStrings.ShowStatsPlayCount, user.Statistics.PlayCount.ToLocalisableString("#,##0"))); - userStats.Add(new UserStatsLine(UsersStrings.ShowStatsTotalScore, user.Statistics.TotalScore.ToLocalisableString("#,##0"))); - userStats.Add(new UserStatsLine(UsersStrings.ShowStatsTotalHits, user.Statistics.TotalHits.ToLocalisableString("#,##0"))); - userStats.Add(new UserStatsLine(UsersStrings.ShowStatsMaximumCombo, user.Statistics.MaxCombo.ToLocalisableString("#,##0"))); - userStats.Add(new UserStatsLine(UsersStrings.ShowStatsReplaysWatchedByOthers, user.Statistics.ReplaysWatched.ToLocalisableString("#,##0"))); - } - } - - private partial class UserStatsLine : Container - { - public UserStatsLine(LocalisableString left, LocalisableString right) - { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - Children = new Drawable[] - { - new OsuSpriteText - { - Font = OsuFont.GetFont(size: 15), - Text = left, - }, - new OsuSpriteText - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold), - Text = right, - }, - }; - } } } } From f7c942ac10b22d365f9f9b98228959d8c5d8350e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 19:00:40 +0100 Subject: [PATCH 1646/2991] Move user stats into detail header container --- .../Header/Components/ExtendedDetails.cs | 6 ++- .../Profile/Header/Components/MainDetails.cs | 1 - .../Profile/Header/DetailHeaderContainer.cs | 44 ++++++++++++++++++- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/ExtendedDetails.cs b/osu.Game/Overlays/Profile/Header/Components/ExtendedDetails.cs index b50b0041d0..50fc52600c 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ExtendedDetails.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ExtendedDetails.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class ExtendedDetails : CompositeDrawable { - public Bindable UserProfile { get; } = new Bindable(); + public Bindable User { get; } = new Bindable(); private SpriteText rankedScore = null!; private SpriteText hitAccuracy = null!; @@ -46,6 +46,7 @@ namespace osu.Game.Overlays.Profile.Header.Components new FillFlowContainer { Name = @"Labels", + AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, Spacing = new Vector2(0, vertical_spacing), Children = new Drawable[] @@ -62,6 +63,7 @@ namespace osu.Game.Overlays.Profile.Header.Components new FillFlowContainer { Name = @"Values", + AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, Spacing = new Vector2(0, vertical_spacing), Children = new Drawable[] @@ -83,7 +85,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { base.LoadComplete(); - UserProfile.BindValueChanged(userProfile => updateStatistics(userProfile.NewValue?.User.Statistics), true); + User.BindValueChanged(user => updateStatistics(user.NewValue?.User.Statistics), true); } private void updateStatistics(UserStatistics? statistics) diff --git a/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs b/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs index 930ba29c7f..b89973c5e5 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs @@ -40,7 +40,6 @@ namespace osu.Game.Overlays.Profile.Header.Components AutoSizeDuration = 200, AutoSizeEasing = Easing.OutQuint, Masking = true, - Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, Direction = FillDirection.Vertical, Spacing = new Vector2(0, 15), Children = new Drawable[] diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 17de8b8ba0..1cc3aae735 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -26,10 +26,50 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background5, }, - new MainDetails + new Container { RelativeSizeAxes = Axes.X, - User = { BindTarget = User } + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + Child = new GridContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + }, + ColumnDimensions = new[] + { + new Dimension(), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + }, + Content = new[] + { + new Drawable[] + { + new MainDetails + { + RelativeSizeAxes = Axes.X, + User = { BindTarget = User } + }, + new Box + { + RelativeSizeAxes = Axes.Y, + Width = 2, + Colour = colourProvider.Background6, + Margin = new MarginPadding { Horizontal = 15 } + }, + new ExtendedDetails + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + User = { BindTarget = User } + } + } + } + } } }; } From 254c881ded6bc1c7b7875d3fe07ab88a02a39409 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 17 Jan 2023 14:12:48 -0800 Subject: [PATCH 1647/2991] Also check null for bindable channel value --- osu.Game/Overlays/Chat/DrawableUsername.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs index 73eb335e99..771ccdcbef 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -68,7 +68,7 @@ namespace osu.Game.Overlays.Chat private UserProfileOverlay? profileOverlay { get; set; } [Resolved] - private Bindable? currentChannel { get; set; } + private Bindable? currentChannel { get; set; } private readonly APIUser user; private readonly OsuSpriteText drawableText; @@ -161,7 +161,7 @@ namespace osu.Game.Overlays.Chat if (!user.Equals(api.LocalUser.Value)) items.Add(new OsuMenuItem(UsersStrings.CardSendMessage, MenuItemType.Standard, openUserChannel)); - if (currentChannel != null) + if (currentChannel?.Value != null) { items.Add(new OsuMenuItem(ChatStrings.MentionUser, MenuItemType.Standard, () => { From dfea42fd163f0ec8c558ba2b954a054a2af2d10c Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 17 Jan 2023 14:13:50 -0800 Subject: [PATCH 1648/2991] Add space after username mention --- osu.Game/Overlays/Chat/DrawableUsername.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs index 771ccdcbef..031a0b6ae2 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -165,7 +165,7 @@ namespace osu.Game.Overlays.Chat { items.Add(new OsuMenuItem(ChatStrings.MentionUser, MenuItemType.Standard, () => { - currentChannel.Value.TextBoxMessage.Value += $"@{user.Username}"; + currentChannel.Value.TextBoxMessage.Value += $"@{user.Username} "; })); } From 12544c16eab2510ce4c8d90ba415103ba632b364 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 18 Jan 2023 02:10:02 +0300 Subject: [PATCH 1649/2991] Remove canBeNull --- osu.Game/Overlays/Comments/DrawableComment.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 834abd5e9f..70ffbd8baf 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -70,7 +70,7 @@ namespace osu.Game.Overlays.Comments private GridContainer content = null!; private VotePill votePill = null!; - [Resolved(canBeNull: true)] + [Resolved] private IDialogOverlay? dialogOverlay { get; set; } [Resolved] @@ -79,7 +79,7 @@ namespace osu.Game.Overlays.Comments [Resolved] private GameHost host { get; set; } = null!; - [Resolved(canBeNull: true)] + [Resolved] private OnScreenDisplay? onScreenDisplay { get; set; } public DrawableComment(Comment comment) From ca3be7138149e9ed8f6af73986cef0b559fa60f6 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 18 Jan 2023 02:11:07 +0300 Subject: [PATCH 1650/2991] Track comment's nesting and reduce padding for too nested --- osu.Game/Overlays/Comments/DrawableComment.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 70ffbd8baf..1df65ab4b1 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -57,6 +57,11 @@ namespace osu.Game.Overlays.Comments /// public bool WasDeleted { get; protected set; } + /// + /// Tracks this comment's level of nesting. 0 means that this comment has no parents. + /// + public int Level { get; private set; } + private FillFlowContainer childCommentsVisibilityContainer = null!; private FillFlowContainer childCommentsContainer = null!; private LoadRepliesButton loadRepliesButton = null!; @@ -88,12 +93,16 @@ namespace osu.Game.Overlays.Comments } [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) + private void load(OverlayColourProvider colourProvider, DrawableComment? parentComment) { LinkFlowContainer username; FillFlowContainer info; CommentMarkdownContainer message; + Level = parentComment?.Level + 1 ?? 0; + + float childrenPadding = Level < 6 ? 20 : 5; + RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; InternalChildren = new Drawable[] @@ -248,7 +257,7 @@ namespace osu.Game.Overlays.Comments RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, - Padding = new MarginPadding { Left = 20 }, + Padding = new MarginPadding { Left = childrenPadding }, Children = new Drawable[] { childCommentsContainer = new FillFlowContainer From 4ad79a8a0ac721be0e409a9fd729a45d5c6c1bd0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 12:00:47 +0900 Subject: [PATCH 1651/2991] Move `IsLoaded` check inside `BeatmapCarousel` --- osu.Game/Screens/Select/BeatmapCarousel.cs | 3 +++ osu.Game/Screens/Select/SongSelect.cs | 9 +++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 19eced08d9..774ecc2c9c 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -596,6 +596,9 @@ namespace osu.Game.Screens.Select public void FlushPendingFilterOperations() { + if (!IsLoaded) + return; + if (PendingFilter?.Completed == false) { applyActiveCriteria(false); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index db4d326991..4b3222c14a 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -860,12 +860,9 @@ namespace osu.Game.Screens.Select Logger.Log($"decoupled ruleset transferred (\"{decoupledRuleset.Value}\" -> \"{Ruleset.Value}\")"); rulesetNoDebounce = decoupledRuleset.Value = Ruleset.Value; - if (Carousel.IsLoaded) - { - // if we have a pending filter operation, we want to run it now. - // it could change selection (ie. if the ruleset has been changed). - Carousel.FlushPendingFilterOperations(); - } + // if we have a pending filter operation, we want to run it now. + // it could change selection (ie. if the ruleset has been changed). + Carousel.FlushPendingFilterOperations(); return true; } From 3630b41a5b182f68249f70d29a33ce71f7910894 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 13:13:20 +0900 Subject: [PATCH 1652/2991] Remove unused usings --- osu.Game.Rulesets.Osu/OsuInputManager.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs index d5eae4b391..99ae706369 100644 --- a/osu.Game.Rulesets.Osu/OsuInputManager.cs +++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs @@ -6,10 +6,8 @@ using System.ComponentModel; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; -using osu.Framework.Input.StateChanges.Events; using osu.Game.Input.Bindings; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; From 45c5bd840310904dd36da949559777b8d4f66e69 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 14:37:09 +0900 Subject: [PATCH 1653/2991] Simplify HUD test to not require casting to specific `ProgressBar` type --- .../Visual/Gameplay/TestSceneHUDOverlay.cs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 713183ebaf..145f9380f8 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -213,17 +213,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("attempt seek", () => { - switch (getSongProgress()) - { - case SongProgressBar defaultBar: - InputManager.MoveMouseTo(defaultBar); - break; - - case ArgonSongProgressBar argonBar: - InputManager.MoveMouseTo(argonBar); - break; - } - + InputManager.MoveMouseTo(getSongProgress() as Drawable); InputManager.Click(MouseButton.Left); }); From afc12e0b835adf6eae3447a7b2ddb611d04462b4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 14:43:20 +0900 Subject: [PATCH 1654/2991] Tidy up `ISongProgressBar` interface --- osu.Game/Screens/Play/HUD/ISongProgressBar.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ISongProgressBar.cs b/osu.Game/Screens/Play/HUD/ISongProgressBar.cs index f1a219e18b..683037577d 100644 --- a/osu.Game/Screens/Play/HUD/ISongProgressBar.cs +++ b/osu.Game/Screens/Play/HUD/ISongProgressBar.cs @@ -7,10 +7,14 @@ namespace osu.Game.Screens.Play.HUD { public interface ISongProgressBar { - public Action? OnSeek { get; set; } - public double StartTime { set; } - public double EndTime { set; } - public double CurrentTime { set; } + /// + /// Whether the progress bar should allow interaction, ie. to perform seek operations. + /// public bool Interactive { get; set; } + + /// + /// Action which is invoked when a seek is requested, with the proposed millisecond value for the seek operation. + /// + public Action? OnSeek { get; set; } } } From 5429979049c822167dec6c86f8be5d52a14dcb7d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 14:55:41 +0900 Subject: [PATCH 1655/2991] Combine common code into `SongProgress` base class --- .../Visual/Gameplay/TestSceneSongProgress.cs | 6 +-- .../Screens/Play/HUD/ArgonSongProgress.cs | 34 ++------------- .../Screens/Play/HUD/DefaultSongProgress.cs | 43 +++---------------- osu.Game/Screens/Play/HUD/SongProgress.cs | 31 ++++++++++--- osu.Game/Skinning/LegacySongProgress.cs | 14 ++---- 5 files changed, 40 insertions(+), 88 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index 415a3c5b07..cecc24a807 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs @@ -54,10 +54,10 @@ namespace osu.Game.Tests.Visual.Gameplay void applyToDefaultProgress(Action action) => this.ChildrenOfType().ForEach(action); - AddStep("allow seeking", () => applyToDefaultProgress(s => s.AllowSeeking.Value = true)); + AddStep("allow seeking", () => applyToDefaultProgress(s => s.Interactive.Value = true)); AddStep("hide graph", () => applyToDefaultProgress(s => s.ShowGraph.Value = false)); - AddStep("disallow seeking", () => applyToDefaultProgress(s => s.AllowSeeking.Value = false)); - AddStep("allow seeking", () => applyToDefaultProgress(s => s.AllowSeeking.Value = true)); + AddStep("disallow seeking", () => applyToDefaultProgress(s => s.Interactive.Value = false)); + AddStep("allow seeking", () => applyToDefaultProgress(s => s.Interactive.Value = true)); AddStep("show graph", () => applyToDefaultProgress(s => s.ShowGraph.Value = true)); } diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs index 8446abecd2..4951ad174b 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs @@ -3,11 +3,9 @@ using System.Collections.Generic; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Timing; -using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.UI; @@ -23,11 +21,6 @@ namespace osu.Game.Screens.Play.HUD private const float bar_height = 10; - public readonly Bindable AllowSeeking = new BindableBool(); - - [SettingSource("Show difficulty graph", "Whether a graph displaying difficulty throughout the beatmap should be shown")] - public Bindable ShowGraph { get; } = new BindableBool(true); - [Resolved] private DrawableRuleset? drawableRuleset { get; set; } @@ -80,14 +73,6 @@ namespace osu.Game.Screens.Play.HUD [BackgroundDependencyLoader] private void load() { - base.LoadComplete(); - - if (drawableRuleset != null) - { - if (player?.Configuration.AllowUserInteraction == true) - ((IBindable)AllowSeeking).BindTo(drawableRuleset.HasReplayLoaded); - } - info.ShowProgress = false; info.TextColour = Colour4.White; info.Font = OsuFont.Torus.With(size: 18, weight: FontWeight.Bold); @@ -95,7 +80,9 @@ namespace osu.Game.Screens.Play.HUD protected override void LoadComplete() { - AllowSeeking.BindValueChanged(_ => updateBarVisibility(), true); + base.LoadComplete(); + + Interactive.BindValueChanged(_ => bar.Interactive = Interactive.Value, true); ShowGraph.BindValueChanged(_ => updateGraphVisibility(), true); } @@ -107,11 +94,6 @@ namespace osu.Game.Screens.Play.HUD info.EndTime = bar.EndTime = LastHitTime; } - private void updateBarVisibility() - { - bar.Interactive = AllowSeeking.Value; - } - private void updateGraphVisibility() { graph.FadeTo(ShowGraph.Value ? 1 : 0, 200, Easing.In); @@ -125,16 +107,6 @@ namespace osu.Game.Screens.Play.HUD graphContainer.Height = bar.Height; } - protected override void PopIn() - { - this.FadeIn(500, Easing.OutQuint); - } - - protected override void PopOut() - { - this.FadeOut(100); - } - protected override void UpdateProgress(double progress, bool isIntro) { bar.ReferenceTime = GameplayClock.CurrentTime; diff --git a/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs b/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs index cb629a0b77..747f292e30 100644 --- a/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs +++ b/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs @@ -3,12 +3,9 @@ using System.Collections.Generic; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.UI; using osuTK; namespace osu.Game.Screens.Play.HUD @@ -27,23 +24,9 @@ namespace osu.Game.Screens.Play.HUD private readonly SongProgressGraph graph; private readonly SongProgressInfo info; - /// - /// Whether seeking is allowed and the progress bar should be shown. - /// - public readonly Bindable AllowSeeking = new Bindable(); - - [SettingSource("Show difficulty graph", "Whether a graph displaying difficulty throughout the beatmap should be shown")] - public Bindable ShowGraph { get; } = new BindableBool(true); - - public override bool HandleNonPositionalInput => AllowSeeking.Value; - public override bool HandlePositionalInput => AllowSeeking.Value; - [Resolved] private Player? player { get; set; } - [Resolved] - private DrawableRuleset? drawableRuleset { get; set; } - public DefaultSongProgress() { RelativeSizeAxes = Axes.X; @@ -75,34 +58,18 @@ namespace osu.Game.Screens.Play.HUD }; } - [BackgroundDependencyLoader(true)] + [BackgroundDependencyLoader] private void load(OsuColour colours) { - base.LoadComplete(); - - if (drawableRuleset != null) - { - if (player?.Configuration.AllowUserInteraction == true) - ((IBindable)AllowSeeking).BindTo(drawableRuleset.HasReplayLoaded); - } - graph.FillColour = bar.FillColour = colours.BlueLighter; } protected override void LoadComplete() { - AllowSeeking.BindValueChanged(_ => updateBarVisibility(), true); + Interactive.BindValueChanged(_ => updateBarVisibility(), true); ShowGraph.BindValueChanged(_ => updateGraphVisibility(), true); - } - protected override void PopIn() - { - this.FadeIn(500, Easing.OutQuint); - } - - protected override void PopOut() - { - this.FadeOut(100); + base.LoadComplete(); } protected override void UpdateObjects(IEnumerable objects) @@ -133,7 +100,7 @@ namespace osu.Game.Screens.Play.HUD private void updateBarVisibility() { - bar.Interactive = AllowSeeking.Value; + bar.Interactive = Interactive.Value; updateInfoMargin(); } @@ -150,7 +117,7 @@ namespace osu.Game.Screens.Play.HUD private void updateInfoMargin() { - float finalMargin = bottom_bar_height + (AllowSeeking.Value ? handle_size.Y : 0) + (ShowGraph.Value ? graph_height : 0); + float finalMargin = bottom_bar_height + (Interactive.Value ? handle_size.Y : 0) + (ShowGraph.Value ? graph_height : 0); info.TransformTo(nameof(info.Margin), new MarginPadding { Bottom = finalMargin }, transition_duration, Easing.In); } } diff --git a/osu.Game/Screens/Play/HUD/SongProgress.cs b/osu.Game/Screens/Play/HUD/SongProgress.cs index 4504745eb9..a708b07fc8 100644 --- a/osu.Game/Screens/Play/HUD/SongProgress.cs +++ b/osu.Game/Screens/Play/HUD/SongProgress.cs @@ -4,8 +4,11 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Timing; +using osu.Game.Configuration; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.UI; using osu.Game.Skinning; @@ -16,18 +19,27 @@ namespace osu.Game.Screens.Play.HUD { // Some implementations of this element allow seeking during gameplay playback. // Set a sane default of never handling input to override the behaviour provided by OverlayContainer. - public override bool HandleNonPositionalInput => false; - public override bool HandlePositionalInput => false; + public override bool HandleNonPositionalInput => Interactive.Value; + public override bool HandlePositionalInput => Interactive.Value; + protected override bool BlockScrollInput => false; + /// + /// Whether interaction should be allowed (ie. seeking). If false, interaction controls will not be displayed. + /// + /// + /// By default, this will be automatically decided based on the gameplay state. + /// + public readonly Bindable Interactive = new Bindable(); + + [SettingSource("Show difficulty graph", "Whether a graph displaying difficulty throughout the beatmap should be shown")] + public Bindable ShowGraph { get; } = new BindableBool(true); + public bool UsesFixedAnchor { get; set; } [Resolved] protected IGameplayClock GameplayClock { get; private set; } = null!; - [Resolved(canBeNull: true)] - private DrawableRuleset? drawableRuleset { get; set; } - private IClock? referenceClock; private IEnumerable? objects; @@ -58,15 +70,22 @@ namespace osu.Game.Screens.Play.HUD protected virtual void UpdateObjects(IEnumerable objects) { } [BackgroundDependencyLoader] - private void load() + private void load(DrawableRuleset? drawableRuleset, Player? player) { if (drawableRuleset != null) { + if (player?.Configuration.AllowUserInteraction == true) + ((IBindable)Interactive).BindTo(drawableRuleset.HasReplayLoaded); + Objects = drawableRuleset.Objects; referenceClock = drawableRuleset.FrameStableClock; } } + protected override void PopIn() => this.FadeIn(500, Easing.OutQuint); + + protected override void PopOut() => this.FadeOut(100); + protected override void Update() { base.Update(); diff --git a/osu.Game/Skinning/LegacySongProgress.cs b/osu.Game/Skinning/LegacySongProgress.cs index 10d1431ed4..22aea99291 100644 --- a/osu.Game/Skinning/LegacySongProgress.cs +++ b/osu.Game/Skinning/LegacySongProgress.cs @@ -15,6 +15,10 @@ namespace osu.Game.Skinning { private CircularProgress circularProgress = null!; + // Legacy song progress doesn't support interaction for now. + public override bool HandleNonPositionalInput => false; + public override bool HandlePositionalInput => false; + [BackgroundDependencyLoader] private void load() { @@ -56,16 +60,6 @@ namespace osu.Game.Skinning }; } - protected override void PopIn() - { - this.FadeIn(500, Easing.OutQuint); - } - - protected override void PopOut() - { - this.FadeOut(100); - } - protected override void UpdateProgress(double progress, bool isIntro) { if (isIntro) From f9dd3f6defcf56255338de446931cbaa1f39ecdc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 15:10:01 +0900 Subject: [PATCH 1656/2991] Switch test to specifically target the argon verison of the progress bar --- osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 145f9380f8..c7a4071d54 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -188,7 +188,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestInputDoesntWorkWhenHUDHidden() { - ISongProgressBar? getSongProgress() => hudOverlay.ChildrenOfType().SingleOrDefault(); + ArgonSongProgress? getSongProgress() => hudOverlay.ChildrenOfType().SingleOrDefault(); bool seeked = false; @@ -204,8 +204,8 @@ namespace osu.Game.Tests.Visual.Gameplay Debug.Assert(progress != null); - progress.Interactive = true; - progress.OnSeek += _ => seeked = true; + progress.Interactive.Value = true; + progress.ChildrenOfType().Single().OnSeek += _ => seeked = true; }); AddStep("set showhud false", () => hudOverlay.ShowHud.Value = false); From e8770b84cd2f81f6cf14aada7fa9f51e3ecf6d7c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 15:11:13 +0900 Subject: [PATCH 1657/2991] Remove no longer necessary interface type --- .../Visual/Gameplay/TestSceneHUDOverlay.cs | 2 +- .../TestSceneMultiSpectatorScreen.cs | 2 +- .../Screens/Play/HUD/ArgonSongProgressBar.cs | 2 +- osu.Game/Screens/Play/HUD/ISongProgressBar.cs | 20 ------------------- osu.Game/Screens/Play/HUD/SongProgressBar.cs | 20 ++++++++++++------- 5 files changed, 16 insertions(+), 30 deletions(-) delete mode 100644 osu.Game/Screens/Play/HUD/ISongProgressBar.cs diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index c7a4071d54..5e1412d79b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -213,7 +213,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("attempt seek", () => { - InputManager.MoveMouseTo(getSongProgress() as Drawable); + InputManager.MoveMouseTo(getSongProgress()); InputManager.Click(MouseButton.Left); }); diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs index dd891b456c..e09496b6e9 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs @@ -121,7 +121,7 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("all interactive elements removed", () => this.ChildrenOfType().All(p => !p.ChildrenOfType().Any() && !p.ChildrenOfType().Any() && - p.ChildrenOfType().SingleOrDefault()?.Interactive == false)); + p.ChildrenOfType().SingleOrDefault()?.Interactive == false)); AddStep("restore config hud visibility", () => config.SetValue(OsuSetting.HUDVisibilityMode, originalConfigValue)); } diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs index ff999aa6a3..a76b3d4b50 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play.HUD { - public partial class ArgonSongProgressBar : SliderBar, ISongProgressBar + public partial class ArgonSongProgressBar : SliderBar { private readonly float baseHeight; private readonly float catchupBaseDepth; diff --git a/osu.Game/Screens/Play/HUD/ISongProgressBar.cs b/osu.Game/Screens/Play/HUD/ISongProgressBar.cs deleted file mode 100644 index 683037577d..0000000000 --- a/osu.Game/Screens/Play/HUD/ISongProgressBar.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; - -namespace osu.Game.Screens.Play.HUD -{ - public interface ISongProgressBar - { - /// - /// Whether the progress bar should allow interaction, ie. to perform seek operations. - /// - public bool Interactive { get; set; } - - /// - /// Action which is invoked when a seek is requested, with the proposed millisecond value for the seek operation. - /// - public Action? OnSeek { get; set; } - } -} diff --git a/osu.Game/Screens/Play/HUD/SongProgressBar.cs b/osu.Game/Screens/Play/HUD/SongProgressBar.cs index fade562e3c..c2889d7e8a 100644 --- a/osu.Game/Screens/Play/HUD/SongProgressBar.cs +++ b/osu.Game/Screens/Play/HUD/SongProgressBar.cs @@ -13,16 +13,16 @@ using osu.Framework.Threading; namespace osu.Game.Screens.Play.HUD { - public partial class SongProgressBar : SliderBar, ISongProgressBar + public partial class SongProgressBar : SliderBar { + /// + /// Action which is invoked when a seek is requested, with the proposed millisecond value for the seek operation. + /// public Action? OnSeek { get; set; } - private readonly Box fill; - private readonly Container handleBase; - private readonly Container handleContainer; - - private bool showHandle; - + /// + /// Whether the progress bar should allow interaction, ie. to perform seek operations. + /// public bool Interactive { get => showHandle; @@ -57,6 +57,12 @@ namespace osu.Game.Screens.Play.HUD set => CurrentNumber.Value = value; } + private readonly Box fill; + private readonly Container handleBase; + private readonly Container handleContainer; + + private bool showHandle; + public SongProgressBar(float barHeight, float handleBarHeight, Vector2 handleSize) { CurrentNumber.MinValue = 0; From 742a02607710b79e1c34a61581919815e20befd4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 15:24:03 +0900 Subject: [PATCH 1658/2991] Add comment mentioning why reference clock fallback logic is required --- osu.Game/Screens/Play/HUD/ArgonSongProgress.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs index 4951ad174b..7f4123b094 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs @@ -24,6 +24,8 @@ namespace osu.Game.Screens.Play.HUD [Resolved] private DrawableRuleset? drawableRuleset { get; set; } + // Even though `FrameStabilityContainer` caches as a `GameplayClock`, we need to check it directly via `drawableRuleset` + // as this calculator is not contained within the `FrameStabilityContainer` and won't see the dependency. private IClock referenceClock => drawableRuleset?.FrameStableClock ?? GameplayClock; [Resolved] From 7266d8e10d49027dc8117824f793ab8dc7108ee4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 15:31:55 +0900 Subject: [PATCH 1659/2991] Move "show difficulty graph" settings back to respective implementations to avoid legacy version showing it --- osu.Game/Screens/Play/HUD/ArgonSongProgress.cs | 5 +++++ osu.Game/Screens/Play/HUD/DefaultSongProgress.cs | 5 +++++ osu.Game/Screens/Play/HUD/SongProgress.cs | 4 ---- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs index 7f4123b094..1290101138 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs @@ -3,9 +3,11 @@ using System.Collections.Generic; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Timing; +using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.UI; @@ -21,6 +23,9 @@ namespace osu.Game.Screens.Play.HUD private const float bar_height = 10; + [SettingSource("Show difficulty graph", "Whether a graph displaying difficulty throughout the beatmap should be shown")] + public Bindable ShowGraph { get; } = new BindableBool(true); + [Resolved] private DrawableRuleset? drawableRuleset { get; set; } diff --git a/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs b/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs index 747f292e30..a8bbe87e86 100644 --- a/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs +++ b/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Rulesets.Objects; using osuTK; @@ -24,6 +26,9 @@ namespace osu.Game.Screens.Play.HUD private readonly SongProgressGraph graph; private readonly SongProgressInfo info; + [SettingSource("Show difficulty graph", "Whether a graph displaying difficulty throughout the beatmap should be shown")] + public Bindable ShowGraph { get; } = new BindableBool(true); + [Resolved] private Player? player { get; set; } diff --git a/osu.Game/Screens/Play/HUD/SongProgress.cs b/osu.Game/Screens/Play/HUD/SongProgress.cs index a708b07fc8..4ae79bda5d 100644 --- a/osu.Game/Screens/Play/HUD/SongProgress.cs +++ b/osu.Game/Screens/Play/HUD/SongProgress.cs @@ -8,7 +8,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Timing; -using osu.Game.Configuration; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.UI; using osu.Game.Skinning; @@ -32,9 +31,6 @@ namespace osu.Game.Screens.Play.HUD /// public readonly Bindable Interactive = new Bindable(); - [SettingSource("Show difficulty graph", "Whether a graph displaying difficulty throughout the beatmap should be shown")] - public Bindable ShowGraph { get; } = new BindableBool(true); - public bool UsesFixedAnchor { get; set; } [Resolved] From 1e5dd9165a270aca3a519124e4751912d38a5cb8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 15:37:46 +0900 Subject: [PATCH 1660/2991] Adjust `SkinnableTestScene` to give more breathing room to `RelativeSize` components --- osu.Game/Tests/Visual/SkinnableTestScene.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/osu.Game/Tests/Visual/SkinnableTestScene.cs b/osu.Game/Tests/Visual/SkinnableTestScene.cs index e8f51f9afa..aab1b72990 100644 --- a/osu.Game/Tests/Visual/SkinnableTestScene.cs +++ b/osu.Game/Tests/Visual/SkinnableTestScene.cs @@ -91,7 +91,7 @@ namespace osu.Game.Tests.Visual { RelativeSizeAxes = Axes.Both, BorderColour = Color4.White, - BorderThickness = 5, + BorderThickness = 3, Masking = true, Children = new Drawable[] @@ -142,8 +142,15 @@ namespace osu.Game.Tests.Visual c.AutoSizeAxes = Axes.None; c.Size = Vector2.Zero; - c.RelativeSizeAxes = !autoSize ? Axes.Both : Axes.None; - c.AutoSizeAxes = autoSize ? Axes.Both : Axes.None; + if (autoSize) + c.AutoSizeAxes = Axes.Both; + else + { + c.RelativeSizeAxes = Axes.Both; + c.Anchor = Anchor.Centre; + c.Origin = Anchor.Centre; + c.Size = new Vector2(0.97f); + } } outlineBox.Alpha = autoSize ? 1 : 0; From 04c0a5d7283ff1185349e30666893e0e9cc71708 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 15:44:19 +0900 Subject: [PATCH 1661/2991] Update `TestSceneSongProgress` to properly work with new implementation --- .../Visual/Gameplay/TestSceneSongProgress.cs | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index cecc24a807..bd6a42f9c0 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; @@ -38,28 +39,38 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("reset clock", () => gameplayClockContainer.Reset()); AddStep("set hit objects", setHitObjects); + AddStep("hook seeking", () => + { + applyToDefaultProgress(d => d.ChildrenOfType().Single().OnSeek += t => gameplayClockContainer.Seek(t)); + applyToArgonProgress(d => d.ChildrenOfType().Single().OnSeek += t => gameplayClockContainer.Seek(t)); + }); + AddStep("seek to intro", () => gameplayClockContainer.Seek(skip_target_time)); + AddStep("start", gameplayClockContainer.Start); } [Test] - public void TestDisplay() + public void TestBasic() { - AddStep("seek to intro", () => gameplayClockContainer.Seek(skip_target_time)); - AddStep("start", gameplayClockContainer.Start); + AddToggleStep("toggle seeking", b => + { + applyToDefaultProgress(s => s.Interactive.Value = b); + applyToArgonProgress(s => s.Interactive.Value = b); + }); + + AddToggleStep("toggle graph", b => + { + applyToDefaultProgress(s => s.ShowGraph.Value = b); + applyToArgonProgress(s => s.ShowGraph.Value = b); + }); + AddStep("stop", gameplayClockContainer.Stop); } - [Test] - public void TestToggleSeeking() - { - void applyToDefaultProgress(Action action) => - this.ChildrenOfType().ForEach(action); + private void applyToArgonProgress(Action action) => + this.ChildrenOfType().ForEach(action); - AddStep("allow seeking", () => applyToDefaultProgress(s => s.Interactive.Value = true)); - AddStep("hide graph", () => applyToDefaultProgress(s => s.ShowGraph.Value = false)); - AddStep("disallow seeking", () => applyToDefaultProgress(s => s.Interactive.Value = false)); - AddStep("allow seeking", () => applyToDefaultProgress(s => s.Interactive.Value = true)); - AddStep("show graph", () => applyToDefaultProgress(s => s.ShowGraph.Value = true)); - } + private void applyToDefaultProgress(Action action) => + this.ChildrenOfType().ForEach(action); private void setHitObjects() { From bfb75730a99da5543172053741c3872aea813e87 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 15:45:16 +0900 Subject: [PATCH 1662/2991] Prefix subclasses of `DefaultSongProgress` with `Default` --- ...gressGraph.cs => TestSceneDefaultSongProgressGraph.cs} | 4 ++-- osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs | 2 +- osu.Game/Screens/Play/HUD/DefaultSongProgress.cs | 8 ++++---- .../HUD/{SongProgressBar.cs => DefaultSongProgressBar.cs} | 4 ++-- .../{SongProgressGraph.cs => DefaultSongProgressGraph.cs} | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) rename osu.Game.Tests/Visual/Gameplay/{TestSceneSongProgressGraph.cs => TestSceneDefaultSongProgressGraph.cs} (93%) rename osu.Game/Screens/Play/HUD/{SongProgressBar.cs => DefaultSongProgressBar.cs} (96%) rename osu.Game/Screens/Play/HUD/{SongProgressGraph.cs => DefaultSongProgressGraph.cs} (95%) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgressGraph.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneDefaultSongProgressGraph.cs similarity index 93% rename from osu.Game.Tests/Visual/Gameplay/TestSceneSongProgressGraph.cs rename to osu.Game.Tests/Visual/Gameplay/TestSceneDefaultSongProgressGraph.cs index 5a61502978..66671a506f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgressGraph.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneDefaultSongProgressGraph.cs @@ -14,7 +14,7 @@ using osu.Game.Screens.Play.HUD; namespace osu.Game.Tests.Visual.Gameplay { [TestFixture] - public partial class TestSceneSongProgressGraph : OsuTestScene + public partial class TestSceneDefaultSongProgressGraph : OsuTestScene { private TestSongProgressGraph graph; @@ -59,7 +59,7 @@ namespace osu.Game.Tests.Visual.Gameplay graph.Objects = objects; } - private partial class TestSongProgressGraph : SongProgressGraph + private partial class TestSongProgressGraph : DefaultSongProgressGraph { public int CreationCount { get; private set; } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index bd6a42f9c0..61b15c092b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs @@ -41,7 +41,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("set hit objects", setHitObjects); AddStep("hook seeking", () => { - applyToDefaultProgress(d => d.ChildrenOfType().Single().OnSeek += t => gameplayClockContainer.Seek(t)); + applyToDefaultProgress(d => d.ChildrenOfType().Single().OnSeek += t => gameplayClockContainer.Seek(t)); applyToArgonProgress(d => d.ChildrenOfType().Single().OnSeek += t => gameplayClockContainer.Seek(t)); }); AddStep("seek to intro", () => gameplayClockContainer.Seek(skip_target_time)); diff --git a/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs b/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs index a8bbe87e86..91a34fe374 100644 --- a/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs +++ b/osu.Game/Screens/Play/HUD/DefaultSongProgress.cs @@ -22,8 +22,8 @@ namespace osu.Game.Screens.Play.HUD private const float transition_duration = 200; - private readonly SongProgressBar bar; - private readonly SongProgressGraph graph; + private readonly DefaultSongProgressBar bar; + private readonly DefaultSongProgressGraph graph; private readonly SongProgressInfo info; [SettingSource("Show difficulty graph", "Whether a graph displaying difficulty throughout the beatmap should be shown")] @@ -46,7 +46,7 @@ namespace osu.Game.Screens.Play.HUD Anchor = Anchor.BottomLeft, RelativeSizeAxes = Axes.X, }, - graph = new SongProgressGraph + graph = new DefaultSongProgressGraph { RelativeSizeAxes = Axes.X, Origin = Anchor.BottomLeft, @@ -54,7 +54,7 @@ namespace osu.Game.Screens.Play.HUD Height = graph_height, Margin = new MarginPadding { Bottom = bottom_bar_height }, }, - bar = new SongProgressBar(bottom_bar_height, graph_height, handle_size) + bar = new DefaultSongProgressBar(bottom_bar_height, graph_height, handle_size) { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, diff --git a/osu.Game/Screens/Play/HUD/SongProgressBar.cs b/osu.Game/Screens/Play/HUD/DefaultSongProgressBar.cs similarity index 96% rename from osu.Game/Screens/Play/HUD/SongProgressBar.cs rename to osu.Game/Screens/Play/HUD/DefaultSongProgressBar.cs index c2889d7e8a..0e16067dcc 100644 --- a/osu.Game/Screens/Play/HUD/SongProgressBar.cs +++ b/osu.Game/Screens/Play/HUD/DefaultSongProgressBar.cs @@ -13,7 +13,7 @@ using osu.Framework.Threading; namespace osu.Game.Screens.Play.HUD { - public partial class SongProgressBar : SliderBar + public partial class DefaultSongProgressBar : SliderBar { /// /// Action which is invoked when a seek is requested, with the proposed millisecond value for the seek operation. @@ -63,7 +63,7 @@ namespace osu.Game.Screens.Play.HUD private bool showHandle; - public SongProgressBar(float barHeight, float handleBarHeight, Vector2 handleSize) + public DefaultSongProgressBar(float barHeight, float handleBarHeight, Vector2 handleSize) { CurrentNumber.MinValue = 0; CurrentNumber.MaxValue = 1; diff --git a/osu.Game/Screens/Play/HUD/SongProgressGraph.cs b/osu.Game/Screens/Play/HUD/DefaultSongProgressGraph.cs similarity index 95% rename from osu.Game/Screens/Play/HUD/SongProgressGraph.cs rename to osu.Game/Screens/Play/HUD/DefaultSongProgressGraph.cs index f69a1eccd6..bee5978817 100644 --- a/osu.Game/Screens/Play/HUD/SongProgressGraph.cs +++ b/osu.Game/Screens/Play/HUD/DefaultSongProgressGraph.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Objects; namespace osu.Game.Screens.Play.HUD { - public partial class SongProgressGraph : SquareGraph + public partial class DefaultSongProgressGraph : SquareGraph { private IEnumerable objects; From 8bfd8538897aa288af5a15663c817bff2a4216e7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 16:04:14 +0900 Subject: [PATCH 1663/2991] Fix missing comment --- osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs index a76b3d4b50..7483d9cb51 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs @@ -173,7 +173,7 @@ namespace osu.Game.Screens.Play.HUD protected override void UpdateValue(float value) { - // + // Handled in Update } protected override void Update() From 8030194cd58fddf5b30e90597d339684f509f1f2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 16:04:07 +0900 Subject: [PATCH 1664/2991] Use actual beatmap's hitobjects in test to better display density --- .../Visual/Gameplay/TestSceneSongProgress.cs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index 61b15c092b..561d34285b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs @@ -2,14 +2,12 @@ // 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.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Testing; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu; using osu.Game.Screens.Play; using osu.Game.Screens.Play.HUD; @@ -38,7 +36,7 @@ namespace osu.Game.Tests.Visual.Gameplay public void SetupSteps() { AddStep("reset clock", () => gameplayClockContainer.Reset()); - AddStep("set hit objects", setHitObjects); + AddStep("set hit objects", () => this.ChildrenOfType().ForEach(progress => progress.Objects = Beatmap.Value.Beatmap.HitObjects)); AddStep("hook seeking", () => { applyToDefaultProgress(d => d.ChildrenOfType().Single().OnSeek += t => gameplayClockContainer.Seek(t)); @@ -72,15 +70,6 @@ namespace osu.Game.Tests.Visual.Gameplay private void applyToDefaultProgress(Action action) => this.ChildrenOfType().ForEach(action); - private void setHitObjects() - { - var objects = new List(); - for (double i = 0; i < 5000; i++) - objects.Add(new HitObject { StartTime = i }); - - this.ChildrenOfType().ForEach(progress => progress.Objects = objects); - } - protected override Drawable CreateDefaultImplementation() => new DefaultSongProgress(); protected override Drawable CreateArgonImplementation() => new ArgonSongProgress(); From 5ead85f461eb99775896d09f3931005e0857d030 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 16:13:43 +0900 Subject: [PATCH 1665/2991] Limit catch-up speed in test to emulate gameplay --- .../Visual/Gameplay/TestSceneSongProgress.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index 561d34285b..05e0c05b61 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs @@ -9,6 +9,7 @@ using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Testing; using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.UI; using osu.Game.Screens.Play; using osu.Game.Screens.Play.HUD; using osu.Game.Skinning; @@ -27,9 +28,17 @@ namespace osu.Game.Tests.Visual.Gameplay { Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); - Add(gameplayClockContainer = new MasterGameplayClockContainer(Beatmap.Value, skip_target_time)); + FrameStabilityContainer frameStabilityContainer; - Dependencies.CacheAs(gameplayClockContainer); + Add(gameplayClockContainer = new MasterGameplayClockContainer(Beatmap.Value, skip_target_time) + { + Child = frameStabilityContainer = new FrameStabilityContainer + { + MaxCatchUpFrames = 1 + } + }); + + Dependencies.CacheAs(frameStabilityContainer); } [SetUpSteps] From 42e9b2b48cd8031ba9a75933845a09be14127ae9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 16:29:42 +0900 Subject: [PATCH 1666/2991] Tidy up clock logic in all `SongProgress` classes --- .../Visual/Gameplay/TestSceneSongProgress.cs | 3 ++- .../Screens/Play/HUD/ArgonSongProgress.cs | 13 ++--------- .../Screens/Play/HUD/ArgonSongProgressBar.cs | 22 +++++++++---------- .../ClicksPerSecondCalculator.cs | 8 +++---- osu.Game/Screens/Play/HUD/SongProgress.cs | 15 ++++++++----- osu.Game/Screens/Play/Player.cs | 1 + 6 files changed, 29 insertions(+), 33 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index 05e0c05b61..76cd1b56d7 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs @@ -38,7 +38,8 @@ namespace osu.Game.Tests.Visual.Gameplay } }); - Dependencies.CacheAs(frameStabilityContainer); + Dependencies.CacheAs(gameplayClockContainer); + Dependencies.CacheAs(frameStabilityContainer); } [SetUpSteps] diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs index 1290101138..3a2cd6fe2a 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs @@ -6,11 +6,9 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Timing; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.UI; namespace osu.Game.Screens.Play.HUD { @@ -26,13 +24,6 @@ namespace osu.Game.Screens.Play.HUD [SettingSource("Show difficulty graph", "Whether a graph displaying difficulty throughout the beatmap should be shown")] public Bindable ShowGraph { get; } = new BindableBool(true); - [Resolved] - private DrawableRuleset? drawableRuleset { get; set; } - - // Even though `FrameStabilityContainer` caches as a `GameplayClock`, we need to check it directly via `drawableRuleset` - // as this calculator is not contained within the `FrameStabilityContainer` and won't see the dependency. - private IClock referenceClock => drawableRuleset?.FrameStableClock ?? GameplayClock; - [Resolved] private Player? player { get; set; } @@ -116,12 +107,12 @@ namespace osu.Game.Screens.Play.HUD protected override void UpdateProgress(double progress, bool isIntro) { - bar.ReferenceTime = GameplayClock.CurrentTime; + bar.TrackTime = GameplayClock.CurrentTime; if (isIntro) bar.CurrentTime = 0; else - bar.CurrentTime = referenceClock.CurrentTime; + bar.CurrentTime = FrameStableClock.CurrentTime; } } } diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs index 7483d9cb51..f69d56873d 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs @@ -64,21 +64,21 @@ namespace osu.Game.Screens.Play.HUD set => CurrentNumber.Value = value; } - public double ReferenceTime + public double TrackTime { - private get => currentReference.Value; - set => currentReference.Value = value; + private get => currentTrackTime.Value; + set => currentTrackTime.Value = value; } private double length => EndTime - StartTime; - private readonly BindableNumber currentReference; + private readonly BindableNumber currentTrackTime; public bool Interactive { get; set; } public ArgonSongProgressBar(float barHeight) { - currentReference = new BindableDouble(); + currentTrackTime = new BindableDouble(); setupAlternateValue(); StartTime = 0; @@ -124,9 +124,9 @@ namespace osu.Game.Screens.Play.HUD private void setupAlternateValue() { - CurrentNumber.MaxValueChanged += v => currentReference.MaxValue = v; - CurrentNumber.MinValueChanged += v => currentReference.MinValue = v; - CurrentNumber.PrecisionChanged += v => currentReference.Precision = v; + CurrentNumber.MaxValueChanged += v => currentTrackTime.MaxValue = v; + CurrentNumber.MinValueChanged += v => currentTrackTime.MinValue = v; + CurrentNumber.PrecisionChanged += v => currentTrackTime.Precision = v; } private float normalizedReference @@ -136,7 +136,7 @@ namespace osu.Game.Screens.Play.HUD if (EndTime - StartTime == 0) return 1; - return (float)((ReferenceTime - StartTime) / length); + return (float)((TrackTime - StartTime) / length); } } @@ -183,12 +183,12 @@ namespace osu.Game.Screens.Play.HUD playfieldBar.Length = (float)Interpolation.Lerp(playfieldBar.Length, NormalizedValue, Math.Clamp(Time.Elapsed / 40, 0, 1)); catchupBar.Length = (float)Interpolation.Lerp(catchupBar.Length, normalizedReference, Math.Clamp(Time.Elapsed / 40, 0, 1)); - if (ReferenceTime < CurrentTime) + if (TrackTime < CurrentTime) ChangeChildDepth(catchupBar, playfieldBar.Depth - 0.1f); else ChangeChildDepth(catchupBar, catchupBaseDepth); - float timeDelta = (float)(Math.Abs(CurrentTime - ReferenceTime)); + float timeDelta = (float)(Math.Abs(CurrentTime - TrackTime)); catchupBar.Alpha = MathHelper.Clamp(timeDelta, 0, alpha_threshold) / alpha_threshold; } diff --git a/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs b/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs index bf1f508d7b..ba0c47dc8b 100644 --- a/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs +++ b/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs @@ -15,14 +15,12 @@ namespace osu.Game.Screens.Play.HUD.ClicksPerSecond [Resolved] private IGameplayClock gameplayClock { get; set; } = null!; - [Resolved(canBeNull: true)] - private DrawableRuleset? drawableRuleset { get; set; } + [Resolved] + private IFrameStableClock? frameStableClock { get; set; } public int Value { get; private set; } - // Even though `FrameStabilityContainer` caches as a `GameplayClock`, we need to check it directly via `drawableRuleset` - // as this calculator is not contained within the `FrameStabilityContainer` and won't see the dependency. - private IGameplayClock clock => drawableRuleset?.FrameStableClock ?? gameplayClock; + private IGameplayClock clock => frameStableClock ?? gameplayClock; public ClicksPerSecondCalculator() { diff --git a/osu.Game/Screens/Play/HUD/SongProgress.cs b/osu.Game/Screens/Play/HUD/SongProgress.cs index 4ae79bda5d..4647c0352b 100644 --- a/osu.Game/Screens/Play/HUD/SongProgress.cs +++ b/osu.Game/Screens/Play/HUD/SongProgress.cs @@ -36,7 +36,15 @@ namespace osu.Game.Screens.Play.HUD [Resolved] protected IGameplayClock GameplayClock { get; private set; } = null!; - private IClock? referenceClock; + [Resolved] + private IFrameStableClock? frameStableClock { get; set; } + + /// + /// The reference clock is used to accurately tell the current playfield's time (including catch-up lag). + /// However, if none is available (i.e. used in tests), we fall back to the gameplay clock. + /// + protected IClock FrameStableClock => frameStableClock ?? GameplayClock; + private IEnumerable? objects; public IEnumerable Objects @@ -74,7 +82,6 @@ namespace osu.Game.Screens.Play.HUD ((IBindable)Interactive).BindTo(drawableRuleset.HasReplayLoaded); Objects = drawableRuleset.Objects; - referenceClock = drawableRuleset.FrameStableClock; } } @@ -89,9 +96,7 @@ namespace osu.Game.Screens.Play.HUD if (objects == null) return; - // The reference clock is used to accurately tell the playfield's time. This is obtained from the drawable ruleset. - // However, if no drawable ruleset is available (i.e. used in tests), we fall back to the gameplay clock. - double currentTime = referenceClock?.CurrentTime ?? GameplayClock.CurrentTime; + double currentTime = FrameStableClock.CurrentTime; bool isInIntro = currentTime < FirstHitTime; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 05133fba35..d3ab936a38 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -225,6 +225,7 @@ namespace osu.Game.Screens.Play DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, gameplayMods); dependencies.CacheAs(DrawableRuleset); + dependencies.CacheAs(DrawableRuleset.FrameStableClock); ScoreProcessor = ruleset.CreateScoreProcessor(); ScoreProcessor.Mods.Value = gameplayMods; From 7d0388c55cc9d1131a7a6ba92a73ec72aacc8795 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 16:29:42 +0900 Subject: [PATCH 1667/2991] Cache `IFrameStableClock` in `Player` for easier access Allows directly referencing rather than going through `DrawableRuleset`. Helps with testing and implementation of the new song progress display (#22144). --- .../ClicksPerSecondCalculator.cs | 8 +++----- osu.Game/Screens/Play/HUD/SongProgress.cs | 18 ++++++++++-------- osu.Game/Screens/Play/Player.cs | 1 + 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs b/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs index bf1f508d7b..ba0c47dc8b 100644 --- a/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs +++ b/osu.Game/Screens/Play/HUD/ClicksPerSecond/ClicksPerSecondCalculator.cs @@ -15,14 +15,12 @@ namespace osu.Game.Screens.Play.HUD.ClicksPerSecond [Resolved] private IGameplayClock gameplayClock { get; set; } = null!; - [Resolved(canBeNull: true)] - private DrawableRuleset? drawableRuleset { get; set; } + [Resolved] + private IFrameStableClock? frameStableClock { get; set; } public int Value { get; private set; } - // Even though `FrameStabilityContainer` caches as a `GameplayClock`, we need to check it directly via `drawableRuleset` - // as this calculator is not contained within the `FrameStabilityContainer` and won't see the dependency. - private IGameplayClock clock => drawableRuleset?.FrameStableClock ?? gameplayClock; + private IGameplayClock clock => frameStableClock ?? gameplayClock; public ClicksPerSecondCalculator() { diff --git a/osu.Game/Screens/Play/HUD/SongProgress.cs b/osu.Game/Screens/Play/HUD/SongProgress.cs index 4504745eb9..c5f5de6f48 100644 --- a/osu.Game/Screens/Play/HUD/SongProgress.cs +++ b/osu.Game/Screens/Play/HUD/SongProgress.cs @@ -25,10 +25,15 @@ namespace osu.Game.Screens.Play.HUD [Resolved] protected IGameplayClock GameplayClock { get; private set; } = null!; - [Resolved(canBeNull: true)] - private DrawableRuleset? drawableRuleset { get; set; } + [Resolved] + private IFrameStableClock? frameStableClock { get; set; } + + /// + /// The reference clock is used to accurately tell the current playfield's time (including catch-up lag). + /// However, if none is available (i.e. used in tests), we fall back to the gameplay clock. + /// + protected IClock FrameStableClock => frameStableClock ?? GameplayClock; - private IClock? referenceClock; private IEnumerable? objects; public IEnumerable Objects @@ -58,12 +63,11 @@ namespace osu.Game.Screens.Play.HUD protected virtual void UpdateObjects(IEnumerable objects) { } [BackgroundDependencyLoader] - private void load() + private void load(DrawableRuleset? drawableRuleset) { if (drawableRuleset != null) { Objects = drawableRuleset.Objects; - referenceClock = drawableRuleset.FrameStableClock; } } @@ -74,9 +78,7 @@ namespace osu.Game.Screens.Play.HUD if (objects == null) return; - // The reference clock is used to accurately tell the playfield's time. This is obtained from the drawable ruleset. - // However, if no drawable ruleset is available (i.e. used in tests), we fall back to the gameplay clock. - double currentTime = referenceClock?.CurrentTime ?? GameplayClock.CurrentTime; + double currentTime = FrameStableClock.CurrentTime; bool isInIntro = currentTime < FirstHitTime; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 05133fba35..d3ab936a38 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -225,6 +225,7 @@ namespace osu.Game.Screens.Play DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, gameplayMods); dependencies.CacheAs(DrawableRuleset); + dependencies.CacheAs(DrawableRuleset.FrameStableClock); ScoreProcessor = ruleset.CreateScoreProcessor(); ScoreProcessor.Mods.Value = gameplayMods; From f3677ab33dde950ef65d742b9a0169cbc17d6bb1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 16:38:21 +0900 Subject: [PATCH 1668/2991] Simplify depth change logic --- osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs index f69d56873d..43969f2593 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs @@ -22,7 +22,6 @@ namespace osu.Game.Screens.Play.HUD public partial class ArgonSongProgressBar : SliderBar { private readonly float baseHeight; - private readonly float catchupBaseDepth; private readonly RoundedBar playfieldBar; private readonly RoundedBar catchupBar; @@ -118,7 +117,7 @@ namespace osu.Game.Screens.Play.HUD RelativeSizeAxes = Axes.Both }, }; - catchupBaseDepth = catchupBar.Depth; + mainColourDarkened = Colour4.White.Darken(1 / 3f); } @@ -184,9 +183,9 @@ namespace osu.Game.Screens.Play.HUD catchupBar.Length = (float)Interpolation.Lerp(catchupBar.Length, normalizedReference, Math.Clamp(Time.Elapsed / 40, 0, 1)); if (TrackTime < CurrentTime) - ChangeChildDepth(catchupBar, playfieldBar.Depth - 0.1f); + ChangeChildDepth(catchupBar, -1); else - ChangeChildDepth(catchupBar, catchupBaseDepth); + ChangeChildDepth(catchupBar, 0); float timeDelta = (float)(Math.Abs(CurrentTime - TrackTime)); catchupBar.Alpha = MathHelper.Clamp(timeDelta, 0, alpha_threshold) / alpha_threshold; From 01558a919952c0965c4661b6f538ceae1fe2d3c2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 16:56:07 +0900 Subject: [PATCH 1669/2991] Tidy up height logic and allow hovering above bar for easier interaction --- .../Screens/Play/HUD/ArgonSongProgressBar.cs | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs index 43969f2593..028ba7e35b 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs @@ -4,7 +4,6 @@ using System; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; @@ -21,7 +20,12 @@ namespace osu.Game.Screens.Play.HUD { public partial class ArgonSongProgressBar : SliderBar { - private readonly float baseHeight; + public Action? OnSeek { get; set; } + + // Parent will handle restricting the area of valid input. + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; + + private readonly float barHeight; private readonly RoundedBar playfieldBar; private readonly RoundedBar catchupBar; @@ -32,8 +36,8 @@ namespace osu.Game.Screens.Play.HUD private readonly ColourInfo mainColour; private readonly ColourInfo mainColourDarkened; - private ColourInfo altColour; - private ColourInfo altColourDarkened; + private ColourInfo catchUpColour; + private ColourInfo catchUpColourDarkened; public bool ShowBackground { @@ -43,8 +47,6 @@ namespace osu.Game.Screens.Play.HUD private const float alpha_threshold = 2500; - public Action? OnSeek { get; set; } - public double StartTime { private get => CurrentNumber.MinValue; @@ -84,8 +86,7 @@ namespace osu.Game.Screens.Play.HUD EndTime = 1; RelativeSizeAxes = Axes.X; - baseHeight = barHeight; - Height = baseHeight; + Height = this.barHeight = barHeight; CornerRadius = 5; Masking = true; @@ -142,31 +143,30 @@ namespace osu.Game.Screens.Play.HUD [BackgroundDependencyLoader] private void load(OsuColour colours) { - catchupBar.AccentColour = altColour = colours.BlueLight; - altColourDarkened = colours.BlueLight.Darken(1 / 3f); + catchUpColour = colours.BlueLight; + catchUpColourDarkened = colours.BlueDark; + showBackground.BindValueChanged(_ => updateBackground(), true); } private void updateBackground() { background.FadeTo(showBackground.Value ? 1 / 4f : 0, 200, Easing.In); - catchupBar.TransformTo(nameof(catchupBar.AccentColour), ShowBackground ? altColour : altColourDarkened, 200, Easing.In); + catchupBar.TransformTo(nameof(catchupBar.AccentColour), ShowBackground ? catchUpColour : catchUpColourDarkened, 200, Easing.In); playfieldBar.TransformTo(nameof(playfieldBar.AccentColour), ShowBackground ? mainColour : mainColourDarkened, 200, Easing.In); } protected override bool OnHover(HoverEvent e) { if (Interactive) - this.ResizeHeightTo(baseHeight * 3.5f, 200, Easing.Out); + this.ResizeHeightTo(barHeight * 3.5f, 200, Easing.Out); return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { - if (Interactive) - this.ResizeHeightTo(baseHeight, 200, Easing.In); - + this.ResizeHeightTo(barHeight, 800, Easing.OutQuint); base.OnHoverLost(e); } From 67b40dd2343d279ac13b11b8f5c090e2a9fd1326 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 17:09:39 +0900 Subject: [PATCH 1670/2991] Adjust the seek effect to feel better --- osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs index 028ba7e35b..6db1072fbb 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs @@ -45,8 +45,6 @@ namespace osu.Game.Screens.Play.HUD set => showBackground.Value = value; } - private const float alpha_threshold = 2500; - public double StartTime { private get => CurrentNumber.MinValue; @@ -152,7 +150,6 @@ namespace osu.Game.Screens.Play.HUD private void updateBackground() { background.FadeTo(showBackground.Value ? 1 / 4f : 0, 200, Easing.In); - catchupBar.TransformTo(nameof(catchupBar.AccentColour), ShowBackground ? catchUpColour : catchUpColourDarkened, 200, Easing.In); playfieldBar.TransformTo(nameof(playfieldBar.AccentColour), ShowBackground ? mainColour : mainColourDarkened, 200, Easing.In); } @@ -188,7 +185,17 @@ namespace osu.Game.Screens.Play.HUD ChangeChildDepth(catchupBar, 0); float timeDelta = (float)(Math.Abs(CurrentTime - TrackTime)); - catchupBar.Alpha = MathHelper.Clamp(timeDelta, 0, alpha_threshold) / alpha_threshold; + + const float colour_transition_threshold = 20000; + + catchupBar.AccentColour = Interpolation.ValueAt( + Math.Min(timeDelta, colour_transition_threshold), + ShowBackground ? mainColour : mainColourDarkened, + ShowBackground ? catchUpColour : catchUpColourDarkened, + 0, colour_transition_threshold, + Easing.OutQuint); + + catchupBar.Alpha = Math.Max(1, catchupBar.Length); } private ScheduledDelegate? scheduledSeek; From 04705504c583de28139af134ae8d00d194c104a3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 17:19:57 +0900 Subject: [PATCH 1671/2991] Move cache to more appropriate location --- osu.Game/Screens/Play/Player.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index d3ab936a38..77c16718f5 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -225,7 +225,6 @@ namespace osu.Game.Screens.Play DrawableRuleset = ruleset.CreateDrawableRulesetWith(playableBeatmap, gameplayMods); dependencies.CacheAs(DrawableRuleset); - dependencies.CacheAs(DrawableRuleset.FrameStableClock); ScoreProcessor = ruleset.CreateScoreProcessor(); ScoreProcessor.Mods.Value = gameplayMods; @@ -310,6 +309,8 @@ namespace osu.Game.Screens.Play }); } + dependencies.CacheAs(DrawableRuleset.FrameStableClock); + // add the overlay components as a separate step as they proxy some elements from the above underlay/gameplay components. // also give the overlays the ruleset skin provider to allow rulesets to potentially override HUD elements (used to disable combo counters etc.) // we may want to limit this in the future to disallow rulesets from outright replacing elements the user expects to be there. From ecb4727aeca1d1011a793ccab2b85f8f67bc6dc8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 17:33:14 +0900 Subject: [PATCH 1672/2991] Fix formatting issues --- .../Blueprints/Sliders/Components/SliderBodyPiece.cs | 2 +- .../Blueprints/Sliders/SliderSelectionBlueprint.cs | 2 +- .../Edit/Compose/Components/BlueprintContainer.cs | 11 +++++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs index 4ff38cd1f8..68a44eb2f8 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/SliderBodyPiece.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components /// Offset in absolute (local) coordinates from the end of the curve. /// public Vector2 PathEndLocation => body.PathEndOffset; - + public SliderBodyPiece() { InternalChild = body = new ManualSliderBody diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 90c97e2752..634897e3d5 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -410,7 +410,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders ?? BodyPiece.ToScreenSpace(BodyPiece.PathStartLocation); public override Vector2 ScreenSpaceEndPoint => DrawableObject.SliderBody?.ToScreenSpace(DrawableObject.SliderBody.PathEndOffset) - ?? BodyPiece.ToScreenSpace(BodyPiece.PathEndLocation); + ?? BodyPiece.ToScreenSpace(BodyPiece.PathEndLocation); public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => BodyPiece.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true; diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 113dffbcb0..c9d9f2266a 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -462,8 +462,8 @@ namespace osu.Game.Screens.Edit.Compose.Components movementBlueprints = SortForMovement(SelectionHandler.SelectedBlueprints).ToArray(); movementBlueprintOriginalPositions = movementBlueprints.Select(m => m.ScreenSpaceSelectionPoint).ToArray(); movementBlueprintOriginalEndPositions = movementBlueprints.Where(m => m.ScreenSpaceSelectionPoint != m.ScreenSpaceEndPoint) - .Select(m => m.ScreenSpaceEndPoint).ToArray(); - + .Select(m => m.ScreenSpaceEndPoint).ToArray(); + return true; } @@ -491,12 +491,14 @@ namespace osu.Game.Screens.Edit.Compose.Components if (snapProvider != null) { var currentSelectionPointPositions = movementBlueprints.Select(m => m.ScreenSpaceSelectionPoint).ToArray(); + if (checkSnappingForNearbyObjects(distanceTraveled, movementBlueprintOriginalPositions, currentSelectionPointPositions)) return true; var currentEndPointPositions = movementBlueprints.Where(m => m.ScreenSpaceSelectionPoint != m.ScreenSpaceEndPoint) - .Select(m => m.ScreenSpaceEndPoint) - .ToArray(); + .Select(m => m.ScreenSpaceEndPoint) + .ToArray(); + if (checkSnappingForNearbyObjects(distanceTraveled, movementBlueprintOriginalEndPositions, currentEndPointPositions)) return true; } @@ -542,6 +544,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (SelectionHandler.HandleMovement(new MoveSelectionEvent(movementBlueprints[i], delta))) return true; } + return false; } From 522bb8bccafc93603d068775b6c3a28cd3b58c25 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 18:08:58 +0900 Subject: [PATCH 1673/2991] Use `ComputeAccuracy` to get imminent accuracy --- osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs | 15 +++++++++++++-- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 18 +++++++++++------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs index 78e6acf23a..02d4fb4d67 100644 --- a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs +++ b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs @@ -51,11 +51,22 @@ namespace osu.Game.Rulesets.Mods protected override bool FailCondition(HealthProcessor healthProcessor, JudgementResult result) { - // accuracy calculation logic taken from `ScoreProcessor`. should be updated here if the formula ever changes. if (!result.Type.IsScorable() || result.Type.IsBonus()) return false; - return scoreProcessor.Accuracy.Value < MinimumAccuracy.Value; + return getAccuracyWithImminentResultAdded(result) < MinimumAccuracy.Value; + } + + private double getAccuracyWithImminentResultAdded(JudgementResult result) + { + var score = new ScoreInfo { Ruleset = scoreProcessor.Ruleset.RulesetInfo }; + + // This is super ugly, but if we don't do it this way we will not have the most recent result added to the accuracy value. + // Hopefully we can improve this in the future. + scoreProcessor.PopulateScore(score); + score.Statistics[result.Type]++; + + return scoreProcessor.ComputeAccuracy(score); } } diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index ff0d91c0dd..3ff1b69612 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -97,7 +97,11 @@ namespace osu.Game.Rulesets.Scoring /// protected virtual double ClassicScoreMultiplier => 36; - private readonly Ruleset ruleset; + /// + /// The ruleset this score processor is valid for. + /// + public readonly Ruleset Ruleset; + private readonly double accuracyPortion; private readonly double comboPortion; @@ -145,7 +149,7 @@ namespace osu.Game.Rulesets.Scoring public ScoreProcessor(Ruleset ruleset) { - this.ruleset = ruleset; + this.Ruleset = ruleset; accuracyPortion = DefaultAccuracyPortion; comboPortion = DefaultComboPortion; @@ -291,8 +295,8 @@ namespace osu.Game.Rulesets.Scoring [Pure] public double ComputeAccuracy(ScoreInfo scoreInfo) { - if (!ruleset.RulesetInfo.Equals(scoreInfo.Ruleset)) - throw new ArgumentException($"Unexpected score ruleset. Expected \"{ruleset.RulesetInfo.ShortName}\" but was \"{scoreInfo.Ruleset.ShortName}\"."); + if (!Ruleset.RulesetInfo.Equals(scoreInfo.Ruleset)) + throw new ArgumentException($"Unexpected score ruleset. Expected \"{Ruleset.RulesetInfo.ShortName}\" but was \"{scoreInfo.Ruleset.ShortName}\"."); // We only extract scoring values from the score's statistics. This is because accuracy is always relative to the point of pass or fail rather than relative to the whole beatmap. extractScoringValues(scoreInfo.Statistics, out var current, out var maximum); @@ -312,8 +316,8 @@ namespace osu.Game.Rulesets.Scoring [Pure] public long ComputeScore(ScoringMode mode, ScoreInfo scoreInfo) { - if (!ruleset.RulesetInfo.Equals(scoreInfo.Ruleset)) - throw new ArgumentException($"Unexpected score ruleset. Expected \"{ruleset.RulesetInfo.ShortName}\" but was \"{scoreInfo.Ruleset.ShortName}\"."); + if (!Ruleset.RulesetInfo.Equals(scoreInfo.Ruleset)) + throw new ArgumentException($"Unexpected score ruleset. Expected \"{Ruleset.RulesetInfo.ShortName}\" but was \"{scoreInfo.Ruleset.ShortName}\"."); extractScoringValues(scoreInfo, out var current, out var maximum); @@ -552,7 +556,7 @@ namespace osu.Game.Rulesets.Scoring break; default: - maxResult = maxBasicResult ??= ruleset.GetHitResults().MaxBy(kvp => Judgement.ToNumericResult(kvp.result)).result; + maxResult = maxBasicResult ??= Ruleset.GetHitResults().MaxBy(kvp => Judgement.ToNumericResult(kvp.result)).result; break; } From d4f2cd244db510f7d0096ad514e5af6214ad2067 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 18:12:40 +0900 Subject: [PATCH 1674/2991] Fix broken test step --- osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs index 76cd1b56d7..5855838d3c 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual.Gameplay applyToArgonProgress(d => d.ChildrenOfType().Single().OnSeek += t => gameplayClockContainer.Seek(t)); }); AddStep("seek to intro", () => gameplayClockContainer.Seek(skip_target_time)); - AddStep("start", gameplayClockContainer.Start); + AddStep("start", () => gameplayClockContainer.Start()); } [Test] From 4ef940653bad6fb9097d59401cacc53a417488d6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 19:03:03 +0900 Subject: [PATCH 1675/2991] Fix legacy judgement animation not matching perfectly This will be the final attempt to get it right. I was seemingly drunk last time I wrote the logic. Closes #21892. --- osu.Game/Skinning/LegacyJudgementPieceOld.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game/Skinning/LegacyJudgementPieceOld.cs b/osu.Game/Skinning/LegacyJudgementPieceOld.cs index 0223e7a5a2..796080f4f5 100644 --- a/osu.Game/Skinning/LegacyJudgementPieceOld.cs +++ b/osu.Game/Skinning/LegacyJudgementPieceOld.cs @@ -65,11 +65,14 @@ namespace osu.Game.Skinning default: this.ScaleTo(0.6f).Then() - .ScaleTo(1.1f, fade_in_length * 0.8f).Then() - // this is actually correct to match stable; there were overlapping transforms. - .ScaleTo(0.9f).Delay(fade_in_length * 0.2f) - .ScaleTo(1.1f).ScaleTo(0.9f, fade_in_length * 0.2f).Then() - .ScaleTo(0.95f).ScaleTo(finalScale, fade_in_length * 0.2f); + .ScaleTo(1.1f, fade_in_length * 0.8f).Then() // t = 0.8 + .Delay(fade_in_length * 0.2f) // t = 1.0 + .ScaleTo(0.9f, fade_in_length * 0.2f).Then() // t = 1.2 + + // stable dictates scale of 0.9->1 over time 1.0 to 1.4, but we are already at 1.2. + // so we need to force the current value to be correct at 1.2 (0.95) then complete the + // second half of the transform. + .ScaleTo(0.95f).ScaleTo(finalScale, fade_in_length * 0.2f); // t = 1.4 break; } } From 3b27774561c054b3234c82341c070fb581e4b9b4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Jan 2023 19:13:26 +0900 Subject: [PATCH 1676/2991] Remove `OnlineID` sort consideration --- .../SongSelect/TestSceneBeatmapCarousel.cs | 88 ++++--------------- .../Select/Carousel/CarouselBeatmapSet.cs | 8 +- 2 files changed, 20 insertions(+), 76 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index e658d87497..65ce0429fc 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -613,50 +613,6 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("Items remain in descending added order", () => carousel.BeatmapSets.Select(s => s.DateAdded), () => Is.Ordered.Descending); } - /// - /// Ensures stability is maintained on different sort modes for items with equal properties. - /// - [Test] - public void TestSortingStabilityOnlineID() - { - var sets = new List(); - int idOffset = 0; - - AddStep("Populuate beatmap sets", () => - { - sets.Clear(); - - for (int i = 0; i < 10; i++) - { - var set = TestResources.CreateTestBeatmapSetInfo(); - - // only need to set the first as they are a shared reference. - var beatmap = set.Beatmaps.First(); - - beatmap.Metadata.Artist = $"artist {i / 2}"; - beatmap.Metadata.Title = $"title {9 - i}"; - - // testing the case where DateAdded happens to equal (quite rare). - set.DateAdded = DateTimeOffset.UnixEpoch; - - sets.Add(set); - } - - idOffset = sets.First().OnlineID; - }); - - loadBeatmaps(sets); - - AddStep("Sort by artist", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Artist }, false)); - AddAssert("Items remain in original order", () => carousel.BeatmapSets.Select((set, index) => set.OnlineID == idOffset + index).All(b => b)); - - AddStep("Sort by title", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Title }, false)); - AddAssert("Items are in reverse order", () => carousel.BeatmapSets.Select((set, index) => set.OnlineID == idOffset + sets.Count - index - 1).All(b => b)); - - AddStep("Sort by artist", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Artist }, false)); - AddAssert("Items reset to original order", () => carousel.BeatmapSets.Select((set, index) => set.OnlineID == idOffset + index).All(b => b)); - } - /// /// Ensures stability is maintained on different sort modes while a new item is added to the carousel. /// @@ -664,7 +620,6 @@ namespace osu.Game.Tests.Visual.SongSelect public void TestSortingStabilityWithRemovedAndReaddedItem() { List sets = new List(); - int idOffset = 0; AddStep("Populuate beatmap sets", () => { @@ -685,28 +640,24 @@ namespace osu.Game.Tests.Visual.SongSelect sets.Add(set); } - - idOffset = sets.First().OnlineID; }); + Guid[] originalOrder = null!; + loadBeatmaps(sets); AddStep("Sort by artist", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Artist }, false)); - assertOriginalOrderMaintained(); + + AddAssert("Items in descending added order", () => carousel.BeatmapSets.Select(s => s.DateAdded), () => Is.Ordered.Descending); + AddStep("Save order", () => originalOrder = carousel.BeatmapSets.Select(s => s.ID).ToArray()); AddStep("Remove item", () => carousel.RemoveBeatmapSet(sets[1])); AddStep("Re-add item", () => carousel.UpdateBeatmapSet(sets[1])); - assertOriginalOrderMaintained(); + AddAssert("Order didn't change", () => carousel.BeatmapSets.Select(s => s.ID), () => Is.EqualTo(originalOrder)); AddStep("Sort by title", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Title }, false)); - assertOriginalOrderMaintained(); - - void assertOriginalOrderMaintained() - { - AddAssert("Items remain in original order", - () => carousel.BeatmapSets.Select(s => s.OnlineID), () => Is.EqualTo(carousel.BeatmapSets.Select((set, index) => idOffset + index))); - } + AddAssert("Order didn't change", () => carousel.BeatmapSets.Select(s => s.ID), () => Is.EqualTo(originalOrder)); } /// @@ -716,7 +667,6 @@ namespace osu.Game.Tests.Visual.SongSelect public void TestSortingStabilityWithNewItems() { List sets = new List(); - int idOffset = 0; AddStep("Populuate beatmap sets", () => { @@ -737,14 +687,16 @@ namespace osu.Game.Tests.Visual.SongSelect sets.Add(set); } - - idOffset = sets.First().OnlineID; }); + Guid[] originalOrder = null!; + loadBeatmaps(sets); AddStep("Sort by artist", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Artist }, false)); - assertOriginalOrderMaintained(); + + AddAssert("Items in descending added order", () => carousel.BeatmapSets.Select(s => s.DateAdded), () => Is.Ordered.Descending); + AddStep("Save order", () => originalOrder = carousel.BeatmapSets.Select(s => s.ID).ToArray()); AddStep("Add new item", () => { @@ -756,22 +708,18 @@ namespace osu.Game.Tests.Visual.SongSelect beatmap.Metadata.Artist = "same artist"; beatmap.Metadata.Title = "same title"; - // testing the case where DateAdded happens to equal (quite rare). - set.DateAdded = DateTimeOffset.UnixEpoch; + set.DateAdded = DateTimeOffset.FromUnixTimeSeconds(1); carousel.UpdateBeatmapSet(set); + + // add set to expected ordering + originalOrder = originalOrder.Prepend(set.ID).ToArray(); }); - assertOriginalOrderMaintained(); + AddAssert("Order didn't change", () => carousel.BeatmapSets.Select(s => s.ID), () => Is.EqualTo(originalOrder)); AddStep("Sort by title", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Title }, false)); - assertOriginalOrderMaintained(); - - void assertOriginalOrderMaintained() - { - AddAssert("Items remain in original order", - () => carousel.BeatmapSets.Select(s => s.OnlineID), () => Is.EqualTo(carousel.BeatmapSets.Select((set, index) => idOffset + index))); - } + AddAssert("Order didn't change", () => carousel.BeatmapSets.Select(s => s.ID), () => Is.EqualTo(originalOrder)); } [Test] diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index 7c919d3586..6004c1c04e 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -121,14 +121,10 @@ namespace osu.Game.Screens.Select.Carousel if (comparison != 0) return comparison; - // If the initial sort could not differentiate, attempt to use DateAdded and OnlineID to order sets in a stable fashion. - // This directionality is a touch arbitrary as while DateAdded puts newer beatmaps first, the OnlineID fallback puts lower IDs first. - // Can potentially be changed in the future if users actually notice / have preference, but keeping it this way matches historical tests. - + // If the initial sort could not differentiate, attempt to use DateAdded to order sets in a stable fashion. + // The directionality of this matches the current SortMode.DateAdded, but we may want to reconsider if that becomes a user decision (ie. asc / desc). comparison = otherSet.BeatmapSet.DateAdded.CompareTo(BeatmapSet.DateAdded); - if (comparison != 0) return comparison; - comparison = BeatmapSet.OnlineID.CompareTo(otherSet.BeatmapSet.OnlineID); if (comparison != 0) return comparison; // If no online ID is available, fallback to our internal GUID for stability. From 24ed84aad04b1e2c6d04375f5553e6061836f97d Mon Sep 17 00:00:00 2001 From: StanR Date: Wed, 18 Jan 2023 16:25:11 +0300 Subject: [PATCH 1677/2991] Add tiered level badge colouring --- .../Visual/Online/TestSceneLevelBadge.cs | 58 +++++++++++++++++++ osu.Game/Graphics/OsuColour.cs | 36 ++++++++++++ .../Profile/Header/Components/LevelBadge.cs | 39 +++++++++++-- osu.Game/Scoring/RankingTier.cs | 17 ++++++ 4 files changed, 146 insertions(+), 4 deletions(-) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneLevelBadge.cs create mode 100644 osu.Game/Scoring/RankingTier.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneLevelBadge.cs b/osu.Game.Tests/Visual/Online/TestSceneLevelBadge.cs new file mode 100644 index 0000000000..71c57896d2 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneLevelBadge.cs @@ -0,0 +1,58 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Overlays.Profile.Header.Components; +using osu.Game.Users; +using osuTK; + +namespace osu.Game.Tests.Visual.Online +{ + [TestFixture] + public partial class TestSceneLevelBadge : OsuTestScene + { + public TestSceneLevelBadge() + { + var levels = new List(); + + for (int i = 0; i < 11; i++) + { + levels.Add(new UserStatistics.LevelInfo + { + Current = i * 10 + }); + } + + levels.Add(new UserStatistics.LevelInfo { Current = 101 }); + levels.Add(new UserStatistics.LevelInfo { Current = 105 }); + levels.Add(new UserStatistics.LevelInfo { Current = 110 }); + levels.Add(new UserStatistics.LevelInfo { Current = 115 }); + levels.Add(new UserStatistics.LevelInfo { Current = 120 }); + + Children = new Drawable[] + { + new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5), + ChildrenEnumerable = levels.Select(l => new LevelBadge + { + Size = new Vector2(60), + LevelInfo = { Value = l } + }) + } + }; + } + } +} diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index c5659aaf57..5e2649377a 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -5,6 +5,7 @@ using System; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics.Colour; using osu.Game.Beatmaps; using osu.Game.Online.Rooms; using osu.Game.Overlays; @@ -187,6 +188,41 @@ namespace osu.Game.Graphics } } + /// + /// Retrieves colour for a . + /// See https://www.figma.com/file/YHWhp9wZ089YXgB7pe6L1k/Tier-Colours + /// + public ColourInfo ForRankingTiers(RankingTier tier) + { + switch (tier) + { + default: + case RankingTier.Iron: + return Color4Extensions.FromHex(@"BAB3AB"); + + case RankingTier.Bronze: + return ColourInfo.GradientVertical(Color4Extensions.FromHex(@"B88F7A"), Color4Extensions.FromHex(@"855C47")); + + case RankingTier.Silver: + return ColourInfo.GradientVertical(Color4Extensions.FromHex(@"E0E0EB"), Color4Extensions.FromHex(@"A3A3C2")); + + case RankingTier.Gold: + return ColourInfo.GradientVertical(Color4Extensions.FromHex(@"F0E4A8"), Color4Extensions.FromHex(@"E0C952")); + + case RankingTier.Platinum: + return ColourInfo.GradientVertical(Color4Extensions.FromHex(@"A8F0EF"), Color4Extensions.FromHex(@"52E0DF")); + + case RankingTier.Rhodium: + return ColourInfo.GradientVertical(Color4Extensions.FromHex(@"D9F8D3"), Color4Extensions.FromHex(@"A0CF96")); + + case RankingTier.Radiant: + return ColourInfo.GradientVertical(Color4Extensions.FromHex(@"97DCFF"), Color4Extensions.FromHex(@"ED82FF")); + + case RankingTier.Lustrous: + return ColourInfo.GradientVertical(Color4Extensions.FromHex(@"FFE600"), Color4Extensions.FromHex(@"ED82FF")); + } + } + /// /// Returns a foreground text colour that is supposed to contrast well with /// the supplied . diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index 00bb8cbc75..ddc084a600 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Sprites; @@ -12,6 +13,7 @@ using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Resources.Localisation.Web; +using osu.Game.Scoring; using osu.Game.Users; namespace osu.Game.Overlays.Profile.Header.Components @@ -23,6 +25,10 @@ namespace osu.Game.Overlays.Profile.Header.Components public LocalisableString TooltipText { get; private set; } private OsuSpriteText levelText = null!; + private Sprite sprite = null!; + + [Resolved] + private OsuColour osuColour { get; set; } = null!; public LevelBadge() { @@ -34,7 +40,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { InternalChildren = new Drawable[] { - new Sprite + sprite = new Sprite { RelativeSizeAxes = Axes.Both, Texture = textures.Get("Profile/levelbadge"), @@ -58,9 +64,34 @@ namespace osu.Game.Overlays.Profile.Header.Components private void updateLevel(UserStatistics.LevelInfo? levelInfo) { - string level = levelInfo?.Current.ToString() ?? "0"; - levelText.Text = level; - TooltipText = UsersStrings.ShowStatsLevel(level); + int level = levelInfo?.Current ?? 0; + + levelText.Text = level.ToString(); + TooltipText = UsersStrings.ShowStatsLevel(level.ToString()); + + sprite.Colour = mapLevelToTierColour(level); + } + + private ColourInfo mapLevelToTierColour(int level) + { + var tier = RankingTier.Iron; + + if (level > 0) + { + tier = (RankingTier)(level / 20); + } + + if (level >= 105) + { + tier = RankingTier.Radiant; + } + + if (level >= 110) + { + tier = RankingTier.Lustrous; + } + + return osuColour.ForRankingTiers(tier); } } } diff --git a/osu.Game/Scoring/RankingTier.cs b/osu.Game/Scoring/RankingTier.cs new file mode 100644 index 0000000000..e57c241515 --- /dev/null +++ b/osu.Game/Scoring/RankingTier.cs @@ -0,0 +1,17 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Scoring +{ + public enum RankingTier + { + Iron, + Bronze, + Silver, + Gold, + Platinum, + Rhodium, + Radiant, + Lustrous + } +} From 8ae82484b5ec550261366337eb5fcec04549495d Mon Sep 17 00:00:00 2001 From: StanR Date: Wed, 18 Jan 2023 16:38:58 +0300 Subject: [PATCH 1678/2991] Usings --- osu.Game.Tests/Visual/Online/TestSceneLevelBadge.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneLevelBadge.cs b/osu.Game.Tests/Visual/Online/TestSceneLevelBadge.cs index 71c57896d2..fef6dd0477 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneLevelBadge.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneLevelBadge.cs @@ -6,9 +6,6 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Users; using osuTK; From 18baf3dd5d618b66e237809a0eb61da51af858b7 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 18 Jan 2023 17:30:34 +0300 Subject: [PATCH 1679/2991] Log delete failure --- osu.Game/Overlays/Comments/DrawableComment.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 1df65ab4b1..59ac4b3254 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -22,6 +22,7 @@ using System.Collections.Specialized; using System.Diagnostics; using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Localisation; +using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; @@ -419,8 +420,9 @@ namespace osu.Game.Overlays.Comments if (!ShowDeleted.Value) Hide(); }); - request.Failure += _ => Schedule(() => + request.Failure += e => Schedule(() => { + Logger.Error(e, "Failed to delete comment"); actionsLoading.Hide(); actionsContainer.Show(); }); From c9375c056e3444b4e0fe9730b31ee025ddf3aa95 Mon Sep 17 00:00:00 2001 From: Wleter Date: Wed, 18 Jan 2023 15:54:24 +0100 Subject: [PATCH 1680/2991] revert back name change --- .../Edit/Compose/Components/BlueprintContainer.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index c9d9f2266a..49e4ab5300 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -486,20 +486,20 @@ namespace osu.Game.Screens.Edit.Compose.Components Debug.Assert(movementBlueprintOriginalPositions != null); - Vector2 distanceTraveled = e.ScreenSpaceMousePosition - e.ScreenSpaceMouseDownPosition; + Vector2 distanceTravelled = e.ScreenSpaceMousePosition - e.ScreenSpaceMouseDownPosition; if (snapProvider != null) { var currentSelectionPointPositions = movementBlueprints.Select(m => m.ScreenSpaceSelectionPoint).ToArray(); - if (checkSnappingForNearbyObjects(distanceTraveled, movementBlueprintOriginalPositions, currentSelectionPointPositions)) + if (checkSnappingForNearbyObjects(distanceTravelled, movementBlueprintOriginalPositions, currentSelectionPointPositions)) return true; var currentEndPointPositions = movementBlueprints.Where(m => m.ScreenSpaceSelectionPoint != m.ScreenSpaceEndPoint) .Select(m => m.ScreenSpaceEndPoint) .ToArray(); - if (checkSnappingForNearbyObjects(distanceTraveled, movementBlueprintOriginalEndPositions, currentEndPointPositions)) + if (checkSnappingForNearbyObjects(distanceTravelled, movementBlueprintOriginalEndPositions, currentEndPointPositions)) return true; } @@ -507,7 +507,7 @@ namespace osu.Game.Screens.Edit.Compose.Components // item in the selection. // The final movement position, relative to movementBlueprintOriginalPosition. - Vector2 movePosition = movementBlueprintOriginalPositions.First() + distanceTraveled; + Vector2 movePosition = movementBlueprintOriginalPositions.First() + distanceTravelled; // Retrieve a snapped position. var result = snapProvider?.FindSnappedPositionAndTime(movePosition, ~SnapType.NearbyObjects); @@ -523,16 +523,16 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// Check for positional snap for every given positions. /// - /// Distance traveled since start of dragging action. + /// Distance traveled since start of dragging action. /// The position of objects before start of dragging action. /// The positions of object at the current time. /// Whether found object to snap to. - private bool checkSnappingForNearbyObjects(Vector2 distanceTraveled, Vector2[] originalPositions, Vector2[] currentPositions) + private bool checkSnappingForNearbyObjects(Vector2 distanceTravelled, Vector2[] originalPositions, Vector2[] currentPositions) { for (int i = 0; i < originalPositions.Length; i++) { Vector2 originalPosition = originalPositions[i]; - var testPosition = originalPosition + distanceTraveled; + var testPosition = originalPosition + distanceTravelled; var positionalResult = snapProvider.FindSnappedPositionAndTime(testPosition, SnapType.NearbyObjects); From 0f2ca5d5ed4391c23e7360170e287bbe1ad06c67 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 18 Jan 2023 18:10:35 +0300 Subject: [PATCH 1681/2991] Expose method for drawable comment creation --- osu.Game/Overlays/Comments/CommentsContainer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index a334fac215..c4e4700674 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -301,7 +301,7 @@ namespace osu.Game.Overlays.Comments void addNewComment(Comment comment) { - var drawableComment = getDrawableComment(comment); + var drawableComment = GetDrawableComment(comment); if (comment.ParentId == null) { @@ -333,7 +333,7 @@ namespace osu.Game.Overlays.Comments if (CommentDictionary.ContainsKey(comment.Id)) continue; - topLevelComments.Add(getDrawableComment(comment)); + topLevelComments.Add(GetDrawableComment(comment)); } if (topLevelComments.Any()) @@ -351,7 +351,7 @@ namespace osu.Game.Overlays.Comments } } - private DrawableComment getDrawableComment(Comment comment) + public DrawableComment GetDrawableComment(Comment comment) { if (CommentDictionary.TryGetValue(comment.Id, out var existing)) return existing; From e5eab72aeb493dd870c243c1d7fec184bc2f97e7 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 19 Jan 2023 00:37:36 +0900 Subject: [PATCH 1682/2991] add check for preview time setting --- osu.Game/Rulesets/Edit/BeatmapVerifier.cs | 3 + .../Rulesets/Edit/Checks/CheckPreviewTime.cs | 64 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 osu.Game/Rulesets/Edit/Checks/CheckPreviewTime.cs diff --git a/osu.Game/Rulesets/Edit/BeatmapVerifier.cs b/osu.Game/Rulesets/Edit/BeatmapVerifier.cs index a89a0e76a9..5f5aba26bb 100644 --- a/osu.Game/Rulesets/Edit/BeatmapVerifier.cs +++ b/osu.Game/Rulesets/Edit/BeatmapVerifier.cs @@ -36,6 +36,9 @@ namespace osu.Game.Rulesets.Edit new CheckUnsnappedObjects(), new CheckConcurrentObjects(), new CheckZeroLengthObjects(), + + // Timing + new CheckPreviewTime(), }; public IEnumerable Run(BeatmapVerifierContext context) diff --git a/osu.Game/Rulesets/Edit/Checks/CheckPreviewTime.cs b/osu.Game/Rulesets/Edit/Checks/CheckPreviewTime.cs new file mode 100644 index 0000000000..4fad8c0af6 --- /dev/null +++ b/osu.Game/Rulesets/Edit/Checks/CheckPreviewTime.cs @@ -0,0 +1,64 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Edit.Checks.Components; + +namespace osu.Game.Rulesets.Edit.Checks +{ + public class CheckPreviewTime : ICheck + { + public CheckMetadata Metadata => new CheckMetadata(CheckCategory.Timing, "Check Preview Time Consistency"); + + public IEnumerable PossibleTemplates => new IssueTemplate[] + { + new IssueTemplatePreviewTimeConflict(this), + new IssueTemplateHasNoPreviewTime(this), + }; + + public IEnumerable Run(BeatmapVerifierContext context) + { + var diffList = context.Beatmap.BeatmapInfo.BeatmapSet?.Beatmaps ?? new List(); + int previewTime = context.Beatmap.BeatmapInfo.Metadata.PreviewTime; + + if (previewTime == -1) + { + yield return new IssueTemplateHasNoPreviewTime(this).Create(); + } + + foreach (var diff in diffList) + { + if (diff.Equals(context.Beatmap.BeatmapInfo)) + { + continue; + } + + if (diff.Metadata.PreviewTime != previewTime) + { + yield return new IssueTemplatePreviewTimeConflict(this).Create(diff.DifficultyName); + } + } + } + + public class IssueTemplatePreviewTimeConflict : IssueTemplate + { + public IssueTemplatePreviewTimeConflict(ICheck check) + : base(check, IssueType.Warning, "Audio preview time conflicts with {0} diff") + { + } + + public Issue Create(string diffName) => new Issue(this, diffName); + } + + public class IssueTemplateHasNoPreviewTime : IssueTemplate + { + public IssueTemplateHasNoPreviewTime(ICheck check) + : base(check, IssueType.Warning, "A preview point for this map is not set. Consider settings one from the Timing menu") + { + } + + public Issue Create() => new Issue(this); + } + } +} From 997a1a8b02d0b99ba77a4dbe629ea5f2d8f46a9f Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 19 Jan 2023 01:00:02 +0900 Subject: [PATCH 1683/2991] add test for CheckPreviewTime --- .../Editing/Checks/CheckPreviewTimeTest.cs | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 osu.Game.Tests/Editing/Checks/CheckPreviewTimeTest.cs diff --git a/osu.Game.Tests/Editing/Checks/CheckPreviewTimeTest.cs b/osu.Game.Tests/Editing/Checks/CheckPreviewTimeTest.cs new file mode 100644 index 0000000000..59ff8d4923 --- /dev/null +++ b/osu.Game.Tests/Editing/Checks/CheckPreviewTimeTest.cs @@ -0,0 +1,108 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Edit.Checks; +using osu.Game.Rulesets.Objects; +using osu.Game.Tests.Beatmaps; + +namespace osu.Game.Tests.Editing.Checks +{ + public class CheckPreviewTimeTest + { + private CheckPreviewTime check = null!; + + private IBeatmap beatmap = null!; + + [SetUp] + public void Setup() + { + check = new CheckPreviewTime(); + beatmap = new Beatmap + { + BeatmapInfo = new BeatmapInfo + { + Metadata = new BeatmapMetadata { PreviewTime = -1 }, + BeatmapSet = new BeatmapSetInfo(new List + { + new BeatmapInfo + { + DifficultyName = "Test1", + Metadata = new BeatmapMetadata { PreviewTime = 5 }, + }, + new BeatmapInfo + { + DifficultyName = "Test2", + Metadata = new BeatmapMetadata { PreviewTime = 10 }, + }, + }) + } + }; + } + + [Test] + public void TestPreviewTimeNotSet() + { + setNoPreviewTimeBeatmap(); + var content = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap)); + + var issues = check.Run(content).ToList(); + + Assert.That(issues, Has.Count.EqualTo(1)); + Assert.That(issues.Single().Template is CheckPreviewTime.IssueTemplateHasNoPreviewTime); + } + + [Test] + public void TestPreviewTimeconflict() + { + setPreviewTimeConflictBeatmap(); + + var content = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap)); + + var issues = check.Run(content).ToList(); + + Assert.That(issues, Has.Count.EqualTo(1)); + Assert.That(issues.Single().Template is CheckPreviewTime.IssueTemplatePreviewTimeConflict); + Assert.That(issues.Single().Arguments.Single().ToString() == "Test1"); + } + + private void setNoPreviewTimeBeatmap() + { + beatmap = new Beatmap + { + BeatmapInfo = new BeatmapInfo + { + Metadata = new BeatmapMetadata { PreviewTime = -1 }, + } + }; + } + + private void setPreviewTimeConflictBeatmap() + { + beatmap = new Beatmap + { + BeatmapInfo = new BeatmapInfo + { + Metadata = new BeatmapMetadata { PreviewTime = 10 }, + BeatmapSet = new BeatmapSetInfo(new List + { + new BeatmapInfo + { + DifficultyName = "Test1", + Metadata = new BeatmapMetadata { PreviewTime = 5 }, + }, + new BeatmapInfo + { + DifficultyName = "Test2", + Metadata = new BeatmapMetadata { PreviewTime = 10 }, + }, + }) + } + }; + } + } +} From 7ba448b13c53dd7b95f9f686f8f0c96bd1f73dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 18 Jan 2023 17:12:57 +0100 Subject: [PATCH 1684/2991] Update comment to match implementation --- osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index 6004c1c04e..c52b81f915 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -127,7 +127,7 @@ namespace osu.Game.Screens.Select.Carousel if (comparison != 0) return comparison; - // If no online ID is available, fallback to our internal GUID for stability. + // If DateAdded fails to break the tie, fallback to our internal GUID for stability. // This basically means it's a stable random sort. return otherSet.BeatmapSet.ID.CompareTo(BeatmapSet.ID); } From e0f3fa1af61734545767fac51baa9ff7a1fb1838 Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Wed, 18 Jan 2023 12:22:27 -0500 Subject: [PATCH 1685/2991] remove `this` in ruleset assignment --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 3ff1b69612..b5f42ec2cc 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -149,7 +149,7 @@ namespace osu.Game.Rulesets.Scoring public ScoreProcessor(Ruleset ruleset) { - this.Ruleset = ruleset; + Ruleset = ruleset; accuracyPortion = DefaultAccuracyPortion; comboPortion = DefaultComboPortion; From 150195b8878bd9ca5ed83fe71f92487e92b52403 Mon Sep 17 00:00:00 2001 From: Gabe Livengood <47010459+ggliv@users.noreply.github.com> Date: Wed, 18 Jan 2023 12:24:41 -0500 Subject: [PATCH 1686/2991] use extension method to check accuracy impact --- osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs index 02d4fb4d67..e18164db89 100644 --- a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs +++ b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs @@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Mods protected override bool FailCondition(HealthProcessor healthProcessor, JudgementResult result) { - if (!result.Type.IsScorable() || result.Type.IsBonus()) + if (!result.Type.AffectsAccuracy()) return false; return getAccuracyWithImminentResultAdded(result) < MinimumAccuracy.Value; From c74500b4b4c4010dc8223a4abc58a954a50c12ca Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 18 Jan 2023 20:49:07 +0300 Subject: [PATCH 1687/2991] Add reply editor --- osu.Game/Overlays/Comments/DrawableComment.cs | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 59ac4b3254..a737f014d7 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -576,5 +576,52 @@ namespace osu.Game.Overlays.Comments return parentComment.HasMessage ? parentComment.Message : parentComment.IsDeleted ? CommentsStrings.Deleted : string.Empty; } } + + private partial class ReplyCommentEditor : CancellableCommentEditor + { + [Resolved] + private CommentsContainer commentsContainer { get; set; } = null!; + + [Resolved] + private IAPIProvider api { get; set; } = null!; + + private readonly Comment parentComment; + + public Action? OnPost; + + protected override LocalisableString FooterText => default; + protected override LocalisableString CommitButtonText => CommonStrings.ButtonsReply; + protected override LocalisableString TextBoxPlaceholder => CommentsStrings.PlaceholderReply; + + public ReplyCommentEditor(Comment parent) + { + parentComment = parent; + OnCancel = () => this.FadeOut(200).Expire(); + } + + protected override void OnCommit(string text) + { + ShowLoadingSpinner = true; + CommentPostRequest req = new CommentPostRequest(commentsContainer.Type.Value, commentsContainer.Id.Value, text, parentComment.Id); + req.Failure += e => Schedule(() => + { + ShowLoadingSpinner = false; + Logger.Error(e, "Posting reply comment failed."); + }); + req.Success += cb => Schedule(processPostedComments, cb); + api.Queue(req); + } + + private void processPostedComments(CommentBundle cb) + { + foreach (var comment in cb.Comments) + comment.ParentComment = parentComment; + + var drawables = cb.Comments.Select(commentsContainer.GetDrawableComment).ToArray(); + OnPost?.Invoke(drawables); + + OnCancel!.Invoke(); + } + } } } From 0d91277ea59abf0613c32a50c0b849a342e71fae Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 18 Jan 2023 20:49:30 +0300 Subject: [PATCH 1688/2991] Add ability to change number on replies button --- osu.Game/Overlays/Comments/Buttons/ShowRepliesButton.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Comments/Buttons/ShowRepliesButton.cs b/osu.Game/Overlays/Comments/Buttons/ShowRepliesButton.cs index aa9b2df7e4..555823e996 100644 --- a/osu.Game/Overlays/Comments/Buttons/ShowRepliesButton.cs +++ b/osu.Game/Overlays/Comments/Buttons/ShowRepliesButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using Humanizer; using osu.Framework.Bindables; using osu.Framework.Input.Events; @@ -15,7 +13,12 @@ namespace osu.Game.Overlays.Comments.Buttons public ShowRepliesButton(int count) { - Text = "reply".ToQuantity(count); + Count = count; + } + + public int Count + { + set => Text = "reply".ToQuantity(value); } protected override void LoadComplete() From 77bc4fbf704c7ccdb033fdc8a91f60371428e99e Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 18 Jan 2023 20:50:07 +0300 Subject: [PATCH 1689/2991] Integrate editor into comment --- osu.Game/Overlays/Comments/DrawableComment.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index a737f014d7..0ec793abca 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -75,6 +75,7 @@ namespace osu.Game.Overlays.Comments private OsuSpriteText deletedLabel = null!; private GridContainer content = null!; private VotePill votePill = null!; + private Container replyEditorContainer = null!; [Resolved] private IDialogOverlay? dialogOverlay { get; set; } @@ -233,6 +234,12 @@ namespace osu.Game.Overlays.Comments } } }, + replyEditorContainer = new Container + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Padding = new MarginPadding { Top = 10 }, + }, new Container { AutoSizeAxes = Axes.Both, @@ -255,6 +262,7 @@ namespace osu.Game.Overlays.Comments }, childCommentsVisibilityContainer = new FillFlowContainer { + Name = @"Children comments", RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, @@ -345,6 +353,8 @@ namespace osu.Game.Overlays.Comments actionsContainer.AddLink(CommonStrings.ButtonsPermalink, copyUrl); actionsContainer.AddArbitraryDrawable(Empty().With(d => d.Width = 10)); + actionsContainer.AddLink(CommonStrings.ButtonsReply.ToLower(), toggleReply); + actionsContainer.AddArbitraryDrawable(Empty().With(d => d.Width = 10)); if (Comment.UserId.HasValue && Comment.UserId.Value == api.LocalUser.Value.Id) actionsContainer.AddLink(CommonStrings.ButtonsDelete.ToLower(), deleteComment); @@ -435,6 +445,26 @@ namespace osu.Game.Overlays.Comments onScreenDisplay?.Display(new CopyUrlToast()); } + private void toggleReply() + { + if (replyEditorContainer.Count == 0) + { + replyEditorContainer.Add(new ReplyCommentEditor(Comment) + { + OnPost = comments => + { + Comment.RepliesCount += comments.Length; + showRepliesButton.Count = Comment.RepliesCount; + Replies.AddRange(comments); + } + }); + } + else + { + replyEditorContainer.Clear(true); + } + } + protected override void LoadComplete() { ShowDeleted.BindValueChanged(show => From 7f4d8bdcaaa1d18762802dbf549c276dcc3b72f7 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 18 Jan 2023 21:27:42 +0300 Subject: [PATCH 1690/2991] Add test --- .../Visual/Online/TestSceneCommentActions.cs | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs index d925141510..124d0c239a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs @@ -11,6 +11,8 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Testing; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; @@ -21,6 +23,7 @@ using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; using osu.Game.Overlays.Comments; +using osu.Game.Overlays.Comments.Buttons; using osuTK.Input; namespace osu.Game.Tests.Visual.Online @@ -278,6 +281,93 @@ namespace osu.Game.Tests.Visual.Online AddAssert("Request is correct", () => request != null && request.CommentID == 2 && request.Comment == report_text && request.Reason == CommentReportReason.Other); } + [Test] + public void TestReply() + { + addTestComments(); + DrawableComment? targetComment = null; + AddUntilStep("Comment exists", () => + { + var comments = this.ChildrenOfType(); + targetComment = comments.SingleOrDefault(x => x.Comment.Id == 2); + return targetComment != null; + }); + AddStep("Setup request handling", () => + { + requestLock.Reset(); + + dummyAPI.HandleRequest = r => + { + if (!(r is CommentPostRequest req)) + return false; + + if (req.ParentCommentId != 2) + throw new ArgumentException("Wrong parent ID in request!"); + + if (req.CommentableId != 123 || req.Commentable != CommentableType.Beatmapset) + throw new ArgumentException("Wrong commentable data in request!"); + + Task.Run(() => + { + requestLock.Wait(10000); + req.TriggerSuccess(new CommentBundle + { + Comments = new List + { + new Comment + { + Id = 98, + Message = req.Message, + LegacyName = "FirstUser", + CreatedAt = DateTimeOffset.Now, + VotesCount = 98, + ParentId = req.ParentCommentId, + } + } + }); + }); + + return true; + }; + }); + AddStep("Click reply button", () => + { + var btn = targetComment.ChildrenOfType().Skip(1).First(); + var texts = btn.ChildrenOfType(); + InputManager.MoveMouseTo(texts.Skip(1).First()); + InputManager.Click(MouseButton.Left); + }); + AddAssert("There is 0 replies", () => + { + var replLabel = targetComment.ChildrenOfType().First().ChildrenOfType().First(); + return replLabel.Text.ToString().Contains('0') && targetComment!.Comment.RepliesCount == 0; + }); + AddStep("Focus field", () => + { + InputManager.MoveMouseTo(targetComment.ChildrenOfType().First()); + InputManager.Click(MouseButton.Left); + }); + AddStep("Enter text", () => + { + targetComment.ChildrenOfType().First().Current.Value = "random reply"; + }); + AddStep("Submit", () => + { + InputManager.Key(Key.Enter); + }); + AddStep("Complete request", () => requestLock.Set()); + AddUntilStep("There is 1 reply", () => + { + var replLabel = targetComment.ChildrenOfType().First().ChildrenOfType().First(); + return replLabel.Text.ToString().Contains('1') && targetComment!.Comment.RepliesCount == 1; + }); + AddUntilStep("Submitted comment shown", () => + { + var r = targetComment.ChildrenOfType().Skip(1).FirstOrDefault(); + return r != null && r.Comment.Message == "random reply"; + }); + } + private void addTestComments() { AddStep("set up response", () => From ab78dd0436edd06dba957b54634b30c6ad57807c Mon Sep 17 00:00:00 2001 From: Wleter Date: Wed, 18 Jan 2023 21:34:23 +0100 Subject: [PATCH 1691/2991] add collection of selection points. --- .../Sliders/SliderSelectionBlueprint.cs | 8 +++- .../Edit/HitObjectSelectionBlueprint.cs | 2 - osu.Game/Rulesets/Edit/SelectionBlueprint.cs | 8 ++-- .../Compose/Components/BlueprintContainer.cs | 41 ++++++++----------- 4 files changed, 28 insertions(+), 31 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 634897e3d5..66adcd62a6 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -409,8 +409,12 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders public override Vector2 ScreenSpaceSelectionPoint => DrawableObject.SliderBody?.ToScreenSpace(DrawableObject.SliderBody.PathOffset) ?? BodyPiece.ToScreenSpace(BodyPiece.PathStartLocation); - public override Vector2 ScreenSpaceEndPoint => DrawableObject.SliderBody?.ToScreenSpace(DrawableObject.SliderBody.PathEndOffset) - ?? BodyPiece.ToScreenSpace(BodyPiece.PathEndLocation); + public override Vector2[] ScreenSpaceSelectionPoints => new Vector2[] + { + ScreenSpaceSelectionPoint, + DrawableObject.SliderBody?.ToScreenSpace(DrawableObject.SliderBody.PathEndOffset) + ?? BodyPiece.ToScreenSpace(BodyPiece.PathEndLocation) + }; public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => BodyPiece.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true; diff --git a/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs b/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs index 3aa086582f..93b889792b 100644 --- a/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/HitObjectSelectionBlueprint.cs @@ -48,8 +48,6 @@ namespace osu.Game.Rulesets.Edit public override Vector2 ScreenSpaceSelectionPoint => DrawableObject.ScreenSpaceDrawQuad.Centre; - public override Vector2 ScreenSpaceEndPoint => DrawableObject.ScreenSpaceDrawQuad.Centre; - public override Quad SelectionQuad => DrawableObject.ScreenSpaceDrawQuad; } diff --git a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs index a27a59be34..3b86dbbe81 100644 --- a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs @@ -4,6 +4,7 @@ #nullable disable using System; +using System.Collections.Generic; using osu.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -125,14 +126,15 @@ namespace osu.Game.Rulesets.Edit public virtual MenuItem[] ContextMenuItems => Array.Empty(); /// - /// The screen-space point that causes this to be selected via a drag. + /// The screen-space main point that causes this to be selected via a drag. /// public virtual Vector2 ScreenSpaceSelectionPoint => ScreenSpaceDrawQuad.Centre; /// - /// The screen-space point that mark end of this . + /// The screen-space collection of base points that cause this to be selected via a drag. + /// The first element of this collection is /// - public virtual Vector2 ScreenSpaceEndPoint => ScreenSpaceDrawQuad.Centre; + public virtual Vector2[] ScreenSpaceSelectionPoints => new Vector2[] { ScreenSpaceSelectionPoint }; /// /// The screen-space quad that outlines this for selections. diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 49e4ab5300..750b7697b8 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -439,8 +439,7 @@ namespace osu.Game.Screens.Edit.Compose.Components #region Selection Movement - private Vector2[] movementBlueprintOriginalPositions; - private Vector2[] movementBlueprintOriginalEndPositions; + private Vector2[][] movementBlueprintsOriginalPositions; private SelectionBlueprint[] movementBlueprints; private bool isDraggingBlueprint; @@ -460,9 +459,7 @@ namespace osu.Game.Screens.Edit.Compose.Components // Movement is tracked from the blueprint of the earliest item, since it only makes sense to distance snap from that item movementBlueprints = SortForMovement(SelectionHandler.SelectedBlueprints).ToArray(); - movementBlueprintOriginalPositions = movementBlueprints.Select(m => m.ScreenSpaceSelectionPoint).ToArray(); - movementBlueprintOriginalEndPositions = movementBlueprints.Where(m => m.ScreenSpaceSelectionPoint != m.ScreenSpaceEndPoint) - .Select(m => m.ScreenSpaceEndPoint).ToArray(); + movementBlueprintsOriginalPositions = movementBlueprints.Select(m => m.ScreenSpaceSelectionPoints).ToArray(); return true; } @@ -484,30 +481,24 @@ namespace osu.Game.Screens.Edit.Compose.Components if (movementBlueprints == null) return false; - Debug.Assert(movementBlueprintOriginalPositions != null); + Debug.Assert(movementBlueprintsOriginalPositions != null); Vector2 distanceTravelled = e.ScreenSpaceMousePosition - e.ScreenSpaceMouseDownPosition; if (snapProvider != null) { - var currentSelectionPointPositions = movementBlueprints.Select(m => m.ScreenSpaceSelectionPoint).ToArray(); - - if (checkSnappingForNearbyObjects(distanceTravelled, movementBlueprintOriginalPositions, currentSelectionPointPositions)) - return true; - - var currentEndPointPositions = movementBlueprints.Where(m => m.ScreenSpaceSelectionPoint != m.ScreenSpaceEndPoint) - .Select(m => m.ScreenSpaceEndPoint) - .ToArray(); - - if (checkSnappingForNearbyObjects(distanceTravelled, movementBlueprintOriginalEndPositions, currentEndPointPositions)) - return true; + for (int i = 0; i < movementBlueprints.Length; i++) + { + if (checkSnappingBlueprintToNearbyObjects(movementBlueprints[i], distanceTravelled, movementBlueprintsOriginalPositions[i])) + return true; + } } // if no positional snapping could be performed, try unrestricted snapping from the earliest // item in the selection. // The final movement position, relative to movementBlueprintOriginalPosition. - Vector2 movePosition = movementBlueprintOriginalPositions.First() + distanceTravelled; + Vector2 movePosition = movementBlueprintsOriginalPositions.First().First() + distanceTravelled; // Retrieve a snapped position. var result = snapProvider?.FindSnappedPositionAndTime(movePosition, ~SnapType.NearbyObjects); @@ -521,14 +512,16 @@ namespace osu.Game.Screens.Edit.Compose.Components } /// - /// Check for positional snap for every given positions. + /// Check for positional snap for given blueprint. /// + /// The blueprint to check for snapping /// Distance traveled since start of dragging action. - /// The position of objects before start of dragging action. - /// The positions of object at the current time. + /// The selection positions of blueprint before start of dragging action. /// Whether found object to snap to. - private bool checkSnappingForNearbyObjects(Vector2 distanceTravelled, Vector2[] originalPositions, Vector2[] currentPositions) + private bool checkSnappingBlueprintToNearbyObjects(SelectionBlueprint blueprint, Vector2 distanceTravelled, Vector2[] originalPositions) { + var currentPositions = blueprint.ScreenSpaceSelectionPoints; + for (int i = 0; i < originalPositions.Length; i++) { Vector2 originalPosition = originalPositions[i]; @@ -541,7 +534,7 @@ namespace osu.Game.Screens.Edit.Compose.Components var delta = positionalResult.ScreenSpacePosition - currentPositions[i]; // attempt to move the objects, and abort any time based snapping if we can. - if (SelectionHandler.HandleMovement(new MoveSelectionEvent(movementBlueprints[i], delta))) + if (SelectionHandler.HandleMovement(new MoveSelectionEvent(blueprint, delta))) return true; } @@ -560,7 +553,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (movementBlueprints == null) return false; - movementBlueprintOriginalPositions = null; + movementBlueprintsOriginalPositions = null; movementBlueprints = null; return true; From 06212bca51eed12d8cf887f3e14a6031344043c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 18 Jan 2023 21:41:00 +0100 Subject: [PATCH 1692/2991] Restructure test scene to demonstrate failure --- .../Gameplay/TestSceneJudgementCounter.cs | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index d104e25df0..19c93fab62 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -25,35 +25,33 @@ namespace osu.Game.Tests.Visual.Gameplay private JudgementTally judgementTally = null!; private TestJudgementCounterDisplay counterDisplay = null!; + private DependencyProvidingContainer content = null!; + + protected override Container Content => content; + private readonly Bindable lastJudgementResult = new Bindable(); private int iteration; [SetUpSteps] - public void SetupSteps() => AddStep("Create components", () => + public void SetUpSteps() => AddStep("Create components", () => { var ruleset = CreateRuleset(); Debug.Assert(ruleset != null); scoreProcessor = new ScoreProcessor(ruleset); - Child = new DependencyProvidingContainer + base.Content.Child = new DependencyProvidingContainer { RelativeSizeAxes = Axes.Both, CachedDependencies = new (Type, object)[] { (typeof(ScoreProcessor), scoreProcessor), (typeof(Ruleset), ruleset) }, Children = new Drawable[] { judgementTally = new JudgementTally(), - new DependencyProvidingContainer + content = new DependencyProvidingContainer { RelativeSizeAxes = Axes.Both, CachedDependencies = new (Type, object)[] { (typeof(JudgementTally), judgementTally) }, - Child = counterDisplay = new TestJudgementCounterDisplay - { - Margin = new MarginPadding { Top = 100 }, - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre - } } }, }; @@ -78,6 +76,8 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestAddJudgementsToCounters() { + AddStep("create counter", () => Child = counterDisplay = new TestJudgementCounterDisplay()); + AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Great), 2); AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Miss), 2); AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.Meh), 2); @@ -86,6 +86,8 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestAddWhilstHidden() { + AddStep("create counter", () => Child = counterDisplay = new TestJudgementCounterDisplay()); + AddRepeatStep("Add judgement", () => applyOneJudgement(HitResult.LargeTickHit), 2); AddAssert("Check value added whilst hidden", () => hiddenCount() == 2); AddStep("Show all judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.All); @@ -94,6 +96,8 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestChangeFlowDirection() { + AddStep("create counter", () => Child = counterDisplay = new TestJudgementCounterDisplay()); + AddStep("Set direction vertical", () => counterDisplay.FlowDirection.Value = Direction.Vertical); AddStep("Set direction horizontal", () => counterDisplay.FlowDirection.Value = Direction.Horizontal); } @@ -101,6 +105,8 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestToggleJudgementNames() { + AddStep("create counter", () => Child = counterDisplay = new TestJudgementCounterDisplay()); + AddStep("Hide judgement names", () => counterDisplay.ShowJudgementNames.Value = false); AddWaitStep("wait some", 2); AddAssert("Assert hidden", () => counterDisplay.CounterFlow.Children.First().ResultName.Alpha == 0); @@ -112,6 +118,8 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestHideMaxValue() { + AddStep("create counter", () => Child = counterDisplay = new TestJudgementCounterDisplay()); + AddStep("Hide max judgement", () => counterDisplay.ShowMaxJudgement.Value = false); AddWaitStep("wait some", 2); AddAssert("Check max hidden", () => counterDisplay.CounterFlow.ChildrenOfType().First().Alpha == 0); @@ -121,6 +129,8 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestCycleDisplayModes() { + AddStep("create counter", () => Child = counterDisplay = new TestJudgementCounterDisplay()); + AddStep("Show basic judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.Simple); AddWaitStep("wait some", 2); AddAssert("Check only basic", () => counterDisplay.CounterFlow.ChildrenOfType().Last().Alpha == 0); @@ -139,6 +149,13 @@ namespace osu.Game.Tests.Visual.Gameplay private partial class TestJudgementCounterDisplay : JudgementCounterDisplay { public new FillFlowContainer CounterFlow => base.CounterFlow; + + public TestJudgementCounterDisplay() + { + Margin = new MarginPadding { Top = 100 }; + Anchor = Anchor.TopCentre; + Origin = Anchor.TopCentre; + } } } } From 7299d227d1d30d7b46edce5af93084fadf85b64f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 18 Jan 2023 21:42:22 +0100 Subject: [PATCH 1693/2991] Add failing test case --- .../Visual/Gameplay/TestSceneJudgementCounter.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index 19c93fab62..46900a2af1 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -126,6 +126,16 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("Show max judgement", () => counterDisplay.ShowMaxJudgement.Value = true); } + [Test] + public void TestMaxValueStartsHidden() + { + AddStep("create counter", () => Child = counterDisplay = new TestJudgementCounterDisplay + { + ShowMaxJudgement = { Value = false } + }); + AddAssert("Check max hidden", () => counterDisplay.CounterFlow.ChildrenOfType().First().Alpha == 0); + } + [Test] public void TestCycleDisplayModes() { From 40e99069fcbd31174aefbffb03209a247cce5139 Mon Sep 17 00:00:00 2001 From: Wleter Date: Wed, 18 Jan 2023 21:43:09 +0100 Subject: [PATCH 1694/2991] fix typos and newlines --- .../Screens/Edit/Compose/Components/BlueprintContainer.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 750b7697b8..40aa92a53f 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -460,7 +460,6 @@ namespace osu.Game.Screens.Edit.Compose.Components // Movement is tracked from the blueprint of the earliest item, since it only makes sense to distance snap from that item movementBlueprints = SortForMovement(SelectionHandler.SelectedBlueprints).ToArray(); movementBlueprintsOriginalPositions = movementBlueprints.Select(m => m.ScreenSpaceSelectionPoints).ToArray(); - return true; } @@ -515,7 +514,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// Check for positional snap for given blueprint. /// /// The blueprint to check for snapping - /// Distance traveled since start of dragging action. + /// Distance travelled since start of dragging action. /// The selection positions of blueprint before start of dragging action. /// Whether found object to snap to. private bool checkSnappingBlueprintToNearbyObjects(SelectionBlueprint blueprint, Vector2 distanceTravelled, Vector2[] originalPositions) @@ -537,7 +536,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (SelectionHandler.HandleMovement(new MoveSelectionEvent(blueprint, delta))) return true; } - + return false; } From 769f8c61907fe584d09000385ae6d119fc19fff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 18 Jan 2023 21:46:28 +0100 Subject: [PATCH 1695/2991] Fix `ShowMaxJudgement` callback conflicting with `JudgementCounter.Pop{In,Out}` Both `JudgementCounterDisplay` (via the `ShowMaxJudgement` callback) and the `JudgementCounter.Pop{In,Out}` methods were operating on the alpha of the `JudgementCounter`. This meant that if the counter display was created with max judgement initially hidden, it would be hidden by the `ShowMaxJudgement` callback first, but then _unhidden_ by `PopIn()`. --- .../Play/HUD/JudgementCounter/JudgementCounterDisplay.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 4ec90edeb0..e30f8f9be3 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -68,10 +68,12 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter Mode.BindValueChanged(_ => updateMode(), true); - ShowMaxJudgement.BindValueChanged(value => + ShowMaxJudgement.BindValueChanged(showMax => { var firstChild = CounterFlow.Children.FirstOrDefault(); - firstChild.FadeTo(value.NewValue ? 1 : 0, TRANSFORM_DURATION, Easing.OutQuint); + + if (firstChild != null) + firstChild.State.Value = showMax.NewValue ? Visibility.Visible : Visibility.Hidden; }, true); } From f8d8a627b8d5c75d6fdb2417166be0c537afc731 Mon Sep 17 00:00:00 2001 From: Wleter Date: Wed, 18 Jan 2023 22:00:39 +0100 Subject: [PATCH 1696/2991] change property name --- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 2 +- osu.Game/Rulesets/Edit/SelectionBlueprint.cs | 2 +- .../Screens/Edit/Compose/Components/BlueprintContainer.cs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 66adcd62a6..660976ba33 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -409,7 +409,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders public override Vector2 ScreenSpaceSelectionPoint => DrawableObject.SliderBody?.ToScreenSpace(DrawableObject.SliderBody.PathOffset) ?? BodyPiece.ToScreenSpace(BodyPiece.PathStartLocation); - public override Vector2[] ScreenSpaceSelectionPoints => new Vector2[] + public override Vector2[] ScreenSpaceSnapPoints => new Vector2[] { ScreenSpaceSelectionPoint, DrawableObject.SliderBody?.ToScreenSpace(DrawableObject.SliderBody.PathEndOffset) diff --git a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs index 3b86dbbe81..b2f2fa8a9b 100644 --- a/osu.Game/Rulesets/Edit/SelectionBlueprint.cs +++ b/osu.Game/Rulesets/Edit/SelectionBlueprint.cs @@ -134,7 +134,7 @@ namespace osu.Game.Rulesets.Edit /// The screen-space collection of base points that cause this to be selected via a drag. /// The first element of this collection is /// - public virtual Vector2[] ScreenSpaceSelectionPoints => new Vector2[] { ScreenSpaceSelectionPoint }; + public virtual Vector2[] ScreenSpaceSnapPoints => new Vector2[] { ScreenSpaceSelectionPoint }; /// /// The screen-space quad that outlines this for selections. diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 40aa92a53f..8cb5a1face 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -459,7 +459,7 @@ namespace osu.Game.Screens.Edit.Compose.Components // Movement is tracked from the blueprint of the earliest item, since it only makes sense to distance snap from that item movementBlueprints = SortForMovement(SelectionHandler.SelectedBlueprints).ToArray(); - movementBlueprintsOriginalPositions = movementBlueprints.Select(m => m.ScreenSpaceSelectionPoints).ToArray(); + movementBlueprintsOriginalPositions = movementBlueprints.Select(m => m.ScreenSpaceSnapPoints).ToArray(); return true; } @@ -519,7 +519,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// Whether found object to snap to. private bool checkSnappingBlueprintToNearbyObjects(SelectionBlueprint blueprint, Vector2 distanceTravelled, Vector2[] originalPositions) { - var currentPositions = blueprint.ScreenSpaceSelectionPoints; + var currentPositions = blueprint.ScreenSpaceSnapPoints; for (int i = 0; i < originalPositions.Length; i++) { @@ -536,7 +536,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (SelectionHandler.HandleMovement(new MoveSelectionEvent(blueprint, delta))) return true; } - + return false; } From e09b768a99ca1dd988f35df08444c8f4f2f279f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 18 Jan 2023 22:37:26 +0100 Subject: [PATCH 1697/2991] Add test steps demonstrating failure --- .../Visual/UserInterface/TestSceneSegmentedGraph.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs index 80941569af..1144b9053d 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu; @@ -52,7 +53,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("beatmap density with granularity of 200", () => beatmapDensity()); AddStep("beatmap density with granularity of 300", () => beatmapDensity(300)); AddStep("reversed values from 1-10", () => graph.Values = Enumerable.Range(1, 10).Reverse().ToArray()); - AddStep("change colour", () => + AddStep("change tier colours", () => { graph.TierColours = new[] { @@ -62,7 +63,7 @@ namespace osu.Game.Tests.Visual.UserInterface Colour4.Blue }; }); - AddStep("reset colour", () => + AddStep("reset tier colours", () => { graph.TierColours = new[] { @@ -74,6 +75,12 @@ namespace osu.Game.Tests.Visual.UserInterface Colour4.Green }; }); + + AddStep("set graph colour to blue", () => graph.Colour = Colour4.Blue); + AddStep("set graph colour to transparent", () => graph.Colour = Colour4.Transparent); + AddStep("set graph colour to vertical gradient", () => graph.Colour = ColourInfo.GradientVertical(Colour4.White, Colour4.Black)); + AddStep("set graph colour to horizontal gradient", () => graph.Colour = ColourInfo.GradientHorizontal(Colour4.White, Colour4.Black)); + AddStep("reset graph colour", () => graph.Colour = Colour4.White); } private void sinFunction(int size = 100) From 903c37bf3206421b862ff1b386d6db33223e4eb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 18 Jan 2023 22:51:05 +0100 Subject: [PATCH 1698/2991] Apply draw colour to segmented graph segments --- .../Graphics/UserInterface/SegmentedGraph.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index 8ccba710b8..e0be7c1d0f 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -7,10 +7,12 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Rendering; using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Textures; +using osu.Framework.Utils; using osuTK; namespace osu.Game.Graphics.UserInterface @@ -154,7 +156,19 @@ namespace osu.Game.Graphics.UserInterface segments.Sort(); } - private Colour4 getTierColour(int tier) => tier >= 0 ? tierColours[tier] : new Colour4(0, 0, 0, 0); + private ColourInfo getSegmentColour(SegmentInfo segment) + { + var tierColour = segment.Tier >= 0 ? tierColours[segment.Tier] : new Colour4(0, 0, 0, 0); + var ourColour = DrawColourInfo.Colour; + + return new ColourInfo + { + TopLeft = tierColour * Interpolation.ValueAt(segment.Start, ourColour.TopLeft, ourColour.TopRight, 0, 1), + TopRight = tierColour * Interpolation.ValueAt(segment.End, ourColour.TopLeft, ourColour.TopRight, 0, 1), + BottomLeft = tierColour * Interpolation.ValueAt(segment.Start, ourColour.BottomLeft, ourColour.BottomRight, 0, 1), + BottomRight = tierColour * Interpolation.ValueAt(segment.End, ourColour.BottomLeft, ourColour.BottomRight, 0, 1) + }; + } protected override DrawNode CreateDrawNode() => new SegmentedGraphDrawNode(this); @@ -240,7 +254,7 @@ namespace osu.Game.Graphics.UserInterface Vector2Extensions.Transform(topRight, DrawInfo.Matrix), Vector2Extensions.Transform(bottomLeft, DrawInfo.Matrix), Vector2Extensions.Transform(bottomRight, DrawInfo.Matrix)), - Source.getTierColour(segment.Tier)); + Source.getSegmentColour(segment)); } shader.Unbind(); From b8b7442eb826f74d30383c3c8d81d50f097a48f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 18 Jan 2023 23:35:02 +0100 Subject: [PATCH 1699/2991] Make `SongProgressInfo.ShowProgress` init-only (and remove duplicate init) --- osu.Game/Screens/Play/HUD/ArgonSongProgress.cs | 1 - osu.Game/Screens/Play/HUD/SongProgressInfo.cs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs index 3a2cd6fe2a..bfee6d295e 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgress.cs @@ -71,7 +71,6 @@ namespace osu.Game.Screens.Play.HUD [BackgroundDependencyLoader] private void load() { - info.ShowProgress = false; info.TextColour = Colour4.White; info.Font = OsuFont.Torus.With(size: 18, weight: FontWeight.Bold); } diff --git a/osu.Game/Screens/Play/HUD/SongProgressInfo.cs b/osu.Game/Screens/Play/HUD/SongProgressInfo.cs index 8a5c24a1f1..7f9f353ded 100644 --- a/osu.Game/Screens/Play/HUD/SongProgressInfo.cs +++ b/osu.Game/Screens/Play/HUD/SongProgressInfo.cs @@ -53,7 +53,7 @@ namespace osu.Game.Screens.Play.HUD set => startTime = value; } - public bool ShowProgress = true; + public bool ShowProgress { get; init; } = true; public double EndTime { From a0fe71c706a97f1e294dfb5426538d048554b1fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 19 Jan 2023 00:08:32 +0100 Subject: [PATCH 1700/2991] Use alternative segment colour computation method --- .../Graphics/UserInterface/SegmentedGraph.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index e0be7c1d0f..7a004a7f83 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -12,7 +12,6 @@ using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Rendering; using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Textures; -using osu.Framework.Utils; using osuTK; namespace osu.Game.Graphics.UserInterface @@ -158,16 +157,18 @@ namespace osu.Game.Graphics.UserInterface private ColourInfo getSegmentColour(SegmentInfo segment) { - var tierColour = segment.Tier >= 0 ? tierColours[segment.Tier] : new Colour4(0, 0, 0, 0); - var ourColour = DrawColourInfo.Colour; - - return new ColourInfo + var segmentColour = new ColourInfo { - TopLeft = tierColour * Interpolation.ValueAt(segment.Start, ourColour.TopLeft, ourColour.TopRight, 0, 1), - TopRight = tierColour * Interpolation.ValueAt(segment.End, ourColour.TopLeft, ourColour.TopRight, 0, 1), - BottomLeft = tierColour * Interpolation.ValueAt(segment.Start, ourColour.BottomLeft, ourColour.BottomRight, 0, 1), - BottomRight = tierColour * Interpolation.ValueAt(segment.End, ourColour.BottomLeft, ourColour.BottomRight, 0, 1) + TopLeft = DrawColourInfo.Colour.Interpolate(new Vector2(segment.Start, 0f)), + TopRight = DrawColourInfo.Colour.Interpolate(new Vector2(segment.End, 0f)), + BottomLeft = DrawColourInfo.Colour.Interpolate(new Vector2(segment.Start, 1f)), + BottomRight = DrawColourInfo.Colour.Interpolate(new Vector2(segment.End, 1f)) }; + + var tierColour = segment.Tier >= 0 ? tierColours[segment.Tier] : new Colour4(0, 0, 0, 0); + segmentColour.ApplyChild(tierColour); + + return segmentColour; } protected override DrawNode CreateDrawNode() => new SegmentedGraphDrawNode(this); From 07af18b8a765f7b17da1241d260d6e8d579682ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Jan 2023 16:01:37 +0900 Subject: [PATCH 1701/2991] Remove `ReplyCommentEditor` into its own class --- osu.Game/Overlays/Comments/DrawableComment.cs | 47 -------------- .../Overlays/Comments/ReplyCommentEditor.cs | 63 +++++++++++++++++++ 2 files changed, 63 insertions(+), 47 deletions(-) create mode 100644 osu.Game/Overlays/Comments/ReplyCommentEditor.cs diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 0ec793abca..7bb8b06ee4 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -606,52 +606,5 @@ namespace osu.Game.Overlays.Comments return parentComment.HasMessage ? parentComment.Message : parentComment.IsDeleted ? CommentsStrings.Deleted : string.Empty; } } - - private partial class ReplyCommentEditor : CancellableCommentEditor - { - [Resolved] - private CommentsContainer commentsContainer { get; set; } = null!; - - [Resolved] - private IAPIProvider api { get; set; } = null!; - - private readonly Comment parentComment; - - public Action? OnPost; - - protected override LocalisableString FooterText => default; - protected override LocalisableString CommitButtonText => CommonStrings.ButtonsReply; - protected override LocalisableString TextBoxPlaceholder => CommentsStrings.PlaceholderReply; - - public ReplyCommentEditor(Comment parent) - { - parentComment = parent; - OnCancel = () => this.FadeOut(200).Expire(); - } - - protected override void OnCommit(string text) - { - ShowLoadingSpinner = true; - CommentPostRequest req = new CommentPostRequest(commentsContainer.Type.Value, commentsContainer.Id.Value, text, parentComment.Id); - req.Failure += e => Schedule(() => - { - ShowLoadingSpinner = false; - Logger.Error(e, "Posting reply comment failed."); - }); - req.Success += cb => Schedule(processPostedComments, cb); - api.Queue(req); - } - - private void processPostedComments(CommentBundle cb) - { - foreach (var comment in cb.Comments) - comment.ParentComment = parentComment; - - var drawables = cb.Comments.Select(commentsContainer.GetDrawableComment).ToArray(); - OnPost?.Invoke(drawables); - - OnCancel!.Invoke(); - } - } } } diff --git a/osu.Game/Overlays/Comments/ReplyCommentEditor.cs b/osu.Game/Overlays/Comments/ReplyCommentEditor.cs new file mode 100644 index 0000000000..450309a1a2 --- /dev/null +++ b/osu.Game/Overlays/Comments/ReplyCommentEditor.cs @@ -0,0 +1,63 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Localisation; +using osu.Framework.Logging; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Resources.Localisation.Web; + +namespace osu.Game.Overlays.Comments +{ + public partial class ReplyCommentEditor : CancellableCommentEditor + { + [Resolved] + private CommentsContainer commentsContainer { get; set; } = null!; + + [Resolved] + private IAPIProvider api { get; set; } = null!; + + private readonly Comment parentComment; + + public Action? OnPost; + + protected override LocalisableString FooterText => default; + protected override LocalisableString CommitButtonText => CommonStrings.ButtonsReply; + protected override LocalisableString TextBoxPlaceholder => CommentsStrings.PlaceholderReply; + + public ReplyCommentEditor(Comment parent) + { + parentComment = parent; + OnCancel = () => this.FadeOut(200).Expire(); + } + + protected override void OnCommit(string text) + { + ShowLoadingSpinner = true; + CommentPostRequest req = new CommentPostRequest(commentsContainer.Type.Value, commentsContainer.Id.Value, text, parentComment.Id); + req.Failure += e => Schedule(() => + { + ShowLoadingSpinner = false; + Logger.Error(e, "Posting reply comment failed."); + }); + req.Success += cb => Schedule(processPostedComments, cb); + api.Queue(req); + } + + private void processPostedComments(CommentBundle cb) + { + foreach (var comment in cb.Comments) + comment.ParentComment = parentComment; + + var drawables = cb.Comments.Select(commentsContainer.GetDrawableComment).ToArray(); + OnPost?.Invoke(drawables); + + OnCancel!.Invoke(); + } + } +} From 81e6c3792c023748896367e0c84deb1f9b6010a9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Jan 2023 16:03:46 +0900 Subject: [PATCH 1702/2991] Remove unused method --- osu.Game/Overlays/Comments/DrawableComment.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 7bb8b06ee4..4cc189f3a2 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -477,8 +477,6 @@ namespace osu.Game.Overlays.Comments base.LoadComplete(); } - public bool ContainsReply(long replyId) => loadedReplies.ContainsKey(replyId); - private void onRepliesAdded(IEnumerable replies) { var page = createRepliesPage(replies); From 4916a742d5c4e411719fc758d6dca93b07ca2a2c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Jan 2023 16:08:27 +0900 Subject: [PATCH 1703/2991] Immediately focus the textbox when clicking to reply to a comment --- osu.Game/Overlays/Comments/CommentEditor.cs | 8 ++++---- osu.Game/Overlays/Comments/ReplyCommentEditor.cs | 7 +++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 769263b3fc..ff417a2e15 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -35,6 +35,8 @@ namespace osu.Game.Overlays.Comments private RoundedButton commitButton = null!; private LoadingSpinner loadingSpinner = null!; + protected TextBox TextBox { get; private set; } = null!; + protected bool ShowLoadingSpinner { set @@ -51,8 +53,6 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - EditorTextBox textBox; - RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; Masking = true; @@ -74,7 +74,7 @@ namespace osu.Game.Overlays.Comments Direction = FillDirection.Vertical, Children = new Drawable[] { - textBox = new EditorTextBox + TextBox = new EditorTextBox { Height = 40, RelativeSizeAxes = Axes.X, @@ -133,7 +133,7 @@ namespace osu.Game.Overlays.Comments } }); - textBox.OnCommit += (_, _) => commitButton.TriggerClick(); + TextBox.OnCommit += (_, _) => commitButton.TriggerClick(); } protected override void LoadComplete() diff --git a/osu.Game/Overlays/Comments/ReplyCommentEditor.cs b/osu.Game/Overlays/Comments/ReplyCommentEditor.cs index 450309a1a2..e738e6e7ec 100644 --- a/osu.Game/Overlays/Comments/ReplyCommentEditor.cs +++ b/osu.Game/Overlays/Comments/ReplyCommentEditor.cs @@ -36,6 +36,13 @@ namespace osu.Game.Overlays.Comments OnCancel = () => this.FadeOut(200).Expire(); } + protected override void LoadComplete() + { + base.LoadComplete(); + + GetContainingInputManager().ChangeFocus(TextBox); + } + protected override void OnCommit(string text) { ShowLoadingSpinner = true; From b22363ed8cb4709d31c5532649786ff4cb1118fa Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Thu, 19 Jan 2023 10:31:02 +0100 Subject: [PATCH 1704/2991] Fix JudgementCounterDisplay.cs max judgement always showing upon changing display mode --- .../Gameplay/TestSceneJudgementCounter.cs | 11 +++++++++ .../JudgementCounterDisplay.cs | 23 +++++++++++++------ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs index 46900a2af1..5a802e0d36 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneJudgementCounter.cs @@ -136,6 +136,17 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("Check max hidden", () => counterDisplay.CounterFlow.ChildrenOfType().First().Alpha == 0); } + [Test] + public void TestMaxValueHiddenOnModeChange() + { + AddStep("create counter", () => Child = counterDisplay = new TestJudgementCounterDisplay()); + + AddStep("Set max judgement to hide itself", () => counterDisplay.ShowMaxJudgement.Value = false); + AddStep("Show all judgements", () => counterDisplay.Mode.Value = JudgementCounterDisplay.DisplayMode.All); + AddWaitStep("wait some", 2); + AddAssert("Assert max judgement hidden", () => counterDisplay.CounterFlow.ChildrenOfType().First().Alpha == 0); + } + [Test] public void TestCycleDisplayModes() { diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index e30f8f9be3..27dd98289a 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -66,15 +66,16 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter counter.Direction.Value = convertedDirection; }, true); - Mode.BindValueChanged(_ => updateMode(), true); + Mode.BindValueChanged(_ => + { + updateMode(); + + //Refreshing the counter causes the first child to become visible, so we want to make sure it isn't if it shouldn't be + updateFirstChildVisibility(); + }, true); ShowMaxJudgement.BindValueChanged(showMax => - { - var firstChild = CounterFlow.Children.FirstOrDefault(); - - if (firstChild != null) - firstChild.State.Value = showMax.NewValue ? Visibility.Visible : Visibility.Hidden; - }, true); + updateFirstChildVisibility(), true); } private void updateMode() @@ -109,6 +110,14 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter } } + private void updateFirstChildVisibility() + { + var firstChild = CounterFlow.Children.FirstOrDefault(); + + if (firstChild != null) + firstChild.State.Value = ShowMaxJudgement.Value ? Visibility.Visible : Visibility.Hidden; + } + private FillDirection getFillDirection(Direction flow) { switch (flow) From 2ce32e3209f8ebab80871fee8b91c3ff772d5dd8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Jan 2023 19:27:05 +0900 Subject: [PATCH 1705/2991] Refactor update logic to be easier to follow --- .../JudgementCounterDisplay.cs | 34 ++++++------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs index 27dd98289a..82f24c736e 100644 --- a/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/JudgementCounter/JudgementCounterDisplay.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -66,30 +65,27 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter counter.Direction.Value = convertedDirection; }, true); - Mode.BindValueChanged(_ => - { - updateMode(); - - //Refreshing the counter causes the first child to become visible, so we want to make sure it isn't if it shouldn't be - updateFirstChildVisibility(); - }, true); - - ShowMaxJudgement.BindValueChanged(showMax => - updateFirstChildVisibility(), true); + Mode.BindValueChanged(_ => updateDisplay()); + ShowMaxJudgement.BindValueChanged(_ => updateDisplay(), true); } - private void updateMode() + private void updateDisplay() { - foreach (var counter in CounterFlow.Children) + for (int i = 0; i < CounterFlow.Children.Count; i++) { - if (shouldShow(counter)) + JudgementCounter counter = CounterFlow.Children[i]; + + if (shouldShow(i, counter)) counter.Show(); else counter.Hide(); } - bool shouldShow(JudgementCounter counter) + bool shouldShow(int index, JudgementCounter counter) { + if (index == 0 && !ShowMaxJudgement.Value) + return false; + if (counter.Result.Type.IsBasic()) return true; @@ -110,14 +106,6 @@ namespace osu.Game.Screens.Play.HUD.JudgementCounter } } - private void updateFirstChildVisibility() - { - var firstChild = CounterFlow.Children.FirstOrDefault(); - - if (firstChild != null) - firstChild.State.Value = ShowMaxJudgement.Value ? Visibility.Visible : Visibility.Hidden; - } - private FillDirection getFillDirection(Direction flow) { switch (flow) From 812a4b412a2c1b13a1e1215a00f863ef6fd83e45 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Thu, 19 Jan 2023 19:43:23 +0900 Subject: [PATCH 1706/2991] Move judgement result revert logic to Playfield Previously, some judgement results were not reverted when the source DHO is not alive (e.g. frames skipped in editor). Now, all results are reverted in the exact reverse order. --- .../TestSceneCatcher.cs | 6 +-- .../UI/CatchComboDisplay.cs | 4 +- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 4 +- osu.Game.Rulesets.Catch/UI/Catcher.cs | 6 +-- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 6 +-- .../Judgements/JudgementResultEntry.cs | 26 +++++++++++++ .../Objects/Drawables/DrawableHitObject.cs | 35 ++++++----------- .../Objects/HitObjectLifetimeEntry.cs | 5 +++ osu.Game/Rulesets/UI/DrawableRuleset.cs | 2 +- osu.Game/Rulesets/UI/HitObjectContainer.cs | 8 ---- osu.Game/Rulesets/UI/Playfield.cs | 38 ++++++++++++++++--- 11 files changed, 90 insertions(+), 50 deletions(-) create mode 100644 osu.Game/Rulesets/Judgements/JudgementResultEntry.cs diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs index e8231b07ad..11e3a5be57 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs @@ -74,12 +74,12 @@ namespace osu.Game.Rulesets.Catch.Tests }); AddStep("revert second result", () => { - catcher.OnRevertResult(drawableObject2, result2); + catcher.OnRevertResult(result2); }); checkHyperDash(true); AddStep("revert first result", () => { - catcher.OnRevertResult(drawableObject1, result1); + catcher.OnRevertResult(result1); }); checkHyperDash(false); } @@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Catch.Tests checkState(CatcherAnimationState.Kiai); AddStep("revert result", () => { - catcher.OnRevertResult(drawableObject, result); + catcher.OnRevertResult(result); }); checkState(CatcherAnimationState.Idle); } diff --git a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs index dbbe905879..3d0062d32f 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs @@ -63,12 +63,12 @@ namespace osu.Game.Rulesets.Catch.UI updateCombo(result.ComboAtJudgement + 1, judgedObject.AccentColour.Value); } - public void OnRevertResult(DrawableCatchHitObject judgedObject, JudgementResult result) + public void OnRevertResult(JudgementResult result) { if (!result.Type.AffectsCombo() || !result.HasResult) return; - updateCombo(result.ComboAtJudgement, judgedObject.AccentColour.Value); + updateCombo(result.ComboAtJudgement, null); } private void updateCombo(int newCombo, Color4? hitObjectColour) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index c33d021876..cf7337fd0d 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Catch.UI private void onNewResult(DrawableHitObject judgedObject, JudgementResult result) => CatcherArea.OnNewResult((DrawableCatchHitObject)judgedObject, result); - private void onRevertResult(DrawableHitObject judgedObject, JudgementResult result) - => CatcherArea.OnRevertResult((DrawableCatchHitObject)judgedObject, result); + private void onRevertResult(JudgementResult result) + => CatcherArea.OnRevertResult(result); } } diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 411330f6fc..1c52c092ec 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -254,7 +254,7 @@ namespace osu.Game.Rulesets.Catch.UI } } - public void OnRevertResult(DrawableCatchHitObject drawableObject, JudgementResult result) + public void OnRevertResult(JudgementResult result) { var catchResult = (CatchJudgementResult)result; @@ -268,8 +268,8 @@ namespace osu.Game.Rulesets.Catch.UI SetHyperDashState(); } - caughtObjectContainer.RemoveAll(d => d.HitObject == drawableObject.HitObject, false); - droppedObjectTarget.RemoveAll(d => d.HitObject == drawableObject.HitObject, false); + caughtObjectContainer.RemoveAll(d => d.HitObject == result.HitObject, false); + droppedObjectTarget.RemoveAll(d => d.HitObject == result.HitObject, false); } /// diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 4f7535d13a..1b99270b65 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -73,10 +73,10 @@ namespace osu.Game.Rulesets.Catch.UI comboDisplay.OnNewResult(hitObject, result); } - public void OnRevertResult(DrawableCatchHitObject hitObject, JudgementResult result) + public void OnRevertResult(JudgementResult result) { - comboDisplay.OnRevertResult(hitObject, result); - Catcher.OnRevertResult(hitObject, result); + comboDisplay.OnRevertResult(result); + Catcher.OnRevertResult(result); } protected override void Update() diff --git a/osu.Game/Rulesets/Judgements/JudgementResultEntry.cs b/osu.Game/Rulesets/Judgements/JudgementResultEntry.cs new file mode 100644 index 0000000000..c3f44804c3 --- /dev/null +++ b/osu.Game/Rulesets/Judgements/JudgementResultEntry.cs @@ -0,0 +1,26 @@ +// 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.Game.Rulesets.Objects; + +namespace osu.Game.Rulesets.Judgements +{ + internal class JudgementResultEntry : IComparable + { + public readonly double Time; + + public readonly HitObjectLifetimeEntry HitObjectEntry; + + public readonly JudgementResult Result; + + public JudgementResultEntry(double time, HitObjectLifetimeEntry hitObjectEntry, JudgementResult result) + { + Time = time; + HitObjectEntry = hitObjectEntry; + Result = result; + } + + public int CompareTo(JudgementResultEntry? other) => Time.CompareTo(other?.Time); + } +} \ No newline at end of file diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index be5a7f71e7..02fc5637d8 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -82,6 +82,9 @@ namespace osu.Game.Rulesets.Objects.Drawables /// /// Invoked by this or a nested prior to a being reverted. /// + /// + /// This is only invoked if this is alive when the result is reverted. + /// public event Action OnRevertResult; /// @@ -222,6 +225,8 @@ namespace osu.Game.Rulesets.Objects.Drawables ensureEntryHasResult(); + entry.RevertResult += onRevertResult; + foreach (var h in HitObject.NestedHitObjects) { var pooledDrawableNested = pooledObjectProvider?.GetPooledDrawableRepresentation(h, this); @@ -234,7 +239,6 @@ namespace osu.Game.Rulesets.Objects.Drawables OnNestedDrawableCreated?.Invoke(drawableNested); drawableNested.OnNewResult += onNewResult; - drawableNested.OnRevertResult += onRevertResult; drawableNested.ApplyCustomUpdateState += onApplyCustomUpdateState; // This is only necessary for non-pooled DHOs. For pooled DHOs, this is handled inside GetPooledDrawableRepresentation(). @@ -309,7 +313,6 @@ namespace osu.Game.Rulesets.Objects.Drawables foreach (var obj in nestedHitObjects) { obj.OnNewResult -= onNewResult; - obj.OnRevertResult -= onRevertResult; obj.ApplyCustomUpdateState -= onApplyCustomUpdateState; } @@ -318,6 +321,8 @@ namespace osu.Game.Rulesets.Objects.Drawables HitObject.DefaultsApplied -= onDefaultsApplied; + entry.RevertResult -= onRevertResult; + OnFree(); ParentHitObject = null; @@ -366,7 +371,11 @@ namespace osu.Game.Rulesets.Objects.Drawables private void onNewResult(DrawableHitObject drawableHitObject, JudgementResult result) => OnNewResult?.Invoke(drawableHitObject, result); - private void onRevertResult(DrawableHitObject drawableHitObject, JudgementResult result) => OnRevertResult?.Invoke(drawableHitObject, result); + private void onRevertResult() + { + updateState(ArmedState.Idle); + OnRevertResult?.Invoke(this, Result); + } private void onApplyCustomUpdateState(DrawableHitObject drawableHitObject, ArmedState state) => ApplyCustomUpdateState?.Invoke(drawableHitObject, state); @@ -578,26 +587,6 @@ namespace osu.Game.Rulesets.Objects.Drawables #endregion - protected override void Update() - { - base.Update(); - - if (Result != null && Result.HasResult) - { - double endTime = HitObject.GetEndTime(); - - if (Result.TimeOffset + endTime > Time.Current) - { - OnRevertResult?.Invoke(this, Result); - - Result.TimeOffset = 0; - Result.Type = HitResult.None; - - updateState(ArmedState.Idle); - } - } - } - public override bool UpdateSubTreeMasking(Drawable source, RectangleF maskingBounds) => false; protected override void UpdateAfterChildren() diff --git a/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs b/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs index fedf419973..b517f6b9e6 100644 --- a/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.cs +++ b/osu.Game/Rulesets/Objects/HitObjectLifetimeEntry.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.Framework.Graphics.Performance; using osu.Game.Rulesets.Judgements; @@ -26,6 +27,8 @@ namespace osu.Game.Rulesets.Objects private readonly IBindable startTimeBindable = new BindableDouble(); + internal event Action? RevertResult; + /// /// Creates a new . /// @@ -95,5 +98,7 @@ namespace osu.Game.Rulesets.Objects /// Set using . /// internal void SetInitialLifetime() => LifetimeStart = HitObject.StartTime - InitialLifetimeOffset; + + internal void OnRevertResult() => RevertResult?.Invoke(); } } diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 71b452c309..8edc5517cb 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -134,7 +134,7 @@ namespace osu.Game.Rulesets.UI playfield = new Lazy(() => CreatePlayfield().With(p => { p.NewResult += (_, r) => NewResult?.Invoke(r); - p.RevertResult += (_, r) => RevertResult?.Invoke(r); + p.RevertResult += r => RevertResult?.Invoke(r); })); } diff --git a/osu.Game/Rulesets/UI/HitObjectContainer.cs b/osu.Game/Rulesets/UI/HitObjectContainer.cs index 7cbf49aa31..099be486b3 100644 --- a/osu.Game/Rulesets/UI/HitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/HitObjectContainer.cs @@ -28,11 +28,6 @@ namespace osu.Game.Rulesets.UI /// public event Action NewResult; - /// - /// Invoked when a judgement is reverted. - /// - public event Action RevertResult; - /// /// Invoked when a becomes used by a . /// @@ -111,7 +106,6 @@ namespace osu.Game.Rulesets.UI private void addDrawable(DrawableHitObject drawable) { drawable.OnNewResult += onNewResult; - drawable.OnRevertResult += onRevertResult; bindStartTime(drawable); AddInternal(drawable); @@ -120,7 +114,6 @@ namespace osu.Game.Rulesets.UI private void removeDrawable(DrawableHitObject drawable) { drawable.OnNewResult -= onNewResult; - drawable.OnRevertResult -= onRevertResult; unbindStartTime(drawable); @@ -154,7 +147,6 @@ namespace osu.Game.Rulesets.UI #endregion private void onNewResult(DrawableHitObject d, JudgementResult r) => NewResult?.Invoke(d, r); - private void onRevertResult(DrawableHitObject d, JudgementResult r) => RevertResult?.Invoke(d, r); #region Comparator + StartTime tracking diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index a7881678f1..9535ebb9ed 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -22,6 +22,8 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Skinning; using osuTK; using osu.Game.Rulesets.Objects.Pooling; +using osu.Game.Rulesets.Scoring; +using osu.Framework.Extensions.ObjectExtensions; namespace osu.Game.Rulesets.UI { @@ -35,9 +37,9 @@ namespace osu.Game.Rulesets.UI public event Action NewResult; /// - /// Invoked when a judgement is reverted. + /// Invoked when a judgement result is reverted. /// - public event Action RevertResult; + public event Action RevertResult; /// /// The contained in this Playfield. @@ -98,6 +100,8 @@ namespace osu.Game.Rulesets.UI private readonly HitObjectEntryManager entryManager = new HitObjectEntryManager(); + private readonly Stack judgementResults; + /// /// Creates a new . /// @@ -107,14 +111,15 @@ namespace osu.Game.Rulesets.UI hitObjectContainerLazy = new Lazy(() => CreateHitObjectContainer().With(h => { - h.NewResult += (d, r) => NewResult?.Invoke(d, r); - h.RevertResult += (d, r) => RevertResult?.Invoke(d, r); + h.NewResult += onNewResult; h.HitObjectUsageBegan += o => HitObjectUsageBegan?.Invoke(o); h.HitObjectUsageFinished += o => HitObjectUsageFinished?.Invoke(o); })); entryManager.OnEntryAdded += onEntryAdded; entryManager.OnEntryRemoved += onEntryRemoved; + + judgementResults = new Stack(); } [BackgroundDependencyLoader] @@ -224,7 +229,7 @@ namespace osu.Game.Rulesets.UI otherPlayfield.DisplayJudgements.BindTo(DisplayJudgements); otherPlayfield.NewResult += (d, r) => NewResult?.Invoke(d, r); - otherPlayfield.RevertResult += (d, r) => RevertResult?.Invoke(d, r); + otherPlayfield.RevertResult += r => RevertResult?.Invoke(r); otherPlayfield.HitObjectUsageBegan += h => HitObjectUsageBegan?.Invoke(h); otherPlayfield.HitObjectUsageFinished += h => HitObjectUsageFinished?.Invoke(h); @@ -252,6 +257,10 @@ namespace osu.Game.Rulesets.UI updatable.Update(this); } } + + // When rewinding, revert future judgements in the reverse order. + while (judgementResults.Count > 0 && Time.Current < judgementResults.Peek().Time) + revertResult(judgementResults.Pop()); } /// @@ -443,6 +452,25 @@ namespace osu.Game.Rulesets.UI #endregion + private void onNewResult(DrawableHitObject drawable, JudgementResult result) + { + // Not using result.TimeAbsolute because that might change and also there is a potential precision issue. + judgementResults.Push(new JudgementResultEntry(Time.Current, drawable.Entry.AsNonNull(), result)); + + NewResult?.Invoke(drawable, result); + } + + private void revertResult(JudgementResultEntry entry) + { + var result = entry.Result; + RevertResult?.Invoke(result); + + result.TimeOffset = 0; + result.Type = HitResult.None; + + entry.HitObjectEntry.OnRevertResult(); + } + #region Editor logic /// From 32acaa44be3009b3120e05753308e157c8f0219a Mon Sep 17 00:00:00 2001 From: ekrctb Date: Thu, 19 Jan 2023 19:52:37 +0900 Subject: [PATCH 1707/2991] Remove now-redundant code --- .../TestSceneCatcher.cs | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs index 11e3a5be57..f60ae29f77 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs @@ -60,17 +60,15 @@ namespace osu.Game.Rulesets.Catch.Tests [Test] public void TestCatcherHyperStateReverted() { - DrawableCatchHitObject drawableObject1 = null; - DrawableCatchHitObject drawableObject2 = null; JudgementResult result1 = null; JudgementResult result2 = null; AddStep("catch hyper fruit", () => { - attemptCatch(new Fruit { HyperDashTarget = new Fruit { X = 100 } }, out drawableObject1, out result1); + result1 = attemptCatch(new Fruit { HyperDashTarget = new Fruit { X = 100 } }); }); AddStep("catch normal fruit", () => { - attemptCatch(new Fruit(), out drawableObject2, out result2); + result2 = attemptCatch(new Fruit()); }); AddStep("revert second result", () => { @@ -87,11 +85,10 @@ namespace osu.Game.Rulesets.Catch.Tests [Test] public void TestCatcherAnimationStateReverted() { - DrawableCatchHitObject drawableObject = null; JudgementResult result = null; AddStep("catch kiai fruit", () => { - attemptCatch(new TestKiaiFruit(), out drawableObject, out result); + result = attemptCatch(new TestKiaiFruit()); }); checkState(CatcherAnimationState.Kiai); AddStep("revert result", () => @@ -268,23 +265,19 @@ namespace osu.Game.Rulesets.Catch.Tests private void checkHyperDash(bool state) => AddAssert($"catcher is {(state ? "" : "not ")}hyper dashing", () => catcher.HyperDashing == state); - private void attemptCatch(CatchHitObject hitObject) - { - attemptCatch(() => hitObject, 1); - } - private void attemptCatch(Func hitObject, int count) { for (int i = 0; i < count; i++) - attemptCatch(hitObject(), out _, out _); + attemptCatch(hitObject()); } - private void attemptCatch(CatchHitObject hitObject, out DrawableCatchHitObject drawableObject, out JudgementResult result) + private JudgementResult attemptCatch(CatchHitObject hitObject) { hitObject.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); - drawableObject = createDrawableObject(hitObject); - result = createResult(hitObject); + var drawableObject = createDrawableObject(hitObject); + var result = createResult(hitObject); applyResult(drawableObject, result); + return result; } private void applyResult(DrawableCatchHitObject drawableObject, JudgementResult result) From 11e1b22bf5be695bebc5dad23ea9c2aa268d4be7 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Thu, 19 Jan 2023 20:53:35 +0900 Subject: [PATCH 1708/2991] Move MaximumJudgementOffset to HitObject We want to access this property for computing lifetime --- .../Objects/Drawables/DrawableHoldNote.cs | 2 -- .../Objects/Drawables/DrawableHoldNoteTail.cs | 11 +---------- osu.Game.Rulesets.Mania/Objects/HoldNote.cs | 2 ++ osu.Game.Rulesets.Mania/Objects/TailNote.cs | 9 +++++++++ .../Objects/Drawables/DrawableSpinnerTick.cs | 2 -- osu.Game.Rulesets.Osu/Objects/Spinner.cs | 4 ++-- osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs | 7 +++++++ .../Objects/Drawables/DrawableDrumRollTick.cs | 2 -- osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs | 2 ++ .../Objects/Drawables/DrawableHitObject.cs | 14 +------------- osu.Game/Rulesets/Objects/HitObject.cs | 8 ++++++++ 11 files changed, 32 insertions(+), 31 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 759d2346e8..8863de5ee3 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -69,8 +69,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// private double? releaseTime; - public override double MaximumJudgementOffset => Tail.MaximumJudgementOffset; - public DrawableHoldNote() : this(null) { diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs index bf477277c6..20ea962994 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs @@ -15,13 +15,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// public partial class DrawableHoldNoteTail : DrawableNote { - /// - /// Lenience of release hit windows. This is to make cases where the hold note release - /// is timed alongside presses of other hit objects less awkward. - /// Todo: This shouldn't exist for non-LegacyBeatmapDecoder beatmaps - /// - private const double release_window_lenience = 1.5; - protected override ManiaSkinComponents Component => ManiaSkinComponents.HoldNoteTail; protected DrawableHoldNote HoldNote => (DrawableHoldNote)ParentHitObject; @@ -40,14 +33,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables public void UpdateResult() => base.UpdateResult(true); - public override double MaximumJudgementOffset => base.MaximumJudgementOffset * release_window_lenience; - protected override void CheckForResult(bool userTriggered, double timeOffset) { Debug.Assert(HitObject.HitWindows != null); // Factor in the release lenience - timeOffset /= release_window_lenience; + timeOffset /= TailNote.RELEASE_WINDOW_LENIENCE; if (!userTriggered) { diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs index 22fab15c1b..c367886efe 100644 --- a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs @@ -81,6 +81,8 @@ namespace osu.Game.Rulesets.Mania.Objects /// public TailNote Tail { get; private set; } + public override double MaximumJudgementOffset => Tail.MaximumJudgementOffset; + /// /// The time between ticks of this hold. /// diff --git a/osu.Game.Rulesets.Mania/Objects/TailNote.cs b/osu.Game.Rulesets.Mania/Objects/TailNote.cs index cda8e2fa31..d6dc25079a 100644 --- a/osu.Game.Rulesets.Mania/Objects/TailNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/TailNote.cs @@ -10,6 +10,15 @@ namespace osu.Game.Rulesets.Mania.Objects { public class TailNote : Note { + /// + /// Lenience of release hit windows. This is to make cases where the hold note release + /// is timed alongside presses of other hit objects less awkward. + /// Todo: This shouldn't exist for non-LegacyBeatmapDecoder beatmaps + /// + public const double RELEASE_WINDOW_LENIENCE = 1.5; + public override Judgement CreateJudgement() => new ManiaJudgement(); + + public override double MaximumJudgementOffset => base.MaximumJudgementOffset * RELEASE_WINDOW_LENIENCE; } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinnerTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinnerTick.cs index b9ce07363c..34253e3d4f 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinnerTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinnerTick.cs @@ -25,8 +25,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Origin = Anchor.Centre; } - public override double MaximumJudgementOffset => DrawableSpinner.HitObject.Duration; - /// /// Apply a judgement result. /// diff --git a/osu.Game.Rulesets.Osu/Objects/Spinner.cs b/osu.Game.Rulesets.Osu/Objects/Spinner.cs index 0e1fe56cea..ed6f8a9a6a 100644 --- a/osu.Game.Rulesets.Osu/Objects/Spinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Spinner.cs @@ -71,8 +71,8 @@ namespace osu.Game.Rulesets.Osu.Objects double startTime = StartTime + (float)(i + 1) / totalSpins * Duration; AddNested(i < SpinsRequired - ? new SpinnerTick { StartTime = startTime } - : new SpinnerBonusTick { StartTime = startTime }); + ? new SpinnerTick { StartTime = startTime, SpinnerDuration = Duration } + : new SpinnerBonusTick { StartTime = startTime, SpinnerDuration = Duration }); } } diff --git a/osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs b/osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs index 650d02c675..c890f3771b 100644 --- a/osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs @@ -11,10 +11,17 @@ namespace osu.Game.Rulesets.Osu.Objects { public class SpinnerTick : OsuHitObject { + /// + /// Duration of the containing this spinner tick. + /// + public double SpinnerDuration { get; set; } + public override Judgement CreateJudgement() => new OsuSpinnerTickJudgement(); protected override HitWindows CreateHitWindows() => HitWindows.Empty; + public override double MaximumJudgementOffset => SpinnerDuration; + public class OsuSpinnerTickJudgement : OsuJudgement { public override HitResult MaxResult => HitResult.SmallBonus; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 45e25ee7dc..abecd19545 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -37,8 +37,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece()); - public override double MaximumJudgementOffset => HitObject.HitWindow; - protected override void OnApply() { base.OnApply(); diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs index 433fdab908..6bcb8674e6 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs @@ -31,6 +31,8 @@ namespace osu.Game.Rulesets.Taiko.Objects protected override HitWindows CreateHitWindows() => HitWindows.Empty; + public override double MaximumJudgementOffset => HitWindow; + protected override StrongNestedHitObject CreateStrongNestedHit(double startTime) => new StrongNestedHit { StartTime = startTime }; public class StrongNestedHit : StrongNestedHitObject diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index be5a7f71e7..43431d7703 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -651,18 +651,6 @@ namespace osu.Game.Rulesets.Objects.Drawables UpdateResult(false); } - /// - /// The maximum offset from the end time of at which this can be judged. - /// The time offset of will be clamped to this value during . - /// - /// Defaults to the miss window of . - /// - /// - /// - /// This does not affect the time offset provided to invocations of . - /// - public virtual double MaximumJudgementOffset => HitObject.HitWindows?.WindowFor(HitResult.Miss) ?? 0; - /// /// Applies the of this , notifying responders such as /// the of the . @@ -684,7 +672,7 @@ namespace osu.Game.Rulesets.Objects.Drawables $"{GetType().ReadableName()} applied an invalid hit result (was: {Result.Type}, expected: [{Result.Judgement.MinResult} ... {Result.Judgement.MaxResult}])."); } - Result.TimeOffset = Math.Min(MaximumJudgementOffset, Time.Current - HitObject.GetEndTime()); + Result.TimeOffset = Math.Min(HitObject.MaximumJudgementOffset, Time.Current - HitObject.GetEndTime()); if (Result.HasResult) updateState(Result.IsHit ? ArmedState.Hit : ArmedState.Miss); diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 0f79e58201..25f538d211 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -200,6 +200,14 @@ namespace osu.Game.Rulesets.Objects [NotNull] protected virtual HitWindows CreateHitWindows() => new HitWindows(); + /// + /// The maximum offset from the end time of at which this can be judged. + /// + /// Defaults to the miss window. + /// + /// + public virtual double MaximumJudgementOffset => HitWindows?.WindowFor(HitResult.Miss) ?? 0; + public IList CreateSlidingSamples() { var slidingSamples = new List(); From d8f9b7d02f2a4e3b86976b45226f7488ef1639f8 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Thu, 19 Jan 2023 21:25:21 +0900 Subject: [PATCH 1709/2991] Use MaximumJudgementOffset for lifetime --- osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 3559a1521c..b93a427196 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -232,8 +232,7 @@ namespace osu.Game.Rulesets.UI.Scrolling double computedStartTime = computeDisplayStartTime(entry); // always load the hitobject before its first judgement offset - double judgementOffset = entry.HitObject.HitWindows?.WindowFor(Scoring.HitResult.Miss) ?? 0; - entry.LifetimeStart = Math.Min(entry.HitObject.StartTime - judgementOffset, computedStartTime); + entry.LifetimeStart = Math.Min(entry.HitObject.StartTime - entry.HitObject.MaximumJudgementOffset, computedStartTime); } private void updateLayoutRecursive(DrawableHitObject hitObject, double? parentHitObjectStartTime = null) From f0464b0340172cf6139d04ec5cc1ca68581ee556 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 19 Jan 2023 22:38:54 +0300 Subject: [PATCH 1710/2991] Actually fix intermittent failure in beatmap options state test --- osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index a61171abad..feab86d3ee 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -1064,7 +1064,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("options enabled", () => songSelect.ChildrenOfType().Single().Enabled.Value); AddStep("delete all beatmaps", () => manager.Delete()); - AddWaitStep("wait for debounce", 1); + AddUntilStep("wait for no beatmap", () => Beatmap.IsDefault); AddAssert("options disabled", () => !songSelect.ChildrenOfType().Single().Enabled.Value); } From 8174ef06c3caaabdbd6a5c89410d18caf227d5ff Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 20 Jan 2023 01:18:41 +0300 Subject: [PATCH 1711/2991] Fix intermittent failure in playlists match loading test --- .../Visual/Playlists/TestScenePlaylistsRoomCreation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomCreation.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomCreation.cs index bdae91de59..6c732f4295 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomCreation.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomCreation.cs @@ -79,7 +79,7 @@ namespace osu.Game.Tests.Visual.Playlists AddUntilStep("Leaderboard shows two aggregate scores", () => match.ChildrenOfType().Count(s => s.ScoreText.Text != "0") == 2); - AddStep("start match", () => match.ChildrenOfType().First().TriggerClick()); + ClickButtonWhenEnabled(); AddUntilStep("player loader loaded", () => Stack.CurrentScreen is PlayerLoader); } From 7e466e1eba35c196a5039a40c881f829fe9f4959 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Fri, 20 Jan 2023 21:00:01 +0900 Subject: [PATCH 1712/2991] Fix SPM calculation division by zero --- .../Skinning/Default/SpinnerSpmCalculator.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs index 0bd5fd4cac..44962c8548 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs @@ -35,14 +35,14 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default public void SetRotation(float currentRotation) { - // Never calculate SPM by same time of record to avoid 0 / 0 = NaN or X / 0 = Infinity result. - if (Precision.AlmostEquals(0, Time.Elapsed)) - return; - // If we've gone back in time, it's fine to work with a fresh set of records for now if (records.Count > 0 && Time.Current < records.Last().Time) records.Clear(); + // Never calculate SPM by same time of record to avoid 0 / 0 = NaN or X / 0 = Infinity result. + if (records.Count > 0 && Precision.AlmostEquals(Time.Current, records.Last().Time)) + return; + if (records.Count > 0) { var record = records.Peek(); From 19450bfe12e5742a161cff59f9f3ebbf8fe1ac59 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 20 Jan 2023 23:23:25 +0900 Subject: [PATCH 1713/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index c6cf7812d1..71944065bf 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -10,7 +10,7 @@ true - + true true + manifestmerger.jar + + + diff --git a/osu.Android/AndroidManifest.xml b/osu.Android/AndroidManifest.xml index 9ea57969b7..bc2f49b1a9 100644 --- a/osu.Android/AndroidManifest.xml +++ b/osu.Android/AndroidManifest.xml @@ -2,16 +2,4 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/osu.Android/Properties/AndroidManifestOverlay.xml b/osu.Android/Properties/AndroidManifestOverlay.xml new file mode 100644 index 0000000000..815f935383 --- /dev/null +++ b/osu.Android/Properties/AndroidManifestOverlay.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/osu.Game.Rulesets.Catch.Tests.Android/AndroidManifest.xml b/osu.Game.Rulesets.Catch.Tests.Android/AndroidManifest.xml index 22b4ea9191..bf7c0bfeca 100644 --- a/osu.Game.Rulesets.Catch.Tests.Android/AndroidManifest.xml +++ b/osu.Game.Rulesets.Catch.Tests.Android/AndroidManifest.xml @@ -3,16 +3,4 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania.Tests.Android/AndroidManifest.xml b/osu.Game.Rulesets.Mania.Tests.Android/AndroidManifest.xml index c8b0de9f42..4a1545a423 100644 --- a/osu.Game.Rulesets.Mania.Tests.Android/AndroidManifest.xml +++ b/osu.Game.Rulesets.Mania.Tests.Android/AndroidManifest.xml @@ -2,16 +2,4 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu.Tests.Android/AndroidManifest.xml b/osu.Game.Rulesets.Osu.Tests.Android/AndroidManifest.xml index d91fc062fe..45d27dda70 100644 --- a/osu.Game.Rulesets.Osu.Tests.Android/AndroidManifest.xml +++ b/osu.Game.Rulesets.Osu.Tests.Android/AndroidManifest.xml @@ -2,16 +2,4 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko.Tests.Android/AndroidManifest.xml b/osu.Game.Rulesets.Taiko.Tests.Android/AndroidManifest.xml index f678d63dbb..452b9683ec 100644 --- a/osu.Game.Rulesets.Taiko.Tests.Android/AndroidManifest.xml +++ b/osu.Game.Rulesets.Taiko.Tests.Android/AndroidManifest.xml @@ -2,16 +2,4 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/osu.Game.Tests.Android/AndroidManifest.xml b/osu.Game.Tests.Android/AndroidManifest.xml index 105f2b1e8b..f25b2e5328 100644 --- a/osu.Game.Tests.Android/AndroidManifest.xml +++ b/osu.Game.Tests.Android/AndroidManifest.xml @@ -2,16 +2,4 @@ - - - - - - - - - - - - \ No newline at end of file From 908651cc11251cf80e13b8b539abcfc0bd4454a2 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 5 Mar 2023 20:57:26 +0100 Subject: [PATCH 2368/2991] make `ResetConfirmDialog` properly utilise its parent's logic Adjust name of `DeleteAction` to `DangerousAction` --- .../Collections/DeleteCollectionDialog.cs | 2 +- .../Overlays/Dialog/DangerousActionDialog.cs | 4 ++-- .../Overlays/Mods/DeleteModPresetDialog.cs | 2 +- .../MassDeleteConfirmationDialog.cs | 2 +- osu.Game/Overlays/SkinEditor/SkinEditor.cs | 19 ++----------------- .../DeleteDifficultyConfirmationDialog.cs | 2 +- .../Select/BeatmapClearScoresDialog.cs | 2 +- .../Screens/Select/BeatmapDeleteDialog.cs | 2 +- .../Carousel/UpdateLocalConfirmationDialog.cs | 2 +- .../Screens/Select/LocalScoreDeleteDialog.cs | 2 +- osu.Game/Screens/Select/SkinDeleteDialog.cs | 2 +- 11 files changed, 13 insertions(+), 28 deletions(-) diff --git a/osu.Game/Collections/DeleteCollectionDialog.cs b/osu.Game/Collections/DeleteCollectionDialog.cs index 4da2979481..9edc213077 100644 --- a/osu.Game/Collections/DeleteCollectionDialog.cs +++ b/osu.Game/Collections/DeleteCollectionDialog.cs @@ -13,7 +13,7 @@ namespace osu.Game.Collections public DeleteCollectionDialog(Live collection, Action deleteAction) { BodyText = collection.PerformRead(c => $"{c.Name} ({"beatmap".ToQuantity(c.BeatmapMD5Hashes.Count)})"); - DeleteAction = deleteAction; + DangerousAction = deleteAction; } } } diff --git a/osu.Game/Overlays/Dialog/DangerousActionDialog.cs b/osu.Game/Overlays/Dialog/DangerousActionDialog.cs index aaec72fc4d..85cae5e0d2 100644 --- a/osu.Game/Overlays/Dialog/DangerousActionDialog.cs +++ b/osu.Game/Overlays/Dialog/DangerousActionDialog.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Dialog /// /// The action which performs the deletion. /// - protected Action? DeleteAction { get; set; } + protected Action? DangerousAction { get; set; } protected DangerousActionDialog() { @@ -30,7 +30,7 @@ namespace osu.Game.Overlays.Dialog new PopupDialogDangerousButton { Text = DeleteConfirmationDialogStrings.Confirm, - Action = () => DeleteAction?.Invoke() + Action = () => DangerousAction?.Invoke() }, new PopupDialogCancelButton { diff --git a/osu.Game/Overlays/Mods/DeleteModPresetDialog.cs b/osu.Game/Overlays/Mods/DeleteModPresetDialog.cs index 5b329a32d5..9788764453 100644 --- a/osu.Game/Overlays/Mods/DeleteModPresetDialog.cs +++ b/osu.Game/Overlays/Mods/DeleteModPresetDialog.cs @@ -12,7 +12,7 @@ namespace osu.Game.Overlays.Mods public DeleteModPresetDialog(Live modPreset) { BodyText = modPreset.PerformRead(preset => preset.Name); - DeleteAction = () => modPreset.PerformWrite(preset => preset.DeletePending = true); + DangerousAction = () => modPreset.PerformWrite(preset => preset.DeletePending = true); } } } diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/MassDeleteConfirmationDialog.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/MassDeleteConfirmationDialog.cs index 71226803c8..99ef62d94b 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/MassDeleteConfirmationDialog.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/MassDeleteConfirmationDialog.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance public MassDeleteConfirmationDialog(Action deleteAction) { BodyText = "Everything?"; - DeleteAction = deleteAction; + DangerousAction = deleteAction; } } } diff --git a/osu.Game/Overlays/SkinEditor/SkinEditor.cs b/osu.Game/Overlays/SkinEditor/SkinEditor.cs index 5ffdaa11d4..a7fe459aa4 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditor.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditor.cs @@ -12,7 +12,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input; using osu.Framework.Input.Bindings; @@ -633,25 +632,11 @@ namespace osu.Game.Overlays.SkinEditor public partial class ResetConfirmDialog : DangerousActionDialog { - public ResetConfirmDialog(Action reset) + public ResetConfirmDialog(Action revert) { HeaderText = SkinEditorStrings.RevertToDefaultDescription; BodyText = SkinEditorStrings.ResetDialogue; - - Icon = FontAwesome.Solid.ExclamationTriangle; - - Buttons = new PopupDialogButton[] - { - new PopupDialogDangerousButton - { - Text = BeatmapOverlayStrings.UserContentConfirmButtonText, - Action = reset - }, - new PopupDialogCancelButton - { - Text = Web.CommonStrings.ButtonsCancel, - }, - }; + DangerousAction = revert; } } diff --git a/osu.Game/Screens/Edit/DeleteDifficultyConfirmationDialog.cs b/osu.Game/Screens/Edit/DeleteDifficultyConfirmationDialog.cs index 6db31967d6..8556949528 100644 --- a/osu.Game/Screens/Edit/DeleteDifficultyConfirmationDialog.cs +++ b/osu.Game/Screens/Edit/DeleteDifficultyConfirmationDialog.cs @@ -12,7 +12,7 @@ namespace osu.Game.Screens.Edit public DeleteDifficultyConfirmationDialog(BeatmapInfo beatmapInfo, Action deleteAction) { BodyText = $"\"{beatmapInfo.DifficultyName}\" difficulty"; - DeleteAction = deleteAction; + DangerousAction = deleteAction; } } } diff --git a/osu.Game/Screens/Select/BeatmapClearScoresDialog.cs b/osu.Game/Screens/Select/BeatmapClearScoresDialog.cs index 2704a1afb4..8efad451df 100644 --- a/osu.Game/Screens/Select/BeatmapClearScoresDialog.cs +++ b/osu.Game/Screens/Select/BeatmapClearScoresDialog.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Select public BeatmapClearScoresDialog(BeatmapInfo beatmapInfo, Action onCompletion) { BodyText = $"All local scores on {beatmapInfo.GetDisplayTitle()}"; - DeleteAction = () => + DangerousAction = () => { Task.Run(() => scoreManager.Delete(beatmapInfo)) .ContinueWith(_ => onCompletion); diff --git a/osu.Game/Screens/Select/BeatmapDeleteDialog.cs b/osu.Game/Screens/Select/BeatmapDeleteDialog.cs index 0692cc3745..e98af8cca2 100644 --- a/osu.Game/Screens/Select/BeatmapDeleteDialog.cs +++ b/osu.Game/Screens/Select/BeatmapDeleteDialog.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.Select [BackgroundDependencyLoader] private void load(BeatmapManager beatmapManager) { - DeleteAction = () => beatmapManager.Delete(beatmapSet); + DangerousAction = () => beatmapManager.Delete(beatmapSet); } } } diff --git a/osu.Game/Screens/Select/Carousel/UpdateLocalConfirmationDialog.cs b/osu.Game/Screens/Select/Carousel/UpdateLocalConfirmationDialog.cs index ecb21d4e2c..6157e8f6a5 100644 --- a/osu.Game/Screens/Select/Carousel/UpdateLocalConfirmationDialog.cs +++ b/osu.Game/Screens/Select/Carousel/UpdateLocalConfirmationDialog.cs @@ -15,7 +15,7 @@ namespace osu.Game.Screens.Select.Carousel HeaderText = PopupDialogStrings.UpdateLocallyModifiedText; BodyText = PopupDialogStrings.UpdateLocallyModifiedDescription; Icon = FontAwesome.Solid.ExclamationTriangle; - DeleteAction = onConfirm; + DangerousAction = onConfirm; } } } diff --git a/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs b/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs index 660122c80e..c4add31a4f 100644 --- a/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs +++ b/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs @@ -28,7 +28,7 @@ namespace osu.Game.Screens.Select BodyText = $"{score.User} ({score.DisplayAccuracy}, {score.Rank})"; Icon = FontAwesome.Regular.TrashAlt; - DeleteAction = () => scoreManager.Delete(score); + DangerousAction = () => scoreManager.Delete(score); } } } diff --git a/osu.Game/Screens/Select/SkinDeleteDialog.cs b/osu.Game/Screens/Select/SkinDeleteDialog.cs index 3c95de0620..6612ae837a 100644 --- a/osu.Game/Screens/Select/SkinDeleteDialog.cs +++ b/osu.Game/Screens/Select/SkinDeleteDialog.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.Select [BackgroundDependencyLoader] private void load(SkinManager manager) { - DeleteAction = () => + DangerousAction = () => { manager.Delete(skin.SkinInfo.Value); manager.CurrentSkinInfo.SetDefault(); From 082bfe3621f8502b81376f5a92e031cf3c7d4803 Mon Sep 17 00:00:00 2001 From: tsrk Date: Sun, 5 Mar 2023 23:09:02 +0000 Subject: [PATCH 2369/2991] refactor: `SkinnableAvatar` to `PlayerAvatar` --- .../Screens/Play/HUD/{SkinnableAvatar.cs => PlayerAvatar.cs} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename osu.Game/Screens/Play/HUD/{SkinnableAvatar.cs => PlayerAvatar.cs} (92%) diff --git a/osu.Game/Screens/Play/HUD/SkinnableAvatar.cs b/osu.Game/Screens/Play/HUD/PlayerAvatar.cs similarity index 92% rename from osu.Game/Screens/Play/HUD/SkinnableAvatar.cs rename to osu.Game/Screens/Play/HUD/PlayerAvatar.cs index 41fe8c6a06..d4ab555d04 100644 --- a/osu.Game/Screens/Play/HUD/SkinnableAvatar.cs +++ b/osu.Game/Screens/Play/HUD/PlayerAvatar.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Screens.Play.HUD { - public partial class SkinnableAvatar : CompositeDrawable, ISerialisableDrawable + public partial class PlayerAvatar : CompositeDrawable, ISerialisableDrawable { [SettingSource("Corner radius", "How much the edges should be rounded.")] public new BindableFloat CornerRadius { get; set; } = new BindableFloat @@ -27,7 +27,7 @@ namespace osu.Game.Screens.Play.HUD private readonly UpdateableAvatar avatar; - public SkinnableAvatar() + public PlayerAvatar() { Size = new Vector2(128f); InternalChild = avatar = new UpdateableAvatar(isInteractive: false) From 654eacd4496cde2601015abc053d8d081f25869d Mon Sep 17 00:00:00 2001 From: tsrk Date: Sun, 5 Mar 2023 23:10:42 +0000 Subject: [PATCH 2370/2991] feat(l10n): localise `CornerRadius` --- .../SkinComponents/SkinnableComponentStrings.cs | 10 ++++++++++ osu.Game/Screens/Play/HUD/PlayerAvatar.cs | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game/Localisation/SkinComponents/SkinnableComponentStrings.cs b/osu.Game/Localisation/SkinComponents/SkinnableComponentStrings.cs index 547df86fc7..5cec9442e4 100644 --- a/osu.Game/Localisation/SkinComponents/SkinnableComponentStrings.cs +++ b/osu.Game/Localisation/SkinComponents/SkinnableComponentStrings.cs @@ -39,6 +39,16 @@ namespace osu.Game.Localisation.SkinComponents /// public static LocalisableString TextElementTextDescription => new TranslatableString(getKey(@"text_element_text_description"), "The text to be displayed."); + /// + /// "Corner Radius" + /// + public static LocalisableString CornerRadius => new TranslatableString(getKey(@"corner_radius"), "Corner Radius"); + + /// + /// "How rounded the corners should be." + /// + public static LocalisableString CornerRadiusDescription => new TranslatableString(getKey(@"corner_radius_description"), "How rounded the corners should be."); + private static string getKey(string key) => $"{prefix}:{key}"; } } diff --git a/osu.Game/Screens/Play/HUD/PlayerAvatar.cs b/osu.Game/Screens/Play/HUD/PlayerAvatar.cs index d4ab555d04..6cea463193 100644 --- a/osu.Game/Screens/Play/HUD/PlayerAvatar.cs +++ b/osu.Game/Screens/Play/HUD/PlayerAvatar.cs @@ -6,6 +6,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Configuration; +using osu.Game.Localisation.SkinComponents; using osu.Game.Skinning; using osu.Game.Users.Drawables; using osuTK; @@ -14,7 +15,7 @@ namespace osu.Game.Screens.Play.HUD { public partial class PlayerAvatar : CompositeDrawable, ISerialisableDrawable { - [SettingSource("Corner radius", "How much the edges should be rounded.")] + [SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.CornerRadius), nameof(SkinnableComponentStrings.CornerRadiusDescription))] public new BindableFloat CornerRadius { get; set; } = new BindableFloat { MinValue = 0, From 20a610ea6c4c407cedcdffc8a9ac3ae0fbd1f8b0 Mon Sep 17 00:00:00 2001 From: tsrk Date: Sun, 5 Mar 2023 23:15:58 +0000 Subject: [PATCH 2371/2991] style: a NRT pass on `UpdateableFlag` --- osu.Game/Users/Drawables/UpdateableFlag.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/osu.Game/Users/Drawables/UpdateableFlag.cs b/osu.Game/Users/Drawables/UpdateableFlag.cs index a208f3c7c4..8f8d7052e5 100644 --- a/osu.Game/Users/Drawables/UpdateableFlag.cs +++ b/osu.Game/Users/Drawables/UpdateableFlag.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -30,14 +28,14 @@ namespace osu.Game.Users.Drawables /// Perform an action in addition to showing the country ranking. /// This should be used to perform auxiliary tasks and not as a primary action for clicking a flag (to maintain a consistent UX). /// - public Action Action; + public Action? Action; public UpdateableFlag(CountryCode countryCode = CountryCode.Unknown) { CountryCode = countryCode; } - protected override Drawable CreateDrawable(CountryCode countryCode) + protected override Drawable? CreateDrawable(CountryCode countryCode) { if (countryCode == CountryCode.Unknown && !ShowPlaceholderOnUnknown) return null; @@ -56,8 +54,8 @@ namespace osu.Game.Users.Drawables }; } - [Resolved(canBeNull: true)] - private RankingsOverlay rankingsOverlay { get; set; } + [Resolved] + private RankingsOverlay? rankingsOverlay { get; set; } protected override bool OnClick(ClickEvent e) { From 07bde4990d50836a64e62f61a60f991165bb6436 Mon Sep 17 00:00:00 2001 From: tsrk Date: Sun, 5 Mar 2023 23:17:30 +0000 Subject: [PATCH 2372/2991] feat: implement `PlayerAvatar` --- osu.Game/Screens/Play/HUD/PlayerFlag.cs | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 osu.Game/Screens/Play/HUD/PlayerFlag.cs diff --git a/osu.Game/Screens/Play/HUD/PlayerFlag.cs b/osu.Game/Screens/Play/HUD/PlayerFlag.cs new file mode 100644 index 0000000000..17188d0009 --- /dev/null +++ b/osu.Game/Screens/Play/HUD/PlayerFlag.cs @@ -0,0 +1,38 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Skinning; +using osu.Game.Users.Drawables; +using osuTK; + +namespace osu.Game.Screens.Play.HUD +{ + public partial class PlayerFlag : CompositeDrawable, ISerialisableDrawable + { + [Resolved] + private GameplayState gameplayState { get; set; } = null!; + + private readonly UpdateableFlag flag; + + public PlayerFlag() + { + Size = new Vector2(114, 80); + InternalChild = flag = new UpdateableFlag + { + RelativeSizeAxes = Axes.Both, + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + flag.CountryCode = gameplayState.Score.ScoreInfo.User.CountryCode; + } + + public bool UsesFixedAnchor { get; set; } + } +} From ddee6400dfa3c28f476e0c9fea11a17874c82257 Mon Sep 17 00:00:00 2001 From: tsrk Date: Sun, 5 Mar 2023 23:46:51 +0000 Subject: [PATCH 2373/2991] test: add coverage for `Player{Avatar,Flag}` --- .../Archives/modified-argon-20230305.osk | Bin 0 -> 1897 bytes osu.Game.Tests/Skins/SkinDeserialisationTest.cs | 7 ++++++- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/Resources/Archives/modified-argon-20230305.osk diff --git a/osu.Game.Tests/Resources/Archives/modified-argon-20230305.osk b/osu.Game.Tests/Resources/Archives/modified-argon-20230305.osk new file mode 100644 index 0000000000000000000000000000000000000000..c85f3b6352af3357089a797c287659a0d8e848f7 GIT binary patch literal 1897 zcmZ`)2{ha37XJrDwM>j<6dg)aofm6Nl`=@FlHetRpxP!SwNw*ZQW6}y5s4*KF={EH zN^R8^#bCygmIl?)Djh?_UPTSDj7j_Ey*c&X`@VC}J@-4`@1A?V@7~`N?B_rB4NU|rVlAmS1QZ5D)sBQZsC%Y@)DD`?fvQgW%$c95cG#nwX5eaNBy!>}^x zSMnoc3Ae1r;c-(M3B@4=N}}*4N1bz$rM~DOQvG&rj>c9JM;D3N!SAoqeU77@MDnSzO%AM%6NUOL18A1WCPf&1x=^Hr@-YKH;#HEae+Y?K$)9#Y zp;nQ74leahsHb|mF3#Vh5!whYHwEo9pbyiB4LJ|=_WzS(|IFS21k?HUW@x)deu|SE zay7-W`RrQ#+Um2lqAv@=yCBKoklbWQt{}W1+)sdtTOW(bo;~2>!=EPb*$XDIi@-{# zJdTBE@q7q;9w5sc$)t(`K$Q{zC<+5~!21zxU97E0*8@pJ0x>k?Q>067Xwn-aaFkl@ z9*+0=gl%$GFDSe>pM2y|arf9e_DM01wq8$Pm^!<`W^m8^Y2CufVp;Vdp8Vb2E8{mN zZwtncE^kiH6pF`XhGLyWl%Go~&CPFdp0mECH6>MyEWXe-D>w<=HN&b+n zHvTxQ&#A2@r^Q?FE^O+n-!W*D@YYu?FVAORzPojLrfOT|EO}!VJ9mclb(~0#l>XZb z(c4ukV&`+0>4li7y=#00?T+CDS8+PE_$gE_IC#8$Y^|wb)Tlbg4m)q;`(f9V$V8vB(W^<3RQMb^q4L(#q25!yjaJWPgxI?H|lk0dHv z69fR(A^`A(uv;-Cq7Q};K=2Cv)TZPNB(YN;oVan5Dgj;SmGVPav9<4gD884XAvs>8 zYp)cWU}zI{S3OH~UA5KiwxyKpxwm~0duCDLlo4!vSQCT-xC(8*>Fw(iJ434N=Sk_qq46_?0cwbTrb3fm^Ie z_w9``>IV!Cb~kcIe9W1q@W}E(?v0LzBjo0Ex0GAwih;z|%R|JIw ziO2*0f5ZqM^wjSYAg1##)PG2RKXgCg{tfjKe(e9I-~B%Jm%-mY YWDopTQJ|0q#6MmT6Yf=^#(%Q@1WNchY5)KL literal 0 HcmV?d00001 diff --git a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs index 04b8c6dd4e..eb1df954aa 100644 --- a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs +++ b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs @@ -9,6 +9,7 @@ using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; +using osu.Framework.Logging; using osu.Game.Audio; using osu.Game.IO; using osu.Game.IO.Archives; @@ -48,7 +49,9 @@ namespace osu.Game.Tests.Skins // Covers BPM counter. "Archives/modified-default-20221205.osk", // Covers judgement counter. - "Archives/modified-default-20230117.osk" + "Archives/modified-default-20230117.osk", + // Covers player avatar and flag. + "Archives/modified-argon-20230305.osk", }; /// @@ -61,6 +64,8 @@ namespace osu.Game.Tests.Skins foreach (string oskFile in available_skins) { + Logger.Log($"Testing file {oskFile}..."); + using (var stream = TestResources.OpenResource(oskFile)) using (var storage = new ZipArchiveReader(stream)) { From 87d0bef313fc9e5563dc3d368f3daf59b437c6aa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 6 Mar 2023 15:16:31 +0900 Subject: [PATCH 2374/2991] Use nullable comparison helper method instead of manual implementation --- .../Screens/Select/Carousel/CarouselBeatmapSet.cs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index 63493a3b02..67822a27ee 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -87,7 +87,7 @@ namespace osu.Game.Screens.Select.Carousel break; case SortMode.DateRanked: - comparison = compareNullableDateTimeOffset(BeatmapSet.DateRanked, otherSet.BeatmapSet.DateRanked); + comparison = Nullable.Compare(otherSet.BeatmapSet.DateRanked, BeatmapSet.DateRanked); break; case SortMode.LastPlayed: @@ -107,7 +107,7 @@ namespace osu.Game.Screens.Select.Carousel break; case SortMode.DateSubmitted: - comparison = compareNullableDateTimeOffset(BeatmapSet.DateSubmitted, otherSet.BeatmapSet.DateSubmitted); + comparison = Nullable.Compare(otherSet.BeatmapSet.DateSubmitted, BeatmapSet.DateSubmitted); break; } @@ -124,14 +124,6 @@ namespace osu.Game.Screens.Select.Carousel return otherSet.BeatmapSet.ID.CompareTo(BeatmapSet.ID); } - private static int compareNullableDateTimeOffset(DateTimeOffset? x, DateTimeOffset? y) - { - if (x == null) return 1; - if (y == null) return -1; - - return y.Value.CompareTo(x.Value); - } - /// /// All beatmaps which are not filtered and valid for display. /// From 3a240aaa5fa1e55bcc9b50c26345ebdf0c001d99 Mon Sep 17 00:00:00 2001 From: tsrk Date: Mon, 6 Mar 2023 10:27:59 +0000 Subject: [PATCH 2375/2991] style: use 64 radius --- osu.Game/Screens/Play/HUD/PlayerAvatar.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/PlayerAvatar.cs b/osu.Game/Screens/Play/HUD/PlayerAvatar.cs index 6cea463193..32ed045df7 100644 --- a/osu.Game/Screens/Play/HUD/PlayerAvatar.cs +++ b/osu.Game/Screens/Play/HUD/PlayerAvatar.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.Play.HUD public new BindableFloat CornerRadius { get; set; } = new BindableFloat { MinValue = 0, - MaxValue = 63, + MaxValue = 64, Precision = 0.01f }; From df34bdc825e5496339de30ad3173f93dd28f40df Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 6 Mar 2023 19:31:45 +0900 Subject: [PATCH 2376/2991] Use lang version 10 --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 3b6b985961..734374c840 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@  - 9.0 + 10.0 true enable From a7be59175d15298d1a7eff2c9e090dca03c8492f Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Mon, 6 Mar 2023 10:57:09 +0000 Subject: [PATCH 2377/2991] Made private + renamed Taiko Single Tap tracking variables for better readability --- .../Mods/TaikoModSingleTap.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs index 1130338521..30e4946833 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs @@ -29,9 +29,9 @@ namespace osu.Game.Rulesets.Taiko.Mods protected bool CheckValidNewAction(TaikoAction action) { if (action == TaikoAction.LeftCentre || action == TaikoAction.RightCentre) - return LastAcceptedDonAction == null || LastAcceptedDonAction == action; + return lastAcceptedCentreAction == null || lastAcceptedCentreAction == action; if (action == TaikoAction.LeftRim || action == TaikoAction.RightRim) - return LastAcceptedKatAction == null || LastAcceptedKatAction == action; + return lastAcceptedRimAction == null || lastAcceptedRimAction == action; return true; } @@ -44,8 +44,8 @@ namespace osu.Game.Rulesets.Taiko.Mods private TaikoPlayfield playfield { get; set; } = null!; - protected TaikoAction? LastAcceptedDonAction { get; private set; } - protected TaikoAction? LastAcceptedKatAction { get; private set; } + private TaikoAction? lastAcceptedCentreAction { get; set; } + private TaikoAction? lastAcceptedRimAction { get; set; } /// /// A tracker for periods where alternate should not be forced (i.e. non-gameplay periods). @@ -84,11 +84,11 @@ namespace osu.Game.Rulesets.Taiko.Mods { if (!nonGameplayPeriods.IsInAny(gameplayClock.CurrentTime)) return; - if (LastAcceptedDonAction != null) - LastAcceptedDonAction = null; + if (lastAcceptedCentreAction != null) + lastAcceptedCentreAction = null; - if (LastAcceptedKatAction != null) - LastAcceptedKatAction = null; + if (lastAcceptedRimAction != null) + lastAcceptedRimAction = null; } private bool checkCorrectAction(TaikoAction action) @@ -105,9 +105,9 @@ namespace osu.Game.Rulesets.Taiko.Mods if (CheckValidNewAction(action)) { if (action == TaikoAction.LeftCentre || action == TaikoAction.RightCentre) - LastAcceptedDonAction = action; + lastAcceptedCentreAction = action; if (action == TaikoAction.LeftRim || action == TaikoAction.RightRim) - LastAcceptedKatAction = action; + lastAcceptedRimAction = action; return true; } From ac6c8e600a4ef58cedae8f19b8fabf50fa8aa6fc Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Mon, 6 Mar 2023 10:59:47 +0000 Subject: [PATCH 2378/2991] Updated a comment for correctness --- osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs index 30e4946833..9b411b49d4 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Taiko.Mods private TaikoAction? lastAcceptedRimAction { get; set; } /// - /// A tracker for periods where alternate should not be forced (i.e. non-gameplay periods). + /// A tracker for periods where single tap should not be enforced (i.e. non-gameplay periods). /// /// /// This is different from in that the periods here end strictly at the first object after the break, rather than the break's end time. From 4ae2661f1bd90181b54917ef55df431c7622ad57 Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Mon, 6 Mar 2023 11:00:37 +0000 Subject: [PATCH 2379/2991] Removed useless null checks --- osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs index 9b411b49d4..92aff90ae0 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs @@ -84,11 +84,8 @@ namespace osu.Game.Rulesets.Taiko.Mods { if (!nonGameplayPeriods.IsInAny(gameplayClock.CurrentTime)) return; - if (lastAcceptedCentreAction != null) - lastAcceptedCentreAction = null; - - if (lastAcceptedRimAction != null) - lastAcceptedRimAction = null; + lastAcceptedCentreAction = null; + lastAcceptedRimAction = null; } private bool checkCorrectAction(TaikoAction action) From 36108ea841603febdc2602e9f4a85ad69c25f34a Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Mon, 6 Mar 2023 11:10:57 +0000 Subject: [PATCH 2380/2991] Moved `CheckValidNewAction` checks into `checkCorrectAction` --- .../Mods/TaikoModSingleTap.cs | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs index 92aff90ae0..556e31d2c2 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs @@ -26,16 +26,6 @@ namespace osu.Game.Rulesets.Taiko.Mods public override string Acronym => @"SG"; public override LocalisableString Description => @"One key for dons, one key for kats."; - protected bool CheckValidNewAction(TaikoAction action) - { - if (action == TaikoAction.LeftCentre || action == TaikoAction.RightCentre) - return lastAcceptedCentreAction == null || lastAcceptedCentreAction == action; - if (action == TaikoAction.LeftRim || action == TaikoAction.RightRim) - return lastAcceptedRimAction == null || lastAcceptedRimAction == action; - - return true; - } - public override double ScoreMultiplier => 1.0; public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(ModRelax), typeof(TaikoModCinema) }; public override ModType Type => ModType.Conversion; @@ -99,13 +89,17 @@ namespace osu.Game.Rulesets.Taiko.Mods && hitObject is not DrumRoll) return true; - if (CheckValidNewAction(action)) + if ((action == TaikoAction.LeftCentre || action == TaikoAction.RightCentre) + && (lastAcceptedCentreAction == null || lastAcceptedCentreAction == action)) { - if (action == TaikoAction.LeftCentre || action == TaikoAction.RightCentre) - lastAcceptedCentreAction = action; - if (action == TaikoAction.LeftRim || action == TaikoAction.RightRim) - lastAcceptedRimAction = action; + lastAcceptedCentreAction = action; + return true; + } + if ((action == TaikoAction.LeftRim || action == TaikoAction.RightRim) + && (lastAcceptedRimAction == null || lastAcceptedRimAction == action)) + { + lastAcceptedRimAction = action; return true; } From b2d453fd2edae6478bb0dfbfa860bea39a8251c3 Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Mon, 6 Mar 2023 11:44:00 +0000 Subject: [PATCH 2381/2991] Fixed indentation --- osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs index 556e31d2c2..fa876555e1 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs @@ -90,14 +90,14 @@ namespace osu.Game.Rulesets.Taiko.Mods return true; if ((action == TaikoAction.LeftCentre || action == TaikoAction.RightCentre) - && (lastAcceptedCentreAction == null || lastAcceptedCentreAction == action)) + && (lastAcceptedCentreAction == null || lastAcceptedCentreAction == action)) { lastAcceptedCentreAction = action; return true; } if ((action == TaikoAction.LeftRim || action == TaikoAction.RightRim) - && (lastAcceptedRimAction == null || lastAcceptedRimAction == action)) + && (lastAcceptedRimAction == null || lastAcceptedRimAction == action)) { lastAcceptedRimAction = action; return true; From 1fcf41379d5d5c37d211644fc96e4e99c4710ab0 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Mon, 6 Mar 2023 16:20:36 +0100 Subject: [PATCH 2382/2991] Added maintainability patch by bdach --- osu.Game/Beatmaps/BeatmapInfoExtensions.cs | 22 +++++------- .../Beatmaps/BeatmapMetadataInfoExtensions.cs | 35 +++++++++++++------ 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapInfoExtensions.cs b/osu.Game/Beatmaps/BeatmapInfoExtensions.cs index 460944d2fa..3aab9a24e1 100644 --- a/osu.Game/Beatmaps/BeatmapInfoExtensions.cs +++ b/osu.Game/Beatmaps/BeatmapInfoExtensions.cs @@ -1,7 +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 System.Collections.Generic; using osu.Framework.Localisation; namespace osu.Game.Beatmaps @@ -29,25 +29,19 @@ namespace osu.Game.Beatmaps return new RomanisableString($"{metadata.GetPreferred(true)}".Trim(), $"{metadata.GetPreferred(false)}".Trim()); } - public static ReadOnlySpan GetSearchableTerms(this IBeatmapInfo beatmapInfo) + public static List GetSearchableTerms(this IBeatmapInfo beatmapInfo) { - string[] terms = new string[8]; - int i = 0; - var metadata = beatmapInfo.Metadata; + var termsList = new List(BeatmapMetadataInfoExtensions.MAX_SEARCHABLE_TERM_COUNT + 1); + addIfNotNull(beatmapInfo.DifficultyName); - addIfNotNull(metadata.Author.Username); - addIfNotNull(metadata.Artist); - addIfNotNull(metadata.ArtistUnicode); - addIfNotNull(metadata.Title); - addIfNotNull(metadata.TitleUnicode); - addIfNotNull(metadata.Source); - addIfNotNull(metadata.Tags); - return terms.AsSpan(0, i); + + BeatmapMetadataInfoExtensions.CollectSearchableTerms(beatmapInfo.Metadata, termsList); + return termsList; void addIfNotNull(string? s) { if (!string.IsNullOrEmpty(s)) - terms[i++] = s; + termsList.Add(s); } } diff --git a/osu.Game/Beatmaps/BeatmapMetadataInfoExtensions.cs b/osu.Game/Beatmaps/BeatmapMetadataInfoExtensions.cs index 738bdb0839..fe4e815e62 100644 --- a/osu.Game/Beatmaps/BeatmapMetadataInfoExtensions.cs +++ b/osu.Game/Beatmaps/BeatmapMetadataInfoExtensions.cs @@ -3,7 +3,7 @@ #nullable disable -using System.Linq; +using System.Collections.Generic; using osu.Framework.Localisation; namespace osu.Game.Beatmaps @@ -13,16 +13,31 @@ namespace osu.Game.Beatmaps /// /// An array of all searchable terms provided in contained metadata. /// - public static string[] GetSearchableTerms(this IBeatmapMetadataInfo metadataInfo) => new[] + public static string[] GetSearchableTerms(this IBeatmapMetadataInfo metadataInfo) { - metadataInfo.Author.Username, - metadataInfo.Artist, - metadataInfo.ArtistUnicode, - metadataInfo.Title, - metadataInfo.TitleUnicode, - metadataInfo.Source, - metadataInfo.Tags - }.Where(s => !string.IsNullOrEmpty(s)).ToArray(); + var termsList = new List(MAX_SEARCHABLE_TERM_COUNT); + CollectSearchableTerms(metadataInfo, termsList); + return termsList.ToArray(); + } + + internal const int MAX_SEARCHABLE_TERM_COUNT = 7; + + internal static void CollectSearchableTerms(IBeatmapMetadataInfo metadataInfo, IList termsList) + { + addIfNotNull(metadataInfo.Author.Username); + addIfNotNull(metadataInfo.Artist); + addIfNotNull(metadataInfo.ArtistUnicode); + addIfNotNull(metadataInfo.Title); + addIfNotNull(metadataInfo.TitleUnicode); + addIfNotNull(metadataInfo.Source); + addIfNotNull(metadataInfo.Tags); + + void addIfNotNull(string s) + { + if (!string.IsNullOrEmpty(s)) + termsList.Add(s); + } + } /// /// A user-presentable display title representing this metadata. From 4858d3fd4282e0f2ea48f3a5f1138f341d00edc6 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Tue, 7 Mar 2023 02:00:40 +0900 Subject: [PATCH 2383/2991] Added ability to edit mod presets --- .../UserInterface/TestSceneModPresetColumn.cs | 171 +++++++++++++++++- osu.Game/Overlays/Mods/EditPresetPopover.cs | 140 ++++++++++++++ osu.Game/Overlays/Mods/ModPresetPanel.cs | 8 +- 3 files changed, 316 insertions(+), 3 deletions(-) create mode 100644 osu.Game/Overlays/Mods/EditPresetPopover.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs index 1090764788..f48c52ad40 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs @@ -243,7 +243,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddUntilStep("wait for context menu", () => this.ChildrenOfType().Any()); AddStep("click delete", () => { - var deleteItem = this.ChildrenOfType().Single(); + var deleteItem = this.ChildrenOfType().ElementAt(1); InputManager.MoveMouseTo(deleteItem); InputManager.Click(MouseButton.Left); }); @@ -261,6 +261,175 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("preset soft-deleted", () => Realm.Run(r => r.All().Count(preset => preset.DeletePending) == 1)); } + [Test] + public void TestEditPresentName() + { + ModPresetColumn modPresetColumn = null!; + string presetName = null!; + + AddStep("clear mods", () => SelectedMods.Value = Array.Empty()); + AddStep("create content", () => Child = modPresetColumn = new ModPresetColumn + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + + AddUntilStep("items loaded", () => modPresetColumn.IsLoaded && modPresetColumn.ItemsLoaded); + AddStep("right click first panel", () => + { + var panel = this.ChildrenOfType().First(); + presetName = panel.Preset.Value.Name; + InputManager.MoveMouseTo(panel); + InputManager.Click(MouseButton.Right); + }); + + AddUntilStep("wait for context menu", () => this.ChildrenOfType().Any()); + AddStep("click edit", () => + { + var editItem = this.ChildrenOfType().ElementAt(0); + InputManager.MoveMouseTo(editItem); + InputManager.Click(MouseButton.Left); + }); + + OsuPopover? popover = null; + AddUntilStep("wait for popover", () => (popover = this.ChildrenOfType().FirstOrDefault()) != null); + AddStep("clear preset name", () => popover.ChildrenOfType().First().Current.Value = ""); + AddStep("attempt preset edit", () => + { + InputManager.MoveMouseTo(popover.ChildrenOfType().Single()); + InputManager.Click(MouseButton.Left); + }); + + AddWaitStep("wait some", 3); + AddAssert("present is not changed", () => this.ChildrenOfType().First().Preset.Value.Name == presetName); + AddUntilStep("popover is unchanged", () => this.ChildrenOfType().FirstOrDefault() == popover); + AddStep("edit preset name", () => popover.ChildrenOfType().First().Current.Value = "something new"); + AddStep("attempt preset edit", () => + { + InputManager.MoveMouseTo(popover.ChildrenOfType().Single()); + InputManager.Click(MouseButton.Left); + }); + AddUntilStep("popover closed", () => !this.ChildrenOfType().Any()); + AddAssert("present is changed", () => this.ChildrenOfType().First().Preset.Value.Name != presetName); + } + + [Test] + public void TestEditPresetMod() + { + ModPresetColumn modPresetColumn = null!; + var mods = new Mod[] { new OsuModHidden(), new OsuModHardRock() }; + + AddStep("clear mods", () => SelectedMods.Value = Array.Empty()); + AddStep("create content", () => Child = modPresetColumn = new ModPresetColumn + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + + AddUntilStep("items loaded", () => modPresetColumn.IsLoaded && modPresetColumn.ItemsLoaded); + AddStep("select mods", () => SelectedMods.Value = mods); + AddStep("right click first panel", () => + { + var panel = this.ChildrenOfType().First(); + InputManager.MoveMouseTo(panel); + InputManager.Click(MouseButton.Right); + }); + + AddUntilStep("wait for context menu", () => this.ChildrenOfType().Any()); + AddStep("click edit", () => + { + var editItem = this.ChildrenOfType().ElementAt(0); + InputManager.MoveMouseTo(editItem); + InputManager.Click(MouseButton.Left); + }); + + OsuPopover? popover = null; + AddUntilStep("wait for popover", () => (popover = this.ChildrenOfType().FirstOrDefault()) != null); + AddStep("enable switch", () => popover.ChildrenOfType().Single().Current.Value = true); + AddStep("attempt preset edit", () => + { + InputManager.MoveMouseTo(popover.ChildrenOfType().Single()); + InputManager.Click(MouseButton.Left); + }); + AddUntilStep("popover closed", () => !this.ChildrenOfType().Any()); + AddAssert("present mod is changed", () => this.ChildrenOfType().First().Preset.Value.Mods.Count == 2); + } + + [Test] + public void TestEditModSwitchDisableWithNoModSelest() + { + ModPresetColumn modPresetColumn = null!; + + AddStep("clear mods", () => SelectedMods.Value = Array.Empty()); + AddStep("create content", () => Child = modPresetColumn = new ModPresetColumn + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + + AddUntilStep("items loaded", () => modPresetColumn.IsLoaded && modPresetColumn.ItemsLoaded); + AddStep("right click first panel", () => + { + var panel = this.ChildrenOfType().First(); + InputManager.MoveMouseTo(panel); + InputManager.Click(MouseButton.Right); + }); + + AddUntilStep("wait for context menu", () => this.ChildrenOfType().Any()); + AddStep("click edit", () => + { + var editItem = this.ChildrenOfType().ElementAt(0); + InputManager.MoveMouseTo(editItem); + InputManager.Click(MouseButton.Left); + }); + + OsuPopover? popover = null; + AddUntilStep("wait for popover", () => (popover = this.ChildrenOfType().FirstOrDefault()) != null); + AddAssert("use current mod is disblaed", () => popover.ChildrenOfType().Single().Current.Value == false); + AddAssert("use current mod switch cannot be switch", () => popover.ChildrenOfType().Single().Current.Disabled == true); + } + + [Test] + public void TestEditModSwitchDisableWithPresetSelest() + { + ModPresetColumn modPresetColumn = null!; + + AddStep("clear mods", () => SelectedMods.Value = Array.Empty()); + AddStep("create content", () => Child = modPresetColumn = new ModPresetColumn + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + + AddUntilStep("items loaded", () => modPresetColumn.IsLoaded && modPresetColumn.ItemsLoaded); + AddStep("select first preset mod", () => + SelectedMods.Value = this.ChildrenOfType().First().Preset.Value.Mods.ToList()); + + AddStep("right click first panel", () => + { + var panel = this.ChildrenOfType().First(); + InputManager.MoveMouseTo(panel); + InputManager.Click(MouseButton.Right); + }); + + AddUntilStep("wait for context menu", () => this.ChildrenOfType().Any()); + AddStep("click edit", () => + { + var editItem = this.ChildrenOfType().ElementAt(0); + InputManager.MoveMouseTo(editItem); + InputManager.Click(MouseButton.Left); + }); + + OsuPopover? popover = null; + AddUntilStep("wait for popover", () => (popover = this.ChildrenOfType().FirstOrDefault()) != null); + AddAssert("use current mod is enabled", () => popover.ChildrenOfType().Single().Current.Value == true); + AddAssert("use current mod switch cannot be switch", () => popover.ChildrenOfType().Single().Current.Disabled == true); + + AddStep("clear mods", () => SelectedMods.Value = Array.Empty()); + AddAssert("use current mod is disblaed", () => popover.ChildrenOfType().Single().Current.Value == false); + AddAssert("use current mod switch cannot be switch", () => popover.ChildrenOfType().Single().Current.Disabled == true); + } + private ICollection createTestPresets() => new[] { new ModPreset diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs new file mode 100644 index 0000000000..270b6f43d9 --- /dev/null +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -0,0 +1,140 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Extensions; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Localisation; +using osu.Game.Rulesets.Mods; +using osuTK; + +namespace osu.Game.Overlays.Mods +{ + internal partial class EditPresetPopover : OsuPopover + { + private readonly ModPresetPanel button; + + private readonly LabelledTextBox nameTextBox; + private readonly LabelledTextBox descriptionTextBox; + private readonly LabelledSwitchButton useCurrentSwitch; + private readonly ShearedButton createButton; + + [Resolved] + private Bindable> selectedMods { get; set; } = null!; + + private readonly ModPreset preset; + + public EditPresetPopover(ModPresetPanel modPresetPanel) + { + button = modPresetPanel; + preset = button.Preset.Value; + + Child = new FillFlowContainer + { + Width = 300, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(7), + Children = new Drawable[] + { + nameTextBox = new LabelledTextBox + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Label = CommonStrings.Name, + TabbableContentContainer = this + }, + descriptionTextBox = new LabelledTextBox + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Label = CommonStrings.Description, + TabbableContentContainer = this + }, + useCurrentSwitch = new LabelledSwitchButton + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Label = "Use Current Mod select", + }, + createButton = new ShearedButton + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = CommonStrings.MenuBarEdit, + Action = tryEditPreset + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider, OsuColour colours) + { + Body.BorderThickness = 3; + Body.BorderColour = colours.Orange1; + + nameTextBox.Current.Value = preset.Name; + descriptionTextBox.Current.Value = preset.Description; + + selectedMods.BindValueChanged(_ => updateMods(), true); + + createButton.DarkerColour = colours.Orange1; + createButton.LighterColour = colours.Orange0; + createButton.TextColour = colourProvider.Background6; + } + + private void updateMods() + { + useCurrentSwitch.Current.Disabled = false; + + // disable the switch when mod is equal. + if (button.Active.Value) + { + useCurrentSwitch.Current.Value = true; + useCurrentSwitch.Current.Disabled = true; + } + else + { + useCurrentSwitch.Current.Value = false; + useCurrentSwitch.Current.Disabled = !selectedMods.Value.Any(); + } + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + ScheduleAfterChildren(() => GetContainingInputManager().ChangeFocus(nameTextBox)); + } + + private void tryEditPreset() + { + if (string.IsNullOrWhiteSpace(nameTextBox.Current.Value)) + { + Body.Shake(); + return; + } + + button.Preset.PerformWrite(s => + { + s.Name = nameTextBox.Current.Value; + s.Description = descriptionTextBox.Current.Value; + + if (useCurrentSwitch.Current.Value) + { + s.Mods = selectedMods.Value.ToArray(); + } + }); + + this.HidePopover(); + } + } +} diff --git a/osu.Game/Overlays/Mods/ModPresetPanel.cs b/osu.Game/Overlays/Mods/ModPresetPanel.cs index 6e12e34124..f4f1af50df 100644 --- a/osu.Game/Overlays/Mods/ModPresetPanel.cs +++ b/osu.Game/Overlays/Mods/ModPresetPanel.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.UserInterface; using osu.Game.Configuration; @@ -17,7 +18,7 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Overlays.Mods { - public partial class ModPresetPanel : ModSelectPanel, IHasCustomTooltip, IHasContextMenu + public partial class ModPresetPanel : ModSelectPanel, IHasCustomTooltip, IHasContextMenu, IHasPopover { public readonly Live Preset; @@ -91,7 +92,8 @@ namespace osu.Game.Overlays.Mods public MenuItem[] ContextMenuItems => new MenuItem[] { - new OsuMenuItem(CommonStrings.ButtonsDelete, MenuItemType.Destructive, () => dialogOverlay?.Push(new DeleteModPresetDialog(Preset))) + new OsuMenuItem(CommonStrings.ButtonsEdit, MenuItemType.Highlighted, this.ShowPopover), + new OsuMenuItem(CommonStrings.ButtonsDelete, MenuItemType.Destructive, () => dialogOverlay?.Push(new DeleteModPresetDialog(Preset))), }; #endregion @@ -102,5 +104,7 @@ namespace osu.Game.Overlays.Mods settingChangeTracker?.Dispose(); } + + public Popover GetPopover() => new EditPresetPopover(this); } } From 0095fd85cad0a7b8dcddd29c983991af959a57fb Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Tue, 7 Mar 2023 02:18:34 +0900 Subject: [PATCH 2384/2991] remove `== true` --- .../Visual/UserInterface/TestSceneModPresetColumn.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs index f48c52ad40..8fbc8940c7 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs @@ -386,7 +386,7 @@ namespace osu.Game.Tests.Visual.UserInterface OsuPopover? popover = null; AddUntilStep("wait for popover", () => (popover = this.ChildrenOfType().FirstOrDefault()) != null); AddAssert("use current mod is disblaed", () => popover.ChildrenOfType().Single().Current.Value == false); - AddAssert("use current mod switch cannot be switch", () => popover.ChildrenOfType().Single().Current.Disabled == true); + AddAssert("use current mod switch cannot be switch", () => popover.ChildrenOfType().Single().Current.Disabled); } [Test] @@ -422,12 +422,12 @@ namespace osu.Game.Tests.Visual.UserInterface OsuPopover? popover = null; AddUntilStep("wait for popover", () => (popover = this.ChildrenOfType().FirstOrDefault()) != null); - AddAssert("use current mod is enabled", () => popover.ChildrenOfType().Single().Current.Value == true); - AddAssert("use current mod switch cannot be switch", () => popover.ChildrenOfType().Single().Current.Disabled == true); + AddAssert("use current mod is enabled", () => popover.ChildrenOfType().Single().Current.Value); + AddAssert("use current mod switch cannot be switch", () => popover.ChildrenOfType().Single().Current.Disabled); AddStep("clear mods", () => SelectedMods.Value = Array.Empty()); AddAssert("use current mod is disblaed", () => popover.ChildrenOfType().Single().Current.Value == false); - AddAssert("use current mod switch cannot be switch", () => popover.ChildrenOfType().Single().Current.Disabled == true); + AddAssert("use current mod switch cannot be switch", () => popover.ChildrenOfType().Single().Current.Disabled); } private ICollection createTestPresets() => new[] From 952814604ed43ab85b799198268cd222b7f9b9a9 Mon Sep 17 00:00:00 2001 From: tsrk Date: Mon, 6 Mar 2023 20:06:56 +0000 Subject: [PATCH 2385/2991] style: fix late night oopsies --- osu.Game.Tests/Skins/SkinDeserialisationTest.cs | 3 --- osu.Game/Screens/Play/HUD/PlayerAvatar.cs | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs index eb1df954aa..bd8088cfb6 100644 --- a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs +++ b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs @@ -9,7 +9,6 @@ using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; -using osu.Framework.Logging; using osu.Game.Audio; using osu.Game.IO; using osu.Game.IO.Archives; @@ -64,8 +63,6 @@ namespace osu.Game.Tests.Skins foreach (string oskFile in available_skins) { - Logger.Log($"Testing file {oskFile}..."); - using (var stream = TestResources.OpenResource(oskFile)) using (var storage = new ZipArchiveReader(stream)) { diff --git a/osu.Game/Screens/Play/HUD/PlayerAvatar.cs b/osu.Game/Screens/Play/HUD/PlayerAvatar.cs index 32ed045df7..d2f4f0be17 100644 --- a/osu.Game/Screens/Play/HUD/PlayerAvatar.cs +++ b/osu.Game/Screens/Play/HUD/PlayerAvatar.cs @@ -43,8 +43,7 @@ namespace osu.Game.Screens.Play.HUD base.LoadComplete(); avatar.User = gameplayState.Score.ScoreInfo.User; - avatar.CornerRadius = CornerRadius.Value; - CornerRadius.BindValueChanged(e => avatar.CornerRadius = e.NewValue); + CornerRadius.BindValueChanged(e => avatar.CornerRadius = e.NewValue, true); } public bool UsesFixedAnchor { get; set; } From fc0e27fb15e3eb1a143e5924a9adf3f472944a06 Mon Sep 17 00:00:00 2001 From: tsrk Date: Mon, 6 Mar 2023 20:11:52 +0000 Subject: [PATCH 2386/2991] style: use normalised `CornerRadius` values --- osu.Game/Screens/Play/HUD/PlayerAvatar.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/PlayerAvatar.cs b/osu.Game/Screens/Play/HUD/PlayerAvatar.cs index d2f4f0be17..f293199911 100644 --- a/osu.Game/Screens/Play/HUD/PlayerAvatar.cs +++ b/osu.Game/Screens/Play/HUD/PlayerAvatar.cs @@ -16,10 +16,10 @@ namespace osu.Game.Screens.Play.HUD public partial class PlayerAvatar : CompositeDrawable, ISerialisableDrawable { [SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.CornerRadius), nameof(SkinnableComponentStrings.CornerRadiusDescription))] - public new BindableFloat CornerRadius { get; set; } = new BindableFloat + public new BindableFloat CornerRadius { get; set; } = new BindableFloat(0.25f) { MinValue = 0, - MaxValue = 64, + MaxValue = 0.5f, Precision = 0.01f }; @@ -43,7 +43,7 @@ namespace osu.Game.Screens.Play.HUD base.LoadComplete(); avatar.User = gameplayState.Score.ScoreInfo.User; - CornerRadius.BindValueChanged(e => avatar.CornerRadius = e.NewValue, true); + CornerRadius.BindValueChanged(e => avatar.CornerRadius = e.NewValue * 128f, true); } public bool UsesFixedAnchor { get; set; } From 21bdbb20e6b362f96f53863614474dfae32f1726 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 7 Mar 2023 14:22:12 +0900 Subject: [PATCH 2387/2991] Add optional support for cyclic selection to `BlueprintContainer` --- .../SkinEditor/SkinBlueprintContainer.cs | 2 + .../Compose/Components/BlueprintContainer.cs | 72 +++++++++++++++---- 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/SkinEditor/SkinBlueprintContainer.cs b/osu.Game/Overlays/SkinEditor/SkinBlueprintContainer.cs index 3f8d9f80d4..db27e20010 100644 --- a/osu.Game/Overlays/SkinEditor/SkinBlueprintContainer.cs +++ b/osu.Game/Overlays/SkinEditor/SkinBlueprintContainer.cs @@ -25,6 +25,8 @@ namespace osu.Game.Overlays.SkinEditor [Resolved] private SkinEditor editor { get; set; } = null!; + protected override bool AllowCyclicSelection => true; + public SkinBlueprintContainer(ISerialisableDrawableContainer targetContainer) { this.targetContainer = targetContainer; diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index e4e67d10d7..87cee59d83 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -45,6 +45,15 @@ namespace osu.Game.Screens.Edit.Compose.Components protected readonly BindableList SelectedItems = new BindableList(); + /// + /// Whether to allow cyclic selection on clicking multiple times. + /// + /// + /// Disabled by default as it does not work well with editors that support double-clicking or other advanced interactions. + /// Can probably be made to work with more thought. + /// + protected virtual bool AllowCyclicSelection => false; + protected BlueprintContainer() { RelativeSizeAxes = Axes.Both; @@ -167,7 +176,7 @@ namespace osu.Game.Screens.Edit.Compose.Components Schedule(() => { endClickSelection(e); - clickSelectionBegan = false; + clickSelectionHandled = false; isDraggingBlueprint = false; }); @@ -339,7 +348,12 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// Whether a blueprint was selected by a previous click event. /// - private bool clickSelectionBegan; + private bool clickSelectionHandled; + + /// + /// Whether the selected blueprint(s) were already selected on mouse down. Generally used to perform selection cycling on mouse up in such a case. + /// + private bool selectedBlueprintAlreadySelectedOnMouseDown; /// /// Attempts to select any hovered blueprints. @@ -354,7 +368,8 @@ namespace osu.Game.Screens.Edit.Compose.Components { if (!blueprint.IsHovered) continue; - return clickSelectionBegan = SelectionHandler.MouseDownSelectionRequested(blueprint, e); + selectedBlueprintAlreadySelectedOnMouseDown = blueprint.State == SelectionState.Selected; + return clickSelectionHandled = SelectionHandler.MouseDownSelectionRequested(blueprint, e); } return false; @@ -367,18 +382,45 @@ namespace osu.Game.Screens.Edit.Compose.Components /// Whether a click selection was active. private bool endClickSelection(MouseButtonEvent e) { - if (!clickSelectionBegan && !isDraggingBlueprint) + if (!clickSelectionHandled && !isDraggingBlueprint) { - // if a selection didn't occur, we may want to trigger a deselection. - if (e.ControlPressed && e.Button == MouseButton.Left) + if (e.Button == MouseButton.Left) { - // Iterate from the top of the input stack (blueprints closest to the front of the screen first). - // Priority is given to already-selected blueprints. - foreach (SelectionBlueprint blueprint in SelectionBlueprints.AliveChildren.Reverse().OrderByDescending(b => b.IsSelected)) + if (e.ControlPressed) { - if (!blueprint.IsHovered) continue; + // if a selection didn't occur, we may want to trigger a deselection. - return clickSelectionBegan = SelectionHandler.MouseUpSelectionRequested(blueprint, e); + // Iterate from the top of the input stack (blueprints closest to the front of the screen first). + // Priority is given to already-selected blueprints. + foreach (SelectionBlueprint blueprint in SelectionBlueprints.AliveChildren.OrderByDescending(b => b.IsSelected)) + { + if (!blueprint.IsHovered) continue; + + return clickSelectionHandled = SelectionHandler.MouseUpSelectionRequested(blueprint, e); + } + } + else if (selectedBlueprintAlreadySelectedOnMouseDown && AllowCyclicSelection) + { + // If a click occurred and was handled by the currently selected blueprint but didn't result in a drag, + // cycle between other blueprints which are also under the cursor. + + // The depth of blueprints is constantly changing (see above where selected blueprints are brought to the front). + // For this logic, we want a stable sort order so we can correctly cycle, thus using the blueprintMap instead. + IEnumerable> cyclingSelectionBlueprints = blueprintMap.Values; + + // If there's already a selection, let's start from the blueprint after the selection. + cyclingSelectionBlueprints = cyclingSelectionBlueprints.SkipWhile(b => !b.IsSelected).Skip(1); + + // Add the blueprints from before the selection to the end of the enumerable to allow for cyclic selection. + cyclingSelectionBlueprints = cyclingSelectionBlueprints.Concat(blueprintMap.Values.TakeWhile(b => !b.IsSelected)); + + foreach (SelectionBlueprint blueprint in cyclingSelectionBlueprints) + { + if (!blueprint.IsHovered) continue; + + // We are performing a mouse up, but selection handlers perform selection on mouse down, so we need to call that instead. + return clickSelectionHandled = SelectionHandler.MouseDownSelectionRequested(blueprint, e); + } } } @@ -441,7 +483,11 @@ namespace osu.Game.Screens.Edit.Compose.Components private Vector2[][] movementBlueprintsOriginalPositions; private SelectionBlueprint[] movementBlueprints; - private bool isDraggingBlueprint; + + /// + /// Whether a blueprint is currently being dragged. + /// + private bool isDraggingBlueprint { get; set; } /// /// Attempts to begin the movement of any selected blueprints. @@ -454,7 +500,7 @@ namespace osu.Game.Screens.Edit.Compose.Components // Any selected blueprint that is hovered can begin the movement of the group, however only the first item (according to SortForMovement) is used for movement. // A special case is added for when a click selection occurred before the drag - if (!clickSelectionBegan && !SelectionHandler.SelectedBlueprints.Any(b => b.IsHovered)) + if (!clickSelectionHandled && !SelectionHandler.SelectedBlueprints.Any(b => b.IsHovered)) return false; // Movement is tracked from the blueprint of the earliest item, since it only makes sense to distance snap from that item From d2fcdf6e0e464ec389cff62ca715411402df6323 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 7 Mar 2023 14:22:19 +0900 Subject: [PATCH 2388/2991] Add test coverage of cyclic selection in skin editor --- .../Visual/Gameplay/TestSceneSkinEditor.cs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs index 9690d00d4c..7af2b7d6fe 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs @@ -17,6 +17,8 @@ using osu.Game.Rulesets.Osu; using osu.Game.Screens.Edit; using osu.Game.Screens.Play.HUD.HitErrorMeters; using osu.Game.Skinning; +using osu.Game.Skinning.Components; +using osuTK; using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay @@ -52,6 +54,44 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for loaded", () => skinEditor.IsLoaded); } + [Test] + public void TestCyclicSelection() + { + SkinBlueprint[] blueprints = null!; + + AddStep("Add big black boxes", () => + { + InputManager.MoveMouseTo(skinEditor.ChildrenOfType().First()); + InputManager.Click(MouseButton.Left); + InputManager.Click(MouseButton.Left); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("Three black boxes added", () => targetContainer.Components.OfType().Count(), () => Is.EqualTo(3)); + + AddStep("Store black box blueprints", () => + { + blueprints = skinEditor.ChildrenOfType().Where(b => b.Item is BigBlackBox).ToArray(); + }); + + AddAssert("Selection is black box 1", () => skinEditor.SelectedComponents.Single(), () => Is.EqualTo(blueprints[0].Item)); + + AddStep("move cursor to black box", () => + { + // Slightly offset from centre to avoid random failures (see https://github.com/ppy/osu-framework/issues/5669). + InputManager.MoveMouseTo(((Drawable)blueprints[0].Item).ScreenSpaceDrawQuad.Centre + new Vector2(1)); + }); + + AddStep("click on black box stack", () => InputManager.Click(MouseButton.Left)); + AddAssert("Selection is black box 2", () => skinEditor.SelectedComponents.Single(), () => Is.EqualTo(blueprints[1].Item)); + + AddStep("click on black box stack", () => InputManager.Click(MouseButton.Left)); + AddAssert("Selection is black box 3", () => skinEditor.SelectedComponents.Single(), () => Is.EqualTo(blueprints[2].Item)); + + AddStep("click on black box stack", () => InputManager.Click(MouseButton.Left)); + AddAssert("Selection is black box 1", () => skinEditor.SelectedComponents.Single(), () => Is.EqualTo(blueprints[0].Item)); + } + [TestCase(false)] [TestCase(true)] public void TestBringToFront(bool alterSelectionOrder) From 2cce785fa5bb7fd1ab6b77d1a757a76a6fc3f94b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 7 Mar 2023 15:54:33 +0900 Subject: [PATCH 2389/2991] Fix storyboard videos not fading out on completion Closes https://github.com/ppy/osu/issues/22802. Stable uses a 1,000 ms fade-in / out. Rather than matching that, I've stuck with 500ms (what lazer was already using for the fade-in) because I think it feels better. Tested using the beatmap linked in the issue thread. --- osu.Game/Storyboards/Drawables/DrawableStoryboardVideo.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardVideo.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardVideo.cs index f4b0692619..eec2cd6a60 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardVideo.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardVideo.cs @@ -58,7 +58,11 @@ namespace osu.Game.Storyboards.Drawables using (drawableVideo.BeginAbsoluteSequence(Video.StartTime)) { Schedule(() => drawableVideo.PlaybackPosition = Time.Current - Video.StartTime); + drawableVideo.FadeIn(500); + + using (drawableVideo.BeginDelayedSequence(drawableVideo.Duration - 500)) + drawableVideo.FadeOut(500); } } } From 15d65059b5403824059b753fd9359280a475afb2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 7 Mar 2023 16:21:57 +0900 Subject: [PATCH 2390/2991] Tidy up `Add` method logic --- .../Visual/Gameplay/TestSceneKeyCounter.cs | 16 ++++++------ osu.Game/Screens/Play/KeyCounterDisplay.cs | 26 ++++++------------- 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs index 12cd7e1be9..d0c691e23f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs @@ -3,7 +3,6 @@ #nullable disable -using System.Linq; using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Utils; @@ -21,15 +20,16 @@ namespace osu.Game.Tests.Visual.Gameplay { Origin = Anchor.Centre, Anchor = Anchor.Centre, - Triggers = new InputTrigger[] - { - new KeyCounterKeyboardTrigger(Key.X), - new KeyCounterKeyboardTrigger(Key.X), - new KeyCounterMouseTrigger(MouseButton.Left), - new KeyCounterMouseTrigger(MouseButton.Right), - } }; + kc.AddTriggerRange(new InputTrigger[] + { + new KeyCounterKeyboardTrigger(Key.X), + new KeyCounterKeyboardTrigger(Key.X), + new KeyCounterMouseTrigger(MouseButton.Left), + new KeyCounterMouseTrigger(MouseButton.Right), + }); + var testCounter = (DefaultKeyCounter)kc.Children.First(); AddStep("Add random", () => diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs index 01686ae6de..50670fb2fe 100644 --- a/osu.Game/Screens/Play/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs @@ -25,16 +25,6 @@ namespace osu.Game.Screens.Play public Bindable IsCounting { get; } = new BindableBool(true); - public IReadOnlyList Triggers - { - get => Children.Select(c => c.Trigger).ToArray(); - set - { - Clear(); - value.ForEach(AddTrigger); - } - } - protected readonly Bindable ConfigVisibility = new Bindable(); protected abstract void UpdateVisibility(); @@ -60,17 +50,17 @@ namespace osu.Game.Screens.Play public void AddTriggerRange(IEnumerable triggers) => triggers.ForEach(AddTrigger); - private bool checkType(KeyCounter key) => acceptedTypes.Length == 0 || acceptedTypes.Any(t => t.IsInstanceOfType(key)); - - public override void Add(KeyCounter key) + public override void Add(KeyCounter counter) { - if (!checkType(key)) - throw new InvalidOperationException($"{key.GetType()} is not a supported counter type. (hint: you may want to use {nameof(AddTrigger)} instead.)"); + if (!checkType(counter)) + throw new InvalidOperationException($"{counter.GetType()} is not a supported counter type. (hint: you may want to use {nameof(AddTrigger)} instead.)"); - base.Add(key); - key.IsCounting.BindTo(IsCounting); + base.Add(counter); + counter.IsCounting.BindTo(IsCounting); } + private bool checkType(KeyCounter counter) => acceptedTypes.Length == 0 || acceptedTypes.Any(t => t.IsInstanceOfType(counter)); + [BackgroundDependencyLoader] private void load(OsuConfigManager config) { @@ -110,7 +100,7 @@ namespace osu.Game.Screens.Play case KeyUpEvent: case MouseDownEvent: case MouseUpEvent: - return Target.Children.Any(c => c.TriggerEvent(e)); + return Target.InternalChildren.Any(c => c.TriggerEvent(e)); } return base.Handle(e); From 28520414aa5d857724b093b6e6b1999d80c6a21b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 7 Mar 2023 16:28:54 +0900 Subject: [PATCH 2391/2991] Move `KeyCounter` components to `HUD` namespace --- osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs | 1 + osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs | 3 ++- .../Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs | 1 + .../Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs | 1 + .../Navigation/TestSceneChangeAndUseGameplayBindings.cs | 1 + osu.Game/Rulesets/UI/DrawableRuleset.cs | 1 + osu.Game/Rulesets/UI/RulesetInputManager.cs | 2 +- osu.Game/Screens/Play/{ => HUD}/DefaultKeyCounter.cs | 2 +- osu.Game/Screens/Play/{ => HUD}/DefaultKeyCounterDisplay.cs | 2 +- osu.Game/Screens/Play/{ => HUD}/InputTrigger.cs | 2 +- osu.Game/Screens/Play/{ => HUD}/KeyCounter.cs | 2 +- osu.Game/Screens/Play/{ => HUD}/KeyCounterActionTrigger.cs | 2 +- osu.Game/Screens/Play/{ => HUD}/KeyCounterDisplay.cs | 2 +- osu.Game/Screens/Play/{ => HUD}/KeyCounterKeyboardTrigger.cs | 2 +- osu.Game/Screens/Play/{ => HUD}/KeyCounterMouseTrigger.cs | 4 ++-- 15 files changed, 17 insertions(+), 11 deletions(-) rename osu.Game/Screens/Play/{ => HUD}/DefaultKeyCounter.cs (99%) rename osu.Game/Screens/Play/{ => HUD}/DefaultKeyCounterDisplay.cs (98%) rename osu.Game/Screens/Play/{ => HUD}/InputTrigger.cs (94%) rename osu.Game/Screens/Play/{ => HUD}/KeyCounter.cs (98%) rename osu.Game/Screens/Play/{ => HUD}/KeyCounterActionTrigger.cs (96%) rename osu.Game/Screens/Play/{ => HUD}/KeyCounterDisplay.cs (99%) rename osu.Game/Screens/Play/{ => HUD}/KeyCounterKeyboardTrigger.cs (95%) rename osu.Game/Screens/Play/{ => HUD}/KeyCounterMouseTrigger.cs (97%) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs index ec8fad9bf3..4e13bde755 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs @@ -22,6 +22,7 @@ using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.UI.Cursor; using osu.Game.Screens.Play; +using osu.Game.Screens.Play.HUD; using osu.Game.Tests.Visual; using osuTK; using osuTK.Graphics; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs index d0c691e23f..3260ba8e33 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs @@ -3,10 +3,11 @@ #nullable disable +using System.Linq; using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Utils; -using osu.Game.Screens.Play; +using osu.Game.Screens.Play.HUD; using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs index 01d3bfa23e..aa7119829a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs @@ -14,6 +14,7 @@ using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Edit; using osu.Game.Screens.Play; +using osu.Game.Screens.Play.HUD; using osu.Game.Tests.Gameplay; using osuTK.Input; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs index 9848894f84..808241729b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs @@ -18,6 +18,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play; +using osu.Game.Screens.Play.HUD; using osu.Game.Tests.Gameplay; using osuTK.Input; diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs b/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs index 59a0f9cea8..224e7e411e 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs @@ -14,6 +14,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Input.Bindings; using osu.Game.Overlays.Settings.Sections.Input; using osu.Game.Screens.Play; +using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Select; using osu.Game.Tests.Beatmaps.IO; using osuTK.Input; diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 64fe9c8a86..4f22c0c617 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -30,6 +30,7 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; using osu.Game.Screens.Play; +using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.HUD.ClicksPerSecond; using osuTK; diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index 32b2a19e21..c2f0b1a951 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -19,7 +19,7 @@ using osu.Game.Input; using osu.Game.Input.Bindings; using osu.Game.Input.Handlers; using osu.Game.Rulesets.Scoring; -using osu.Game.Screens.Play; +using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.HUD.ClicksPerSecond; using static osu.Game.Input.Handlers.ReplayInputHandler; diff --git a/osu.Game/Screens/Play/DefaultKeyCounter.cs b/osu.Game/Screens/Play/HUD/DefaultKeyCounter.cs similarity index 99% rename from osu.Game/Screens/Play/DefaultKeyCounter.cs rename to osu.Game/Screens/Play/HUD/DefaultKeyCounter.cs index 3673281577..69a3e53dfc 100644 --- a/osu.Game/Screens/Play/DefaultKeyCounter.cs +++ b/osu.Game/Screens/Play/HUD/DefaultKeyCounter.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics.Sprites; using osuTK; using osuTK.Graphics; -namespace osu.Game.Screens.Play +namespace osu.Game.Screens.Play.HUD { public partial class DefaultKeyCounter : KeyCounter { diff --git a/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs similarity index 98% rename from osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs rename to osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs index 10f5a3cfe0..1d79b2d27a 100644 --- a/osu.Game/Screens/Play/DefaultKeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs @@ -6,7 +6,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osuTK.Graphics; -namespace osu.Game.Screens.Play +namespace osu.Game.Screens.Play.HUD { public partial class DefaultKeyCounterDisplay : KeyCounterDisplay { diff --git a/osu.Game/Screens/Play/InputTrigger.cs b/osu.Game/Screens/Play/HUD/InputTrigger.cs similarity index 94% rename from osu.Game/Screens/Play/InputTrigger.cs rename to osu.Game/Screens/Play/HUD/InputTrigger.cs index b8951b0f8e..34d286d697 100644 --- a/osu.Game/Screens/Play/InputTrigger.cs +++ b/osu.Game/Screens/Play/HUD/InputTrigger.cs @@ -4,7 +4,7 @@ using System; using osu.Framework.Graphics; -namespace osu.Game.Screens.Play +namespace osu.Game.Screens.Play.HUD { public abstract partial class InputTrigger : Component { diff --git a/osu.Game/Screens/Play/KeyCounter.cs b/osu.Game/Screens/Play/HUD/KeyCounter.cs similarity index 98% rename from osu.Game/Screens/Play/KeyCounter.cs rename to osu.Game/Screens/Play/HUD/KeyCounter.cs index 7ee9c94f62..4b3da4f785 100644 --- a/osu.Game/Screens/Play/KeyCounter.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounter.cs @@ -5,7 +5,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -namespace osu.Game.Screens.Play +namespace osu.Game.Screens.Play.HUD { public abstract partial class KeyCounter : Container { diff --git a/osu.Game/Screens/Play/KeyCounterActionTrigger.cs b/osu.Game/Screens/Play/HUD/KeyCounterActionTrigger.cs similarity index 96% rename from osu.Game/Screens/Play/KeyCounterActionTrigger.cs rename to osu.Game/Screens/Play/HUD/KeyCounterActionTrigger.cs index be0d259f85..1af69fdd81 100644 --- a/osu.Game/Screens/Play/KeyCounterActionTrigger.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounterActionTrigger.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; -namespace osu.Game.Screens.Play +namespace osu.Game.Screens.Play.HUD { public partial class KeyCounterActionTrigger : InputTrigger where T : struct diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs similarity index 99% rename from osu.Game/Screens/Play/KeyCounterDisplay.cs rename to osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs index 50670fb2fe..0dbae50466 100644 --- a/osu.Game/Screens/Play/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs @@ -13,7 +13,7 @@ using osu.Framework.Input.Events; using osu.Game.Configuration; using osuTK; -namespace osu.Game.Screens.Play +namespace osu.Game.Screens.Play.HUD { public abstract partial class KeyCounterDisplay : Container { diff --git a/osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs b/osu.Game/Screens/Play/HUD/KeyCounterKeyboardTrigger.cs similarity index 95% rename from osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs rename to osu.Game/Screens/Play/HUD/KeyCounterKeyboardTrigger.cs index 1d89c58fc3..742cbc1569 100644 --- a/osu.Game/Screens/Play/KeyCounterKeyboardTrigger.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounterKeyboardTrigger.cs @@ -6,7 +6,7 @@ using osu.Framework.Input.Events; using osuTK.Input; -namespace osu.Game.Screens.Play +namespace osu.Game.Screens.Play.HUD { public partial class KeyCounterKeyboardTrigger : InputTrigger { diff --git a/osu.Game/Screens/Play/KeyCounterMouseTrigger.cs b/osu.Game/Screens/Play/HUD/KeyCounterMouseTrigger.cs similarity index 97% rename from osu.Game/Screens/Play/KeyCounterMouseTrigger.cs rename to osu.Game/Screens/Play/HUD/KeyCounterMouseTrigger.cs index e710c6e33f..cd71fef705 100644 --- a/osu.Game/Screens/Play/KeyCounterMouseTrigger.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounterMouseTrigger.cs @@ -4,10 +4,10 @@ #nullable disable using osu.Framework.Input.Events; -using osuTK.Input; using osuTK; +using osuTK.Input; -namespace osu.Game.Screens.Play +namespace osu.Game.Screens.Play.HUD { public partial class KeyCounterMouseTrigger : InputTrigger { From 97ba236eb146fe69eb318aff6dce1db3ba8bf78d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 7 Mar 2023 16:31:36 +0900 Subject: [PATCH 2392/2991] Add basic xmldoc to `KeyCounter` classes --- osu.Game/Screens/Play/HUD/InputTrigger.cs | 3 +++ osu.Game/Screens/Play/HUD/KeyCounter.cs | 3 +++ osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs | 3 +++ 3 files changed, 9 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/InputTrigger.cs b/osu.Game/Screens/Play/HUD/InputTrigger.cs index 34d286d697..93b45daab3 100644 --- a/osu.Game/Screens/Play/HUD/InputTrigger.cs +++ b/osu.Game/Screens/Play/HUD/InputTrigger.cs @@ -6,6 +6,9 @@ using osu.Framework.Graphics; namespace osu.Game.Screens.Play.HUD { + /// + /// An event trigger which can be used with to create visual tracking of button/key presses. + /// public abstract partial class InputTrigger : Component { public event Action? OnActivate; diff --git a/osu.Game/Screens/Play/HUD/KeyCounter.cs b/osu.Game/Screens/Play/HUD/KeyCounter.cs index 4b3da4f785..93cc4f908a 100644 --- a/osu.Game/Screens/Play/HUD/KeyCounter.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounter.cs @@ -7,6 +7,9 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Screens.Play.HUD { + /// + /// An individual key display which is intended to be displayed within a . + /// public abstract partial class KeyCounter : Container { public readonly InputTrigger Trigger; diff --git a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs index 0dbae50466..4080e561cd 100644 --- a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs @@ -15,6 +15,9 @@ using osuTK; namespace osu.Game.Screens.Play.HUD { + /// + /// A flowing display of all gameplay keys. Individual keys can be added using implementations. + /// public abstract partial class KeyCounterDisplay : Container { /// From 6a7c4d0bf7ffef86abc7eef6f34a09d26238ffc3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 7 Mar 2023 16:32:38 +0900 Subject: [PATCH 2393/2991] Remove `NRT` disables in new classes --- osu.Game/Screens/Play/HUD/KeyCounterActionTrigger.cs | 2 -- osu.Game/Screens/Play/HUD/KeyCounterKeyboardTrigger.cs | 2 -- osu.Game/Screens/Play/HUD/KeyCounterMouseTrigger.cs | 2 -- 3 files changed, 6 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/KeyCounterActionTrigger.cs b/osu.Game/Screens/Play/HUD/KeyCounterActionTrigger.cs index 1af69fdd81..e5951a8bf4 100644 --- a/osu.Game/Screens/Play/HUD/KeyCounterActionTrigger.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounterActionTrigger.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; namespace osu.Game.Screens.Play.HUD diff --git a/osu.Game/Screens/Play/HUD/KeyCounterKeyboardTrigger.cs b/osu.Game/Screens/Play/HUD/KeyCounterKeyboardTrigger.cs index 742cbc1569..3052c1e666 100644 --- a/osu.Game/Screens/Play/HUD/KeyCounterKeyboardTrigger.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounterKeyboardTrigger.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Input.Events; using osuTK.Input; diff --git a/osu.Game/Screens/Play/HUD/KeyCounterMouseTrigger.cs b/osu.Game/Screens/Play/HUD/KeyCounterMouseTrigger.cs index cd71fef705..369aaa9f74 100644 --- a/osu.Game/Screens/Play/HUD/KeyCounterMouseTrigger.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounterMouseTrigger.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Input.Events; using osuTK; using osuTK.Input; From f7f1dff6471784c79a14c27e79f168597ca30a0c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 7 Mar 2023 16:45:33 +0900 Subject: [PATCH 2394/2991] Fix incorrect case of localisable string for "corner radius" --- .../Localisation/SkinComponents/SkinnableComponentStrings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Localisation/SkinComponents/SkinnableComponentStrings.cs b/osu.Game/Localisation/SkinComponents/SkinnableComponentStrings.cs index 5cec9442e4..7c11ea6ac6 100644 --- a/osu.Game/Localisation/SkinComponents/SkinnableComponentStrings.cs +++ b/osu.Game/Localisation/SkinComponents/SkinnableComponentStrings.cs @@ -40,9 +40,9 @@ namespace osu.Game.Localisation.SkinComponents public static LocalisableString TextElementTextDescription => new TranslatableString(getKey(@"text_element_text_description"), "The text to be displayed."); /// - /// "Corner Radius" + /// "Corner radius" /// - public static LocalisableString CornerRadius => new TranslatableString(getKey(@"corner_radius"), "Corner Radius"); + public static LocalisableString CornerRadius => new TranslatableString(getKey(@"corner_radius"), "Corner radius"); /// /// "How rounded the corners should be." From d98199961b2d0820a3e4ff12816ac1c8e2190004 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 7 Mar 2023 17:00:10 +0900 Subject: [PATCH 2395/2991] Adjust default sizing to fit a bit better with existing elements --- osu.Game/Screens/Play/HUD/PlayerAvatar.cs | 7 +++++-- osu.Game/Screens/Play/HUD/PlayerFlag.cs | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/PlayerAvatar.cs b/osu.Game/Screens/Play/HUD/PlayerAvatar.cs index f293199911..1c558aaa8a 100644 --- a/osu.Game/Screens/Play/HUD/PlayerAvatar.cs +++ b/osu.Game/Screens/Play/HUD/PlayerAvatar.cs @@ -28,9 +28,12 @@ namespace osu.Game.Screens.Play.HUD private readonly UpdateableAvatar avatar; + private const float default_size = 80f; + public PlayerAvatar() { - Size = new Vector2(128f); + Size = new Vector2(default_size); + InternalChild = avatar = new UpdateableAvatar(isInteractive: false) { RelativeSizeAxes = Axes.Both, @@ -43,7 +46,7 @@ namespace osu.Game.Screens.Play.HUD base.LoadComplete(); avatar.User = gameplayState.Score.ScoreInfo.User; - CornerRadius.BindValueChanged(e => avatar.CornerRadius = e.NewValue * 128f, true); + CornerRadius.BindValueChanged(e => avatar.CornerRadius = e.NewValue * default_size, true); } public bool UsesFixedAnchor { get; set; } diff --git a/osu.Game/Screens/Play/HUD/PlayerFlag.cs b/osu.Game/Screens/Play/HUD/PlayerFlag.cs index 17188d0009..bf65ee23d8 100644 --- a/osu.Game/Screens/Play/HUD/PlayerFlag.cs +++ b/osu.Game/Screens/Play/HUD/PlayerFlag.cs @@ -17,9 +17,11 @@ namespace osu.Game.Screens.Play.HUD private readonly UpdateableFlag flag; + private const float default_size = 40f; + public PlayerFlag() { - Size = new Vector2(114, 80); + Size = new Vector2(default_size, default_size / 1.4f); InternalChild = flag = new UpdateableFlag { RelativeSizeAxes = Axes.Both, From 5e90b67be09b842a9fb4b7114f49e4463afdce52 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 7 Mar 2023 17:01:29 +0900 Subject: [PATCH 2396/2991] Move `GameplayState` usage to BDL --- osu.Game/Screens/Play/HUD/PlayerFlag.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/PlayerFlag.cs b/osu.Game/Screens/Play/HUD/PlayerFlag.cs index bf65ee23d8..85799c03d3 100644 --- a/osu.Game/Screens/Play/HUD/PlayerFlag.cs +++ b/osu.Game/Screens/Play/HUD/PlayerFlag.cs @@ -12,9 +12,6 @@ namespace osu.Game.Screens.Play.HUD { public partial class PlayerFlag : CompositeDrawable, ISerialisableDrawable { - [Resolved] - private GameplayState gameplayState { get; set; } = null!; - private readonly UpdateableFlag flag; private const float default_size = 40f; @@ -28,10 +25,9 @@ namespace osu.Game.Screens.Play.HUD }; } - protected override void LoadComplete() + [BackgroundDependencyLoader] + private void load(GameplayState gameplayState) { - base.LoadComplete(); - flag.CountryCode = gameplayState.Score.ScoreInfo.User.CountryCode; } From 5af41bb1c81054205c4cb77ccc9b0faf4686288d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 7 Mar 2023 17:24:17 +0900 Subject: [PATCH 2397/2991] Move filter matching code into own method to simplify early returns --- .../Select/Carousel/CarouselBeatmap.cs | 28 +++++++------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs index 2cfa163b7a..7e48bc5cdd 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs @@ -26,6 +26,11 @@ namespace osu.Game.Screens.Select.Carousel { base.Filter(criteria); + Filtered.Value = !checkMatch(criteria); + } + + private bool checkMatch(FilterCriteria criteria) + { bool match = criteria.Ruleset == null || BeatmapInfo.Ruleset.ShortName == criteria.Ruleset.ShortName || @@ -34,8 +39,7 @@ namespace osu.Game.Screens.Select.Carousel if (BeatmapInfo.BeatmapSet?.Equals(criteria.SelectedBeatmapSet) == true) { // only check ruleset equality or convertability for selected beatmap - Filtered.Value = !match; - return; + return match; } match &= !criteria.StarDifficulty.HasFilter || criteria.StarDifficulty.IsInRange(BeatmapInfo.StarRating); @@ -49,11 +53,7 @@ namespace osu.Game.Screens.Select.Carousel match &= !criteria.BeatDivisor.HasFilter || criteria.BeatDivisor.IsInRange(BeatmapInfo.BeatDivisor); match &= !criteria.OnlineStatus.HasFilter || criteria.OnlineStatus.IsInRange(BeatmapInfo.Status); - if (!match) - { - Filtered.Value = !match; - return; - } + if (!match) return false; match &= !criteria.Creator.HasFilter || criteria.Creator.Matches(BeatmapInfo.Metadata.Author.Username); match &= !criteria.Artist.HasFilter || criteria.Artist.Matches(BeatmapInfo.Metadata.Artist) || @@ -61,11 +61,7 @@ namespace osu.Game.Screens.Select.Carousel match &= !criteria.UserStarDifficulty.HasFilter || criteria.UserStarDifficulty.IsInRange(BeatmapInfo.StarRating); - if (!match) - { - Filtered.Value = !match; - return; - } + if (!match) return false; if (criteria.SearchTerms.Length > 0) { @@ -99,18 +95,14 @@ namespace osu.Game.Screens.Select.Carousel } } - if (!match) - { - Filtered.Value = !match; - return; - } + if (!match) return false; match &= criteria.CollectionBeatmapMD5Hashes?.Contains(BeatmapInfo.MD5Hash) ?? true; if (match && criteria.RulesetCriteria != null) match &= criteria.RulesetCriteria.Matches(BeatmapInfo); - Filtered.Value = !match; + return match; } public override int CompareTo(FilterCriteria criteria, CarouselItem other) From dc2945f4f8635a08c83c84fd57f65c6da4eb8e47 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 7 Mar 2023 17:39:21 +0900 Subject: [PATCH 2398/2991] Move avatar user loading to BDL also --- osu.Game/Screens/Play/HUD/PlayerAvatar.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/PlayerAvatar.cs b/osu.Game/Screens/Play/HUD/PlayerAvatar.cs index 1c558aaa8a..e3fab499f3 100644 --- a/osu.Game/Screens/Play/HUD/PlayerAvatar.cs +++ b/osu.Game/Screens/Play/HUD/PlayerAvatar.cs @@ -23,9 +23,6 @@ namespace osu.Game.Screens.Play.HUD Precision = 0.01f }; - [Resolved] - private GameplayState gameplayState { get; set; } = null!; - private readonly UpdateableAvatar avatar; private const float default_size = 80f; @@ -41,11 +38,16 @@ namespace osu.Game.Screens.Play.HUD }; } + [BackgroundDependencyLoader] + private void load(GameplayState gameplayState) + { + avatar.User = gameplayState.Score.ScoreInfo.User; + } + protected override void LoadComplete() { base.LoadComplete(); - avatar.User = gameplayState.Score.ScoreInfo.User; CornerRadius.BindValueChanged(e => avatar.CornerRadius = e.NewValue * default_size, true); } From 55467fcbe35cc6c8c7a94740c372b665eaa77519 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 7 Mar 2023 18:00:37 +0900 Subject: [PATCH 2399/2991] Update xmldoc for `DangerousActionDialog` to match new behaviour --- osu.Game/Overlays/Dialog/DangerousActionDialog.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Dialog/DangerousActionDialog.cs b/osu.Game/Overlays/Dialog/DangerousActionDialog.cs index 85cae5e0d2..c86570386f 100644 --- a/osu.Game/Overlays/Dialog/DangerousActionDialog.cs +++ b/osu.Game/Overlays/Dialog/DangerousActionDialog.cs @@ -8,10 +8,14 @@ using osu.Game.Localisation; namespace osu.Game.Overlays.Dialog { /// - /// Base class for various confirmation dialogs that concern deletion actions. + /// A dialog which provides confirmation for actions which result in permanent consequences. /// Differs from in that the confirmation button is a "dangerous" one /// (requires the confirm button to be held). /// + /// + /// The default implementation comes with text for a generic deletion operation. + /// This can be further customised by specifying custom . + /// public abstract partial class DangerousActionDialog : PopupDialog { /// From 26ef7c2637ddde346c65ff6bd853a48c03d5863e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 7 Mar 2023 18:01:13 +0900 Subject: [PATCH 2400/2991] Rename confirmation dialog class to mention `revert` not `reset` --- osu.Game/Overlays/SkinEditor/SkinEditor.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/SkinEditor/SkinEditor.cs b/osu.Game/Overlays/SkinEditor/SkinEditor.cs index a7fe459aa4..c6d190502b 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditor.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditor.cs @@ -153,7 +153,7 @@ namespace osu.Game.Overlays.SkinEditor Items = new[] { new EditorMenuItem(Web.CommonStrings.ButtonsSave, MenuItemType.Standard, () => Save()), - new EditorMenuItem(CommonStrings.RevertToDefault, MenuItemType.Destructive, () => dialogOverlay?.Push(new ResetConfirmDialog(revert))), + new EditorMenuItem(CommonStrings.RevertToDefault, MenuItemType.Destructive, () => dialogOverlay?.Push(new RevertConfirmDialog(revert))), new EditorMenuItemSpacer(), new EditorMenuItem(CommonStrings.Exit, MenuItemType.Standard, () => skinEditorOverlay?.Hide()), }, @@ -630,9 +630,9 @@ namespace osu.Game.Overlays.SkinEditor } } - public partial class ResetConfirmDialog : DangerousActionDialog + public partial class RevertConfirmDialog : DangerousActionDialog { - public ResetConfirmDialog(Action revert) + public RevertConfirmDialog(Action revert) { HeaderText = SkinEditorStrings.RevertToDefaultDescription; BodyText = SkinEditorStrings.ResetDialogue; From 97bee4db89048419265aeb9a1a6c9ffa478cc68a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 7 Mar 2023 18:07:53 +0900 Subject: [PATCH 2401/2991] Fix localisations --- osu.Game/Localisation/SkinEditorStrings.cs | 9 ++------- osu.Game/Overlays/SkinEditor/SkinEditor.cs | 4 ++-- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/osu.Game/Localisation/SkinEditorStrings.cs b/osu.Game/Localisation/SkinEditorStrings.cs index a6b59418fd..3c1d1ff40d 100644 --- a/osu.Game/Localisation/SkinEditorStrings.cs +++ b/osu.Game/Localisation/SkinEditorStrings.cs @@ -45,14 +45,9 @@ namespace osu.Game.Localisation public static LocalisableString CurrentlyEditing => new TranslatableString(getKey(@"currently_editing"), @"Currently editing"); /// - /// "Revert to default." + /// "All layout elements for layers in the current screen will be reset to defaults." /// - public static LocalisableString RevertToDefaultDescription => new TranslatableString(getKey(@"revert_to_default"), @"Revert to default."); - - /// - /// "Return the skin to its default state" - /// - public static LocalisableString ResetDialogue => new TranslatableString(getKey(@"return_the_skin_to_its"), @"Return the skin to its default state"); + public static LocalisableString RevertToDefaultDescription => new TranslatableString(getKey(@"revert_to_default_description"), @"All layout elements for layers in the current screen will be reset to defaults."); private static string getKey(string key) => $@"{prefix}:{key}"; } diff --git a/osu.Game/Overlays/SkinEditor/SkinEditor.cs b/osu.Game/Overlays/SkinEditor/SkinEditor.cs index c6d190502b..ac40d1335e 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditor.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditor.cs @@ -634,8 +634,8 @@ namespace osu.Game.Overlays.SkinEditor { public RevertConfirmDialog(Action revert) { - HeaderText = SkinEditorStrings.RevertToDefaultDescription; - BodyText = SkinEditorStrings.ResetDialogue; + HeaderText = CommonStrings.RevertToDefault; + BodyText = SkinEditorStrings.RevertToDefaultDescription; DangerousAction = revert; } } From 54564e05578df03133636cad564becd6b892378f Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Tue, 7 Mar 2023 21:13:35 +0900 Subject: [PATCH 2402/2991] new design --- .../UserInterface/TestSceneModPresetColumn.cs | 86 ++----------------- osu.Game/Overlays/Mods/EditPresetPopover.cs | 62 ++++++------- 2 files changed, 38 insertions(+), 110 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs index 8fbc8940c7..d6065374ac 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs @@ -296,7 +296,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("clear preset name", () => popover.ChildrenOfType().First().Current.Value = ""); AddStep("attempt preset edit", () => { - InputManager.MoveMouseTo(popover.ChildrenOfType().Single()); + InputManager.MoveMouseTo(popover.ChildrenOfType().ElementAt(1)); InputManager.Click(MouseButton.Left); }); @@ -306,7 +306,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("edit preset name", () => popover.ChildrenOfType().First().Current.Value = "something new"); AddStep("attempt preset edit", () => { - InputManager.MoveMouseTo(popover.ChildrenOfType().Single()); + InputManager.MoveMouseTo(popover.ChildrenOfType().ElementAt(1)); InputManager.Click(MouseButton.Left); }); AddUntilStep("popover closed", () => !this.ChildrenOfType().Any()); @@ -345,91 +345,15 @@ namespace osu.Game.Tests.Visual.UserInterface OsuPopover? popover = null; AddUntilStep("wait for popover", () => (popover = this.ChildrenOfType().FirstOrDefault()) != null); - AddStep("enable switch", () => popover.ChildrenOfType().Single().Current.Value = true); - AddStep("attempt preset edit", () => + AddStep("click use current mods", () => { - InputManager.MoveMouseTo(popover.ChildrenOfType().Single()); + InputManager.MoveMouseTo(popover.ChildrenOfType().ElementAt(0)); InputManager.Click(MouseButton.Left); }); - AddUntilStep("popover closed", () => !this.ChildrenOfType().Any()); + AddUntilStep("popover not closed", () => this.ChildrenOfType().Any()); AddAssert("present mod is changed", () => this.ChildrenOfType().First().Preset.Value.Mods.Count == 2); } - [Test] - public void TestEditModSwitchDisableWithNoModSelest() - { - ModPresetColumn modPresetColumn = null!; - - AddStep("clear mods", () => SelectedMods.Value = Array.Empty()); - AddStep("create content", () => Child = modPresetColumn = new ModPresetColumn - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }); - - AddUntilStep("items loaded", () => modPresetColumn.IsLoaded && modPresetColumn.ItemsLoaded); - AddStep("right click first panel", () => - { - var panel = this.ChildrenOfType().First(); - InputManager.MoveMouseTo(panel); - InputManager.Click(MouseButton.Right); - }); - - AddUntilStep("wait for context menu", () => this.ChildrenOfType().Any()); - AddStep("click edit", () => - { - var editItem = this.ChildrenOfType().ElementAt(0); - InputManager.MoveMouseTo(editItem); - InputManager.Click(MouseButton.Left); - }); - - OsuPopover? popover = null; - AddUntilStep("wait for popover", () => (popover = this.ChildrenOfType().FirstOrDefault()) != null); - AddAssert("use current mod is disblaed", () => popover.ChildrenOfType().Single().Current.Value == false); - AddAssert("use current mod switch cannot be switch", () => popover.ChildrenOfType().Single().Current.Disabled); - } - - [Test] - public void TestEditModSwitchDisableWithPresetSelest() - { - ModPresetColumn modPresetColumn = null!; - - AddStep("clear mods", () => SelectedMods.Value = Array.Empty()); - AddStep("create content", () => Child = modPresetColumn = new ModPresetColumn - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }); - - AddUntilStep("items loaded", () => modPresetColumn.IsLoaded && modPresetColumn.ItemsLoaded); - AddStep("select first preset mod", () => - SelectedMods.Value = this.ChildrenOfType().First().Preset.Value.Mods.ToList()); - - AddStep("right click first panel", () => - { - var panel = this.ChildrenOfType().First(); - InputManager.MoveMouseTo(panel); - InputManager.Click(MouseButton.Right); - }); - - AddUntilStep("wait for context menu", () => this.ChildrenOfType().Any()); - AddStep("click edit", () => - { - var editItem = this.ChildrenOfType().ElementAt(0); - InputManager.MoveMouseTo(editItem); - InputManager.Click(MouseButton.Left); - }); - - OsuPopover? popover = null; - AddUntilStep("wait for popover", () => (popover = this.ChildrenOfType().FirstOrDefault()) != null); - AddAssert("use current mod is enabled", () => popover.ChildrenOfType().Single().Current.Value); - AddAssert("use current mod switch cannot be switch", () => popover.ChildrenOfType().Single().Current.Disabled); - - AddStep("clear mods", () => SelectedMods.Value = Array.Empty()); - AddAssert("use current mod is disblaed", () => popover.ChildrenOfType().Single().Current.Value == false); - AddAssert("use current mod switch cannot be switch", () => popover.ChildrenOfType().Single().Current.Disabled); - } - private ICollection createTestPresets() => new[] { new ModPreset diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs index 270b6f43d9..4eaf5e19db 100644 --- a/osu.Game/Overlays/Mods/EditPresetPopover.cs +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Mods private readonly LabelledTextBox nameTextBox; private readonly LabelledTextBox descriptionTextBox; - private readonly LabelledSwitchButton useCurrentSwitch; + private readonly ShearedButton useCurrentModButton; private readonly ShearedButton createButton; [Resolved] @@ -42,6 +42,7 @@ namespace osu.Game.Overlays.Mods Width = 300, AutoSizeAxes = Axes.Y, Spacing = new Vector2(7), + Direction = FillDirection.Vertical, Children = new Drawable[] { nameTextBox = new LabelledTextBox @@ -58,18 +59,30 @@ namespace osu.Game.Overlays.Mods Label = CommonStrings.Description, TabbableContentContainer = this }, - useCurrentSwitch = new LabelledSwitchButton + new FillFlowContainer { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - Label = "Use Current Mod select", - }, - createButton = new ShearedButton - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Text = CommonStrings.MenuBarEdit, - Action = tryEditPreset + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(7), + Children = new Drawable[] + { + useCurrentModButton = new ShearedButton + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = "Use Current Mods", + Action = trySaveCurrentMod + }, + createButton = new ShearedButton + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + Text = Resources.Localisation.Web.CommonStrings.ButtonsSave, + Action = tryEditPreset + }, + } } } }; @@ -84,28 +97,24 @@ namespace osu.Game.Overlays.Mods nameTextBox.Current.Value = preset.Name; descriptionTextBox.Current.Value = preset.Description; - selectedMods.BindValueChanged(_ => updateMods(), true); - createButton.DarkerColour = colours.Orange1; createButton.LighterColour = colours.Orange0; createButton.TextColour = colourProvider.Background6; + + useCurrentModButton.DarkerColour = colours.Blue1; + useCurrentModButton.LighterColour = colours.Blue0; + useCurrentModButton.TextColour = colourProvider.Background6; } - private void updateMods() + private void trySaveCurrentMod() { - useCurrentSwitch.Current.Disabled = false; + if (button.Active.Value || !selectedMods.Value.Any()) + return; - // disable the switch when mod is equal. - if (button.Active.Value) + button.Preset.PerformWrite(s => { - useCurrentSwitch.Current.Value = true; - useCurrentSwitch.Current.Disabled = true; - } - else - { - useCurrentSwitch.Current.Value = false; - useCurrentSwitch.Current.Disabled = !selectedMods.Value.Any(); - } + s.Mods = selectedMods.Value.ToArray(); + }); } protected override void LoadComplete() @@ -127,11 +136,6 @@ namespace osu.Game.Overlays.Mods { s.Name = nameTextBox.Current.Value; s.Description = descriptionTextBox.Current.Value; - - if (useCurrentSwitch.Current.Value) - { - s.Mods = selectedMods.Value.ToArray(); - } }); this.HidePopover(); From 5191204569241e0e92c93b51681a9384d711a019 Mon Sep 17 00:00:00 2001 From: Cootz Date: Tue, 7 Mar 2023 15:39:43 +0300 Subject: [PATCH 2403/2991] Bring truncating logic back to `Export` method --- osu.Game/Database/LegacyExporter.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 0fa7b9e03c..9981e08442 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -48,15 +48,7 @@ namespace osu.Game.Database UserFileStorage = storage.GetStorageForDirectory(@"files"); } - protected virtual string GetFilename(TModel item) - { - string filename = item.GetDisplayString(); - - if (filename.Length > MAX_FILENAME_LENGTH - FileExtension.Length) - return filename.Remove(MAX_FILENAME_LENGTH - FileExtension.Length); - - return filename; - } + protected virtual string GetFilename(TModel item) => item.GetDisplayString(); /// /// Exports an item to a legacy (.zip based) package. @@ -73,6 +65,14 @@ namespace osu.Game.Database string filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); + if (filename.Length > MAX_FILENAME_LENGTH) + { + string filenameWithoutExtension = Path.GetFileNameWithoutExtension(filename); + + filenameWithoutExtension = filenameWithoutExtension.Remove(MAX_FILENAME_LENGTH - FileExtension.Length); + filename = $"{filenameWithoutExtension}{FileExtension}"; + } + using (var stream = exportStorage.CreateFileSafely(filename)) ExportModelTo(item, stream); From 7107834b9ec297062ff29442fa1a550c03ff5a94 Mon Sep 17 00:00:00 2001 From: Cootz Date: Tue, 7 Mar 2023 15:43:03 +0300 Subject: [PATCH 2404/2991] Fix truncating bug --- osu.Game/Database/LegacyExporter.cs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 9981e08442..8da285daa3 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -58,6 +58,9 @@ namespace osu.Game.Database { string itemFilename = GetFilename(item).GetValidFilename(); + if (itemFilename.Length > MAX_FILENAME_LENGTH - FileExtension.Length) + itemFilename = itemFilename.Remove(MAX_FILENAME_LENGTH - FileExtension.Length); + IEnumerable existingExports = exportStorage .GetFiles(string.Empty, $"{itemFilename}*{FileExtension}") @@ -65,14 +68,6 @@ namespace osu.Game.Database string filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); - if (filename.Length > MAX_FILENAME_LENGTH) - { - string filenameWithoutExtension = Path.GetFileNameWithoutExtension(filename); - - filenameWithoutExtension = filenameWithoutExtension.Remove(MAX_FILENAME_LENGTH - FileExtension.Length); - filename = $"{filenameWithoutExtension}{FileExtension}"; - } - using (var stream = exportStorage.CreateFileSafely(filename)) ExportModelTo(item, stream); From bedf4cc2596f9202a8760cbbe731ca2f1f6bf8ed Mon Sep 17 00:00:00 2001 From: Terochi Date: Tue, 7 Mar 2023 16:03:11 +0100 Subject: [PATCH 2405/2991] Remove extra code --- .../Visual/UserInterface/TestSceneModSelectOverlay.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs index a354a22fb7..75efc07d43 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs @@ -553,8 +553,6 @@ namespace osu.Game.Tests.Visual.UserInterface waitForColumnLoad(); AddAssert("unimplemented mod panel is filtered", () => getPanelForMod(typeof(TestUnimplementedMod)).Filtered.Value); - - AddStep("disable panel filtering", () => getPanelForMod(typeof(TestUnimplementedMod)).Filtered.Value = false); } [Test] From 7ade525eef4a3c887de1d50123682140ee9c605a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 7 Mar 2023 19:43:52 +0100 Subject: [PATCH 2406/2991] Display corner radius setting as percentage --- .../Settings/SettingsPercentageSlider.cs | 20 +++++++++++++++++++ .../Rulesets/Mods/ModAccuracyChallenge.cs | 11 +--------- osu.Game/Screens/Play/HUD/PlayerAvatar.cs | 4 +++- 3 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 osu.Game/Overlays/Settings/SettingsPercentageSlider.cs diff --git a/osu.Game/Overlays/Settings/SettingsPercentageSlider.cs b/osu.Game/Overlays/Settings/SettingsPercentageSlider.cs new file mode 100644 index 0000000000..fa59d18de1 --- /dev/null +++ b/osu.Game/Overlays/Settings/SettingsPercentageSlider.cs @@ -0,0 +1,20 @@ +// 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.Graphics; +using osu.Game.Configuration; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Overlays.Settings +{ + /// + /// A that displays its value as a percentage by default. + /// Mostly provided for convenience of use with . + /// + public partial class SettingsPercentageSlider : SettingsSlider + where TValue : struct, IEquatable, IComparable, IConvertible + { + protected override Drawable CreateControl() => ((RoundedSliderBar)base.CreateControl()).With(sliderBar => sliderBar.DisplayAsPercentage = true); + } +} diff --git a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs index dc7594f469..d4223a80c2 100644 --- a/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs +++ b/osu.Game/Rulesets/Mods/ModAccuracyChallenge.cs @@ -7,7 +7,6 @@ using System.Linq; using osu.Framework.Bindables; using osu.Framework.Localisation; using osu.Game.Configuration; -using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Judgements; @@ -33,7 +32,7 @@ namespace osu.Game.Rulesets.Mods public override string SettingDescription => base.SettingDescription.Replace(MinimumAccuracy.ToString(), MinimumAccuracy.Value.ToString("##%", NumberFormatInfo.InvariantInfo)); - [SettingSource("Minimum accuracy", "Trigger a failure if your accuracy goes below this value.", SettingControlType = typeof(SettingsSlider))] + [SettingSource("Minimum accuracy", "Trigger a failure if your accuracy goes below this value.", SettingControlType = typeof(SettingsPercentageSlider))] public BindableNumber MinimumAccuracy { get; } = new BindableDouble { MinValue = 0.60, @@ -69,12 +68,4 @@ namespace osu.Game.Rulesets.Mods return scoreProcessor.ComputeAccuracy(score); } } - - public partial class PercentSlider : RoundedSliderBar - { - public PercentSlider() - { - DisplayAsPercentage = true; - } - } } diff --git a/osu.Game/Screens/Play/HUD/PlayerAvatar.cs b/osu.Game/Screens/Play/HUD/PlayerAvatar.cs index e3fab499f3..1d0331593a 100644 --- a/osu.Game/Screens/Play/HUD/PlayerAvatar.cs +++ b/osu.Game/Screens/Play/HUD/PlayerAvatar.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Configuration; using osu.Game.Localisation.SkinComponents; +using osu.Game.Overlays.Settings; using osu.Game.Skinning; using osu.Game.Users.Drawables; using osuTK; @@ -15,7 +16,8 @@ namespace osu.Game.Screens.Play.HUD { public partial class PlayerAvatar : CompositeDrawable, ISerialisableDrawable { - [SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.CornerRadius), nameof(SkinnableComponentStrings.CornerRadiusDescription))] + [SettingSource(typeof(SkinnableComponentStrings), nameof(SkinnableComponentStrings.CornerRadius), nameof(SkinnableComponentStrings.CornerRadiusDescription), + SettingControlType = typeof(SettingsPercentageSlider))] public new BindableFloat CornerRadius { get; set; } = new BindableFloat(0.25f) { MinValue = 0, From 9ea93e0a9fb7b5a9d629519cd6e257e80acd1510 Mon Sep 17 00:00:00 2001 From: Terochi Date: Tue, 7 Mar 2023 20:38:33 +0100 Subject: [PATCH 2407/2991] Add more tests --- osu.Game.Tests/Mods/ModSettingsTest.cs | 91 +++++++++++++++++++++----- 1 file changed, 75 insertions(+), 16 deletions(-) diff --git a/osu.Game.Tests/Mods/ModSettingsTest.cs b/osu.Game.Tests/Mods/ModSettingsTest.cs index 99198f6bae..45e162df1a 100644 --- a/osu.Game.Tests/Mods/ModSettingsTest.cs +++ b/osu.Game.Tests/Mods/ModSettingsTest.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 NUnit.Framework; using osu.Framework.Bindables; using osu.Framework.Localisation; @@ -37,34 +38,92 @@ namespace osu.Game.Tests.Mods } [Test] - public void TestCopySharedSettingsOfDifferentType() + public void TestDifferentTypeSettingsKeptWhenCopied() { - const double setting_change = 2.5; + const double setting_change = 50.4; - var osuMod = new TestNonMatchinSettingTypeOsuMod(); - var maniaMod = new TestNonMatchinSettingTypeManiaMod(); + var modDouble = new TestNonMatchingSettingTypeModDouble(); + var modBool = new TestNonMatchingSettingTypeModBool(); - osuMod.TestSetting.Value = setting_change; - maniaMod.CopySharedSettings(osuMod); - osuMod.CopySharedSettings(maniaMod); + modDouble.TestSetting.Value = setting_change; + modBool.TestSetting.Value = !modBool.TestSetting.Default; + modDouble.CopySharedSettings(modBool); + modBool.CopySharedSettings(modDouble); - Assert.That(maniaMod.TestSetting.IsDefault, "Value has been changed"); - Assert.That(osuMod.TestSetting.Value == setting_change); + Assert.That(modDouble.TestSetting.Value, Is.EqualTo(setting_change)); + Assert.That(modBool.TestSetting.Value, Is.EqualTo(!modBool.TestSetting.Default)); } - private class TestNonMatchinSettingTypeOsuMod : TestNonMatchinSettingTypeMod + [Test] + public void TestCopyDoubleToIntWithDefaultRange() { - public override string Acronym => "NMO"; - public override BindableNumber TestSetting { get; } = new BindableDouble(3.5); + const double setting_change = 50.4; + + var modDouble = new TestNonMatchingSettingTypeModDouble { TestSetting = { Value = setting_change } }; + var modInt = new TestNonMatchingSettingTypeModInt(); + + modInt.CopySharedSettings(modDouble); + + Assert.That(modInt.TestSetting.Value, Is.EqualTo((int)setting_change)); } - private class TestNonMatchinSettingTypeManiaMod : TestNonMatchinSettingTypeMod + [Test] + public void TestCopyIntToDoubleWithDefaultRange() { - public override string Acronym => "NMM"; - public override Bindable TestSetting { get; } = new BindableBool(true); + const int setting_change = 50; + + var modInt = new TestNonMatchingSettingTypeModInt { TestSetting = { Value = setting_change } }; + var modDouble = new TestNonMatchingSettingTypeModDouble(); + + modDouble.CopySharedSettings(modInt); + + Assert.That(modDouble.TestSetting.Value, Is.EqualTo(setting_change)); } - private abstract class TestNonMatchinSettingTypeMod : Mod + [Test] + public void TestCopyDoubleToIntWithClampedRange() + { + const double setting_change = 50.4; + + var modDouble = new TestNonMatchingSettingTypeModDouble { TestSetting = { MaxValue = 100, MinValue = 0, Value = setting_change } }; + var modInt = new TestNonMatchingSettingTypeModInt { TestSetting = { MaxValue = 200, MinValue = 0 } }; + + modInt.CopySharedSettings(modDouble); + + Assert.That(modInt.TestSetting.Value, Is.EqualTo(Convert.ToInt32(setting_change * 2))); + } + + [Test] + public void TestDefaultValueKeptWhenCopied() + { + var modBoolTrue = new TestNonMatchingSettingTypeModBool { TestSetting = { Default = true, Value = false } }; + var modBoolFalse = new TestNonMatchingSettingTypeModBool { TestSetting = { Default = false, Value = true } }; + + modBoolFalse.CopySharedSettings(modBoolTrue); + + Assert.That(modBoolFalse.TestSetting.Default, Is.EqualTo(false)); + Assert.That(modBoolFalse.TestSetting.Value, Is.EqualTo(modBoolTrue.TestSetting.Value)); + } + + private class TestNonMatchingSettingTypeModDouble : TestNonMatchingSettingTypeMod + { + public override string Acronym => "NMD"; + public override BindableNumber TestSetting { get; } = new BindableDouble(); + } + + private class TestNonMatchingSettingTypeModInt : TestNonMatchingSettingTypeMod + { + public override string Acronym => "NMI"; + public override BindableNumber TestSetting { get; } = new BindableInt(); + } + + private class TestNonMatchingSettingTypeModBool : TestNonMatchingSettingTypeMod + { + public override string Acronym => "NMB"; + public override Bindable TestSetting { get; } = new BindableBool(); + } + + private abstract class TestNonMatchingSettingTypeMod : Mod { public override string Name => "Non-matching setting type mod"; public override LocalisableString Description => "Description"; From 8bf84869a5334c14aec47ebeb43470c8a0d808a1 Mon Sep 17 00:00:00 2001 From: Terochi Date: Tue, 7 Mar 2023 20:39:50 +0100 Subject: [PATCH 2408/2991] Fixed errors covered in new tests --- osu.Game/Rulesets/Mods/Mod.cs | 44 +++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index f6c0e851fd..e630a53045 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -165,6 +165,10 @@ namespace osu.Game.Rulesets.Mods /// The mod to copy properties from. internal void CopySharedSettings(Mod source) { + const string min_value = nameof(BindableNumber.MinValue); + const string max_value = nameof(BindableNumber.MaxValue); + const string value = nameof(Bindable.Value); + Dictionary oldSettings = new Dictionary(); foreach (var (_, property) in source.GetSettingsSourceProperties()) @@ -190,27 +194,47 @@ namespace osu.Game.Rulesets.Mods { if (getGenericBaseType(targetSetting, typeof(Bindable<>))!.GenericTypeArguments.Single() == getGenericBaseType(sourceSetting, typeof(Bindable<>))!.GenericTypeArguments.Single()) + { // change settings only if the type is the same - CopyAdjustedSetting((IBindable)targetSetting, sourceSetting); + setValue(targetSetting, value, getValue(sourceSetting, value)); + } continue; } - double targetMin = getValue(targetSetting, nameof(IBindableNumber.MinValue)); - double targetMax = getValue(targetSetting, nameof(IBindableNumber.MaxValue)); - double sourceMin = getValue(sourceSetting, nameof(IBindableNumber.MinValue)); - double sourceMax = getValue(sourceSetting, nameof(IBindableNumber.MaxValue)); - double sourceValue = getValue(sourceSetting, nameof(IBindableNumber.Value)); + Type targetGenericType = targetType.GenericTypeArguments.Single(); + Type sourceGenericType = sourceType.GenericTypeArguments.Single(); + + double allowedMin = Math.Max( + Convert.ToDouble(targetGenericType.GetField("MinValue")!.GetValue(null)), + Convert.ToDouble(sourceGenericType.GetField("MinValue")!.GetValue(null)) + ); + + double allowedMax = Math.Min( + Convert.ToDouble(targetGenericType.GetField("MaxValue")!.GetValue(null)), + Convert.ToDouble(sourceGenericType.GetField("MaxValue")!.GetValue(null)) + ); + + double targetMin = getValueDouble(targetSetting, min_value); + double targetMax = getValueDouble(targetSetting, max_value); + double sourceMin = getValueDouble(sourceSetting, min_value); + double sourceMax = getValueDouble(sourceSetting, max_value); + double sourceValue = getValueDouble(sourceSetting, value); // convert value to same ratio double targetValue = (sourceValue - sourceMin) / (sourceMax - sourceMin) * (targetMax - targetMin) + targetMin; - targetType.GetProperty(nameof(IBindableNumber.Value))!.SetValue(targetSetting, - Convert.ChangeType(targetValue, targetType.GenericTypeArguments.Single())); + setValue(targetSetting, value, Convert.ChangeType(targetValue, targetType.GenericTypeArguments.Single())); + + double getValueDouble(object target, string name) => + Math.Clamp(Convert.ToDouble(getValue(target, name)!), allowedMin, allowedMax); } - double getValue(object target, string name) => - Convert.ToDouble(target.GetType().GetProperty(name)!.GetValue(target)!); + object? getValue(object target, string name) => + target.GetType().GetProperty(name)!.GetValue(target); + + void setValue(object target, string name, object? newValue) => + target.GetType().GetProperty(name)!.SetValue(target, newValue); Type? getGenericBaseType(object target, Type genericType) => target.GetType().GetTypeInheritance().FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == genericType); From f711915e5fd89447a98322b7eb8070f218770a5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 7 Mar 2023 21:16:30 +0100 Subject: [PATCH 2409/2991] Remove unused using directive --- osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs index 4e13bde755..b90081a29f 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs @@ -21,7 +21,6 @@ using osu.Game.Configuration; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.UI.Cursor; -using osu.Game.Screens.Play; using osu.Game.Screens.Play.HUD; using osu.Game.Tests.Visual; using osuTK; From 98f40b2679bb37f7b15f2ea7a33f6971cda91b32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 7 Mar 2023 21:22:59 +0100 Subject: [PATCH 2410/2991] Improve documentation of `InputTrigger` --- osu.Game/Screens/Play/HUD/InputTrigger.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/InputTrigger.cs b/osu.Game/Screens/Play/HUD/InputTrigger.cs index 93b45daab3..b57f2cdf91 100644 --- a/osu.Game/Screens/Play/HUD/InputTrigger.cs +++ b/osu.Game/Screens/Play/HUD/InputTrigger.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 osu.Framework.Graphics; namespace osu.Game.Screens.Play.HUD @@ -11,8 +10,20 @@ namespace osu.Game.Screens.Play.HUD /// public abstract partial class InputTrigger : Component { - public event Action? OnActivate; - public event Action? OnDeactivate; + /// + /// Callback to invoke when the associated input has been activated. + /// + /// Whether gameplay is progressing in the forward direction time-wise. + public delegate void OnActivateCallback(bool forwardPlayback); + + /// + /// Callback to invoke when the associated input has been deactivated. + /// + /// Whether gameplay is progressing in the forward direction time-wise. + public delegate void OnDeactivateCallback(bool forwardPlayback); + + public event OnActivateCallback? OnActivate; + public event OnDeactivateCallback? OnDeactivate; protected InputTrigger(string name) { From 12af002c4d81dcc98b60e4c5058aeccfdd676f05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 7 Mar 2023 21:28:42 +0100 Subject: [PATCH 2411/2991] Reorder and add xmldoc to `KeyCounter` members --- osu.Game/Screens/Play/HUD/KeyCounter.cs | 26 ++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/KeyCounter.cs b/osu.Game/Screens/Play/HUD/KeyCounter.cs index 93cc4f908a..2a4ab1993a 100644 --- a/osu.Game/Screens/Play/HUD/KeyCounter.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounter.cs @@ -12,21 +12,35 @@ namespace osu.Game.Screens.Play.HUD /// public abstract partial class KeyCounter : Container { + /// + /// The which activates and deactivates this . + /// public readonly InputTrigger Trigger; - private readonly Container content; - - protected override Container Content => content; + /// + /// Whether the actions reported by should be counted. + /// + public Bindable IsCounting { get; } = new BindableBool(true); private readonly Bindable countPresses = new BindableInt { MinValue = 0 }; - public Bindable IsCounting { get; } = new BindableBool(true); - + /// + /// The current count of registered key presses. + /// public IBindable CountPresses => countPresses; + private readonly Container content; + + protected override Container Content => content; + + /// + /// Whether this is currently in the "activated" state because the associated key is currently pressed. + /// + protected readonly Bindable IsActive = new BindableBool(); + protected KeyCounter(InputTrigger trigger) { InternalChildren = new Drawable[] @@ -44,8 +58,6 @@ namespace osu.Game.Screens.Play.HUD Name = trigger.Name; } - protected readonly Bindable IsActive = new BindableBool(); - private void increment() { if (!IsCounting.Value) From 44297a7d0a01e44f24d2860cdd4ce2584988e341 Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 8 Mar 2023 00:47:16 +0000 Subject: [PATCH 2412/2991] refactor: make KCD a `CompositeDrawable` --- .../Visual/Gameplay/TestSceneAutoplay.cs | 4 +-- .../Gameplay/TestSceneGameplayRewinding.cs | 4 +-- .../Visual/Gameplay/TestSceneKeyCounter.cs | 4 +-- .../Visual/Gameplay/TestSceneReplay.cs | 2 +- osu.Game/Rulesets/UI/RulesetInputManager.cs | 4 +-- .../Play/HUD/DefaultKeyCounterDisplay.cs | 28 ++++--------------- .../Screens/Play/HUD/KeyCounterDisplay.cs | 25 ++++------------- 7 files changed, 20 insertions(+), 51 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs index 903cd178b7..f3f942b74b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs @@ -35,14 +35,14 @@ namespace osu.Game.Tests.Visual.Gameplay var referenceBeatmap = CreateBeatmap(new OsuRuleset().RulesetInfo); AddUntilStep("score above zero", () => Player.ScoreProcessor.TotalScore.Value > 0); - AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses.Value > 2)); + AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Counters.Any(kc => kc.CountPresses.Value > 2)); seekTo(referenceBeatmap.Breaks[0].StartTime); AddAssert("keys not counting", () => !Player.HUDOverlay.KeyCounter.IsCounting.Value); 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.Value == 0)); + AddUntilStep("key counter reset", () => Player.HUDOverlay.KeyCounter.Counters.All(kc => kc.CountPresses.Value == 0)); seekTo(referenceBeatmap.HitObjects[^1].GetEndTime()); AddUntilStep("results displayed", () => getResultsScreen()?.IsLoaded == true); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs index 9f485cd7bf..751aeb4e13 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs @@ -31,11 +31,11 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning); addSeekStep(3000); AddAssert("all judged", () => Player.DrawableRuleset.Playfield.AllHitObjects.All(h => h.Judged)); - AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.Select(kc => kc.CountPresses.Value).Sum() == 15); + AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Counters.Select(kc => kc.CountPresses.Value).Sum() == 15); AddStep("clear results", () => Player.Results.Clear()); addSeekStep(0); AddAssert("none judged", () => Player.DrawableRuleset.Playfield.AllHitObjects.All(h => !h.Judged)); - AddUntilStep("key counters reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses.Value == 0)); + AddUntilStep("key counters reset", () => Player.HUDOverlay.KeyCounter.Counters.All(kc => kc.CountPresses.Value == 0)); AddAssert("no results triggered", () => Player.Results.Count == 0); } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs index 3260ba8e33..6dc07ca9d3 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs @@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual.Gameplay new KeyCounterMouseTrigger(MouseButton.Right), }); - var testCounter = (DefaultKeyCounter)kc.Children.First(); + var testCounter = (DefaultKeyCounter)kc.Counters.First(); AddStep("Add random", () => { @@ -39,7 +39,7 @@ namespace osu.Game.Tests.Visual.Gameplay kc.AddTrigger(new KeyCounterKeyboardTrigger(key)); }); - Key testKey = ((KeyCounterKeyboardTrigger)kc.Children.First().Trigger).Key; + Key testKey = ((KeyCounterKeyboardTrigger)kc.Counters.First().Trigger).Key; void addPressKeyStep() { diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplay.cs index 542686f0cd..bf9b13b320 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplay.cs @@ -27,7 +27,7 @@ namespace osu.Game.Tests.Visual.Gameplay protected override void AddCheckSteps() { AddUntilStep("score above zero", () => ((ScoreAccessibleReplayPlayer)Player).ScoreProcessor.TotalScore.Value > 0); - AddUntilStep("key counter counted keys", () => ((ScoreAccessibleReplayPlayer)Player).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses.Value > 0)); + AddUntilStep("key counter counted keys", () => ((ScoreAccessibleReplayPlayer)Player).HUDOverlay.KeyCounter.Counters.Any(kc => kc.CountPresses.Value > 0)); AddAssert("cannot fail", () => !((ScoreAccessibleReplayPlayer)Player).AllowFail); } diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index c2f0b1a951..ea9dc3fb01 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -176,14 +176,14 @@ namespace osu.Game.Rulesets.UI { } - public bool OnPressed(KeyBindingPressEvent e) => Target.Children.Where(c => c.Trigger is KeyCounterActionTrigger) + public bool OnPressed(KeyBindingPressEvent e) => Target.Counters.Where(c => c.Trigger is KeyCounterActionTrigger) .Select(c => (KeyCounterActionTrigger)c.Trigger) .Any(c => c.OnPressed(e.Action, Clock.Rate >= 0)); public void OnReleased(KeyBindingReleaseEvent e) { foreach (var c - in Target.Children.Where(c => c.Trigger is KeyCounterActionTrigger).Select(c => (KeyCounterActionTrigger)c.Trigger)) + in Target.Counters.Where(c => c.Trigger is KeyCounterActionTrigger).Select(c => (KeyCounterActionTrigger)c.Trigger)) c.OnReleased(e.Action, Clock.Rate >= 0); } } diff --git a/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs index 1d79b2d27a..9499263474 100644 --- a/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs @@ -13,18 +13,11 @@ namespace osu.Game.Screens.Play.HUD private const int duration = 100; private const double key_fade_time = 80; - private readonly FillFlowContainer keyFlow = new FillFlowContainer(); + private readonly FillFlowContainer keyFlow = new FillFlowContainer(); - protected override Container Content => keyFlow; - - public new IReadOnlyList Children - { - get => (IReadOnlyList)base.Children; - set => base.Children = value; - } + public override IEnumerable Counters => keyFlow; public DefaultKeyCounterDisplay() - : base(typeof(DefaultKeyCounter)) { keyFlow.Direction = FillDirection.Horizontal; keyFlow.AutoSizeAxes = Axes.Both; @@ -45,23 +38,12 @@ namespace osu.Game.Screens.Play.HUD public override void AddTrigger(InputTrigger trigger) { DefaultKeyCounter key = new DefaultKeyCounter(trigger); - Add(key); + keyFlow.Add(key); key.FadeTime = key_fade_time; key.KeyDownTextColor = KeyDownTextColor; key.KeyUpTextColor = KeyUpTextColor; } - public override void Add(KeyCounter key) - { - base.Add(key); - - DefaultKeyCounter defaultKey = (DefaultKeyCounter)key; - - defaultKey.FadeTime = key_fade_time; - defaultKey.KeyDownTextColor = KeyDownTextColor; - defaultKey.KeyUpTextColor = KeyUpTextColor; - } - protected override void UpdateVisibility() => // Isolate changing visibility of the key counters from fading this component. keyFlow.FadeTo(AlwaysVisible.Value || ConfigVisibility.Value ? 1 : 0, duration); @@ -76,7 +58,7 @@ namespace osu.Game.Screens.Play.HUD if (value != keyDownTextColor) { keyDownTextColor = value; - foreach (var child in Children) + foreach (var child in keyFlow) child.KeyDownTextColor = value; } } @@ -92,7 +74,7 @@ namespace osu.Game.Screens.Play.HUD if (value != keyUpTextColor) { keyUpTextColor = value; - foreach (var child in Children) + foreach (var child in keyFlow) child.KeyUpTextColor = value; } } diff --git a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs index 4080e561cd..9a28d40418 100644 --- a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Play.HUD /// /// A flowing display of all gameplay keys. Individual keys can be added using implementations. /// - public abstract partial class KeyCounterDisplay : Container + public abstract partial class KeyCounterDisplay : CompositeDrawable { /// /// Whether the key counter should be visible regardless of the configuration value. @@ -26,6 +26,11 @@ namespace osu.Game.Screens.Play.HUD /// public Bindable AlwaysVisible { get; } = new Bindable(true); + /// + /// The s contained in this . + /// + public abstract IEnumerable Counters { get; } + public Bindable IsCounting { get; } = new BindableBool(true); protected readonly Bindable ConfigVisibility = new Bindable(); @@ -34,13 +39,6 @@ namespace osu.Game.Screens.Play.HUD private Receptor? receptor; - private readonly Type[] acceptedTypes; - - protected KeyCounterDisplay(params Type[] acceptedTypes) - { - this.acceptedTypes = acceptedTypes; - } - public void SetReceptor(Receptor receptor) { if (this.receptor != null) @@ -53,17 +51,6 @@ namespace osu.Game.Screens.Play.HUD public void AddTriggerRange(IEnumerable triggers) => triggers.ForEach(AddTrigger); - public override void Add(KeyCounter counter) - { - if (!checkType(counter)) - throw new InvalidOperationException($"{counter.GetType()} is not a supported counter type. (hint: you may want to use {nameof(AddTrigger)} instead.)"); - - base.Add(counter); - counter.IsCounting.BindTo(IsCounting); - } - - private bool checkType(KeyCounter counter) => acceptedTypes.Length == 0 || acceptedTypes.Any(t => t.IsInstanceOfType(counter)); - [BackgroundDependencyLoader] private void load(OsuConfigManager config) { From 5b0db94a242a8e5896806a4e76831d399b33010a Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 8 Mar 2023 00:58:54 +0000 Subject: [PATCH 2413/2991] docs: add XMLDoc for methods in KCD --- osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs index 9a28d40418..0e0f8a1190 100644 --- a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs @@ -31,6 +31,9 @@ namespace osu.Game.Screens.Play.HUD /// public abstract IEnumerable Counters { get; } + /// + /// Whether the actions reported by all s within this should be counted. + /// public Bindable IsCounting { get; } = new BindableBool(true); protected readonly Bindable ConfigVisibility = new Bindable(); @@ -47,8 +50,16 @@ namespace osu.Game.Screens.Play.HUD this.receptor = receptor; } + /// + /// Adds a new to this . + /// + /// The the resulting will react to. public abstract void AddTrigger(InputTrigger trigger); + /// + /// Adds a range of new s to this . + /// + /// The s the resulting s will react to. public void AddTriggerRange(IEnumerable triggers) => triggers.ForEach(AddTrigger); [BackgroundDependencyLoader] From 5d15426c275084144d68e8790f0275d985c52269 Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 8 Mar 2023 01:52:12 +0000 Subject: [PATCH 2414/2991] refactor: make `Counters` return a `Container` --- osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs | 9 ++++----- osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs index 9499263474..dce0be9cde 100644 --- a/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.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.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osuTK.Graphics; @@ -13,9 +12,9 @@ namespace osu.Game.Screens.Play.HUD private const int duration = 100; private const double key_fade_time = 80; - private readonly FillFlowContainer keyFlow = new FillFlowContainer(); + private readonly FillFlowContainer keyFlow = new FillFlowContainer(); - public override IEnumerable Counters => keyFlow; + public override Container Counters => keyFlow; public DefaultKeyCounterDisplay() { @@ -59,7 +58,7 @@ namespace osu.Game.Screens.Play.HUD { keyDownTextColor = value; foreach (var child in keyFlow) - child.KeyDownTextColor = value; + ((DefaultKeyCounter)child).KeyDownTextColor = value; } } } @@ -75,7 +74,7 @@ namespace osu.Game.Screens.Play.HUD { keyUpTextColor = value; foreach (var child in keyFlow) - child.KeyUpTextColor = value; + ((DefaultKeyCounter)child).KeyUpTextColor = value; } } } diff --git a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs index 0e0f8a1190..2c90d1474d 100644 --- a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs @@ -29,7 +29,7 @@ namespace osu.Game.Screens.Play.HUD /// /// The s contained in this . /// - public abstract IEnumerable Counters { get; } + public abstract Container Counters { get; } /// /// Whether the actions reported by all s within this should be counted. From 245c3c025c9fa2dd4e75c279fa41b2281b3abfdb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 8 Mar 2023 19:23:32 +0900 Subject: [PATCH 2415/2991] Refactor `endClickSelection` to reduce nesting --- .../Compose/Components/BlueprintContainer.cs | 76 +++++++++---------- 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 87cee59d83..3bf9f42957 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -382,52 +382,48 @@ namespace osu.Game.Screens.Edit.Compose.Components /// Whether a click selection was active. private bool endClickSelection(MouseButtonEvent e) { - if (!clickSelectionHandled && !isDraggingBlueprint) + // If already handled a selection or drag, we don't want to perform a mouse up / click action. + if (clickSelectionHandled || isDraggingBlueprint) return true; + + if (e.Button != MouseButton.Left) return false; + + if (e.ControlPressed) { - if (e.Button == MouseButton.Left) - { - if (e.ControlPressed) - { - // if a selection didn't occur, we may want to trigger a deselection. + // if a selection didn't occur, we may want to trigger a deselection. - // Iterate from the top of the input stack (blueprints closest to the front of the screen first). - // Priority is given to already-selected blueprints. - foreach (SelectionBlueprint blueprint in SelectionBlueprints.AliveChildren.OrderByDescending(b => b.IsSelected)) - { - if (!blueprint.IsHovered) continue; - - return clickSelectionHandled = SelectionHandler.MouseUpSelectionRequested(blueprint, e); - } - } - else if (selectedBlueprintAlreadySelectedOnMouseDown && AllowCyclicSelection) - { - // If a click occurred and was handled by the currently selected blueprint but didn't result in a drag, - // cycle between other blueprints which are also under the cursor. - - // The depth of blueprints is constantly changing (see above where selected blueprints are brought to the front). - // For this logic, we want a stable sort order so we can correctly cycle, thus using the blueprintMap instead. - IEnumerable> cyclingSelectionBlueprints = blueprintMap.Values; - - // If there's already a selection, let's start from the blueprint after the selection. - cyclingSelectionBlueprints = cyclingSelectionBlueprints.SkipWhile(b => !b.IsSelected).Skip(1); - - // Add the blueprints from before the selection to the end of the enumerable to allow for cyclic selection. - cyclingSelectionBlueprints = cyclingSelectionBlueprints.Concat(blueprintMap.Values.TakeWhile(b => !b.IsSelected)); - - foreach (SelectionBlueprint blueprint in cyclingSelectionBlueprints) - { - if (!blueprint.IsHovered) continue; - - // We are performing a mouse up, but selection handlers perform selection on mouse down, so we need to call that instead. - return clickSelectionHandled = SelectionHandler.MouseDownSelectionRequested(blueprint, e); - } - } - } + // Iterate from the top of the input stack (blueprints closest to the front of the screen first). + // Priority is given to already-selected blueprints. + foreach (SelectionBlueprint blueprint in SelectionBlueprints.AliveChildren.Where(b => b.IsHovered).OrderByDescending(b => b.IsSelected)) + return clickSelectionHandled = SelectionHandler.MouseUpSelectionRequested(blueprint, e); return false; } - return true; + if (selectedBlueprintAlreadySelectedOnMouseDown && AllowCyclicSelection) + { + // If a click occurred and was handled by the currently selected blueprint but didn't result in a drag, + // cycle between other blueprints which are also under the cursor. + + // The depth of blueprints is constantly changing (see above where selected blueprints are brought to the front). + // For this logic, we want a stable sort order so we can correctly cycle, thus using the blueprintMap instead. + IEnumerable> cyclingSelectionBlueprints = blueprintMap.Values; + + // If there's already a selection, let's start from the blueprint after the selection. + cyclingSelectionBlueprints = cyclingSelectionBlueprints.SkipWhile(b => !b.IsSelected).Skip(1); + + // Add the blueprints from before the selection to the end of the enumerable to allow for cyclic selection. + cyclingSelectionBlueprints = cyclingSelectionBlueprints.Concat(blueprintMap.Values.TakeWhile(b => !b.IsSelected)); + + foreach (SelectionBlueprint blueprint in cyclingSelectionBlueprints) + { + if (!blueprint.IsHovered) continue; + + // We are performing a mouse up, but selection handlers perform selection on mouse down, so we need to call that instead. + return clickSelectionHandled = SelectionHandler.MouseDownSelectionRequested(blueprint, e); + } + } + + return false; } /// From 4f7be332f3736fc14fd02008fee3239fa2beb657 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 8 Mar 2023 19:24:03 +0900 Subject: [PATCH 2416/2991] Revert `isDraggingBlueprint` to field --- osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 3bf9f42957..3ba71cebe6 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -483,7 +483,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// Whether a blueprint is currently being dragged. /// - private bool isDraggingBlueprint { get; set; } + private bool isDraggingBlueprint; /// /// Attempts to begin the movement of any selected blueprints. From b8e87e3a08d0cc92363a24d7bf32127509a67311 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 8 Mar 2023 19:58:05 +0900 Subject: [PATCH 2417/2991] Update osu!mania argon colours to match new proposal --- .../Argon/ManiaArgonSkinTransformer.cs | 249 +++++++++++++++--- 1 file changed, 207 insertions(+), 42 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs index 057b7eb0d9..75ecd53cd1 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs @@ -69,6 +69,17 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon return base.GetDrawableComponent(lookup); } + private static readonly Color4 colour_special_column = new Color4(169, 106, 255, 255); + + private const int total_colours = 6; + + private static readonly Color4 colour_yellow = new Color4(255, 197, 40, 255); + private static readonly Color4 colour_orange = new Color4(252, 109, 1, 255); + private static readonly Color4 colour_pink = new Color4(213, 35, 90, 255); + private static readonly Color4 colour_purple = new Color4(203, 60, 236, 255); + private static readonly Color4 colour_cyan = new Color4(72, 198, 255, 255); + private static readonly Color4 colour_green = new Color4(100, 192, 92, 255); + public override IBindable? GetConfig(TLookup lookup) { if (lookup is ManiaSkinConfigurationLookup maniaLookup) @@ -92,48 +103,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon case LegacyManiaSkinConfigurationLookups.ColumnBackgroundColour: - Color4 colour; - - const int total_colours = 7; - - if (stage.IsSpecialColumn(column)) - colour = new Color4(159, 101, 255, 255); - else - { - switch (column % total_colours) - { - case 0: - colour = new Color4(240, 216, 0, 255); - break; - - case 1: - colour = new Color4(240, 101, 0, 255); - break; - - case 2: - colour = new Color4(240, 0, 130, 255); - break; - - case 3: - colour = new Color4(192, 0, 240, 255); - break; - - case 4: - colour = new Color4(0, 96, 240, 255); - break; - - case 5: - colour = new Color4(0, 226, 240, 255); - break; - - case 6: - colour = new Color4(0, 240, 96, 255); - break; - - default: - throw new ArgumentOutOfRangeException(); - } - } + var colour = getColourForLayout(column, stage); return SkinUtils.As(new Bindable(colour)); } @@ -141,5 +111,200 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon return base.GetConfig(lookup); } + + private Color4 getColourForLayout(int column, StageDefinition stage) + { + // For now, these are defined per column count as per https://user-images.githubusercontent.com/50823728/218038463-b450f46c-ef21-4551-b133-f866be59970c.png + // See https://github.com/ppy/osu/discussions/21996 for discussion. + switch (stage.Columns) + { + case 1: + return colour_yellow; + + case 2: + switch (column) + { + case 0: return colour_green; + + case 1: return colour_cyan; + + default: throw new ArgumentOutOfRangeException(); + } + + case 3: + switch (column) + { + case 0: return colour_pink; + + case 1: return colour_purple; + + case 2: return colour_special_column; + + default: throw new ArgumentOutOfRangeException(); + } + + case 4: + switch (column) + { + case 0: return colour_yellow; + + case 1: return colour_orange; + + case 2: return colour_pink; + + case 3: return colour_purple; + + default: throw new ArgumentOutOfRangeException(); + } + + case 5: + switch (column) + { + case 0: return colour_pink; + + case 1: return colour_orange; + + case 2: return colour_yellow; + + case 3: return colour_green; + + case 4: return colour_cyan; + + default: throw new ArgumentOutOfRangeException(); + } + + case 6: + switch (column) + { + case 0: return colour_pink; + + case 1: return colour_orange; + + case 2: return colour_yellow; + + case 3: return colour_cyan; + + case 4: return colour_purple; + + case 5: return colour_pink; + + default: throw new ArgumentOutOfRangeException(); + } + + case 7: + switch (column) + { + case 0: return colour_pink; + + case 1: return colour_cyan; + + case 2: return colour_pink; + + case 3: return colour_special_column; + + case 4: return colour_green; + + case 5: return colour_cyan; + + case 6: return colour_green; + + default: throw new ArgumentOutOfRangeException(); + } + + case 8: + switch (column) + { + case 0: return colour_purple; + + case 1: return colour_pink; + + case 2: return colour_orange; + + case 3: return colour_yellow; + + case 4: return colour_yellow; + + case 5: return colour_orange; + + case 6: return colour_pink; + + case 7: return colour_purple; + + default: throw new ArgumentOutOfRangeException(); + } + + case 9: + switch (column) + { + case 0: return colour_purple; + + case 1: return colour_pink; + + case 2: return colour_orange; + + case 3: return colour_yellow; + + case 4: return colour_special_column; + + case 5: return colour_yellow; + + case 6: return colour_orange; + + case 7: return colour_pink; + + case 8: return colour_purple; + + default: throw new ArgumentOutOfRangeException(); + } + + case 10: + switch (column) + { + case 0: return colour_purple; + + case 1: return colour_pink; + + case 2: return colour_orange; + + case 3: return colour_yellow; + + case 4: return colour_cyan; + + case 5: return colour_green; + + case 6: return colour_yellow; + + case 7: return colour_orange; + + case 8: return colour_pink; + + case 9: return colour_purple; + + default: throw new ArgumentOutOfRangeException(); + } + } + + // fallback for unhandled scenarios + + if (stage.IsSpecialColumn(column)) + return colour_special_column; + + switch (column % total_colours) + { + case 0: return new Color4(255, 197, 40, 255); + + case 1: return new Color4(252, 109, 1, 255); + + case 2: return new Color4(213, 35, 90, 255); + + case 3: return new Color4(203, 60, 236, 255); + + case 4: return new Color4(72, 198, 255, 255); + + case 5: return new Color4(100, 192, 92, 255); + + default: throw new ArgumentOutOfRangeException(); + } + } } } From 686259a33c62aed9ce227001f8cedccdf3031f56 Mon Sep 17 00:00:00 2001 From: EXtremeExploit Date: Wed, 8 Mar 2023 13:57:20 -0300 Subject: [PATCH 2418/2991] Make support badge in list match groups --- osu.Game/Users/UserListPanel.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Users/UserListPanel.cs b/osu.Game/Users/UserListPanel.cs index 9b5b0e9f6d..3047e70a1a 100644 --- a/osu.Game/Users/UserListPanel.cs +++ b/osu.Game/Users/UserListPanel.cs @@ -67,6 +67,7 @@ namespace osu.Game.Users { username.Anchor = Anchor.CentreLeft; username.Origin = Anchor.CentreLeft; + username.UseFullGlyphHeight = false; }) } }, @@ -111,7 +112,7 @@ namespace osu.Game.Users { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Height = 20, + Height = 16, SupportLevel = User.SupportLevel }); } From 430b09acb211f1b8ab44c7e889d7b2d22cc7ea0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 8 Mar 2023 22:52:06 +0100 Subject: [PATCH 2419/2991] Expose taiko input manager in same manner as osu! --- osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs | 2 +- osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs index fa876555e1..a5cffca06f 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModSingleTap.cs @@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Taiko.Mods public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { ruleset = (DrawableTaikoRuleset)drawableRuleset; - ruleset.InputManager.Add(new InputInterceptor(this)); + ruleset.KeyBindingInputManager.Add(new InputInterceptor(this)); playfield = (TaikoPlayfield)ruleset.Playfield; var periods = new List(); diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs index 5390d3b138..a08877e2dd 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Taiko.UI public readonly BindableBool LockPlayfieldMaxAspect = new BindableBool(true); - public TaikoInputManager InputManager { get; private set; } + public new TaikoInputManager KeyBindingInputManager => (TaikoInputManager)base.KeyBindingInputManager; protected override ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Overlapping; @@ -95,7 +95,7 @@ namespace osu.Game.Rulesets.Taiko.UI LockPlayfieldMaxAspect = { BindTarget = LockPlayfieldMaxAspect } }; - protected override PassThroughInputManager CreateInputManager() => InputManager = new TaikoInputManager(Ruleset.RulesetInfo); + protected override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo); protected override Playfield CreatePlayfield() => new TaikoPlayfield(); From e2467848679538557c64608152dc4ad3872223d0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 9 Mar 2023 18:25:30 +0900 Subject: [PATCH 2420/2991] Fix dual stage column colours not being looked up correctly --- .../Argon/ManiaArgonSkinTransformer.cs | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs index 75ecd53cd1..0beca815b2 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs @@ -84,8 +84,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon { if (lookup is ManiaSkinConfigurationLookup maniaLookup) { - int column = maniaLookup.ColumnIndex ?? 0; - var stage = beatmap.GetStageForColumnIndex(column); + int columnIndex = maniaLookup.ColumnIndex ?? 0; + var stage = beatmap.GetStageForColumnIndex(columnIndex); switch (maniaLookup.Lookup) { @@ -98,12 +98,12 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon case LegacyManiaSkinConfigurationLookups.ColumnWidth: return SkinUtils.As(new Bindable( - stage.IsSpecialColumn(column) ? 120 : 60 + stage.IsSpecialColumn(columnIndex) ? 120 : 60 )); case LegacyManiaSkinConfigurationLookups.ColumnBackgroundColour: - var colour = getColourForLayout(column, stage); + var colour = getColourForLayout(columnIndex, stage); return SkinUtils.As(new Bindable(colour)); } @@ -112,8 +112,11 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon return base.GetConfig(lookup); } - private Color4 getColourForLayout(int column, StageDefinition stage) + private Color4 getColourForLayout(int columnIndex, StageDefinition stage) { + // Account for cases like dual-stage (assume that all stages have the same column count for now). + columnIndex %= stage.Columns; + // For now, these are defined per column count as per https://user-images.githubusercontent.com/50823728/218038463-b450f46c-ef21-4551-b133-f866be59970c.png // See https://github.com/ppy/osu/discussions/21996 for discussion. switch (stage.Columns) @@ -122,7 +125,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon return colour_yellow; case 2: - switch (column) + switch (columnIndex) { case 0: return colour_green; @@ -132,7 +135,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon } case 3: - switch (column) + switch (columnIndex) { case 0: return colour_pink; @@ -144,7 +147,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon } case 4: - switch (column) + switch (columnIndex) { case 0: return colour_yellow; @@ -158,7 +161,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon } case 5: - switch (column) + switch (columnIndex) { case 0: return colour_pink; @@ -174,7 +177,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon } case 6: - switch (column) + switch (columnIndex) { case 0: return colour_pink; @@ -192,7 +195,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon } case 7: - switch (column) + switch (columnIndex) { case 0: return colour_pink; @@ -212,7 +215,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon } case 8: - switch (column) + switch (columnIndex) { case 0: return colour_purple; @@ -234,7 +237,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon } case 9: - switch (column) + switch (columnIndex) { case 0: return colour_purple; @@ -258,7 +261,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon } case 10: - switch (column) + switch (columnIndex) { case 0: return colour_purple; @@ -286,10 +289,10 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon // fallback for unhandled scenarios - if (stage.IsSpecialColumn(column)) + if (stage.IsSpecialColumn(columnIndex)) return colour_special_column; - switch (column % total_colours) + switch (columnIndex % total_colours) { case 0: return new Color4(255, 197, 40, 255); From 030742c64820fcaffb4dc58b06946489e165849c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 9 Mar 2023 19:02:15 +0900 Subject: [PATCH 2421/2991] Use different icon style on hold note heads --- .../Skinning/Argon/ArgonHoldNoteHeadPiece.cs | 19 +++++++++++++++ .../Skinning/Argon/ArgonNotePiece.cs | 24 +++++++++++-------- .../Argon/ManiaArgonSkinTransformer.cs | 2 ++ 3 files changed, 35 insertions(+), 10 deletions(-) create mode 100644 osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteHeadPiece.cs diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteHeadPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteHeadPiece.cs new file mode 100644 index 0000000000..16381a6dec --- /dev/null +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteHeadPiece.cs @@ -0,0 +1,19 @@ +// 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.Graphics; +using osu.Framework.Graphics.Shapes; +using osuTK; + +namespace osu.Game.Rulesets.Mania.Skinning.Argon +{ + internal partial class ArgonHoldNoteHeadPiece : ArgonNotePiece + { + protected override Drawable CreateIcon() => new Circle + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(20, 5), + }; + } +} diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonNotePiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonNotePiece.cs index 2a5bce255c..49d9cebc2e 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonNotePiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonNotePiece.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon CornerRadius = CORNER_RADIUS; Masking = true; - InternalChildren = new Drawable[] + InternalChildren = new[] { shadow = new Box { @@ -65,18 +65,22 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon RelativeSizeAxes = Axes.X, Height = CORNER_RADIUS * 2, }, - new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Y = 4, - Icon = FontAwesome.Solid.AngleDown, - Size = new Vector2(20), - Scale = new Vector2(1, 0.7f) - } + CreateIcon(), }; } + protected virtual Drawable CreateIcon() => new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Y = 4, + // TODO: replace with a non-squashed version. + // The 0.7f height scale should be removed. + Icon = FontAwesome.Solid.AngleDown, + Size = new Vector2(20), + Scale = new Vector2(1, 0.7f) + }; + [BackgroundDependencyLoader(true)] private void load(IScrollingInfo scrollingInfo, DrawableHitObject? drawableObject) { diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs index 057b7eb0d9..faf55c15fe 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs @@ -50,6 +50,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon return new ArgonHoldNoteTailPiece(); case ManiaSkinComponents.HoldNoteHead: + return new ArgonHoldNoteHeadPiece(); + case ManiaSkinComponents.Note: return new ArgonNotePiece(); From d806b85a30ca59d2515b29bc18b7362ae7931902 Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 8 Mar 2023 21:10:34 +0000 Subject: [PATCH 2422/2991] revert: make `counters` an `IEnumerable` again As suggested by bdach as this would make the last two commits useless Refs: 5d15426 --- osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs | 3 +-- .../Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs | 4 +--- osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs | 9 +++++---- osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs | 2 +- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index aeb7aa7dbe..42683a3eec 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -8,7 +8,6 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Framework.Timing; using osu.Game.Configuration; @@ -45,7 +44,7 @@ namespace osu.Game.Tests.Visual.Gameplay // best way to check without exposing. private Drawable hideTarget => hudOverlay.KeyCounter; - private FillFlowContainer keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType>().First(); + private Drawable keyCounterFlow => (Drawable)hudOverlay.KeyCounter.Counters; [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs index 808241729b..3eda80719a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs @@ -10,8 +10,6 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Testing; using osu.Framework.Timing; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -44,7 +42,7 @@ namespace osu.Game.Tests.Visual.Gameplay // best way to check without exposing. private Drawable hideTarget => hudOverlay.KeyCounter; - private FillFlowContainer keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType>().First(); + private Drawable keyCounterFlow => (Drawable)hudOverlay.KeyCounter.Counters; [Test] public void TestComboCounterIncrementing() diff --git a/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs index dce0be9cde..9499263474 100644 --- a/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.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.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osuTK.Graphics; @@ -12,9 +13,9 @@ namespace osu.Game.Screens.Play.HUD private const int duration = 100; private const double key_fade_time = 80; - private readonly FillFlowContainer keyFlow = new FillFlowContainer(); + private readonly FillFlowContainer keyFlow = new FillFlowContainer(); - public override Container Counters => keyFlow; + public override IEnumerable Counters => keyFlow; public DefaultKeyCounterDisplay() { @@ -58,7 +59,7 @@ namespace osu.Game.Screens.Play.HUD { keyDownTextColor = value; foreach (var child in keyFlow) - ((DefaultKeyCounter)child).KeyDownTextColor = value; + child.KeyDownTextColor = value; } } } @@ -74,7 +75,7 @@ namespace osu.Game.Screens.Play.HUD { keyUpTextColor = value; foreach (var child in keyFlow) - ((DefaultKeyCounter)child).KeyUpTextColor = value; + child.KeyUpTextColor = value; } } } diff --git a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs index 2c90d1474d..0e0f8a1190 100644 --- a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs @@ -29,7 +29,7 @@ namespace osu.Game.Screens.Play.HUD /// /// The s contained in this . /// - public abstract Container Counters { get; } + public abstract IEnumerable Counters { get; } /// /// Whether the actions reported by all s within this should be counted. From bfc0b946fbbdc0943b1a9c2d52df0382db261f97 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 9 Mar 2023 20:26:35 +0900 Subject: [PATCH 2423/2991] Remove additive blending from argon body piece --- osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldBodyPiece.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldBodyPiece.cs index 1f52f5f15f..39a030d621 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldBodyPiece.cs @@ -32,7 +32,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon // Without this, the width of the body will be slightly larger than the head/tail. Masking = true; CornerRadius = ArgonNotePiece.CORNER_RADIUS; - Blending = BlendingParameters.Additive; } [BackgroundDependencyLoader(true)] From ed3ff62e4f9b9042fccef2f05dd757cfa5c4e762 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 9 Mar 2023 20:26:48 +0900 Subject: [PATCH 2424/2991] Add note about why `bodyPiece` sizing is done as it is I think we're going to have to change this as it's quite limiting in what you can do with osu!mania skin implementation, but for now I want to leave a note as to why this is done, because each time I have to trial and error check what breaks when adjusting it. --- osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 25d0573a82..6e1c6cf80f 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -236,6 +236,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables }; // Position and resize the body to lie half-way under the head and the tail notes. + // The rationale for this is account for heads/tails with corner radius. bodyPiece.Y = (Direction.Value == ScrollingDirection.Up ? 1 : -1) * Head.Height / 2; bodyPiece.Height = DrawHeight - Head.Height / 2 + Tail.Height / 2; From 526eeedec2d81b10931235fd55637c184a08d108 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 9 Mar 2023 20:27:43 +0900 Subject: [PATCH 2425/2991] Adjust explosion and hit target to not include shadow portion in height calculation --- osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitExplosion.cs | 5 +++-- osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitTarget.cs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitExplosion.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitExplosion.cs index e32de6f3f3..8e27b4abd7 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitExplosion.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitExplosion.cs @@ -43,9 +43,10 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon { largeFaint = new Container { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, RelativeSizeAxes = Axes.Both, + Height = ArgonNotePiece.NOTE_ACCENT_RATIO, Masking = true, CornerRadius = ArgonNotePiece.CORNER_RADIUS, Blending = BlendingParameters.Additive, diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitTarget.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitTarget.cs index 4ffb4a435b..cf5931231c 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitTarget.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitTarget.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon private void load(IScrollingInfo scrollingInfo) { RelativeSizeAxes = Axes.X; - Height = ArgonNotePiece.NOTE_HEIGHT; + Height = ArgonNotePiece.NOTE_HEIGHT * ArgonNotePiece.NOTE_ACCENT_RATIO; Masking = true; CornerRadius = ArgonNotePiece.CORNER_RADIUS; From 2ad531f263ad20386e9ab57724c9a9e39c36d547 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 9 Mar 2023 20:27:58 +0900 Subject: [PATCH 2426/2991] Adjust argon note shadows and body to be closer in line with new design proposal --- .../Skinning/Argon/ArgonHoldNoteTailPiece.cs | 45 ++++++++++++------- .../Skinning/Argon/ArgonNotePiece.cs | 3 +- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs index 428439d52c..abfd9c4dc8 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs @@ -5,6 +5,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Objects.Drawables; @@ -19,7 +20,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon private readonly IBindable direction = new Bindable(); private readonly IBindable accentColour = new Bindable(); - private readonly Box shadeBackground; + private readonly Box shadow; private readonly Box shadeForeground; public ArgonHoldNoteTailPiece() @@ -27,30 +28,40 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon RelativeSizeAxes = Axes.X; Height = ArgonNotePiece.NOTE_HEIGHT; - CornerRadius = ArgonNotePiece.CORNER_RADIUS; - Masking = true; - InternalChildren = new Drawable[] { - shadeBackground = new Box - { - RelativeSizeAxes = Axes.Both, - }, new Container { - RelativeSizeAxes = Axes.Both, - Height = ArgonNotePiece.NOTE_ACCENT_RATIO, - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.X, + Height = ArgonNotePiece.NOTE_HEIGHT, CornerRadius = ArgonNotePiece.CORNER_RADIUS, Masking = true, Children = new Drawable[] { - shadeForeground = new Box + shadow = new Box { RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0), Colour4.Black), + // Avoid ugly single pixel overlap. + Height = 0.9f, }, - }, + new Container + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Height = ArgonNotePiece.NOTE_ACCENT_RATIO, + CornerRadius = ArgonNotePiece.CORNER_RADIUS, + Masking = true, + Children = new Drawable[] + { + shadeForeground = new Box + { + RelativeSizeAxes = Axes.Both, + }, + }, + }, + } }, }; } @@ -75,8 +86,10 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon private void onAccentChanged(ValueChangedEvent accent) { - shadeBackground.Colour = accent.NewValue.Darken(1.7f); - shadeForeground.Colour = accent.NewValue.Darken(1.1f); + shadeForeground.Colour = ColourInfo.GradientVertical( + accent.NewValue.Darken(0.2f), + accent.NewValue.Darken(1.2f) // matches body + ); } } } diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonNotePiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonNotePiece.cs index 49d9cebc2e..24ce22eccc 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonNotePiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonNotePiece.cs @@ -41,6 +41,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon shadow = new Box { RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0), Colour4.Black) }, new Container { @@ -109,8 +110,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon accent.NewValue.Lighten(0.1f), accent.NewValue ); - - shadow.Colour = accent.NewValue.Darken(0.5f); } } } From e12ab165b87adc0ed63b72b5de01d02de52cfcaa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 9 Mar 2023 20:42:59 +0900 Subject: [PATCH 2427/2991] Adjust colours a bit to make hold note bodies more accented --- .../Skinning/Argon/ArgonHoldBodyPiece.cs | 2 +- .../Skinning/Argon/ArgonHoldNoteTailPiece.cs | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldBodyPiece.cs index 39a030d621..91eda57c8f 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldBodyPiece.cs @@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon AccentColour.BindValueChanged(colour => { - background.Colour = colour.NewValue.Darken(1.2f); + background.Colour = colour.NewValue.Darken(0.6f); foreground.Colour = colour.NewValue.Opacity(0.2f); }, true); diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs index abfd9c4dc8..140c3d5ecc 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs @@ -21,7 +21,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon private readonly IBindable accentColour = new Bindable(); private readonly Box shadow; - private readonly Box shadeForeground; + private readonly Box foreground; + private readonly Box foregroundAdditive; public ArgonHoldNoteTailPiece() { @@ -55,10 +56,16 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon Masking = true, Children = new Drawable[] { - shadeForeground = new Box + foreground = new Box { RelativeSizeAxes = Axes.Both, }, + foregroundAdditive = new Box + { + RelativeSizeAxes = Axes.Both, + Blending = BlendingParameters.Additive, + Height = 0.5f, + }, }, }, } @@ -86,9 +93,11 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon private void onAccentChanged(ValueChangedEvent accent) { - shadeForeground.Colour = ColourInfo.GradientVertical( - accent.NewValue.Darken(0.2f), - accent.NewValue.Darken(1.2f) // matches body + foreground.Colour = accent.NewValue.Darken(0.6f); // matches body + + foregroundAdditive.Colour = ColourInfo.GradientVertical( + accent.NewValue.Opacity(0.4f), + accent.NewValue.Opacity(0) ); } } From 08b88ed6395835de3bede8d4e028aa42a4238b59 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 9 Mar 2023 20:43:42 +0900 Subject: [PATCH 2428/2991] Adjust hold note head icon to be more centered --- osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteHeadPiece.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteHeadPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteHeadPiece.cs index 16381a6dec..b9cc73c75c 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteHeadPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteHeadPiece.cs @@ -13,6 +13,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon { Anchor = Anchor.Centre, Origin = Anchor.Centre, + Y = 2, Size = new Vector2(20, 5), }; } From 5a1316f0e5eb0d7acd8c813e84849cef5c584dbb Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 9 Mar 2023 22:23:13 +0900 Subject: [PATCH 2429/2991] split save logic --- osu.Game/Overlays/Mods/EditPresetPopover.cs | 8 ++------ osu.Game/Overlays/Mods/ModPresetPanel.cs | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs index 4eaf5e19db..32d4aeae76 100644 --- a/osu.Game/Overlays/Mods/EditPresetPopover.cs +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions; @@ -108,13 +107,10 @@ namespace osu.Game.Overlays.Mods private void trySaveCurrentMod() { - if (button.Active.Value || !selectedMods.Value.Any()) + if (button.SaveCurrentMod()) return; - button.Preset.PerformWrite(s => - { - s.Mods = selectedMods.Value.ToArray(); - }); + Body.Shake(); } protected override void LoadComplete() diff --git a/osu.Game/Overlays/Mods/ModPresetPanel.cs b/osu.Game/Overlays/Mods/ModPresetPanel.cs index f4f1af50df..f861245007 100644 --- a/osu.Game/Overlays/Mods/ModPresetPanel.cs +++ b/osu.Game/Overlays/Mods/ModPresetPanel.cs @@ -98,6 +98,20 @@ namespace osu.Game.Overlays.Mods #endregion + public bool SaveCurrentMod() + { + if (!checkCurrentModCanBeSave()) + return false; + + Preset.PerformWrite(s => + { + s.Mods = selectedMods.Value.ToArray(); + }); + return true; + } + + private bool checkCurrentModCanBeSave() => (!Active.Value && selectedMods.Value.Any()); + protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); From 3d746e8dfbb6cfbd7a08a480eda3d56a3262ed67 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 9 Mar 2023 22:43:11 +0900 Subject: [PATCH 2430/2991] content Menu --- osu.Game/Overlays/Mods/ModPresetPanel.cs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModPresetPanel.cs b/osu.Game/Overlays/Mods/ModPresetPanel.cs index f861245007..f3fb5b5bb0 100644 --- a/osu.Game/Overlays/Mods/ModPresetPanel.cs +++ b/osu.Game/Overlays/Mods/ModPresetPanel.cs @@ -90,11 +90,24 @@ namespace osu.Game.Overlays.Mods #region IHasContextMenu - public MenuItem[] ContextMenuItems => new MenuItem[] + public MenuItem[] ContextMenuItems { - new OsuMenuItem(CommonStrings.ButtonsEdit, MenuItemType.Highlighted, this.ShowPopover), - new OsuMenuItem(CommonStrings.ButtonsDelete, MenuItemType.Destructive, () => dialogOverlay?.Push(new DeleteModPresetDialog(Preset))), - }; + get + { + var menu = new List + { + new OsuMenuItem(CommonStrings.ButtonsEdit, MenuItemType.Highlighted, this.ShowPopover), + new OsuMenuItem(CommonStrings.ButtonsDelete, MenuItemType.Destructive, () => dialogOverlay?.Push(new DeleteModPresetDialog(Preset))), + }; + + if (checkCurrentModCanBeSave()) + { + menu.Insert(1, new OsuMenuItem("Use Current Mods", MenuItemType.Destructive, () => SaveCurrentMod())); + } + + return menu.ToArray(); + } + } #endregion From d009cd8422780247f035bb586851790bac37f6b5 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 9 Mar 2023 22:45:33 +0900 Subject: [PATCH 2431/2991] test --- .../UserInterface/TestSceneModPresetColumn.cs | 73 ++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs index d6065374ac..b67f67db2b 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs @@ -327,6 +327,32 @@ namespace osu.Game.Tests.Visual.UserInterface }); AddUntilStep("items loaded", () => modPresetColumn.IsLoaded && modPresetColumn.ItemsLoaded); + + AddStep("right click first panel", () => + { + var panel = this.ChildrenOfType().First(); + InputManager.MoveMouseTo(panel); + InputManager.Click(MouseButton.Right); + }); + AddUntilStep("wait for context menu", () => this.ChildrenOfType().Any()); + AddStep("click edit", () => + { + var editItem = this.ChildrenOfType().ElementAt(0); + InputManager.MoveMouseTo(editItem); + InputManager.Click(MouseButton.Left); + }); + + OsuPopover? popover = null; + AddUntilStep("wait for popover", () => (popover = this.ChildrenOfType().FirstOrDefault()) != null); + AddStep("click use current mods", () => + { + InputManager.MoveMouseTo(popover.ChildrenOfType().ElementAt(0)); + InputManager.Click(MouseButton.Left); + }); + AddWaitStep("wait some", 3); + AddUntilStep("popover not closed", () => this.ChildrenOfType().Any()); + AddAssert("present mod not changed", () => this.ChildrenOfType().First().Preset.Value.Mods.Count == 1); + AddStep("select mods", () => SelectedMods.Value = mods); AddStep("right click first panel", () => { @@ -343,14 +369,57 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.Click(MouseButton.Left); }); - OsuPopover? popover = null; AddUntilStep("wait for popover", () => (popover = this.ChildrenOfType().FirstOrDefault()) != null); AddStep("click use current mods", () => { InputManager.MoveMouseTo(popover.ChildrenOfType().ElementAt(0)); InputManager.Click(MouseButton.Left); }); - AddUntilStep("popover not closed", () => this.ChildrenOfType().Any()); + AddWaitStep("wait some", 3); + AddUntilStep("popover closed", () => !this.ChildrenOfType().Any()); + AddAssert("present mod is changed", () => this.ChildrenOfType().First().Preset.Value.Mods.Count == 2); + } + + [Test] + public void TestEditPresetModInContextMenu() + { + ModPresetColumn modPresetColumn = null!; + var mods = new Mod[] { new OsuModHidden(), new OsuModHardRock() }; + + AddStep("clear mods", () => SelectedMods.Value = Array.Empty()); + AddStep("create content", () => Child = modPresetColumn = new ModPresetColumn + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + + AddUntilStep("items loaded", () => modPresetColumn.IsLoaded && modPresetColumn.ItemsLoaded); + + AddStep("right click first panel", () => + { + var panel = this.ChildrenOfType().First(); + InputManager.MoveMouseTo(panel); + InputManager.Click(MouseButton.Right); + }); + AddUntilStep("wait for context menu", () => this.ChildrenOfType().Any()); + AddAssert("No Use Current Mods", () => this.ChildrenOfType().Count() == 2); + + AddStep("select mods", () => SelectedMods.Value = mods); + AddStep("right click first panel", () => + { + var panel = this.ChildrenOfType().First(); + InputManager.MoveMouseTo(panel); + InputManager.Click(MouseButton.Right); + }); + + AddUntilStep("wait for context menu", () => this.ChildrenOfType().Any()); + AddAssert("Have Use Current Mods", () => this.ChildrenOfType().Count() == 3); + AddStep("Click Use Current Mods", () => + { + var editItem = this.ChildrenOfType().ElementAt(1); + InputManager.MoveMouseTo(editItem); + InputManager.Click(MouseButton.Left); + }); AddAssert("present mod is changed", () => this.ChildrenOfType().First().Preset.Value.Mods.Count == 2); } From ca416175bb6e168c3c8fa469b296d059a8991541 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 9 Mar 2023 22:58:44 +0900 Subject: [PATCH 2432/2991] remove useless property --- osu.Game/Overlays/Mods/EditPresetPopover.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs index 32d4aeae76..3043f4a544 100644 --- a/osu.Game/Overlays/Mods/EditPresetPopover.cs +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -26,9 +26,6 @@ namespace osu.Game.Overlays.Mods private readonly ShearedButton useCurrentModButton; private readonly ShearedButton createButton; - [Resolved] - private Bindable> selectedMods { get; set; } = null!; - private readonly ModPreset preset; public EditPresetPopover(ModPresetPanel modPresetPanel) From f4e262040275e4466f4e43def09980a6a1b6d432 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Fri, 10 Mar 2023 00:56:22 +0900 Subject: [PATCH 2433/2991] fix test --- .../UserInterface/TestSceneModPresetColumn.cs | 22 +++++++++++-------- osu.Game/Overlays/Mods/EditPresetPopover.cs | 2 -- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs index b67f67db2b..eaa3664623 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs @@ -266,6 +266,7 @@ namespace osu.Game.Tests.Visual.UserInterface { ModPresetColumn modPresetColumn = null!; string presetName = null!; + ModPresetPanel panel = null!; AddStep("clear mods", () => SelectedMods.Value = Array.Empty()); AddStep("create content", () => Child = modPresetColumn = new ModPresetColumn @@ -277,7 +278,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddUntilStep("items loaded", () => modPresetColumn.IsLoaded && modPresetColumn.ItemsLoaded); AddStep("right click first panel", () => { - var panel = this.ChildrenOfType().First(); + panel = this.ChildrenOfType().First(); presetName = panel.Preset.Value.Name; InputManager.MoveMouseTo(panel); InputManager.Click(MouseButton.Right); @@ -301,7 +302,7 @@ namespace osu.Game.Tests.Visual.UserInterface }); AddWaitStep("wait some", 3); - AddAssert("present is not changed", () => this.ChildrenOfType().First().Preset.Value.Name == presetName); + AddAssert("present is not changed", () => panel.Preset.Value.Name == presetName); AddUntilStep("popover is unchanged", () => this.ChildrenOfType().FirstOrDefault() == popover); AddStep("edit preset name", () => popover.ChildrenOfType().First().Current.Value = "something new"); AddStep("attempt preset edit", () => @@ -310,7 +311,7 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.Click(MouseButton.Left); }); AddUntilStep("popover closed", () => !this.ChildrenOfType().Any()); - AddAssert("present is changed", () => this.ChildrenOfType().First().Preset.Value.Name != presetName); + AddAssert("present is changed", () => panel.Preset.Value.Name != presetName); } [Test] @@ -351,7 +352,8 @@ namespace osu.Game.Tests.Visual.UserInterface }); AddWaitStep("wait some", 3); AddUntilStep("popover not closed", () => this.ChildrenOfType().Any()); - AddAssert("present mod not changed", () => this.ChildrenOfType().First().Preset.Value.Mods.Count == 1); + AddAssert("present mod not changed", () => + !new HashSet(this.ChildrenOfType().First().Preset.Value.Mods).SetEquals(mods)); AddStep("select mods", () => SelectedMods.Value = mods); AddStep("right click first panel", () => @@ -377,14 +379,15 @@ namespace osu.Game.Tests.Visual.UserInterface }); AddWaitStep("wait some", 3); AddUntilStep("popover closed", () => !this.ChildrenOfType().Any()); - AddAssert("present mod is changed", () => this.ChildrenOfType().First().Preset.Value.Mods.Count == 2); + AddAssert("present mod is changed", () => + new HashSet(this.ChildrenOfType().First().Preset.Value.Mods).SetEquals(mods)); } [Test] public void TestEditPresetModInContextMenu() { ModPresetColumn modPresetColumn = null!; - var mods = new Mod[] { new OsuModHidden(), new OsuModHardRock() }; + var mods = new Mod[] { new OsuModHidden() }; AddStep("clear mods", () => SelectedMods.Value = Array.Empty()); AddStep("create content", () => Child = modPresetColumn = new ModPresetColumn @@ -405,9 +408,9 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("No Use Current Mods", () => this.ChildrenOfType().Count() == 2); AddStep("select mods", () => SelectedMods.Value = mods); - AddStep("right click first panel", () => + AddStep("right click second panel", () => { - var panel = this.ChildrenOfType().First(); + var panel = this.ChildrenOfType().ElementAt(1); InputManager.MoveMouseTo(panel); InputManager.Click(MouseButton.Right); }); @@ -420,7 +423,8 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.MoveMouseTo(editItem); InputManager.Click(MouseButton.Left); }); - AddAssert("present mod is changed", () => this.ChildrenOfType().First().Preset.Value.Mods.Count == 2); + AddAssert("present mod is changed", () => + new HashSet(this.ChildrenOfType().ElementAt(1).Preset.Value.Mods).SetEquals(mods)); } private ICollection createTestPresets() => new[] diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs index 3043f4a544..a5c562914b 100644 --- a/osu.Game/Overlays/Mods/EditPresetPopover.cs +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -1,9 +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.Collections.Generic; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; From 6b2a70b1126b3fc07a97f02ca35d4c7536ff4e57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 9 Mar 2023 19:14:08 +0100 Subject: [PATCH 2434/2991] Remove unused fields --- .../Skinning/Argon/ArgonHoldNoteTailPiece.cs | 3 +-- osu.Game.Rulesets.Mania/Skinning/Argon/ArgonNotePiece.cs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs index 140c3d5ecc..085e0630fb 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs @@ -20,7 +20,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon private readonly IBindable direction = new Bindable(); private readonly IBindable accentColour = new Bindable(); - private readonly Box shadow; private readonly Box foreground; private readonly Box foregroundAdditive; @@ -39,7 +38,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon Masking = true, Children = new Drawable[] { - shadow = new Box + new Box { RelativeSizeAxes = Axes.Both, Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0), Colour4.Black), diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonNotePiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonNotePiece.cs index 24ce22eccc..3a519283f1 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonNotePiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonNotePiece.cs @@ -26,7 +26,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon private readonly IBindable accentColour = new Bindable(); private readonly Box colouredBox; - private readonly Box shadow; public ArgonNotePiece() { @@ -38,7 +37,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon InternalChildren = new[] { - shadow = new Box + new Box { RelativeSizeAxes = Axes.Both, Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0), Colour4.Black) From b51c41a8043ae04fdc57aad461beb9f74b2320b5 Mon Sep 17 00:00:00 2001 From: Terochi Date: Thu, 9 Mar 2023 20:14:58 +0100 Subject: [PATCH 2435/2991] Addressed changes --- osu.Game.Tests/Mods/ModSettingsTest.cs | 92 ++++++++++++++++++-------- osu.Game/Rulesets/Mods/Mod.cs | 69 ++++++++++++------- 2 files changed, 109 insertions(+), 52 deletions(-) diff --git a/osu.Game.Tests/Mods/ModSettingsTest.cs b/osu.Game.Tests/Mods/ModSettingsTest.cs index 45e162df1a..e2e050870e 100644 --- a/osu.Game.Tests/Mods/ModSettingsTest.cs +++ b/osu.Game.Tests/Mods/ModSettingsTest.cs @@ -14,7 +14,7 @@ namespace osu.Game.Tests.Mods public class ModSettingsTest { [Test] - public void TestModSettingsUnboundWhenCopied() + public void TestModSettingsUnboundWhenCloned() { var original = new OsuModDoubleTime(); var copy = (OsuModDoubleTime)original.DeepClone(); @@ -26,7 +26,7 @@ namespace osu.Game.Tests.Mods } [Test] - public void TestMultiModSettingsUnboundWhenCopied() + public void TestMultiModSettingsUnboundWhenCloned() { var original = new MultiMod(new OsuModDoubleTime()); var copy = (MultiMod)original.DeepClone(); @@ -54,6 +54,42 @@ namespace osu.Game.Tests.Mods Assert.That(modBool.TestSetting.Value, Is.EqualTo(!modBool.TestSetting.Default)); } + [Test] + public void TestDefaultValueKeptWhenCopied() + { + var modBoolTrue = new TestNonMatchingSettingTypeModBool { TestSetting = { Default = true, Value = false } }; + var modBoolFalse = new TestNonMatchingSettingTypeModBool { TestSetting = { Default = false, Value = true } }; + + modBoolFalse.CopySharedSettings(modBoolTrue); + + Assert.That(modBoolFalse.TestSetting.Default, Is.EqualTo(false)); + Assert.That(modBoolFalse.TestSetting.Value, Is.EqualTo(modBoolTrue.TestSetting.Value)); + } + + [Test] + public void TestValueResetsToDefaultWhenCopied() + { + var modDouble = new TestNonMatchingSettingTypeModDouble(); + var modInt = new TestNonMatchingSettingTypeModInt { TestSetting = { Value = 1 } }; + + modInt.CopySharedSettings(modDouble); + + Assert.That(modInt.TestSetting.Value, Is.EqualTo(modInt.TestSetting.Default)); + } + + [Test] + public void TestRelativelyScaleWithClampedRangeWhenCopied() + { + const double setting_change = 50.4; + + var modDouble100 = new TestNonMatchingSettingTypeModDouble { TestSetting = { MaxValue = 100, MinValue = 0, Value = setting_change } }; + var modDouble200 = new TestNonMatchingSettingTypeModDouble { TestSetting = { MaxValue = 200, MinValue = 0 } }; + + modDouble200.CopySharedSettings(modDouble100); + + Assert.That(modDouble200.TestSetting.Value, Is.EqualTo(setting_change * 2)); + } + [Test] public void TestCopyDoubleToIntWithDefaultRange() { @@ -64,7 +100,32 @@ namespace osu.Game.Tests.Mods modInt.CopySharedSettings(modDouble); - Assert.That(modInt.TestSetting.Value, Is.EqualTo((int)setting_change)); + Assert.That(modInt.TestSetting.Value, Is.EqualTo(Convert.ToInt32(setting_change))); + } + + [Test] + public void TestCopyDoubleToIntWithOutOfBoundsRange() + { + const double setting_change = 50.4; + + var modDouble = new TestNonMatchingSettingTypeModDouble { TestSetting = { MinValue = int.MinValue - 1d, Value = setting_change } }; + // make RangeConstrainedBindable.HasDefinedRange return true + var modInt = new TestNonMatchingSettingTypeModInt { TestSetting = { MinValue = int.MinValue + 1 } }; + + modInt.CopySharedSettings(modDouble); + + Assert.That(modInt.TestSetting.Value, Is.EqualTo(Convert.ToInt32(setting_change))); + } + + [Test] + public void TestCopyDoubleToIntWithOutOfBoundsValue() + { + var modDouble = new TestNonMatchingSettingTypeModDouble { TestSetting = { MinValue = int.MinValue + 1, Value = int.MaxValue + 1d } }; + var modInt = new TestNonMatchingSettingTypeModInt { TestSetting = { MinValue = int.MinValue + 1 } }; + + modInt.CopySharedSettings(modDouble); + + Assert.That(modInt.TestSetting.Value, Is.EqualTo(int.MaxValue)); } [Test] @@ -80,31 +141,6 @@ namespace osu.Game.Tests.Mods Assert.That(modDouble.TestSetting.Value, Is.EqualTo(setting_change)); } - [Test] - public void TestCopyDoubleToIntWithClampedRange() - { - const double setting_change = 50.4; - - var modDouble = new TestNonMatchingSettingTypeModDouble { TestSetting = { MaxValue = 100, MinValue = 0, Value = setting_change } }; - var modInt = new TestNonMatchingSettingTypeModInt { TestSetting = { MaxValue = 200, MinValue = 0 } }; - - modInt.CopySharedSettings(modDouble); - - Assert.That(modInt.TestSetting.Value, Is.EqualTo(Convert.ToInt32(setting_change * 2))); - } - - [Test] - public void TestDefaultValueKeptWhenCopied() - { - var modBoolTrue = new TestNonMatchingSettingTypeModBool { TestSetting = { Default = true, Value = false } }; - var modBoolFalse = new TestNonMatchingSettingTypeModBool { TestSetting = { Default = false, Value = true } }; - - modBoolFalse.CopySharedSettings(modBoolTrue); - - Assert.That(modBoolFalse.TestSetting.Default, Is.EqualTo(false)); - Assert.That(modBoolFalse.TestSetting.Value, Is.EqualTo(modBoolTrue.TestSetting.Value)); - } - private class TestNonMatchingSettingTypeModDouble : TestNonMatchingSettingTypeMod { public override string Acronym => "NMD"; diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index e630a53045..85014d555d 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -169,28 +169,31 @@ namespace osu.Game.Rulesets.Mods const string max_value = nameof(BindableNumber.MaxValue); const string value = nameof(Bindable.Value); - Dictionary oldSettings = new Dictionary(); + Dictionary sourceSettings = new Dictionary(); - foreach (var (_, property) in source.GetSettingsSourceProperties()) + foreach (var (_, sourceProperty) in source.GetSettingsSourceProperties()) { - oldSettings.Add(property.Name.ToSnakeCase(), property.GetValue(source)!); + sourceSettings.Add(sourceProperty.Name.ToSnakeCase(), sourceProperty.GetValue(source)!); } - foreach (var (_, property) in this.GetSettingsSourceProperties()) + foreach (var (_, targetProperty) in this.GetSettingsSourceProperties()) { - object targetSetting = property.GetValue(this)!; + object targetSetting = targetProperty.GetValue(this)!; - if (!oldSettings.TryGetValue(property.Name.ToSnakeCase(), out object? sourceSetting)) + if (!sourceSettings.TryGetValue(targetProperty.Name.ToSnakeCase(), out object? sourceSetting)) continue; if (((IBindable)sourceSetting).IsDefault) - // keep at default value if the source is default + { + // reset to default value if the source is default + targetSetting.GetType().GetMethod(nameof(Bindable.SetDefault))!.Invoke(targetSetting, null); continue; + } - Type? targetType = getGenericBaseType(targetSetting, typeof(BindableNumber<>)); - Type? sourceType = getGenericBaseType(sourceSetting, typeof(BindableNumber<>)); + Type? targetBindableNumberType = getGenericBaseType(targetSetting, typeof(BindableNumber<>)); + Type? sourceBindableNumberType = getGenericBaseType(sourceSetting, typeof(BindableNumber<>)); - if (targetType == null || sourceType == null) + if (targetBindableNumberType == null || sourceBindableNumberType == null) { if (getGenericBaseType(targetSetting, typeof(Bindable<>))!.GenericTypeArguments.Single() == getGenericBaseType(sourceSetting, typeof(Bindable<>))!.GenericTypeArguments.Single()) @@ -202,8 +205,16 @@ namespace osu.Game.Rulesets.Mods continue; } - Type targetGenericType = targetType.GenericTypeArguments.Single(); - Type sourceGenericType = sourceType.GenericTypeArguments.Single(); + bool rangeOutOfBounds = false; + + Type targetGenericType = targetBindableNumberType.GenericTypeArguments.Single(); + Type sourceGenericType = sourceBindableNumberType.GenericTypeArguments.Single(); + + if (!Convert.ToBoolean(getValue(targetSetting, nameof(RangeConstrainedBindable.HasDefinedRange))) || + !Convert.ToBoolean(getValue(sourceSetting, nameof(RangeConstrainedBindable.HasDefinedRange)))) + // check if we have a range to rescale from and a range to rescale to + // if not, copy the raw value + rangeOutOfBounds = true; double allowedMin = Math.Max( Convert.ToDouble(targetGenericType.GetField("MinValue")!.GetValue(null)), @@ -219,25 +230,35 @@ namespace osu.Game.Rulesets.Mods double targetMax = getValueDouble(targetSetting, max_value); double sourceMin = getValueDouble(sourceSetting, min_value); double sourceMax = getValueDouble(sourceSetting, max_value); - double sourceValue = getValueDouble(sourceSetting, value); + double sourceValue = Math.Clamp(getValueDouble(sourceSetting, value), allowedMin, allowedMax); - // convert value to same ratio - double targetValue = (sourceValue - sourceMin) / (sourceMax - sourceMin) * (targetMax - targetMin) + targetMin; + double targetValue = rangeOutOfBounds + // keep raw value + ? sourceValue + // convert value to same ratio + : (sourceValue - sourceMin) / (sourceMax - sourceMin) * (targetMax - targetMin) + targetMin; - setValue(targetSetting, value, Convert.ChangeType(targetValue, targetType.GenericTypeArguments.Single())); + setValue(targetSetting, value, Convert.ChangeType(targetValue, targetBindableNumberType.GenericTypeArguments.Single())); - double getValueDouble(object target, string name) => - Math.Clamp(Convert.ToDouble(getValue(target, name)!), allowedMin, allowedMax); + double getValueDouble(object setting, string name) + { + double settingValue = Convert.ToDouble(getValue(setting, name)!); + + if (settingValue < allowedMin || settingValue > allowedMax) + rangeOutOfBounds = true; + + return settingValue; + } } - object? getValue(object target, string name) => - target.GetType().GetProperty(name)!.GetValue(target); + object? getValue(object setting, string name) => + setting.GetType().GetProperty(name)!.GetValue(setting); - void setValue(object target, string name, object? newValue) => - target.GetType().GetProperty(name)!.SetValue(target, newValue); + void setValue(object setting, string name, object? newValue) => + setting.GetType().GetProperty(name)!.SetValue(setting, newValue); - Type? getGenericBaseType(object target, Type genericType) => - target.GetType().GetTypeInheritance().FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == genericType); + Type? getGenericBaseType(object setting, Type genericType) => + setting.GetType().GetTypeInheritance().FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == genericType); } /// From 8b0f127ff2a652cb2d8381d4c500c6cd040b878e Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sat, 11 Mar 2023 11:25:52 +0900 Subject: [PATCH 2436/2991] split ModPresetRow --- osu.Game/Overlays/Mods/ModPresetRow.cs | 64 ++++++++++++++++++++++ osu.Game/Overlays/Mods/ModPresetTooltip.cs | 54 ------------------ 2 files changed, 64 insertions(+), 54 deletions(-) create mode 100644 osu.Game/Overlays/Mods/ModPresetRow.cs diff --git a/osu.Game/Overlays/Mods/ModPresetRow.cs b/osu.Game/Overlays/Mods/ModPresetRow.cs new file mode 100644 index 0000000000..4829e93b87 --- /dev/null +++ b/osu.Game/Overlays/Mods/ModPresetRow.cs @@ -0,0 +1,64 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.UI; +using osuTK; + +namespace osu.Game.Overlays.Mods +{ + public partial class ModPresetRow : FillFlowContainer + { + public ModPresetRow(Mod mod) + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Direction = FillDirection.Vertical; + Spacing = new Vector2(4); + InternalChildren = new Drawable[] + { + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(7), + Children = new Drawable[] + { + new ModSwitchTiny(mod) + { + Active = { Value = true }, + Scale = new Vector2(0.6f), + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft + }, + new OsuSpriteText + { + Text = mod.Name, + Font = OsuFont.Default.With(size: 16, weight: FontWeight.SemiBold), + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + Margin = new MarginPadding { Bottom = 2 } + } + } + } + }; + + if (!string.IsNullOrEmpty(mod.SettingDescription)) + { + AddInternal(new OsuTextFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Left = 14 }, + Text = mod.SettingDescription + }); + } + } + } +} diff --git a/osu.Game/Overlays/Mods/ModPresetTooltip.cs b/osu.Game/Overlays/Mods/ModPresetTooltip.cs index ff4f00da69..8e8259de45 100644 --- a/osu.Game/Overlays/Mods/ModPresetTooltip.cs +++ b/osu.Game/Overlays/Mods/ModPresetTooltip.cs @@ -6,11 +6,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.UI; using osuTK; namespace osu.Game.Overlays.Mods @@ -61,55 +57,5 @@ namespace osu.Game.Overlays.Mods protected override void PopOut() => this.FadeOut(transition_duration, Easing.OutQuint); public void Move(Vector2 pos) => Position = pos; - - private partial class ModPresetRow : FillFlowContainer - { - public ModPresetRow(Mod mod) - { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - Direction = FillDirection.Vertical; - Spacing = new Vector2(4); - InternalChildren = new Drawable[] - { - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(7), - Children = new Drawable[] - { - new ModSwitchTiny(mod) - { - Active = { Value = true }, - Scale = new Vector2(0.6f), - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft - }, - new OsuSpriteText - { - Text = mod.Name, - Font = OsuFont.Default.With(size: 16, weight: FontWeight.SemiBold), - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - Margin = new MarginPadding { Bottom = 2 } - } - } - } - }; - - if (!string.IsNullOrEmpty(mod.SettingDescription)) - { - AddInternal(new OsuTextFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Left = 14 }, - Text = mod.SettingDescription - }); - } - } - } } } From 1cd565193e3a546e0e6d8e603e4eebc09688a0fd Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sat, 11 Mar 2023 11:39:35 +0900 Subject: [PATCH 2437/2991] public CheckCurrentModCanBeSave --- osu.Game/Overlays/Mods/ModPresetPanel.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModPresetPanel.cs b/osu.Game/Overlays/Mods/ModPresetPanel.cs index f3fb5b5bb0..d01981d18c 100644 --- a/osu.Game/Overlays/Mods/ModPresetPanel.cs +++ b/osu.Game/Overlays/Mods/ModPresetPanel.cs @@ -100,7 +100,7 @@ namespace osu.Game.Overlays.Mods new OsuMenuItem(CommonStrings.ButtonsDelete, MenuItemType.Destructive, () => dialogOverlay?.Push(new DeleteModPresetDialog(Preset))), }; - if (checkCurrentModCanBeSave()) + if (CheckCurrentModCanBeSave()) { menu.Insert(1, new OsuMenuItem("Use Current Mods", MenuItemType.Destructive, () => SaveCurrentMod())); } @@ -113,7 +113,7 @@ namespace osu.Game.Overlays.Mods public bool SaveCurrentMod() { - if (!checkCurrentModCanBeSave()) + if (!CheckCurrentModCanBeSave()) return false; Preset.PerformWrite(s => @@ -123,7 +123,7 @@ namespace osu.Game.Overlays.Mods return true; } - private bool checkCurrentModCanBeSave() => (!Active.Value && selectedMods.Value.Any()); + public bool CheckCurrentModCanBeSave() => (!Active.Value && selectedMods.Value.Any()); protected override void Dispose(bool isDisposing) { From 15f11bb1e8ff7ea4d5ed8defa45ea0069fbd303f Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sat, 11 Mar 2023 12:31:33 +0900 Subject: [PATCH 2438/2991] scorll container and save mod after popover hidden Requires manual handling of many visual effects --- .../UserInterface/TestSceneModPresetColumn.cs | 12 ++- osu.Game/Overlays/Mods/EditPresetPopover.cs | 76 +++++++++++++++++-- osu.Game/Overlays/Mods/ModPresetPanel.cs | 12 ++- osu.Game/Overlays/Mods/ModPresetTooltip.cs | 13 ++-- 4 files changed, 95 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs index eaa3664623..68efb2a5f4 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs @@ -353,7 +353,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddWaitStep("wait some", 3); AddUntilStep("popover not closed", () => this.ChildrenOfType().Any()); AddAssert("present mod not changed", () => - !new HashSet(this.ChildrenOfType().First().Preset.Value.Mods).SetEquals(mods)); + !new HashSet(this.ChildrenOfType().First().Mods.Value).SetEquals(mods)); AddStep("select mods", () => SelectedMods.Value = mods); AddStep("right click first panel", () => @@ -378,8 +378,16 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.Click(MouseButton.Left); }); AddWaitStep("wait some", 3); - AddUntilStep("popover closed", () => !this.ChildrenOfType().Any()); + AddUntilStep("popover not closed", () => this.ChildrenOfType().Any()); AddAssert("present mod is changed", () => + new HashSet(this.ChildrenOfType().First().Mods.Value).SetEquals(mods)); + + AddStep("click edit", () => + { + InputManager.MoveMouseTo(popover.ChildrenOfType().ElementAt(1)); + InputManager.Click(MouseButton.Left); + }); + AddAssert("present mod in realm is changed", () => new HashSet(this.ChildrenOfType().First().Preset.Value.Mods).SetEquals(mods)); } diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs index a5c562914b..92860e96a6 100644 --- a/osu.Game/Overlays/Mods/EditPresetPopover.cs +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -1,12 +1,16 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Extensions; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Localisation; @@ -23,8 +27,19 @@ namespace osu.Game.Overlays.Mods private readonly LabelledTextBox descriptionTextBox; private readonly ShearedButton useCurrentModButton; private readonly ShearedButton createButton; + private readonly FillFlowContainer scrollContent; private readonly ModPreset preset; + private List saveModAfterClosed = new List(); + + [Resolved] + private Bindable> selectedMods { get; set; } = null!; + + [Resolved] + private OsuColour colours { get; set; } = null!; + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } = null!; public EditPresetPopover(ModPresetPanel modPresetPanel) { @@ -53,6 +68,19 @@ namespace osu.Game.Overlays.Mods Label = CommonStrings.Description, TabbableContentContainer = this }, + new OsuScrollContainer + { + RelativeSizeAxes = Axes.X, + Height = 100, + Padding = new MarginPadding(7), + Child = scrollContent = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding(7), + Spacing = new Vector2(7), + } + }, new FillFlowContainer { Anchor = Anchor.TopCentre, @@ -83,7 +111,7 @@ namespace osu.Game.Overlays.Mods } [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider, OsuColour colours) + private void load() { Body.BorderThickness = 3; Body.BorderColour = colours.Orange1; @@ -95,17 +123,40 @@ namespace osu.Game.Overlays.Mods createButton.LighterColour = colours.Orange0; createButton.TextColour = colourProvider.Background6; - useCurrentModButton.DarkerColour = colours.Blue1; - useCurrentModButton.LighterColour = colours.Blue0; - useCurrentModButton.TextColour = colourProvider.Background6; + selectedMods.BindValueChanged(_ => updateActiveState(), true); + + scrollContent.ChildrenEnumerable = preset.Mods.Select(mod => new ModPresetRow(mod)); } private void trySaveCurrentMod() { - if (button.SaveCurrentMod()) + if (!button.CheckCurrentModCanBeSave()) + { + Body.Shake(); return; + } - Body.Shake(); + saveModAfterClosed = selectedMods.Value.ToList(); + scrollContent.Clear(); + scrollContent.ChildrenEnumerable = saveModAfterClosed.Select(mod => new ModPresetRow(mod)); + button.Mods.Value = saveModAfterClosed; + updateActiveState(); + } + + private void updateActiveState() + { + if (button.CheckCurrentModCanBeSave()) + { + useCurrentModButton.DarkerColour = colours.Blue1; + useCurrentModButton.LighterColour = colours.Blue0; + useCurrentModButton.TextColour = colourProvider.Background6; + } + else + { + useCurrentModButton.DarkerColour = colours.Blue3; + useCurrentModButton.LighterColour = colours.Blue4; + useCurrentModButton.TextColour = colourProvider.Background2; + } } protected override void LoadComplete() @@ -131,5 +182,18 @@ namespace osu.Game.Overlays.Mods this.HidePopover(); } + + protected override void UpdateState(ValueChangedEvent state) + { + base.UpdateState(state); + + if (state.NewValue == Visibility.Hidden && saveModAfterClosed.Any()) + { + button.Preset.PerformWrite(s => + { + s.Mods = saveModAfterClosed; + }); + } + } } } diff --git a/osu.Game/Overlays/Mods/ModPresetPanel.cs b/osu.Game/Overlays/Mods/ModPresetPanel.cs index d01981d18c..49437c5bb1 100644 --- a/osu.Game/Overlays/Mods/ModPresetPanel.cs +++ b/osu.Game/Overlays/Mods/ModPresetPanel.cs @@ -18,10 +18,12 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Overlays.Mods { - public partial class ModPresetPanel : ModSelectPanel, IHasCustomTooltip, IHasContextMenu, IHasPopover + public partial class ModPresetPanel : ModSelectPanel, IHasCustomTooltip>, IHasContextMenu, IHasPopover { public readonly Live Preset; + public readonly Bindable> Mods = new Bindable>(); + public override BindableBool Active { get; } = new BindableBool(); [Resolved] @@ -35,6 +37,7 @@ namespace osu.Game.Overlays.Mods public ModPresetPanel(Live preset) { Preset = preset; + Mods.Value = preset.Value.Mods.ToList(); Title = preset.Value.Name; Description = preset.Value.Description; @@ -51,6 +54,7 @@ namespace osu.Game.Overlays.Mods base.LoadComplete(); selectedMods.BindValueChanged(_ => selectedModsChanged(), true); + Mods.BindValueChanged(_ => updateActiveState(), true); } protected override void Select() @@ -78,13 +82,13 @@ namespace osu.Game.Overlays.Mods private void updateActiveState() { - Active.Value = new HashSet(Preset.Value.Mods).SetEquals(selectedMods.Value); + Active.Value = new HashSet(Mods.Value).SetEquals(selectedMods.Value); } #region IHasCustomTooltip - public ModPreset TooltipContent => Preset.Value; - public ITooltip GetCustomTooltip() => new ModPresetTooltip(ColourProvider); + public List TooltipContent => Mods.Value; + public ITooltip> GetCustomTooltip() => new ModPresetTooltip(ColourProvider); #endregion diff --git a/osu.Game/Overlays/Mods/ModPresetTooltip.cs b/osu.Game/Overlays/Mods/ModPresetTooltip.cs index 8e8259de45..0b31a97064 100644 --- a/osu.Game/Overlays/Mods/ModPresetTooltip.cs +++ b/osu.Game/Overlays/Mods/ModPresetTooltip.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.Collections.Generic; using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -11,7 +12,7 @@ using osuTK; namespace osu.Game.Overlays.Mods { - public partial class ModPresetTooltip : VisibilityContainer, ITooltip + public partial class ModPresetTooltip : VisibilityContainer, ITooltip> { protected override Container Content { get; } @@ -42,15 +43,15 @@ namespace osu.Game.Overlays.Mods }; } - private ModPreset? lastPreset; + private List? lastPreset; - public void SetContent(ModPreset preset) + public void SetContent(List mods) { - if (ReferenceEquals(preset, lastPreset)) + if (ReferenceEquals(mods, lastPreset)) return; - lastPreset = preset; - Content.ChildrenEnumerable = preset.Mods.Select(mod => new ModPresetRow(mod)); + lastPreset = mods; + Content.ChildrenEnumerable = mods.Select(mod => new ModPresetRow(mod)); } protected override void PopIn() => this.FadeIn(transition_duration, Easing.OutQuint); From 8e8dda3ac0ad1d49043198681fcac2b092c9cdda Mon Sep 17 00:00:00 2001 From: Terochi Date: Sat, 11 Mar 2023 23:29:36 +0100 Subject: [PATCH 2439/2991] Big simplifying --- osu.Game.Tests/Mods/ModSettingsTest.cs | 83 +++---------------- .../TestSceneModSelectOverlay.cs | 42 ---------- osu.Game/Rulesets/Mods/Mod.cs | 61 ++------------ 3 files changed, 19 insertions(+), 167 deletions(-) diff --git a/osu.Game.Tests/Mods/ModSettingsTest.cs b/osu.Game.Tests/Mods/ModSettingsTest.cs index e2e050870e..d943f0ffb1 100644 --- a/osu.Game.Tests/Mods/ModSettingsTest.cs +++ b/osu.Game.Tests/Mods/ModSettingsTest.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 NUnit.Framework; using osu.Framework.Bindables; using osu.Framework.Localisation; @@ -42,16 +41,20 @@ namespace osu.Game.Tests.Mods { const double setting_change = 50.4; - var modDouble = new TestNonMatchingSettingTypeModDouble(); - var modBool = new TestNonMatchingSettingTypeModBool(); + var modDouble = new TestNonMatchingSettingTypeModDouble { TestSetting = { Value = setting_change } }; + var modBool = new TestNonMatchingSettingTypeModBool { TestSetting = { Default = false, Value = true } }; + var modInt = new TestNonMatchingSettingTypeModInt { TestSetting = { Value = (int)setting_change } }; - modDouble.TestSetting.Value = setting_change; - modBool.TestSetting.Value = !modBool.TestSetting.Default; modDouble.CopySharedSettings(modBool); + modDouble.CopySharedSettings(modInt); modBool.CopySharedSettings(modDouble); + modBool.CopySharedSettings(modInt); + modInt.CopySharedSettings(modDouble); + modInt.CopySharedSettings(modBool); Assert.That(modDouble.TestSetting.Value, Is.EqualTo(setting_change)); Assert.That(modBool.TestSetting.Value, Is.EqualTo(!modBool.TestSetting.Default)); + Assert.That(modInt.TestSetting.Value, Is.EqualTo((int)setting_change)); } [Test] @@ -70,75 +73,11 @@ namespace osu.Game.Tests.Mods public void TestValueResetsToDefaultWhenCopied() { var modDouble = new TestNonMatchingSettingTypeModDouble(); - var modInt = new TestNonMatchingSettingTypeModInt { TestSetting = { Value = 1 } }; + var modBool = new TestNonMatchingSettingTypeModBool { TestSetting = { Default = false, Value = true } }; - modInt.CopySharedSettings(modDouble); + modBool.CopySharedSettings(modDouble); - Assert.That(modInt.TestSetting.Value, Is.EqualTo(modInt.TestSetting.Default)); - } - - [Test] - public void TestRelativelyScaleWithClampedRangeWhenCopied() - { - const double setting_change = 50.4; - - var modDouble100 = new TestNonMatchingSettingTypeModDouble { TestSetting = { MaxValue = 100, MinValue = 0, Value = setting_change } }; - var modDouble200 = new TestNonMatchingSettingTypeModDouble { TestSetting = { MaxValue = 200, MinValue = 0 } }; - - modDouble200.CopySharedSettings(modDouble100); - - Assert.That(modDouble200.TestSetting.Value, Is.EqualTo(setting_change * 2)); - } - - [Test] - public void TestCopyDoubleToIntWithDefaultRange() - { - const double setting_change = 50.4; - - var modDouble = new TestNonMatchingSettingTypeModDouble { TestSetting = { Value = setting_change } }; - var modInt = new TestNonMatchingSettingTypeModInt(); - - modInt.CopySharedSettings(modDouble); - - Assert.That(modInt.TestSetting.Value, Is.EqualTo(Convert.ToInt32(setting_change))); - } - - [Test] - public void TestCopyDoubleToIntWithOutOfBoundsRange() - { - const double setting_change = 50.4; - - var modDouble = new TestNonMatchingSettingTypeModDouble { TestSetting = { MinValue = int.MinValue - 1d, Value = setting_change } }; - // make RangeConstrainedBindable.HasDefinedRange return true - var modInt = new TestNonMatchingSettingTypeModInt { TestSetting = { MinValue = int.MinValue + 1 } }; - - modInt.CopySharedSettings(modDouble); - - Assert.That(modInt.TestSetting.Value, Is.EqualTo(Convert.ToInt32(setting_change))); - } - - [Test] - public void TestCopyDoubleToIntWithOutOfBoundsValue() - { - var modDouble = new TestNonMatchingSettingTypeModDouble { TestSetting = { MinValue = int.MinValue + 1, Value = int.MaxValue + 1d } }; - var modInt = new TestNonMatchingSettingTypeModInt { TestSetting = { MinValue = int.MinValue + 1 } }; - - modInt.CopySharedSettings(modDouble); - - Assert.That(modInt.TestSetting.Value, Is.EqualTo(int.MaxValue)); - } - - [Test] - public void TestCopyIntToDoubleWithDefaultRange() - { - const int setting_change = 50; - - var modInt = new TestNonMatchingSettingTypeModInt { TestSetting = { Value = setting_change } }; - var modDouble = new TestNonMatchingSettingTypeModDouble(); - - modDouble.CopySharedSettings(modInt); - - Assert.That(modDouble.TestSetting.Value, Is.EqualTo(setting_change)); + Assert.That(modBool.TestSetting.Value, Is.EqualTo(modBool.TestSetting.Default)); } private class TestNonMatchingSettingTypeModDouble : TestNonMatchingSettingTypeMod diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs index 75efc07d43..b4b5052f23 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs @@ -18,7 +18,6 @@ using osu.Game.Overlays.Mods; using osu.Game.Overlays.Settings; using osu.Game.Rulesets; using osu.Game.Rulesets.Catch.Mods; -using osu.Game.Rulesets.Mania.Mods; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Mods; @@ -417,47 +416,6 @@ namespace osu.Game.Tests.Visual.UserInterface }); } - [Test] - public void TestKeepSharedSettingsRatio() - { - const float setting_change = 1.8f; - - createScreen(); - changeRuleset(0); - - AddStep("select flashlight mod", () => SelectedMods.Value = new[] { Ruleset.Value.CreateInstance().CreateMod()! }); - - changeRuleset(0); - AddAssert("ensure mod still selected", () => SelectedMods.Value.SingleOrDefault() is OsuModFlashlight); - - AddStep("change mod settings", () => - { - var osuMod = getMod(); - - // range <0.5 - 2> - osuMod.SizeMultiplier.Value = setting_change; - }); - - changeRuleset(3); - AddAssert("mania variant selected", () => SelectedMods.Value.SingleOrDefault() is ManiaModFlashlight); - - AddAssert("shared settings changed to closest ratio", () => - { - var maniaMod = getMod(); - - // range <0.5 - 3> - // converted value based on ratio = (setting_change - 0.5) / (2 - 0.5) * (3 - 0.5) + 0.5 = 2.66 - return maniaMod.SizeMultiplier.Value == 2.7f; // taking precision into account - }); - - AddAssert("other settings unchanged", () => - { - var maniaMod = getMod(); - - return maniaMod.ComboBasedSize.IsDefault; - }); - } - [Test] public void TestExternallySetCustomizedMod() { diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 85014d555d..623a734b82 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -165,8 +165,6 @@ namespace osu.Game.Rulesets.Mods /// The mod to copy properties from. internal void CopySharedSettings(Mod source) { - const string min_value = nameof(BindableNumber.MinValue); - const string max_value = nameof(BindableNumber.MaxValue); const string value = nameof(Bindable.Value); Dictionary sourceSettings = new Dictionary(); @@ -190,65 +188,22 @@ namespace osu.Game.Rulesets.Mods continue; } + bool hasSameGenericArgument = getGenericBaseType(targetSetting, typeof(Bindable<>))!.GenericTypeArguments.Single() == + getGenericBaseType(sourceSetting, typeof(Bindable<>))!.GenericTypeArguments.Single(); + + if (!hasSameGenericArgument) + continue; + Type? targetBindableNumberType = getGenericBaseType(targetSetting, typeof(BindableNumber<>)); Type? sourceBindableNumberType = getGenericBaseType(sourceSetting, typeof(BindableNumber<>)); if (targetBindableNumberType == null || sourceBindableNumberType == null) { - if (getGenericBaseType(targetSetting, typeof(Bindable<>))!.GenericTypeArguments.Single() == - getGenericBaseType(sourceSetting, typeof(Bindable<>))!.GenericTypeArguments.Single()) - { - // change settings only if the type is the same - setValue(targetSetting, value, getValue(sourceSetting, value)); - } - + setValue(targetSetting, value, getValue(sourceSetting, value)); continue; } - bool rangeOutOfBounds = false; - - Type targetGenericType = targetBindableNumberType.GenericTypeArguments.Single(); - Type sourceGenericType = sourceBindableNumberType.GenericTypeArguments.Single(); - - if (!Convert.ToBoolean(getValue(targetSetting, nameof(RangeConstrainedBindable.HasDefinedRange))) || - !Convert.ToBoolean(getValue(sourceSetting, nameof(RangeConstrainedBindable.HasDefinedRange)))) - // check if we have a range to rescale from and a range to rescale to - // if not, copy the raw value - rangeOutOfBounds = true; - - double allowedMin = Math.Max( - Convert.ToDouble(targetGenericType.GetField("MinValue")!.GetValue(null)), - Convert.ToDouble(sourceGenericType.GetField("MinValue")!.GetValue(null)) - ); - - double allowedMax = Math.Min( - Convert.ToDouble(targetGenericType.GetField("MaxValue")!.GetValue(null)), - Convert.ToDouble(sourceGenericType.GetField("MaxValue")!.GetValue(null)) - ); - - double targetMin = getValueDouble(targetSetting, min_value); - double targetMax = getValueDouble(targetSetting, max_value); - double sourceMin = getValueDouble(sourceSetting, min_value); - double sourceMax = getValueDouble(sourceSetting, max_value); - double sourceValue = Math.Clamp(getValueDouble(sourceSetting, value), allowedMin, allowedMax); - - double targetValue = rangeOutOfBounds - // keep raw value - ? sourceValue - // convert value to same ratio - : (sourceValue - sourceMin) / (sourceMax - sourceMin) * (targetMax - targetMin) + targetMin; - - setValue(targetSetting, value, Convert.ChangeType(targetValue, targetBindableNumberType.GenericTypeArguments.Single())); - - double getValueDouble(object setting, string name) - { - double settingValue = Convert.ToDouble(getValue(setting, name)!); - - if (settingValue < allowedMin || settingValue > allowedMax) - rangeOutOfBounds = true; - - return settingValue; - } + setValue(targetSetting, value, Convert.ChangeType(getValue(sourceSetting, value), targetBindableNumberType.GenericTypeArguments.Single())); } object? getValue(object setting, string name) => From febdca45470f34a7cdfc493cddc13f371593099c Mon Sep 17 00:00:00 2001 From: Derrick Timmermans Date: Sun, 12 Mar 2023 02:08:00 +0100 Subject: [PATCH 2440/2991] Fix argon progress bar fill being oversized --- osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs index 6db1072fbb..dd6e10ba5d 100644 --- a/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs +++ b/osu.Game/Screens/Play/HUD/ArgonSongProgressBar.cs @@ -242,7 +242,6 @@ namespace osu.Game.Screens.Play.HUD { length = value; mask.Width = value * DrawWidth; - fill.Width = value * DrawWidth; } } From 0cf69a10846b59934a837d3a39b43c812092f848 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 11 Mar 2023 21:35:52 -0800 Subject: [PATCH 2441/2991] Make yaml line strings verbatim --- osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs b/osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs index 5f8bee7558..8dc058bd69 100644 --- a/osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs +++ b/osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs @@ -30,11 +30,11 @@ namespace osu.Game.Overlays.Wiki.Markdown { switch (line.ToString()) { - case "outdated: true": + case @"outdated: true": isOutdated = true; break; - case "needs_cleanup: true": + case @"needs_cleanup: true": needsCleanup = true; break; } From ea88aee41f27491d4022c5bb38a4661f55661e3c Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 11 Mar 2023 21:36:15 -0800 Subject: [PATCH 2442/2991] Display stub notice in marked wiki articles --- .../Overlays/Wiki/Markdown/WikiNoticeContainer.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs b/osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs index 8dc058bd69..df800f47b1 100644 --- a/osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs +++ b/osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs @@ -19,6 +19,7 @@ namespace osu.Game.Overlays.Wiki.Markdown { private readonly bool isOutdated; private readonly bool needsCleanup; + private readonly bool isStub; public WikiNoticeContainer(YamlFrontMatterBlock yamlFrontMatterBlock) { @@ -37,6 +38,10 @@ namespace osu.Game.Overlays.Wiki.Markdown case @"needs_cleanup: true": needsCleanup = true; break; + + case @"stub: true": + isStub = true; + break; } } } @@ -60,6 +65,14 @@ namespace osu.Game.Overlays.Wiki.Markdown Text = WikiStrings.ShowNeedsCleanupOrRewrite, }); } + + if (isStub) + { + Add(new NoticeBox + { + Text = WikiStrings.ShowStub, + }); + } } private partial class NoticeBox : Container From 6e5b1280b7261d37e89a494b973f35905099d630 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 11 Mar 2023 21:18:56 -0800 Subject: [PATCH 2443/2991] Fix multiple notice boxes having no spacing --- osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs b/osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs index df800f47b1..a40bd14878 100644 --- a/osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs +++ b/osu.Game/Overlays/Wiki/Markdown/WikiNoticeContainer.cs @@ -12,6 +12,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Resources.Localisation.Web; +using osuTK; namespace osu.Game.Overlays.Wiki.Markdown { @@ -26,6 +27,7 @@ namespace osu.Game.Overlays.Wiki.Markdown RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; Direction = FillDirection.Vertical; + Spacing = new Vector2(10); foreach (object line in yamlFrontMatterBlock.Lines) { From c1618a7a16f923cf57f891150d19fd9afde06aa7 Mon Sep 17 00:00:00 2001 From: Rovearix Date: Sun, 12 Mar 2023 10:57:53 -0400 Subject: [PATCH 2444/2991] Prevent elements that are anchored in the center from blocking loading --- osu.Game/Graphics/UserInterface/LoadingLayer.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/LoadingLayer.cs b/osu.Game/Graphics/UserInterface/LoadingLayer.cs index 9059b61a33..7cd54304b7 100644 --- a/osu.Game/Graphics/UserInterface/LoadingLayer.cs +++ b/osu.Game/Graphics/UserInterface/LoadingLayer.cs @@ -69,6 +69,10 @@ namespace osu.Game.Graphics.UserInterface // note that this will not work well if touch handling elements are beneath this loading layer (something to consider for the future). case TouchEvent: return false; + + // blocking drag events to prevent unintended ui pausing while loading a beat map (see https://github.com/ppy/osu/issues/22657) + case DragEvent: + return false; } return true; From 12f240e11ad13b2bcc3a348135a78194bb130919 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 13 Mar 2023 18:23:28 +0900 Subject: [PATCH 2445/2991] Apply simple NRT changes to touched test scenes --- .../Formats/LegacyBeatmapDecoderTest.cs | 33 ++++++++++--------- .../Formats/LegacyStoryboardDecoderTest.cs | 14 ++++---- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 85d304da9c..e2a8062569 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -1,9 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; +using System.Diagnostics; using System.IO; using System.Linq; using NUnit.Framework; @@ -320,6 +319,8 @@ namespace osu.Game.Tests.Beatmaps.Formats { var comboColors = decoder.Decode(stream).ComboColours; + Debug.Assert(comboColors != null); + Color4[] expectedColors = { new Color4(142, 199, 255, 255), @@ -330,7 +331,7 @@ namespace osu.Game.Tests.Beatmaps.Formats new Color4(255, 177, 140, 255), new Color4(100, 100, 100, 255), // alpha is specified as 100, but should be ignored. }; - Assert.AreEqual(expectedColors.Length, comboColors?.Count); + Assert.AreEqual(expectedColors.Length, comboColors.Count); for (int i = 0; i < expectedColors.Length; i++) Assert.AreEqual(expectedColors[i], comboColors[i]); } @@ -415,14 +416,14 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsNotNull(positionData); Assert.IsNotNull(curveData); - Assert.AreEqual(new Vector2(192, 168), positionData.Position); + Assert.AreEqual(new Vector2(192, 168), positionData!.Position); Assert.AreEqual(956, hitObjects[0].StartTime); Assert.IsTrue(hitObjects[0].Samples.Any(s => s.Name == HitSampleInfo.HIT_NORMAL)); positionData = hitObjects[1] as IHasPosition; Assert.IsNotNull(positionData); - Assert.AreEqual(new Vector2(304, 56), positionData.Position); + Assert.AreEqual(new Vector2(304, 56), positionData!.Position); Assert.AreEqual(1285, hitObjects[1].StartTime); Assert.IsTrue(hitObjects[1].Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP)); } @@ -578,8 +579,8 @@ namespace osu.Game.Tests.Beatmaps.Formats [Test] public void TestFallbackDecoderForCorruptedHeader() { - Decoder decoder = null; - Beatmap beatmap = null; + Decoder decoder = null!; + Beatmap beatmap = null!; using (var resStream = TestResources.OpenResource("corrupted-header.osu")) using (var stream = new LineBufferedReader(resStream)) @@ -596,8 +597,8 @@ namespace osu.Game.Tests.Beatmaps.Formats [Test] public void TestFallbackDecoderForMissingHeader() { - Decoder decoder = null; - Beatmap beatmap = null; + Decoder decoder = null!; + Beatmap beatmap = null!; using (var resStream = TestResources.OpenResource("missing-header.osu")) using (var stream = new LineBufferedReader(resStream)) @@ -614,8 +615,8 @@ namespace osu.Game.Tests.Beatmaps.Formats [Test] public void TestDecodeFileWithEmptyLinesAtStart() { - Decoder decoder = null; - Beatmap beatmap = null; + Decoder decoder = null!; + Beatmap beatmap = null!; using (var resStream = TestResources.OpenResource("empty-lines-at-start.osu")) using (var stream = new LineBufferedReader(resStream)) @@ -632,8 +633,8 @@ namespace osu.Game.Tests.Beatmaps.Formats [Test] public void TestDecodeFileWithEmptyLinesAndNoHeader() { - Decoder decoder = null; - Beatmap beatmap = null; + Decoder decoder = null!; + Beatmap beatmap = null!; using (var resStream = TestResources.OpenResource("empty-line-instead-of-header.osu")) using (var stream = new LineBufferedReader(resStream)) @@ -650,8 +651,8 @@ namespace osu.Game.Tests.Beatmaps.Formats [Test] public void TestDecodeFileWithContentImmediatelyAfterHeader() { - Decoder decoder = null; - Beatmap beatmap = null; + Decoder decoder = null!; + Beatmap beatmap = null!; using (var resStream = TestResources.OpenResource("no-empty-line-after-header.osu")) using (var stream = new LineBufferedReader(resStream)) @@ -678,7 +679,7 @@ namespace osu.Game.Tests.Beatmaps.Formats [Test] public void TestAllowFallbackDecoderOverwrite() { - Decoder decoder = null; + Decoder decoder = null!; using (var resStream = TestResources.OpenResource("corrupted-header.osu")) using (var stream = new LineBufferedReader(resStream)) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs index 281ea4e4ff..577ae3fe95 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using NUnit.Framework; using osuTK; @@ -30,35 +28,35 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsTrue(storyboard.HasDrawable); Assert.AreEqual(6, storyboard.Layers.Count()); - StoryboardLayer background = storyboard.Layers.FirstOrDefault(l => l.Depth == 3); + StoryboardLayer background = storyboard.Layers.Single(l => l.Depth == 3); Assert.IsNotNull(background); Assert.AreEqual(16, background.Elements.Count); Assert.IsTrue(background.VisibleWhenFailing); Assert.IsTrue(background.VisibleWhenPassing); Assert.AreEqual("Background", background.Name); - StoryboardLayer fail = storyboard.Layers.FirstOrDefault(l => l.Depth == 2); + StoryboardLayer fail = storyboard.Layers.Single(l => l.Depth == 2); Assert.IsNotNull(fail); Assert.AreEqual(0, fail.Elements.Count); Assert.IsTrue(fail.VisibleWhenFailing); Assert.IsFalse(fail.VisibleWhenPassing); Assert.AreEqual("Fail", fail.Name); - StoryboardLayer pass = storyboard.Layers.FirstOrDefault(l => l.Depth == 1); + StoryboardLayer pass = storyboard.Layers.Single(l => l.Depth == 1); Assert.IsNotNull(pass); Assert.AreEqual(0, pass.Elements.Count); Assert.IsFalse(pass.VisibleWhenFailing); Assert.IsTrue(pass.VisibleWhenPassing); Assert.AreEqual("Pass", pass.Name); - StoryboardLayer foreground = storyboard.Layers.FirstOrDefault(l => l.Depth == 0); + StoryboardLayer foreground = storyboard.Layers.Single(l => l.Depth == 0); Assert.IsNotNull(foreground); Assert.AreEqual(151, foreground.Elements.Count); Assert.IsTrue(foreground.VisibleWhenFailing); Assert.IsTrue(foreground.VisibleWhenPassing); Assert.AreEqual("Foreground", foreground.Name); - StoryboardLayer overlay = storyboard.Layers.FirstOrDefault(l => l.Depth == int.MinValue); + StoryboardLayer overlay = storyboard.Layers.Single(l => l.Depth == int.MinValue); Assert.IsNotNull(overlay); Assert.IsEmpty(overlay.Elements); Assert.IsTrue(overlay.VisibleWhenFailing); @@ -76,7 +74,7 @@ namespace osu.Game.Tests.Beatmaps.Formats var sprite = background.Elements.ElementAt(0) as StoryboardSprite; Assert.NotNull(sprite); - Assert.IsTrue(sprite.HasCommands); + Assert.IsTrue(sprite!.HasCommands); Assert.AreEqual(new Vector2(320, 240), sprite.InitialPosition); Assert.IsTrue(sprite.IsDrawable); Assert.AreEqual(Anchor.Centre, sprite.Origin); From 3aea058c98e07bcc4435dcb94ed49aa0c82aff8f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 13 Mar 2023 18:15:17 +0900 Subject: [PATCH 2446/2991] Add test coverage ensuring images are not read as videos --- .../Formats/LegacyStoryboardDecoderTest.cs | 15 +++++++++++++++ .../Resources/image-specified-as-video.osb | 4 ++++ 2 files changed, 19 insertions(+) create mode 100644 osu.Game.Tests/Resources/image-specified-as-video.osb diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs index 577ae3fe95..3a776ac225 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs @@ -169,6 +169,21 @@ namespace osu.Game.Tests.Beatmaps.Formats } } + [Test] + public void TestDecodeImageSpecifiedAsVideo() + { + var decoder = new LegacyStoryboardDecoder(); + + using (var resStream = TestResources.OpenResource("image-specified-as-video.osb")) + using (var stream = new LineBufferedReader(resStream)) + { + var storyboard = decoder.Decode(stream); + + StoryboardLayer foreground = storyboard.Layers.Single(l => l.Name == "Video"); + Assert.That(foreground.Elements.Count, Is.Zero); + } + } + [Test] public void TestDecodeOutOfRangeLoopAnimationType() { diff --git a/osu.Game.Tests/Resources/image-specified-as-video.osb b/osu.Game.Tests/Resources/image-specified-as-video.osb new file mode 100644 index 0000000000..9cea7dd4e7 --- /dev/null +++ b/osu.Game.Tests/Resources/image-specified-as-video.osb @@ -0,0 +1,4 @@ +osu file format v14 + +[Events] +Video,0,"BG.jpg",0,0 From c35c81293a149d00d6c497829a15797ef562c489 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 13 Mar 2023 18:19:18 +0900 Subject: [PATCH 2447/2991] Add test coverage ensuring images specified as videos are used as background image instead --- .../Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index e2a8062569..518981980b 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -160,6 +160,21 @@ namespace osu.Game.Tests.Beatmaps.Formats } } + [Test] + public void TestDecodeImageSpecifiedAsVideo() + { + var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; + + using (var resStream = TestResources.OpenResource("image-specified-as-video.osb")) + using (var stream = new LineBufferedReader(resStream)) + { + var beatmap = decoder.Decode(stream); + var metadata = beatmap.Metadata; + + Assert.AreEqual("BG.jpg", metadata.BackgroundFile); + } + } + [Test] public void TestDecodeBeatmapTimingPoints() { From eb37d740b13b3cafb346a7a0dfb13a8371ebe076 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 13 Mar 2023 17:40:23 +0900 Subject: [PATCH 2448/2991] Update supported video filetypes to match osu-stable --- osu.Game/OsuGameBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index cf58d07b9e..8f27e5dc53 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -71,7 +71,7 @@ namespace osu.Game [Cached(typeof(OsuGameBase))] public partial class OsuGameBase : Framework.Game, ICanAcceptFiles, IBeatSyncProvider { - public static readonly string[] VIDEO_EXTENSIONS = { ".mp4", ".mov", ".avi", ".flv" }; + public static readonly string[] VIDEO_EXTENSIONS = { ".mp4", ".mov", ".avi", ".flv", ".mpg", ".wmv", ".m4v" }; public const string OSU_PROTOCOL = "osu://"; From da947d86613ffe99f19f4d49a6535810ba752c59 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 13 Mar 2023 18:10:16 +0900 Subject: [PATCH 2449/2991] Gracefully handle beatmaps specifying images using the video storyboard type --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 13 +++++++++++++ .../Beatmaps/Formats/LegacyStoryboardDecoder.cs | 11 ++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index eabc63b341..a9bdd21b64 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -363,6 +363,19 @@ namespace osu.Game.Beatmaps.Formats beatmap.BeatmapInfo.Metadata.BackgroundFile = CleanFilename(split[3]); break; + case LegacyEventType.Video: + string filename = CleanFilename(split[2]); + + // Some very old beatmaps had incorrect type specifications for their backgrounds (ie. using 1 for VIDEO + // instead of 0 for BACKGROUND). To handle this gracefully, check the file extension against known supported + // video extensions and handle similar to a background if it doesn't match. + if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(filename))) + { + beatmap.BeatmapInfo.Metadata.BackgroundFile = filename; + } + + break; + case LegacyEventType.Background: beatmap.BeatmapInfo.Metadata.BackgroundFile = CleanFilename(split[2]); break; diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 44dbb3cc9f..f8308fe431 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -109,6 +109,14 @@ namespace osu.Game.Beatmaps.Formats int offset = Parsing.ParseInt(split[1]); string path = CleanFilename(split[2]); + // See handling in LegacyBeatmapDecoder for the special case where a video type is used but + // the file extension is not a valid video. + // + // This avoids potential weird crashes when ffmpeg attempts to parse an image file as a video + // (see https://github.com/ppy/osu/issues/22829#issuecomment-1465552451). + if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(path))) + break; + storyboard.GetLayer("Video").Add(new StoryboardVideo(path, offset)); break; } @@ -276,7 +284,8 @@ namespace osu.Game.Beatmaps.Formats switch (type) { case "A": - timelineGroup?.BlendingParameters.Add(easing, startTime, endTime, BlendingParameters.Additive, startTime == endTime ? BlendingParameters.Additive : BlendingParameters.Inherit); + timelineGroup?.BlendingParameters.Add(easing, startTime, endTime, BlendingParameters.Additive, + startTime == endTime ? BlendingParameters.Additive : BlendingParameters.Inherit); break; case "H": From 1f7721786b02d628d2b2c7c1d16c83b2d1a4a170 Mon Sep 17 00:00:00 2001 From: rozukke Date: Mon, 13 Mar 2023 22:01:26 +1100 Subject: [PATCH 2450/2991] Perform check to account for non-ASCII characters --- osu.Game/Skinning/SkinImporter.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Skinning/SkinImporter.cs b/osu.Game/Skinning/SkinImporter.cs index 9e2e02876d..43760c4a19 100644 --- a/osu.Game/Skinning/SkinImporter.cs +++ b/osu.Game/Skinning/SkinImporter.cs @@ -101,7 +101,8 @@ namespace osu.Game.Skinning // In both of these cases, the expectation from the user is that the filename or folder name is displayed somewhere to identify the skin. if (archiveName != item.Name // lazer exports use this format - && archiveName != item.GetDisplayString()) + // GetValidFilename accounts for skins with non-ASCII characters in the name that have been exported by lazer. + && archiveName != item.GetDisplayString().GetValidFilename()) item.Name = @$"{item.Name} [{archiveName}]"; } From ba728bdab1b4662366e3737fd4f84cf413e2d0e1 Mon Sep 17 00:00:00 2001 From: Rovearix Date: Mon, 13 Mar 2023 07:49:51 -0400 Subject: [PATCH 2451/2991] Changed the event to be the more correct one to block --- osu.Game/Graphics/UserInterface/LoadingLayer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/LoadingLayer.cs b/osu.Game/Graphics/UserInterface/LoadingLayer.cs index 7cd54304b7..3f9856eddd 100644 --- a/osu.Game/Graphics/UserInterface/LoadingLayer.cs +++ b/osu.Game/Graphics/UserInterface/LoadingLayer.cs @@ -71,7 +71,7 @@ namespace osu.Game.Graphics.UserInterface return false; // blocking drag events to prevent unintended ui pausing while loading a beat map (see https://github.com/ppy/osu/issues/22657) - case DragEvent: + case DragStartEvent: return false; } From 9ac9287dbd89051a685d9821cbbf951bdef37d7d Mon Sep 17 00:00:00 2001 From: Rovearix Date: Mon, 13 Mar 2023 08:07:55 -0400 Subject: [PATCH 2452/2991] Switched the implementation to set the blockInput flag for the BeatmapMetadataDisplay's LoadingLayer. This prevents the UIEvents from being being handled in this case without modifying the class --- osu.Game/Graphics/UserInterface/LoadingLayer.cs | 4 ---- osu.Game/Screens/Play/BeatmapMetadataDisplay.cs | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/LoadingLayer.cs b/osu.Game/Graphics/UserInterface/LoadingLayer.cs index 3f9856eddd..9059b61a33 100644 --- a/osu.Game/Graphics/UserInterface/LoadingLayer.cs +++ b/osu.Game/Graphics/UserInterface/LoadingLayer.cs @@ -69,10 +69,6 @@ namespace osu.Game.Graphics.UserInterface // note that this will not work well if touch handling elements are beneath this loading layer (something to consider for the future). case TouchEvent: return false; - - // blocking drag events to prevent unintended ui pausing while loading a beat map (see https://github.com/ppy/osu/issues/22657) - case DragStartEvent: - return false; } return true; diff --git a/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs b/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs index 06509b6465..a152f4be19 100644 --- a/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs +++ b/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs @@ -114,7 +114,7 @@ namespace osu.Game.Screens.Play Anchor = Anchor.Centre, FillMode = FillMode.Fill, }, - loading = new LoadingLayer(true) + loading = new LoadingLayer(dimBackground: true, blockInput: false) } }, versionFlow = new FillFlowContainer From 4570c0030f1211bc166eff6be86ced372c1e0907 Mon Sep 17 00:00:00 2001 From: rozukke Date: Mon, 13 Mar 2023 23:37:45 +1100 Subject: [PATCH 2453/2991] Add test to check for import of exported skin with non-ASCII name --- osu.Game.Tests/Skins/IO/ImportSkinTest.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs index 0bd40e9962..81ebc59729 100644 --- a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs +++ b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs @@ -133,6 +133,25 @@ namespace osu.Game.Tests.Skins.IO assertImportedOnce(import1, import2); }); + [Test] + public Task TestImportExportedNonAsciiSkinFilename() => runSkinTest(async osu => + { + MemoryStream exportStream = new MemoryStream(); + + var import1 = await loadSkinIntoOsu(osu, new ImportTask(createOskWithIni("name 『1』", "author 1"), "custom.osk")); + assertCorrectMetadata(import1, "name 『1』 [custom]", "author 1", osu); + + import1.PerformRead(s => + { + new LegacySkinExporter(osu.Dependencies.Get()).ExportModelTo(s, exportStream); + }); + + string exportFilename = import1.GetDisplayString().GetValidFilename(); + + var import2 = await loadSkinIntoOsu(osu, new ImportTask(exportStream, $"{exportFilename}.osk")); + assertCorrectMetadata(import2, "name 『1』 [custom]", "author 1", osu); + }); + [Test] public Task TestSameMetadataNameSameFolderName([Values] bool batchImport) => runSkinTest(async osu => { From 300d81c46ba58f7fc8867fcfa99396d3ba04d1c0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Mar 2023 16:59:18 +0900 Subject: [PATCH 2454/2991] Add hitting layer to fix hit lighting not being applied to tail piece Taken from https://github.com/ppy/osu/pull/22820#issuecomment-1462626898. --- .../Objects/Drawables/DrawableHoldNoteTail.cs | 2 +- .../Skinning/Argon/ArgonHoldBodyPiece.cs | 41 ++---------- .../Argon/ArgonHoldNoteHittingLayer.cs | 64 +++++++++++++++++++ .../Skinning/Argon/ArgonHoldNoteTailPiece.cs | 31 ++++++++- 4 files changed, 100 insertions(+), 38 deletions(-) create mode 100644 osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteHittingLayer.cs diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs index 20ea962994..e7326df07d 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { protected override ManiaSkinComponents Component => ManiaSkinComponents.HoldNoteTail; - protected DrawableHoldNote HoldNote => (DrawableHoldNote)ParentHitObject; + protected internal DrawableHoldNote HoldNote => (DrawableHoldNote)ParentHitObject; public DrawableHoldNoteTail() : this(null) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldBodyPiece.cs index 91eda57c8f..57fa1c10ae 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldBodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldBodyPiece.cs @@ -20,10 +20,9 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon public partial class ArgonHoldBodyPiece : CompositeDrawable, IHoldNoteBody { protected readonly Bindable AccentColour = new Bindable(); - protected readonly IBindable IsHitting = new Bindable(); private Drawable background = null!; - private Box foreground = null!; + private ArgonHoldNoteHittingLayer hittingLayer = null!; public ArgonHoldBodyPiece() { @@ -40,12 +39,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon InternalChildren = new[] { background = new Box { RelativeSizeAxes = Axes.Both }, - foreground = new Box - { - RelativeSizeAxes = Axes.Both, - Blending = BlendingParameters.Additive, - Alpha = 0, - }, + hittingLayer = new ArgonHoldNoteHittingLayer() }; if (drawableObject != null) @@ -53,44 +47,19 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon var holdNote = (DrawableHoldNote)drawableObject; AccentColour.BindTo(holdNote.AccentColour); - IsHitting.BindTo(holdNote.IsHitting); + hittingLayer.AccentColour.BindTo(holdNote.AccentColour); + ((IBindable)hittingLayer.IsHitting).BindTo(holdNote.IsHitting); } AccentColour.BindValueChanged(colour => { background.Colour = colour.NewValue.Darken(0.6f); - foreground.Colour = colour.NewValue.Opacity(0.2f); }, true); - - IsHitting.BindValueChanged(hitting => - { - const float animation_length = 50; - - foreground.ClearTransforms(); - - if (hitting.NewValue) - { - // wait for the next sync point - double synchronisedOffset = animation_length * 2 - Time.Current % (animation_length * 2); - - using (foreground.BeginDelayedSequence(synchronisedOffset)) - { - foreground.FadeTo(1, animation_length).Then() - .FadeTo(0.5f, animation_length) - .Loop(); - } - } - else - { - foreground.FadeOut(animation_length); - } - }); } public void Recycle() { - foreground.ClearTransforms(); - foreground.Alpha = 0; + hittingLayer.Recycle(); } } } diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteHittingLayer.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteHittingLayer.cs new file mode 100644 index 0000000000..9df7e06a4b --- /dev/null +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteHittingLayer.cs @@ -0,0 +1,64 @@ +// 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.Bindables; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osuTK.Graphics; +using Box = osu.Framework.Graphics.Shapes.Box; + +namespace osu.Game.Rulesets.Mania.Skinning.Argon +{ + public partial class ArgonHoldNoteHittingLayer : Box + { + public readonly Bindable AccentColour = new Bindable(); + public readonly Bindable IsHitting = new Bindable(); + + public ArgonHoldNoteHittingLayer() + { + RelativeSizeAxes = Axes.Both; + Blending = BlendingParameters.Additive; + Alpha = 0; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + AccentColour.BindValueChanged(colour => + { + Colour = colour.NewValue.Opacity(0.2f); + }, true); + + IsHitting.BindValueChanged(hitting => + { + const float animation_length = 50; + + ClearTransforms(); + + if (hitting.NewValue) + { + // wait for the next sync point + double synchronisedOffset = animation_length * 2 - Time.Current % (animation_length * 2); + + using (BeginDelayedSequence(synchronisedOffset)) + { + this.FadeTo(1, animation_length).Then() + .FadeTo(0.5f, animation_length) + .Loop(); + } + } + else + { + this.FadeOut(animation_length); + } + }); + } + + public void Recycle() + { + ClearTransforms(); + Alpha = 0; + } + } +} diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs index 085e0630fb..efd7f4f280 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteTailPiece.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI.Scrolling; using osuTK; @@ -17,10 +18,14 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon { internal partial class ArgonHoldNoteTailPiece : CompositeDrawable { + [Resolved] + private DrawableHitObject? drawableObject { get; set; } + private readonly IBindable direction = new Bindable(); private readonly IBindable accentColour = new Bindable(); private readonly Box foreground; + private readonly ArgonHoldNoteHittingLayer hittingLayer; private readonly Box foregroundAdditive; public ArgonHoldNoteTailPiece() @@ -59,6 +64,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon { RelativeSizeAxes = Axes.Both, }, + hittingLayer = new ArgonHoldNoteHittingLayer(), foregroundAdditive = new Box { RelativeSizeAxes = Axes.Both, @@ -73,7 +79,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon } [BackgroundDependencyLoader(true)] - private void load(IScrollingInfo scrollingInfo, DrawableHitObject? drawableObject) + private void load(IScrollingInfo scrollingInfo) { direction.BindTo(scrollingInfo.Direction); direction.BindValueChanged(onDirectionChanged, true); @@ -82,9 +88,24 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon { accentColour.BindTo(drawableObject.AccentColour); accentColour.BindValueChanged(onAccentChanged, true); + + drawableObject.HitObjectApplied += hitObjectApplied; } } + private void hitObjectApplied(DrawableHitObject drawableHitObject) + { + var holdNoteTail = (DrawableHoldNoteTail)drawableHitObject; + + hittingLayer.Recycle(); + + hittingLayer.AccentColour.UnbindBindings(); + hittingLayer.AccentColour.BindTo(holdNoteTail.HoldNote.AccentColour); + + hittingLayer.IsHitting.UnbindBindings(); + ((IBindable)hittingLayer.IsHitting).BindTo(holdNoteTail.HoldNote.IsHitting); + } + private void onDirectionChanged(ValueChangedEvent direction) { Scale = new Vector2(1, direction.NewValue == ScrollingDirection.Up ? -1 : 1); @@ -99,5 +120,13 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon accent.NewValue.Opacity(0) ); } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (drawableObject != null) + drawableObject.HitObjectApplied -= hitObjectApplied; + } } } From 48d11610b344ac23dd0ff3628b90ee4b4b40402d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Mar 2023 17:44:51 +0900 Subject: [PATCH 2455/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 234575fc62..4e580a6919 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -11,7 +11,7 @@ manifestmerger.jar - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 103ac99172..a84b42d9a4 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index fde45817cf..8738979c57 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -16,6 +16,6 @@ iossimulator-x64 - + From 0b23809585d73617942c7f5a0edebfcab2ca02ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Mar 2023 17:52:17 +0900 Subject: [PATCH 2456/2991] Update resources --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index a84b42d9a4..c08dc9ed8f 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -37,7 +37,7 @@ - + From f40a4b591fe30341289619ca83fc4e3459ee392a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Mar 2023 17:29:54 +0900 Subject: [PATCH 2457/2991] Adjust animation length and colouring of hitting layer --- .../Skinning/Argon/ArgonHoldNoteHittingLayer.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteHittingLayer.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteHittingLayer.cs index 9df7e06a4b..9e7afa8b9e 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteHittingLayer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHoldNoteHittingLayer.cs @@ -27,12 +27,12 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon AccentColour.BindValueChanged(colour => { - Colour = colour.NewValue.Opacity(0.2f); + Colour = colour.NewValue.Lighten(0.2f).Opacity(0.3f); }, true); IsHitting.BindValueChanged(hitting => { - const float animation_length = 50; + const float animation_length = 80; ClearTransforms(); @@ -43,8 +43,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon using (BeginDelayedSequence(synchronisedOffset)) { - this.FadeTo(1, animation_length).Then() - .FadeTo(0.5f, animation_length) + this.FadeTo(1, animation_length, Easing.OutSine).Then() + .FadeTo(0.5f, animation_length, Easing.InSine) .Loop(); } } @@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon { this.FadeOut(animation_length); } - }); + }, true); } public void Recycle() From 5aebbac6c5e8377f265404139c7630b9da834464 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Mar 2023 18:15:18 +0900 Subject: [PATCH 2458/2991] Fix osu!mania hold note animations not correctly re-applying after rewind There's early exit logic in `OnPressed`/`OnReleased` for the sake of keeping order correct, but this doesn't account for the fact that `DrawableHitObject` resets all animations when the hit state changes. A bit of an ugly workaround, but seems to work as expected. --- .../Objects/Drawables/DrawableHoldNote.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 25d0573a82..3bf3aec9c3 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -323,7 +323,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables // do not run any of this logic when rewinding, as it inverts order of presses/releases. if (Time.Elapsed < 0) + { + // Except for the IsHitting state, as this handles animations that need to be reapplied + // after rewind. + isHitting.Value = false; return; + } // Make sure a hold was started if (HoldStartTime == null) From 4cea29402bfae7a537bd27a11df3b338b5b9f350 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Mar 2023 18:32:24 +0900 Subject: [PATCH 2459/2991] Don't show epilepsy warning when storyboards are disabled I have more thoughts on this warning in general (which will likely see it removed or moved in the future) but this seems like a quick QOL fix for now. As mentioned in https://github.com/ppy/osu/discussions/22861. --- osu.Game/Screens/Play/PlayerLoader.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 4f7e4add32..be4229ade9 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -67,6 +67,8 @@ namespace osu.Game.Screens.Play private OsuScrollContainer settingsScroll = null!; + private Bindable showStoryboards = null!; + private bool backgroundBrightnessReduction; private readonly BindableDouble volumeAdjustment = new BindableDouble(1); @@ -149,10 +151,11 @@ namespace osu.Game.Screens.Play } [BackgroundDependencyLoader] - private void load(SessionStatics sessionStatics, AudioManager audio) + private void load(SessionStatics sessionStatics, AudioManager audio, OsuConfigManager config) { muteWarningShownOnce = sessionStatics.GetBindable(Static.MutedAudioNotificationShownOnce); batteryWarningShownOnce = sessionStatics.GetBindable(Static.LowBatteryNotificationShownOnce); + showStoryboards = config.GetBindable(OsuSetting.ShowStoryboard); const float padding = 25; @@ -463,7 +466,10 @@ namespace osu.Game.Screens.Play // only show if the warning was created (i.e. the beatmap needs it) // and this is not a restart of the map (the warning expires after first load). - if (epilepsyWarning?.IsAlive == true) + // + // note the late check of storyboard enable as the user may have just changed it + // from the settings on the loader screen. + if (epilepsyWarning?.IsAlive == true && showStoryboards.Value) { const double epilepsy_display_length = 3000; From d65d09e45f9c02186bec88fcb9ab01867ead71b7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Mar 2023 20:24:39 +0900 Subject: [PATCH 2460/2991] Change field to `const` --- osu.Game/Graphics/Backgrounds/Triangles.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index 5b7b94ff4c..28a715ca0b 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -252,7 +252,7 @@ namespace osu.Game.Graphics.Backgrounds private class TrianglesDrawNode : DrawNode { - private float fill = 1f; + private const float fill = 1f; protected new Triangles Source => (Triangles)base.Source; From b5ea855b6cf8ff9faa5659c1a2e6f4e41b5f5739 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Mar 2023 20:37:50 +0900 Subject: [PATCH 2461/2991] Fix failing `DrawableRulesetDependencies` test --- .../Rulesets/TestSceneDrawableRulesetDependencies.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs b/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs index 5cfcca303f..f8248e88bb 100644 --- a/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs +++ b/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs @@ -80,7 +80,7 @@ namespace osu.Game.Tests.Rulesets dependencies.CacheAs(ParentTextureStore = new TestTextureStore(parent.Get().Renderer)); dependencies.CacheAs(ParentSampleStore = new TestSampleStore()); - dependencies.CacheAs(ParentShaderManager = new TestShaderManager(parent.Get().Renderer)); + dependencies.CacheAs(ParentShaderManager = new TestShaderManager(parent.Get().Renderer, parent.Get())); return new DrawableRulesetDependencies(new OsuRuleset(), dependencies); } @@ -156,12 +156,15 @@ namespace osu.Game.Tests.Rulesets private class TestShaderManager : ShaderManager { - public TestShaderManager(IRenderer renderer) + private readonly ShaderManager parentManager; + + public TestShaderManager(IRenderer renderer, ShaderManager parentManager) : base(renderer, new ResourceStore()) { + this.parentManager = parentManager; } - public override byte[] LoadRaw(string name) => null; + public override byte[] LoadRaw(string name) => parentManager.LoadRaw(name); public bool IsDisposed { get; private set; } From 3c4e2d8700163f8647717643ba6e5575dc3401ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 14 Mar 2023 21:04:51 +0900 Subject: [PATCH 2462/2991] Add tests covering drag selection --- .../Visual/Gameplay/TestSceneSkinEditor.cs | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs index 7af2b7d6fe..a999a9b4fc 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs @@ -54,6 +54,72 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for loaded", () => skinEditor.IsLoaded); } + [Test] + public void TestDragSelection() + { + BigBlackBox box1 = null!; + BigBlackBox box2 = null!; + BigBlackBox box3 = null!; + + AddStep("Add big black boxes", () => + { + var target = Player.ChildrenOfType().First(); + target.Add(box1 = new BigBlackBox + { + Position = new Vector2(-90), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + target.Add(box2 = new BigBlackBox + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + target.Add(box3 = new BigBlackBox + { + Position = new Vector2(90), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + }); + + AddStep("Begin drag top left", () => + { + InputManager.MoveMouseTo(box1.ScreenSpaceDrawQuad.TopLeft - new Vector2(box1.ScreenSpaceDrawQuad.Width / 4)); + InputManager.PressButton(MouseButton.Left); + }); + + AddStep("Drag to bottom right", () => + { + InputManager.MoveMouseTo(box2.ScreenSpaceDrawQuad.Centre + new Vector2(box2.ScreenSpaceDrawQuad.Width / 4)); + }); + + AddStep("Release button", () => + { + InputManager.ReleaseButton(MouseButton.Left); + }); + + AddAssert("First two boxes selected", () => skinEditor.SelectedComponents, () => Is.EqualTo(new[] { box1, box2 })); + + AddStep("Begin drag bottom right", () => + { + InputManager.MoveMouseTo(box3.ScreenSpaceDrawQuad.BottomRight + new Vector2(box3.ScreenSpaceDrawQuad.Width / 4)); + InputManager.PressButton(MouseButton.Left); + }); + + AddStep("Drag to top left", () => + { + InputManager.MoveMouseTo(box2.ScreenSpaceDrawQuad.Centre - new Vector2(box2.ScreenSpaceDrawQuad.Width / 4)); + }); + + AddStep("Release button", () => + { + InputManager.ReleaseButton(MouseButton.Left); + }); + + AddAssert("Last two boxes selected", () => skinEditor.SelectedComponents, () => Is.EqualTo(new[] { box2, box3 })); + } + [Test] public void TestCyclicSelection() { From 1d5e5966153e5fbacb206518bdeb7c70b88955b7 Mon Sep 17 00:00:00 2001 From: Terochi Date: Tue, 14 Mar 2023 20:44:30 +0100 Subject: [PATCH 2463/2991] Update `FailAnimation` to use `SkinnableSound` --- osu.Game/Screens/Play/FailAnimation.cs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index 0214d33549..57bdad079e 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -1,15 +1,13 @@ // 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.Audio; -using osu.Framework.Bindables; -using osu.Game.Rulesets.UI; using System; using System.Collections.Generic; using ManagedBass.Fx; using osu.Framework.Allocation; -using osu.Framework.Audio.Sample; +using osu.Framework.Audio; using osu.Framework.Audio.Track; +using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -21,6 +19,7 @@ using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.UI; using osu.Game.Skinning; using osuTK; using osuTK.Graphics; @@ -50,8 +49,7 @@ namespace osu.Game.Screens.Play private const float duration = 2500; - private ISample? failSample; - private SampleChannel? failSampleChannel; + private SkinnableSound failSample = null!; [Resolved] private OsuConfigManager config { get; set; } = null!; @@ -76,10 +74,10 @@ namespace osu.Game.Screens.Play } [BackgroundDependencyLoader] - private void load(AudioManager audio, ISkinSource skin, IBindable beatmap) + private void load(AudioManager audio, IBindable beatmap) { track = beatmap.Value.Track; - failSample = skin.GetSample(new SampleInfo(@"Gameplay/failsound")); + AddInternal(failSample = new SkinnableSound(new SampleInfo("Gameplay/failsound"))); AddRangeInternal(new Drawable[] { @@ -126,7 +124,7 @@ namespace osu.Game.Screens.Play failHighPassFilter.CutoffTo(300); failLowPassFilter.CutoffTo(300, duration, Easing.OutCubic); - failSampleChannel = failSample?.Play(); + failSample.Play(); track.AddAdjustment(AdjustableProperty.Frequency, trackFreq); track.AddAdjustment(AdjustableProperty.Volume, volumeAdjustment); @@ -159,7 +157,7 @@ namespace osu.Game.Screens.Play /// public void Stop() { - failSampleChannel?.Stop(); + failSample.Stop(); removeFilters(); } From 390ad335d0aa8c1cb7f5a8bb99af0d905c0de034 Mon Sep 17 00:00:00 2001 From: Terochi Date: Tue, 14 Mar 2023 21:35:52 +0100 Subject: [PATCH 2464/2991] Reloading samples before playing then when skin change occurs --- osu.Game/Skinning/SkinnableSound.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 475b79053a..43e16f4930 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -115,6 +115,10 @@ namespace osu.Game.Skinning /// public virtual void Play() { + if (Scheduler.HasPendingTasks) + // update samples queued due to skin change before playing them + UpdateSubTree(); + samplesContainer.ForEach(c => { if (PlayWhenZeroVolume || c.AggregateVolume.Value > 0) From 1cf870d956289393abbdcc2578070b90fe9f8fc9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Mar 2023 15:16:48 +0900 Subject: [PATCH 2465/2991] Add test coverage and fix fail case where a drag selection ends incorrectly with cyclic selection --- osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs | 10 +++++++++- .../Edit/Compose/Components/BlueprintContainer.cs | 9 ++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs index a999a9b4fc..35ba363f4b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs @@ -83,6 +83,14 @@ namespace osu.Game.Tests.Visual.Gameplay }); }); + // This step is specifically added to reproduce an edge case which was found during cyclic selection development. + // If everything is working as expected it should not affect the subsequent drag selections. + AddRepeatStep("Select top left", () => + { + InputManager.MoveMouseTo(box1.ScreenSpaceDrawQuad.TopLeft + new Vector2(box1.ScreenSpaceDrawQuad.Width / 8)); + InputManager.Click(MouseButton.Left); + }, 2); + AddStep("Begin drag top left", () => { InputManager.MoveMouseTo(box1.ScreenSpaceDrawQuad.TopLeft - new Vector2(box1.ScreenSpaceDrawQuad.Width / 4)); @@ -91,7 +99,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("Drag to bottom right", () => { - InputManager.MoveMouseTo(box2.ScreenSpaceDrawQuad.Centre + new Vector2(box2.ScreenSpaceDrawQuad.Width / 4)); + InputManager.MoveMouseTo(box3.ScreenSpaceDrawQuad.TopRight + new Vector2(-box3.ScreenSpaceDrawQuad.Width / 8, box3.ScreenSpaceDrawQuad.Height / 4)); }); AddStep("Release button", () => diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 3ba71cebe6..143f343c7d 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -178,6 +178,7 @@ namespace osu.Game.Screens.Edit.Compose.Components endClickSelection(e); clickSelectionHandled = false; isDraggingBlueprint = false; + wasDragStarted = false; }); finishSelectionMovement(); @@ -191,6 +192,7 @@ namespace osu.Game.Screens.Edit.Compose.Components return false; lastDragEvent = e; + wasDragStarted = true; if (movementBlueprints != null) { @@ -399,7 +401,7 @@ namespace osu.Game.Screens.Edit.Compose.Components return false; } - if (selectedBlueprintAlreadySelectedOnMouseDown && AllowCyclicSelection) + if (!wasDragStarted && selectedBlueprintAlreadySelectedOnMouseDown && AllowCyclicSelection) { // If a click occurred and was handled by the currently selected blueprint but didn't result in a drag, // cycle between other blueprints which are also under the cursor. @@ -485,6 +487,11 @@ namespace osu.Game.Screens.Edit.Compose.Components /// private bool isDraggingBlueprint; + /// + /// Whether a drag operation was started at all. + /// + private bool wasDragStarted; + /// /// Attempts to begin the movement of any selected blueprints. /// From 6c4f596a9a1a2c0321f0ba1f231d8dc23ae41836 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Mar 2023 16:26:36 +0900 Subject: [PATCH 2466/2991] Make osu! touch input aware of the distance travelled of a non-direct touch --- .../TestSceneOsuTouchInput.cs | 28 +++++++++++++++++++ .../UI/OsuTouchInputMapper.cs | 18 ++++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs index 72bcec6045..bd32d820d1 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs @@ -150,6 +150,34 @@ namespace osu.Game.Rulesets.Osu.Tests assertKeyCounter(1, 1); } + [Test] + public void TestPositionalTrackingAfterLongDistanceTravelled() + { + // When a single touch has already travelled enough distance on screen, it should remain as the positional + // tracking touch until released (unless a direct touch occurs). + + beginTouch(TouchSource.Touch1); + + assertKeyCounter(1, 0); + checkPressed(OsuAction.LeftButton); + checkPosition(TouchSource.Touch1); + + // cover some distance + beginTouch(TouchSource.Touch1, new Vector2(0)); + beginTouch(TouchSource.Touch1, new Vector2(9999)); + beginTouch(TouchSource.Touch1, new Vector2(0)); + beginTouch(TouchSource.Touch1, new Vector2(9999)); + beginTouch(TouchSource.Touch1); + + beginTouch(TouchSource.Touch2); + + assertKeyCounter(1, 1); + checkPressed(OsuAction.LeftButton); + checkPressed(OsuAction.RightButton); + // in this case, touch 2 should not become the positional tracking touch. + checkPosition(TouchSource.Touch1); + } + [Test] public void TestPositionalInputUpdatesOnlyFromMostRecentTouch() { diff --git a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs index 8df1c35b5c..76cb388949 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs @@ -97,8 +97,8 @@ namespace osu.Game.Rulesets.Osu.UI return; } - // ..or if the current position tracking touch was not a direct touch (this one is debatable and may be change in the future, but it's the simplest way to handle) - if (!positionTrackingTouch.DirectTouch) + // ..or if the current position tracking touch was not a direct touch (and didn't travel across the screen too far). + if (!positionTrackingTouch.DirectTouch && positionTrackingTouch.DistanceTravelled < 200) { positionTrackingTouch = newTouch; return; @@ -117,6 +117,12 @@ namespace osu.Game.Rulesets.Osu.UI private void handleTouchMovement(TouchEvent touchEvent) { + if (touchEvent is TouchMoveEvent moveEvent) + { + var trackedTouch = trackedTouches.Single(t => t.Source == touchEvent.Touch.Source); + trackedTouch.DistanceTravelled += moveEvent.Delta.Length; + } + // Movement should only be tracked for the most recent touch. if (touchEvent.Touch.Source != positionTrackingTouch?.Source) return; @@ -148,8 +154,16 @@ namespace osu.Game.Rulesets.Osu.UI public OsuAction? Action; + /// + /// Whether the touch was on a hit circle receptor. + /// public readonly bool DirectTouch; + /// + /// The total distance on screen travelled by this touch. + /// + public double DistanceTravelled; + public TrackedTouch(TouchSource source, OsuAction? action, bool directTouch) { Source = source; From 42359a9754d0884b97f3c0ca459f22d8358494b1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Mar 2023 16:38:26 +0900 Subject: [PATCH 2467/2991] Fix previous touch action not being released when it's not a direct touch --- osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs | 2 +- osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs index bd32d820d1..d1880d7552 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs @@ -172,7 +172,7 @@ namespace osu.Game.Rulesets.Osu.Tests beginTouch(TouchSource.Touch2); assertKeyCounter(1, 1); - checkPressed(OsuAction.LeftButton); + checkNotPressed(OsuAction.LeftButton); checkPressed(OsuAction.RightButton); // in this case, touch 2 should not become the positional tracking touch. checkPosition(TouchSource.Touch1); diff --git a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs index 76cb388949..8cec65f515 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs @@ -105,12 +105,12 @@ namespace osu.Game.Rulesets.Osu.UI } // In the case the new touch was not used for position tracking, we should also check the previous position tracking touch. - // If it was a direct touch and still has its action pressed, that action should be released. + // If it still has its action pressed, that action should be released. // // This is done to allow tracking with the initial touch while still having both Left/Right actions available for alternating with two more touches. - if (positionTrackingTouch.DirectTouch && positionTrackingTouch.Action is OsuAction directTouchAction) + if (positionTrackingTouch.Action is OsuAction touchAction) { - osuInputManager.KeyBindingContainer.TriggerReleased(directTouchAction); + osuInputManager.KeyBindingContainer.TriggerReleased(touchAction); positionTrackingTouch.Action = null; } } From a9c349fa6db682c9c2cdfa961f2821e84bac57d4 Mon Sep 17 00:00:00 2001 From: Terochi Date: Wed, 15 Mar 2023 09:00:34 +0100 Subject: [PATCH 2468/2991] Cache any skin changes in `SkinReloadableDrawable` to `ScheduledDelegate` --- osu.Game/Skinning/SkinReloadableDrawable.cs | 19 +++++++++++++++++-- osu.Game/Skinning/SkinnableSound.cs | 6 +++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/osu.Game/Skinning/SkinReloadableDrawable.cs b/osu.Game/Skinning/SkinReloadableDrawable.cs index cef1db4bc0..757ca8de83 100644 --- a/osu.Game/Skinning/SkinReloadableDrawable.cs +++ b/osu.Game/Skinning/SkinReloadableDrawable.cs @@ -5,6 +5,7 @@ using System; using osu.Framework.Allocation; using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.Pooling; +using osu.Framework.Threading; namespace osu.Game.Skinning { @@ -14,6 +15,8 @@ namespace osu.Game.Skinning /// public abstract partial class SkinReloadableDrawable : PoolableDrawable { + private ScheduledDelegate? pendingSkinChange; + /// /// Invoked when has changed. /// @@ -31,10 +34,22 @@ namespace osu.Game.Skinning CurrentSkin.SourceChanged += onChange; } - private void onChange() => + private void onChange() + { // schedule required to avoid calls after disposed. // note that this has the side-effect of components only performing a skin change when they are alive. - Scheduler.AddOnce(skinChanged); + pendingSkinChange?.Cancel(); + pendingSkinChange = Scheduler.Add(skinChanged); + } + + public void FlushPendingSkinChanges() + { + if (pendingSkinChange == null) + return; + + pendingSkinChange.RunTask(); + pendingSkinChange = null; + } protected override void LoadAsyncComplete() { diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 43e16f4930..052b1e5b9f 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -115,12 +115,12 @@ namespace osu.Game.Skinning /// public virtual void Play() { - if (Scheduler.HasPendingTasks) - // update samples queued due to skin change before playing them - UpdateSubTree(); + FlushPendingSkinChanges(); samplesContainer.ForEach(c => { + c.FlushPendingSkinChanges(); + if (PlayWhenZeroVolume || c.AggregateVolume.Value > 0) { c.Stop(); From b0f1a6952393c6035614d791be6a5a6dd494bbbd Mon Sep 17 00:00:00 2001 From: Terochi Date: Wed, 15 Mar 2023 09:05:34 +0100 Subject: [PATCH 2469/2991] Update the pauseLoop sample instantly on skin change --- osu.Game/Screens/Play/PauseOverlay.cs | 1 + osu.Game/Screens/Play/Player.cs | 5 +++++ osu.Game/Skinning/SkinReloadableDrawable.cs | 2 +- osu.Game/Skinning/SkinnableSound.cs | 9 +++++++-- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/PauseOverlay.cs b/osu.Game/Screens/Play/PauseOverlay.cs index db42998c45..452e170cc6 100644 --- a/osu.Game/Screens/Play/PauseOverlay.cs +++ b/osu.Game/Screens/Play/PauseOverlay.cs @@ -28,6 +28,7 @@ namespace osu.Game.Screens.Play private SkinnableSound pauseLoop; + public void FlushPendingSkinChanges() => pauseLoop.FlushPendingSkinChanges(); protected override Action BackAction => () => InternalButtons.First().TriggerClick(); [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index bc453d2151..d4180068d3 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -316,6 +316,11 @@ namespace osu.Game.Screens.Play // we may want to limit this in the future to disallow rulesets from outright replacing elements the user expects to be there. failAnimationLayer.Add(createOverlayComponents(Beatmap.Value)); + rulesetSkinProvider.SourceChanged += () => + { + PauseOverlay.FlushPendingSkinChanges(); + }; + if (!DrawableRuleset.AllowGameplayOverlays) { HUDOverlay.ShowHud.Value = false; diff --git a/osu.Game/Skinning/SkinReloadableDrawable.cs b/osu.Game/Skinning/SkinReloadableDrawable.cs index 757ca8de83..ff51eb6dce 100644 --- a/osu.Game/Skinning/SkinReloadableDrawable.cs +++ b/osu.Game/Skinning/SkinReloadableDrawable.cs @@ -42,7 +42,7 @@ namespace osu.Game.Skinning pendingSkinChange = Scheduler.Add(skinChanged); } - public void FlushPendingSkinChanges() + public virtual void FlushPendingSkinChanges() { if (pendingSkinChange == null) return; diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 052b1e5b9f..f80b1f52fa 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -110,6 +110,13 @@ namespace osu.Game.Skinning } } + public override void FlushPendingSkinChanges() + { + base.FlushPendingSkinChanges(); + + samplesContainer.ForEach(c => c.FlushPendingSkinChanges()); + } + /// /// Plays the samples. /// @@ -119,8 +126,6 @@ namespace osu.Game.Skinning samplesContainer.ForEach(c => { - c.FlushPendingSkinChanges(); - if (PlayWhenZeroVolume || c.AggregateVolume.Value > 0) { c.Stop(); From d87f0557cef3288a72eb0ba9d21610a2433c2124 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Mar 2023 17:18:45 +0900 Subject: [PATCH 2470/2991] Update colours for 3k to not use double-purples --- .../Skinning/Argon/ManiaArgonSkinTransformer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs index 0beca815b2..ca9cd83a63 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs @@ -139,9 +139,9 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon { case 0: return colour_pink; - case 1: return colour_purple; + case 1: return colour_orange; - case 2: return colour_special_column; + case 2: return colour_yellow; default: throw new ArgumentOutOfRangeException(); } From 8908648f97b5397261ffaa8036ec493a96ce36d7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Mar 2023 18:01:22 +0900 Subject: [PATCH 2471/2991] Fix super-dodgy cast of `IEnumerable` to `Drawable` --- osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs | 2 +- osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 42683a3eec..44fa555149 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual.Gameplay // best way to check without exposing. private Drawable hideTarget => hudOverlay.KeyCounter; - private Drawable keyCounterFlow => (Drawable)hudOverlay.KeyCounter.Counters; + private Drawable keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType>().Single(); [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs index 3eda80719a..dd1b37341f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs @@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual.Gameplay // best way to check without exposing. private Drawable hideTarget => hudOverlay.KeyCounter; - private Drawable keyCounterFlow => (Drawable)hudOverlay.KeyCounter.Counters; + private Drawable keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType>().Single(); [Test] public void TestComboCounterIncrementing() From 9e444af380ed0d3e96a17c3f83b3cf35d5a7ae4a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Mar 2023 18:02:12 +0900 Subject: [PATCH 2472/2991] Use object initialisers and fix order of initialisation vs add --- .../Play/HUD/DefaultKeyCounterDisplay.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs index 9499263474..8b910d56f6 100644 --- a/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs @@ -13,17 +13,18 @@ namespace osu.Game.Screens.Play.HUD private const int duration = 100; private const double key_fade_time = 80; - private readonly FillFlowContainer keyFlow = new FillFlowContainer(); + private readonly FillFlowContainer keyFlow; public override IEnumerable Counters => keyFlow; public DefaultKeyCounterDisplay() { - keyFlow.Direction = FillDirection.Horizontal; - keyFlow.AutoSizeAxes = Axes.Both; - keyFlow.Alpha = 0; - - InternalChild = keyFlow; + InternalChild = keyFlow = new FillFlowContainer + { + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + Alpha = 0, + }; } protected override void Update() @@ -36,13 +37,12 @@ namespace osu.Game.Screens.Play.HUD } public override void AddTrigger(InputTrigger trigger) - { - DefaultKeyCounter key = new DefaultKeyCounter(trigger); - keyFlow.Add(key); - key.FadeTime = key_fade_time; - key.KeyDownTextColor = KeyDownTextColor; - key.KeyUpTextColor = KeyUpTextColor; - } + keyFlow.Add(new DefaultKeyCounter(trigger) + { + FadeTime = key_fade_time, + KeyDownTextColor = KeyDownTextColor, + KeyUpTextColor = KeyUpTextColor, + }); protected override void UpdateVisibility() => // Isolate changing visibility of the key counters from fading this component. From 5f9b13a77513df7797581eb8f758d0b5fc37f2d8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Mar 2023 18:02:41 +0900 Subject: [PATCH 2473/2991] Rename `Add`/`AddRange` methods as they are no longer conflicting with `Container` --- osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs | 2 +- osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs | 4 ++-- .../Gameplay/TestSceneSkinEditorMultipleSkins.cs | 2 +- .../Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs | 2 +- osu.Game/Rulesets/UI/RulesetInputManager.cs | 2 +- osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs | 2 +- osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs | 10 ++++------ 7 files changed, 11 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 44fa555149..7bc789ecc4 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -266,7 +266,7 @@ namespace osu.Game.Tests.Visual.Gameplay hudOverlay = new HUDOverlay(null, Array.Empty()); // Add any key just to display the key counter visually. - hudOverlay.KeyCounter.AddTrigger(new KeyCounterKeyboardTrigger(Key.Space)); + hudOverlay.KeyCounter.Add(new KeyCounterKeyboardTrigger(Key.Space)); scoreProcessor.Combo.Value = 1; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs index 6dc07ca9d3..46d5e6c4d2 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs @@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual.Gameplay Anchor = Anchor.Centre, }; - kc.AddTriggerRange(new InputTrigger[] + kc.AddRange(new InputTrigger[] { new KeyCounterKeyboardTrigger(Key.X), new KeyCounterKeyboardTrigger(Key.X), @@ -36,7 +36,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("Add random", () => { Key key = (Key)((int)Key.A + RNG.Next(26)); - kc.AddTrigger(new KeyCounterKeyboardTrigger(key)); + kc.Add(new KeyCounterKeyboardTrigger(key)); }); Key testKey = ((KeyCounterKeyboardTrigger)kc.Counters.First().Trigger).Key; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs index aa7119829a..93fec60de4 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditorMultipleSkins.cs @@ -58,7 +58,7 @@ namespace osu.Game.Tests.Visual.Gameplay }; // Add any key just to display the key counter visually. - hudOverlay.KeyCounter.AddTrigger(new KeyCounterKeyboardTrigger(Key.Space)); + hudOverlay.KeyCounter.Add(new KeyCounterKeyboardTrigger(Key.Space)); scoreProcessor.Combo.Value = 1; return new Container diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs index dd1b37341f..9d8d82108d 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs @@ -87,7 +87,7 @@ namespace osu.Game.Tests.Visual.Gameplay hudOverlay = new HUDOverlay(null, Array.Empty()); // Add any key just to display the key counter visually. - hudOverlay.KeyCounter.AddTrigger(new KeyCounterKeyboardTrigger(Key.Space)); + hudOverlay.KeyCounter.Add(new KeyCounterKeyboardTrigger(Key.Space)); action?.Invoke(hudOverlay); diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index ea9dc3fb01..ce3ee8cc7a 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -162,7 +162,7 @@ namespace osu.Game.Rulesets.UI KeyBindingContainer.Add(receptor); keyCounter.SetReceptor(receptor); - keyCounter.AddTriggerRange(KeyBindingContainer.DefaultKeyBindings + keyCounter.AddRange(KeyBindingContainer.DefaultKeyBindings .Select(b => b.GetAction()) .Distinct() .OrderBy(action => action) diff --git a/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs index 8b910d56f6..14d7f56093 100644 --- a/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs @@ -36,7 +36,7 @@ namespace osu.Game.Screens.Play.HUD Size = keyFlow.Size; } - public override void AddTrigger(InputTrigger trigger) + public override void Add(InputTrigger trigger) => keyFlow.Add(new DefaultKeyCounter(trigger) { FadeTime = key_fade_time, diff --git a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs index 0e0f8a1190..49c0da6793 100644 --- a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs @@ -51,16 +51,14 @@ namespace osu.Game.Screens.Play.HUD } /// - /// Adds a new to this . + /// Add a to this display. /// - /// The the resulting will react to. - public abstract void AddTrigger(InputTrigger trigger); + public abstract void Add(InputTrigger trigger); /// - /// Adds a range of new s to this . + /// Add a range of to this display. /// - /// The s the resulting s will react to. - public void AddTriggerRange(IEnumerable triggers) => triggers.ForEach(AddTrigger); + public void AddRange(IEnumerable triggers) => triggers.ForEach(Add); [BackgroundDependencyLoader] private void load(OsuConfigManager config) From edc63146344a81f6ff3c993d11690e99579dbd6b Mon Sep 17 00:00:00 2001 From: Terochi Date: Wed, 15 Mar 2023 10:49:59 +0100 Subject: [PATCH 2474/2991] Drank some coffee and figured out the fix --- osu.Game/Screens/Play/PauseOverlay.cs | 1 - osu.Game/Screens/Play/Player.cs | 5 ----- osu.Game/Skinning/PoolableSkinnableSample.cs | 2 ++ osu.Game/Skinning/SkinReloadableDrawable.cs | 20 +++++++++++--------- osu.Game/Skinning/SkinnableSound.cs | 7 ------- 5 files changed, 13 insertions(+), 22 deletions(-) diff --git a/osu.Game/Screens/Play/PauseOverlay.cs b/osu.Game/Screens/Play/PauseOverlay.cs index 452e170cc6..db42998c45 100644 --- a/osu.Game/Screens/Play/PauseOverlay.cs +++ b/osu.Game/Screens/Play/PauseOverlay.cs @@ -28,7 +28,6 @@ namespace osu.Game.Screens.Play private SkinnableSound pauseLoop; - public void FlushPendingSkinChanges() => pauseLoop.FlushPendingSkinChanges(); protected override Action BackAction => () => InternalButtons.First().TriggerClick(); [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index d4180068d3..bc453d2151 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -316,11 +316,6 @@ namespace osu.Game.Screens.Play // we may want to limit this in the future to disallow rulesets from outright replacing elements the user expects to be there. failAnimationLayer.Add(createOverlayComponents(Beatmap.Value)); - rulesetSkinProvider.SourceChanged += () => - { - PauseOverlay.FlushPendingSkinChanges(); - }; - if (!DrawableRuleset.AllowGameplayOverlays) { HUDOverlay.ShowHud.Value = false; diff --git a/osu.Game/Skinning/PoolableSkinnableSample.cs b/osu.Game/Skinning/PoolableSkinnableSample.cs index 0158c47ea3..c8b0955db2 100644 --- a/osu.Game/Skinning/PoolableSkinnableSample.cs +++ b/osu.Game/Skinning/PoolableSkinnableSample.cs @@ -132,6 +132,8 @@ namespace osu.Game.Skinning if (Sample == null) return; + FlushPendingSkinChanges(); + activeChannel = Sample.GetChannel(); activeChannel.Looping = Looping; activeChannel.Play(); diff --git a/osu.Game/Skinning/SkinReloadableDrawable.cs b/osu.Game/Skinning/SkinReloadableDrawable.cs index ff51eb6dce..b6b9650048 100644 --- a/osu.Game/Skinning/SkinReloadableDrawable.cs +++ b/osu.Game/Skinning/SkinReloadableDrawable.cs @@ -27,6 +27,15 @@ namespace osu.Game.Skinning /// protected ISkinSource CurrentSkin { get; private set; } = null!; + protected void FlushPendingSkinChanges() + { + if (pendingSkinChange == null) + return; + + pendingSkinChange.RunTask(); + pendingSkinChange = null; + } + [BackgroundDependencyLoader] private void load(ISkinSource source) { @@ -42,15 +51,6 @@ namespace osu.Game.Skinning pendingSkinChange = Scheduler.Add(skinChanged); } - public virtual void FlushPendingSkinChanges() - { - if (pendingSkinChange == null) - return; - - pendingSkinChange.RunTask(); - pendingSkinChange = null; - } - protected override void LoadAsyncComplete() { base.LoadAsyncComplete(); @@ -61,6 +61,8 @@ namespace osu.Game.Skinning { SkinChanged(CurrentSkin); OnSkinChanged?.Invoke(); + + pendingSkinChange = null; } /// diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index f80b1f52fa..59b3799e0a 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -110,13 +110,6 @@ namespace osu.Game.Skinning } } - public override void FlushPendingSkinChanges() - { - base.FlushPendingSkinChanges(); - - samplesContainer.ForEach(c => c.FlushPendingSkinChanges()); - } - /// /// Plays the samples. /// From 89b42ddd98f239ca605bf68311b4bc75a42babdc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Mar 2023 15:02:38 +0900 Subject: [PATCH 2475/2991] Don't localise beatmap count string for now --- osu.Game/Localisation/SongSelectStrings.cs | 5 ----- osu.Game/Screens/Select/SongSelect.cs | 11 +++++++++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/osu.Game/Localisation/SongSelectStrings.cs b/osu.Game/Localisation/SongSelectStrings.cs index 046aec6bcf..e1ac328420 100644 --- a/osu.Game/Localisation/SongSelectStrings.cs +++ b/osu.Game/Localisation/SongSelectStrings.cs @@ -19,11 +19,6 @@ namespace osu.Game.Localisation /// public static LocalisableString LocallyModifiedTooltip => new TranslatableString(getKey(@"locally_modified_tooltip"), @"Has been locally modified"); - /// - /// "{0} beatmaps displayed" - /// - public static LocalisableString BeatmapsDisplayed(int arg0) => new TranslatableString(getKey(@"beatmaps_displayed"), @"{0:#,0} beatmaps displayed", arg0); - private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 9f8c3f1a2c..a3521337ee 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -40,7 +40,6 @@ using osu.Game.Skinning; using osuTK; using osuTK.Graphics; using osuTK.Input; -using osu.Game.Localisation; namespace osu.Game.Screens.Select { @@ -163,7 +162,15 @@ namespace osu.Game.Screens.Select BleedBottom = Footer.HEIGHT, SelectionChanged = updateSelectedBeatmap, BeatmapSetsChanged = carouselBeatmapsLoaded, - FilterApplied = () => FilterControl.InformationalText = SongSelectStrings.BeatmapsDisplayed(Carousel.CountDisplayed), + FilterApplied = () => + { + FilterControl.InformationalText = + Carousel.CountDisplayed == 1 + // Intentionally not localised until we have proper support for this (see https://github.com/ppy/osu-framework/pull/4918 + // but also in this case we want support for formatting a number within a string). + ? $"{Carousel.CountDisplayed:#,0} beatmap displayed" + : $"{Carousel.CountDisplayed:#,0} beatmaps displayed"; + }, GetRecommendedBeatmap = s => recommender?.GetRecommendedBeatmap(s), }, c => carouselContainer.Child = c); From 5378cdff20845d4bfa6cea7cea9f02cdf09b8345 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Mar 2023 15:10:35 +0900 Subject: [PATCH 2476/2991] Apply NRT to `TestSceneSkinnableSound` --- .../Gameplay/TestSceneSkinnableSound.cs | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs index 5c69062e67..40bfe975bc 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -22,8 +20,8 @@ namespace osu.Game.Tests.Visual.Gameplay { public partial class TestSceneSkinnableSound : OsuTestScene { - private TestSkinSourceContainer skinSource; - private PausableSkinnableSound skinnableSound; + private TestSkinSourceContainer skinSource = null!; + private PausableSkinnableSound skinnableSound = null!; [SetUpSteps] public void SetUpSteps() @@ -102,7 +100,7 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestSkinChangeDoesntPlayOnPause() { - DrawableSample sample = null; + DrawableSample? sample = null; AddStep("start sample", () => { skinnableSound.Play(); @@ -118,7 +116,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("retrieve and ensure current sample is different", () => { - DrawableSample oldSample = sample; + DrawableSample? oldSample = sample; sample = skinnableSound.ChildrenOfType().Single(); return sample != oldSample; }); @@ -134,20 +132,27 @@ namespace osu.Game.Tests.Visual.Gameplay private partial class TestSkinSourceContainer : Container, ISkinSource, ISamplePlaybackDisabler { [Resolved] - private ISkinSource source { get; set; } + private ISkinSource source { get; set; } = null!; - public event Action SourceChanged; + public event Action? SourceChanged; public Bindable SamplePlaybackDisabled { get; } = new Bindable(); IBindable ISamplePlaybackDisabler.SamplePlaybackDisabled => SamplePlaybackDisabled; - public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => source?.GetDrawableComponent(lookup); - public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => source?.GetTexture(componentName, wrapModeS, wrapModeT); - public ISample GetSample(ISampleInfo sampleInfo) => source?.GetSample(sampleInfo); - public IBindable GetConfig(TLookup lookup) => source?.GetConfig(lookup); - public ISkin FindProvider(Func lookupFunction) => lookupFunction(this) ? this : source?.FindProvider(lookupFunction); - public IEnumerable AllSources => new[] { this }.Concat(source?.AllSources ?? Enumerable.Empty()); + public Drawable? GetDrawableComponent(ISkinComponentLookup lookup) => source.GetDrawableComponent(lookup); + public Texture? GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => source.GetTexture(componentName, wrapModeS, wrapModeT); + public ISample? GetSample(ISampleInfo sampleInfo) => source.GetSample(sampleInfo); + + public IBindable? GetConfig(TLookup lookup) + where TLookup : notnull + where TValue : notnull + { + return source.GetConfig(lookup); + } + + public ISkin? FindProvider(Func lookupFunction) => lookupFunction(this) ? this : source.FindProvider(lookupFunction); + public IEnumerable AllSources => new[] { this }.Concat(source.AllSources); public void TriggerSourceChanged() { From 297e7d654239ecc02b6516cf80fafb2a34c23afa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Mar 2023 15:33:30 +0900 Subject: [PATCH 2477/2991] Fix `Flush` call being run too late in `PoolableSkinnableSample` --- osu.Game/Skinning/PoolableSkinnableSample.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/PoolableSkinnableSample.cs b/osu.Game/Skinning/PoolableSkinnableSample.cs index c8b0955db2..361c8688e7 100644 --- a/osu.Game/Skinning/PoolableSkinnableSample.cs +++ b/osu.Game/Skinning/PoolableSkinnableSample.cs @@ -129,11 +129,11 @@ namespace osu.Game.Skinning /// public void Play() { + FlushPendingSkinChanges(); + if (Sample == null) return; - FlushPendingSkinChanges(); - activeChannel = Sample.GetChannel(); activeChannel.Looping = Looping; activeChannel.Play(); From 159c8833c7e2506feed18ba05d1ec51df3a54860 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Mar 2023 15:41:05 +0900 Subject: [PATCH 2478/2991] Add test coverage of `SkinnableSound` not updating in time when not present --- .../Gameplay/TestSceneSkinnableSound.cs | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs index 40bfe975bc..cc82ffed2b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs @@ -23,6 +23,8 @@ namespace osu.Game.Tests.Visual.Gameplay private TestSkinSourceContainer skinSource = null!; private PausableSkinnableSound skinnableSound = null!; + private const string sample_lookup = "Gameplay/normal-sliderslide"; + [SetUpSteps] public void SetUpSteps() { @@ -34,7 +36,7 @@ namespace osu.Game.Tests.Visual.Gameplay }; // has to be added after the hierarchy above else the `ISkinSource` dependency won't be cached. - skinSource.Add(skinnableSound = new PausableSkinnableSound(new SampleInfo("Gameplay/normal-sliderslide"))); + skinSource.Add(skinnableSound = new PausableSkinnableSound(new SampleInfo(sample_lookup))); }); } @@ -97,6 +99,27 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("sample not playing", () => !skinnableSound.IsPlaying); } + [Test] + public void TestSampleUpdatedBeforePlaybackWhenNotPresent() + { + AddStep("make sample non-present", () => skinnableSound.Hide()); + AddUntilStep("ensure not present", () => skinnableSound.IsPresent, () => Is.False); + + AddUntilStep("ensure sample loaded", () => skinnableSound.ChildrenOfType().Single().Name, () => Is.EqualTo(sample_lookup)); + + AddStep("Change source", () => + { + skinSource.OverridingSample = new SampleVirtual("new skin"); + skinSource.TriggerSourceChanged(); + }); + + // Samples are nulled on source change immediately + AddUntilStep("wait for sample null", () => skinnableSound.ChildrenOfType().Count(), () => Is.Zero); + + AddStep("start sample", () => skinnableSound.Play()); + AddUntilStep("sample updated", () => skinnableSound.ChildrenOfType().Single().Name, () => Is.EqualTo("new skin")); + } + [Test] public void TestSkinChangeDoesntPlayOnPause() { @@ -138,11 +161,13 @@ namespace osu.Game.Tests.Visual.Gameplay public Bindable SamplePlaybackDisabled { get; } = new Bindable(); + public ISample? OverridingSample; + IBindable ISamplePlaybackDisabler.SamplePlaybackDisabled => SamplePlaybackDisabled; public Drawable? GetDrawableComponent(ISkinComponentLookup lookup) => source.GetDrawableComponent(lookup); public Texture? GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => source.GetTexture(componentName, wrapModeS, wrapModeT); - public ISample? GetSample(ISampleInfo sampleInfo) => source.GetSample(sampleInfo); + public ISample? GetSample(ISampleInfo sampleInfo) => OverridingSample ?? source.GetSample(sampleInfo); public IBindable? GetConfig(TLookup lookup) where TLookup : notnull From 8e6a4559e3ae8c9892866cf9cf8d4e8d1b72afd0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Mar 2023 15:58:42 +0900 Subject: [PATCH 2479/2991] Add xmldoc for new method and reorder methods in `SkinReloadableDrawable` --- osu.Game/Skinning/SkinReloadableDrawable.cs | 47 +++++++++++++-------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/osu.Game/Skinning/SkinReloadableDrawable.cs b/osu.Game/Skinning/SkinReloadableDrawable.cs index b6b9650048..c7b33dc539 100644 --- a/osu.Game/Skinning/SkinReloadableDrawable.cs +++ b/osu.Game/Skinning/SkinReloadableDrawable.cs @@ -27,6 +27,30 @@ namespace osu.Game.Skinning /// protected ISkinSource CurrentSkin { get; private set; } = null!; + [BackgroundDependencyLoader] + private void load(ISkinSource source) + { + CurrentSkin = source; + CurrentSkin.SourceChanged += onChange; + } + + protected override void LoadAsyncComplete() + { + base.LoadAsyncComplete(); + skinChanged(); + } + + /// + /// Force any pending calls to be performed immediately. + /// + /// + /// When a skin change occurs, the handling provided by this class is scheduled. + /// In some cases, such a sample playback, this can result in the sample being played + /// just before it is updated to a potentially different sample. + /// + /// Calling this method will ensure any pending update operations are run immediately. + /// It is recommended to call this before consuming the result of skin changes for anything non-drawable. + /// protected void FlushPendingSkinChanges() { if (pendingSkinChange == null) @@ -36,11 +60,12 @@ namespace osu.Game.Skinning pendingSkinChange = null; } - [BackgroundDependencyLoader] - private void load(ISkinSource source) + /// + /// Called when a change is made to the skin. + /// + /// The new skin. + protected virtual void SkinChanged(ISkinSource skin) { - CurrentSkin = source; - CurrentSkin.SourceChanged += onChange; } private void onChange() @@ -51,12 +76,6 @@ namespace osu.Game.Skinning pendingSkinChange = Scheduler.Add(skinChanged); } - protected override void LoadAsyncComplete() - { - base.LoadAsyncComplete(); - skinChanged(); - } - private void skinChanged() { SkinChanged(CurrentSkin); @@ -65,14 +84,6 @@ namespace osu.Game.Skinning pendingSkinChange = null; } - /// - /// Called when a change is made to the skin. - /// - /// The new skin. - protected virtual void SkinChanged(ISkinSource skin) - { - } - protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); From cd102da3af06d06486ea20daa319f143ab13632c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Mar 2023 16:34:31 +0900 Subject: [PATCH 2480/2991] Move matches string inside text box --- osu.Game/Screens/Select/FilterControl.cs | 50 +++++++++++++++--------- osu.Game/Screens/Select/SongSelect.cs | 4 +- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index b5469abffe..1bcc042f72 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -38,8 +38,8 @@ namespace osu.Game.Screens.Select public LocalisableString InformationalText { - get => filterText.Text; - set => filterText.Text = value; + get => searchTextBox.FilterText.Text; + set => searchTextBox.FilterText.Text = value; } private OsuTabControl sortTabs; @@ -48,12 +48,10 @@ namespace osu.Game.Screens.Select private Bindable groupMode; - private SeekLimitedSearchTextBox searchTextBox; + private FilterControlTextBox searchTextBox; private CollectionDropdown collectionDropdown; - private OsuSpriteText filterText; - public FilterCriteria CreateCriteria() { string query = searchTextBox.Text; @@ -111,22 +109,9 @@ namespace osu.Game.Screens.Select Spacing = new Vector2(0, 5), Children = new Drawable[] { - searchTextBox = new SeekLimitedSearchTextBox { RelativeSizeAxes = Axes.X }, - new Container + searchTextBox = new FilterControlTextBox { RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - AutoSizeDuration = 200, - AutoSizeEasing = Easing.OutQuint, - Children = new Drawable[] - { - filterText = new OsuSpriteText - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Font = OsuFont.Default.With(size: 12), - }, - } }, new Box { @@ -262,5 +247,32 @@ namespace osu.Game.Screens.Select protected override bool OnClick(ClickEvent e) => true; protected override bool OnHover(HoverEvent e) => true; + + private partial class FilterControlTextBox : SeekLimitedSearchTextBox + { + private const float filter_text_size = 12; + + public OsuSpriteText FilterText; + + public FilterControlTextBox() + { + Height += filter_text_size; + TextContainer.Margin = new MarginPadding { Bottom = filter_text_size }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + TextContainer.Add(FilterText = new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.TopLeft, + Depth = float.MinValue, + Font = OsuFont.Default.With(size: filter_text_size, weight: FontWeight.SemiBold), + Margin = new MarginPadding { Top = 2, Left = 2 }, + Colour = colours.Yellow + }); + } + } } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index a3521337ee..722119f82e 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -168,8 +168,8 @@ namespace osu.Game.Screens.Select Carousel.CountDisplayed == 1 // Intentionally not localised until we have proper support for this (see https://github.com/ppy/osu-framework/pull/4918 // but also in this case we want support for formatting a number within a string). - ? $"{Carousel.CountDisplayed:#,0} beatmap displayed" - : $"{Carousel.CountDisplayed:#,0} beatmaps displayed"; + ? $"{Carousel.CountDisplayed:#,0} matching beatmap" + : $"{Carousel.CountDisplayed:#,0} matching beatmaps"; }, GetRecommendedBeatmap = s => recommender?.GetRecommendedBeatmap(s), }, c => carouselContainer.Child = c); From a81408ca0626edc77c36060d0bf574dd1a47cdd5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Mar 2023 17:12:46 +0900 Subject: [PATCH 2481/2991] Add failing test coverage showing that replay will fail on exiting gameplay --- .../Visual/Gameplay/TestSceneReplayPlayer.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs index 3e415af86e..ae10207de0 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs @@ -8,6 +8,7 @@ using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; +using osu.Game.Scoring; using osu.Game.Screens.Play; using osu.Game.Tests.Beatmaps; using osuTK.Input; @@ -45,6 +46,18 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("Time still stopped", () => lastTime == Player.GameplayClockContainer.CurrentTime); } + [Test] + public void TestDoesNotFailOnExit() + { + loadPlayerWithBeatmap(); + + AddUntilStep("wait for first hit", () => Player.ScoreProcessor.TotalScore.Value > 0); + AddAssert("ensure rank is not fail", () => Player.ScoreProcessor.Rank.Value, () => Is.Not.EqualTo(ScoreRank.F)); + AddStep("exit player", () => Player.Exit()); + AddUntilStep("wait for exit", () => Player.Parent == null); + AddAssert("ensure rank is not fail", () => Player.ScoreProcessor.Rank.Value, () => Is.Not.EqualTo(ScoreRank.F)); + } + [Test] public void TestPauseViaSpaceWithSkip() { From 3b62f87b64f966bd277323d9afc7e256e1dea5e0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Mar 2023 17:14:20 +0900 Subject: [PATCH 2482/2991] Ensure `Player` does not fail a score on exit if a replay is currently loaded --- osu.Game/Screens/Play/Player.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index bc453d2151..8d0da8c44f 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -1111,7 +1111,7 @@ namespace osu.Game.Screens.Play GameplayState.HasQuit = true; // if arriving here and the results screen preparation task hasn't run, it's safe to say the user has not completed the beatmap. - if (prepareScoreForDisplayTask == null) + if (prepareScoreForDisplayTask == null && DrawableRuleset.ReplayScore == null) ScoreProcessor.FailScore(Score.ScoreInfo); } From 42bcc8bafc01005ad91035dde8d80d027b3552f5 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 16 Mar 2023 19:15:50 +0900 Subject: [PATCH 2483/2991] revert mod store --- osu.Game/Overlays/Mods/ModPresetPanel.cs | 12 ++++-------- osu.Game/Overlays/Mods/ModPresetTooltip.cs | 13 ++++++------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModPresetPanel.cs b/osu.Game/Overlays/Mods/ModPresetPanel.cs index 49437c5bb1..d01981d18c 100644 --- a/osu.Game/Overlays/Mods/ModPresetPanel.cs +++ b/osu.Game/Overlays/Mods/ModPresetPanel.cs @@ -18,12 +18,10 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Overlays.Mods { - public partial class ModPresetPanel : ModSelectPanel, IHasCustomTooltip>, IHasContextMenu, IHasPopover + public partial class ModPresetPanel : ModSelectPanel, IHasCustomTooltip, IHasContextMenu, IHasPopover { public readonly Live Preset; - public readonly Bindable> Mods = new Bindable>(); - public override BindableBool Active { get; } = new BindableBool(); [Resolved] @@ -37,7 +35,6 @@ namespace osu.Game.Overlays.Mods public ModPresetPanel(Live preset) { Preset = preset; - Mods.Value = preset.Value.Mods.ToList(); Title = preset.Value.Name; Description = preset.Value.Description; @@ -54,7 +51,6 @@ namespace osu.Game.Overlays.Mods base.LoadComplete(); selectedMods.BindValueChanged(_ => selectedModsChanged(), true); - Mods.BindValueChanged(_ => updateActiveState(), true); } protected override void Select() @@ -82,13 +78,13 @@ namespace osu.Game.Overlays.Mods private void updateActiveState() { - Active.Value = new HashSet(Mods.Value).SetEquals(selectedMods.Value); + Active.Value = new HashSet(Preset.Value.Mods).SetEquals(selectedMods.Value); } #region IHasCustomTooltip - public List TooltipContent => Mods.Value; - public ITooltip> GetCustomTooltip() => new ModPresetTooltip(ColourProvider); + public ModPreset TooltipContent => Preset.Value; + public ITooltip GetCustomTooltip() => new ModPresetTooltip(ColourProvider); #endregion diff --git a/osu.Game/Overlays/Mods/ModPresetTooltip.cs b/osu.Game/Overlays/Mods/ModPresetTooltip.cs index 0b31a97064..8e8259de45 100644 --- a/osu.Game/Overlays/Mods/ModPresetTooltip.cs +++ b/osu.Game/Overlays/Mods/ModPresetTooltip.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.Collections.Generic; using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -12,7 +11,7 @@ using osuTK; namespace osu.Game.Overlays.Mods { - public partial class ModPresetTooltip : VisibilityContainer, ITooltip> + public partial class ModPresetTooltip : VisibilityContainer, ITooltip { protected override Container Content { get; } @@ -43,15 +42,15 @@ namespace osu.Game.Overlays.Mods }; } - private List? lastPreset; + private ModPreset? lastPreset; - public void SetContent(List mods) + public void SetContent(ModPreset preset) { - if (ReferenceEquals(mods, lastPreset)) + if (ReferenceEquals(preset, lastPreset)) return; - lastPreset = mods; - Content.ChildrenEnumerable = mods.Select(mod => new ModPresetRow(mod)); + lastPreset = preset; + Content.ChildrenEnumerable = preset.Mods.Select(mod => new ModPresetRow(mod)); } protected override void PopIn() => this.FadeIn(transition_duration, Easing.OutQuint); From cb9b14b30fd8c3620d5b45aadb9152a9b29f3617 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 16 Mar 2023 19:48:36 +0900 Subject: [PATCH 2484/2991] Revert "Merge pull request #22741 from cdwcgt/do-not-fetch-deletePending" This reverts commit 15c44a281725189671c29fb569949f7c8be66cbe, reversing changes made to de2ab05e785dfaf2fb108c68c4c7424c8db417a5. --- osu.Game/Scoring/Legacy/DatabasedLegacyScoreDecoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Scoring/Legacy/DatabasedLegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/DatabasedLegacyScoreDecoder.cs index 8ee2cc6241..8908163646 100644 --- a/osu.Game/Scoring/Legacy/DatabasedLegacyScoreDecoder.cs +++ b/osu.Game/Scoring/Legacy/DatabasedLegacyScoreDecoder.cs @@ -24,6 +24,6 @@ namespace osu.Game.Scoring.Legacy } protected override Ruleset GetRuleset(int rulesetId) => rulesets.GetRuleset(rulesetId)?.CreateInstance(); - protected override WorkingBeatmap GetBeatmap(string md5Hash) => beatmaps.GetWorkingBeatmap(beatmaps.QueryBeatmap(b => b.MD5Hash == md5Hash && !b.BeatmapSet.DeletePending)); + protected override WorkingBeatmap GetBeatmap(string md5Hash) => beatmaps.GetWorkingBeatmap(beatmaps.QueryBeatmap(b => b.MD5Hash == md5Hash)); } } From d025c441ca2249489b6d0c523d55b44ef1da6108 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 16 Mar 2023 19:38:52 +0900 Subject: [PATCH 2485/2991] delay mod save after click save or not popover hidden --- .../UserInterface/TestSceneModPresetColumn.cs | 20 ++++++----- osu.Game/Overlays/Mods/EditPresetPopover.cs | 36 ++++++++++--------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs index 68efb2a5f4..c4c5584c5e 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs @@ -319,6 +319,7 @@ namespace osu.Game.Tests.Visual.UserInterface { ModPresetColumn modPresetColumn = null!; var mods = new Mod[] { new OsuModHidden(), new OsuModHardRock() }; + List previousMod = null!; AddStep("clear mods", () => SelectedMods.Value = Array.Empty()); AddStep("create content", () => Child = modPresetColumn = new ModPresetColumn @@ -332,6 +333,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("right click first panel", () => { var panel = this.ChildrenOfType().First(); + previousMod = panel.Preset.Value.Mods.ToList(); InputManager.MoveMouseTo(panel); InputManager.Click(MouseButton.Right); }); @@ -350,10 +352,14 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.MoveMouseTo(popover.ChildrenOfType().ElementAt(0)); InputManager.Click(MouseButton.Left); }); + AddStep("attempt preset edit", () => + { + InputManager.MoveMouseTo(popover.ChildrenOfType().ElementAt(1)); + InputManager.Click(MouseButton.Left); + }); AddWaitStep("wait some", 3); - AddUntilStep("popover not closed", () => this.ChildrenOfType().Any()); AddAssert("present mod not changed", () => - !new HashSet(this.ChildrenOfType().First().Mods.Value).SetEquals(mods)); + new HashSet(this.ChildrenOfType().First().Preset.Value.Mods).SetEquals(previousMod)); AddStep("select mods", () => SelectedMods.Value = mods); AddStep("right click first panel", () => @@ -377,17 +383,13 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.MoveMouseTo(popover.ChildrenOfType().ElementAt(0)); InputManager.Click(MouseButton.Left); }); - AddWaitStep("wait some", 3); - AddUntilStep("popover not closed", () => this.ChildrenOfType().Any()); - AddAssert("present mod is changed", () => - new HashSet(this.ChildrenOfType().First().Mods.Value).SetEquals(mods)); - - AddStep("click edit", () => + AddStep("attempt preset edit", () => { InputManager.MoveMouseTo(popover.ChildrenOfType().ElementAt(1)); InputManager.Click(MouseButton.Left); }); - AddAssert("present mod in realm is changed", () => + AddWaitStep("wait some", 3); + AddAssert("present mod is changed", () => new HashSet(this.ChildrenOfType().First().Preset.Value.Mods).SetEquals(mods)); } diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs index 92860e96a6..0e21260493 100644 --- a/osu.Game/Overlays/Mods/EditPresetPopover.cs +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -130,7 +130,7 @@ namespace osu.Game.Overlays.Mods private void trySaveCurrentMod() { - if (!button.CheckCurrentModCanBeSave()) + if (!checkCanBeSave()) { Body.Shake(); return; @@ -139,13 +139,12 @@ namespace osu.Game.Overlays.Mods saveModAfterClosed = selectedMods.Value.ToList(); scrollContent.Clear(); scrollContent.ChildrenEnumerable = saveModAfterClosed.Select(mod => new ModPresetRow(mod)); - button.Mods.Value = saveModAfterClosed; updateActiveState(); } private void updateActiveState() { - if (button.CheckCurrentModCanBeSave()) + if (checkCanBeSave()) { useCurrentModButton.DarkerColour = colours.Blue1; useCurrentModButton.LighterColour = colours.Blue0; @@ -159,6 +158,19 @@ namespace osu.Game.Overlays.Mods } } + private bool checkCanBeSave() + { + if (!selectedMods.Value.Any()) + return false; + + if (saveModAfterClosed.Any()) + { + return !new HashSet(saveModAfterClosed).SetEquals(selectedMods.Value); + } + + return button.CheckCurrentModCanBeSave(); + } + protected override void LoadComplete() { base.LoadComplete(); @@ -178,22 +190,14 @@ namespace osu.Game.Overlays.Mods { s.Name = nameTextBox.Current.Value; s.Description = descriptionTextBox.Current.Value; + + if (saveModAfterClosed.Any()) + { + s.Mods = saveModAfterClosed; + } }); this.HidePopover(); } - - protected override void UpdateState(ValueChangedEvent state) - { - base.UpdateState(state); - - if (state.NewValue == Visibility.Hidden && saveModAfterClosed.Any()) - { - button.Preset.PerformWrite(s => - { - s.Mods = saveModAfterClosed; - }); - } - } } } From 678e8ed736b4b89617988300888997fab85d4373 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 16 Mar 2023 14:06:35 +0300 Subject: [PATCH 2486/2991] Update UBO usages inline with framework changes --- osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs | 5 +++-- .../Visual/Background/TestSceneTriangleBorderShader.cs | 8 ++++---- osu.Game/Graphics/Backgrounds/Triangles.cs | 2 +- osu.Game/Graphics/Backgrounds/TrianglesV2.cs | 2 +- osu.Game/Graphics/Sprites/LogoAnimation.cs | 8 ++++---- osu.Game/Rulesets/Mods/ModFlashlight.cs | 2 +- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs index a824f202ec..9d64c354e2 100644 --- a/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs +++ b/osu.Game.Rulesets.Osu/Skinning/SmokeSegment.cs @@ -252,13 +252,14 @@ namespace osu.Game.Rulesets.Osu.Skinning renderer.SetBlend(BlendingParameters.Additive); renderer.PushLocalMatrix(DrawInfo.Matrix); - TextureShader.Bind(); + BindTextureShader(renderer); + texture.Bind(); for (int i = 0; i < points.Count; i++) drawPointQuad(points[i], textureRect, i + firstVisiblePointIndex); - TextureShader.Unbind(); + UnbindTextureShader(renderer); renderer.PopLocalMatrix(); } diff --git a/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs b/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs index 07427c242f..711d9ab5ea 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneTriangleBorderShader.cs @@ -100,8 +100,10 @@ namespace osu.Game.Tests.Visual.Background private IUniformBuffer? borderDataBuffer; - public override void Draw(IRenderer renderer) + protected override void BindUniformResources(IShader shader, IRenderer renderer) { + base.BindUniformResources(shader, renderer); + borderDataBuffer ??= renderer.CreateUniformBuffer(); borderDataBuffer.Data = borderDataBuffer.Data with { @@ -109,9 +111,7 @@ namespace osu.Game.Tests.Visual.Background TexelSize = texelSize }; - TextureShader.BindUniformBlock("m_BorderData", borderDataBuffer); - - base.Draw(renderer); + shader.BindUniformBlock("m_BorderData", borderDataBuffer); } protected override bool CanDrawOpaqueInterior => false; diff --git a/osu.Game/Graphics/Backgrounds/Triangles.cs b/osu.Game/Graphics/Backgrounds/Triangles.cs index 28a715ca0b..0ee42c69d5 100644 --- a/osu.Game/Graphics/Backgrounds/Triangles.cs +++ b/osu.Game/Graphics/Backgrounds/Triangles.cs @@ -306,7 +306,7 @@ namespace osu.Game.Graphics.Backgrounds }; shader.Bind(); - shader.BindUniformBlock("m_BorderData", borderDataBuffer); + shader.BindUniformBlock(@"m_BorderData", borderDataBuffer); foreach (TriangleParticle particle in parts) { diff --git a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs index 6a34fefa3a..750e96440d 100644 --- a/osu.Game/Graphics/Backgrounds/TrianglesV2.cs +++ b/osu.Game/Graphics/Backgrounds/TrianglesV2.cs @@ -249,7 +249,7 @@ namespace osu.Game.Graphics.Backgrounds }; shader.Bind(); - shader.BindUniformBlock("m_BorderData", borderDataBuffer); + shader.BindUniformBlock(@"m_BorderData", borderDataBuffer); Vector2 relativeSize = Vector2.Divide(triangleSize, size); diff --git a/osu.Game/Graphics/Sprites/LogoAnimation.cs b/osu.Game/Graphics/Sprites/LogoAnimation.cs index 220f57e9fa..eb7613a1b2 100644 --- a/osu.Game/Graphics/Sprites/LogoAnimation.cs +++ b/osu.Game/Graphics/Sprites/LogoAnimation.cs @@ -59,14 +59,14 @@ namespace osu.Game.Graphics.Sprites private IUniformBuffer animationDataBuffer; - protected override void Blit(IRenderer renderer) + protected override void BindUniformResources(IShader shader, IRenderer renderer) { + base.BindUniformResources(shader, renderer); + animationDataBuffer ??= renderer.CreateUniformBuffer(); animationDataBuffer.Data = animationDataBuffer.Data with { Progress = progress }; - TextureShader.BindUniformBlock("m_AnimationData", animationDataBuffer); - - base.Blit(renderer); + shader.BindUniformBlock(@"m_AnimationData", animationDataBuffer); } protected override bool CanDrawOpaqueInterior => false; diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index a7889cb98d..f8c3a730f2 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -273,7 +273,7 @@ namespace osu.Game.Rulesets.Mods }; shader.Bind(); - shader.BindUniformBlock("m_FlashlightParameters", flashlightParametersBuffer); + shader.BindUniformBlock(@"m_FlashlightParameters", flashlightParametersBuffer); renderer.DrawQuad(renderer.WhitePixel, screenSpaceDrawQuad, DrawColourInfo.Colour, vertexAction: addAction); From 1c3b60b9e6c6d31a2d955fcf0dafe41b20774abf Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Thu, 16 Mar 2023 23:56:41 +0900 Subject: [PATCH 2487/2991] Use custom vertex shader for logo animation --- osu.Game/Graphics/Sprites/LogoAnimation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Sprites/LogoAnimation.cs b/osu.Game/Graphics/Sprites/LogoAnimation.cs index 220f57e9fa..619a28ecad 100644 --- a/osu.Game/Graphics/Sprites/LogoAnimation.cs +++ b/osu.Game/Graphics/Sprites/LogoAnimation.cs @@ -18,7 +18,7 @@ namespace osu.Game.Graphics.Sprites [BackgroundDependencyLoader] private void load(ShaderManager shaders) { - TextureShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, @"LogoAnimation"); + TextureShader = shaders.Load(@"LogoAnimation", @"LogoAnimation"); } private float animationProgress; From 8bdb89d05dbc779fda0a6b9f924b6e07eca2b63c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 17 Mar 2023 19:12:43 +0900 Subject: [PATCH 2488/2991] Update resources --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index c08dc9ed8f..ce9cf37ec3 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -37,7 +37,7 @@ - + From bcd24873d6361992339ca2ef5e1fdd6053419c33 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 17 Mar 2023 20:37:05 +0900 Subject: [PATCH 2489/2991] Use custom vertex type --- osu.Game/Graphics/Sprites/LogoAnimation.cs | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/osu.Game/Graphics/Sprites/LogoAnimation.cs b/osu.Game/Graphics/Sprites/LogoAnimation.cs index 619a28ecad..3b8b0bfc88 100644 --- a/osu.Game/Graphics/Sprites/LogoAnimation.cs +++ b/osu.Game/Graphics/Sprites/LogoAnimation.cs @@ -3,13 +3,18 @@ #nullable disable +using System; using System.Runtime.InteropServices; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Rendering; +using osu.Framework.Graphics.Rendering.Vertices; using osu.Framework.Graphics.Shaders; using osu.Framework.Graphics.Shaders.Types; using osu.Framework.Graphics.Sprites; +using osuTK; +using osuTK.Graphics; +using osuTK.Graphics.ES30; namespace osu.Game.Graphics.Sprites { @@ -43,11 +48,22 @@ namespace osu.Game.Graphics.Sprites { private LogoAnimation source => (LogoAnimation)Source; + private readonly Action addVertexAction; + private float progress; public LogoAnimationDrawNode(LogoAnimation source) : base(source) { + addVertexAction = v => + { + animationVertexBatch!.Add(new LogoAnimationVertex + { + Position = v.Position, + Colour = v.Colour, + TexturePosition = v.TexturePosition, + }); + }; } public override void ApplyState() @@ -58,10 +74,13 @@ namespace osu.Game.Graphics.Sprites } private IUniformBuffer animationDataBuffer; + private IVertexBatch animationVertexBatch; protected override void Blit(IRenderer renderer) { animationDataBuffer ??= renderer.CreateUniformBuffer(); + animationVertexBatch ??= renderer.CreateQuadBatch(1, 2); + animationDataBuffer.Data = animationDataBuffer.Data with { Progress = progress }; TextureShader.BindUniformBlock("m_AnimationData", animationDataBuffer); @@ -83,6 +102,24 @@ namespace osu.Game.Graphics.Sprites public UniformFloat Progress; private readonly UniformPadding12 pad1; } + + [StructLayout(LayoutKind.Sequential)] + private struct LogoAnimationVertex : IEquatable, IVertex + { + [VertexMember(2, VertexAttribPointerType.Float)] + public Vector2 Position; + + [VertexMember(4, VertexAttribPointerType.Float)] + public Color4 Colour; + + [VertexMember(2, VertexAttribPointerType.Float)] + public Vector2 TexturePosition; + + public readonly bool Equals(LogoAnimationVertex other) => + Position.Equals(other.Position) + && TexturePosition.Equals(other.TexturePosition) + && Colour.Equals(other.Colour); + } } } } From c08513d59049e78c8151a2b2fbaaa4df1921ccef Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 17 Mar 2023 20:47:11 +0900 Subject: [PATCH 2490/2991] Actually use custom vertex action --- osu.Game/Graphics/Sprites/LogoAnimation.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Sprites/LogoAnimation.cs b/osu.Game/Graphics/Sprites/LogoAnimation.cs index 3b8b0bfc88..fbf8717d3c 100644 --- a/osu.Game/Graphics/Sprites/LogoAnimation.cs +++ b/osu.Game/Graphics/Sprites/LogoAnimation.cs @@ -78,6 +78,9 @@ namespace osu.Game.Graphics.Sprites protected override void Blit(IRenderer renderer) { + if (DrawRectangle.Width == 0 || DrawRectangle.Height == 0) + return; + animationDataBuffer ??= renderer.CreateUniformBuffer(); animationVertexBatch ??= renderer.CreateQuadBatch(1, 2); @@ -85,7 +88,13 @@ namespace osu.Game.Graphics.Sprites TextureShader.BindUniformBlock("m_AnimationData", animationDataBuffer); - base.Blit(renderer); + renderer.DrawQuad( + Texture, + ScreenSpaceDrawQuad, + DrawColourInfo.Colour, + inflationPercentage: new Vector2(InflationAmount.X / DrawRectangle.Width, InflationAmount.Y / DrawRectangle.Height), + textureCoords: TextureCoords, + vertexAction: addVertexAction); } protected override bool CanDrawOpaqueInterior => false; From 970df5d88a09d6d55797739164ce20cb08b9aed4 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 12 Mar 2023 18:46:34 -0700 Subject: [PATCH 2491/2991] Update profile kudosu section in line with web --- .../Profile/Sections/Kudosu/KudosuInfo.cs | 24 +------------------ 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs index d2f01ef9f7..7b26640e50 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs @@ -2,15 +2,12 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Bindables; -using osuTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Framework.Allocation; using osu.Framework.Extensions.LocalisationExtensions; using osu.Game.Resources.Localisation.Web; using osu.Framework.Localisation; @@ -52,7 +49,6 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { private readonly OsuSpriteText valueText; protected readonly LinkFlowContainer DescriptionText; - private readonly Box lineBackground; public new int Count { @@ -63,25 +59,14 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - Padding = new MarginPadding { Top = 10, Bottom = 20 }; + Padding = new MarginPadding { Bottom = 20 }; Child = new FillFlowContainer { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 5), Children = new Drawable[] { - new CircularContainer - { - Masking = true, - RelativeSizeAxes = Axes.X, - Height = 2, - Child = lineBackground = new Box - { - RelativeSizeAxes = Axes.Both, - } - }, new OsuSpriteText { Text = header, @@ -91,7 +76,6 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { Text = "0", Font = OsuFont.GetFont(size: 40, weight: FontWeight.Light), - UseFullGlyphHeight = false, }, DescriptionText = new LinkFlowContainer(t => t.Font = t.Font.With(size: 14)) { @@ -101,12 +85,6 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu } }; } - - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - lineBackground.Colour = colourProvider.Highlight1; - } } } } From 48b6e214af56fab60571964a91474c5f8d3ce296 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Sun, 19 Mar 2023 17:12:12 +0100 Subject: [PATCH 2492/2991] Fix URL handling on macOS --- osu.Desktop/OsuGameDesktop.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index b3f6370ccb..3fe251cb00 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -139,7 +139,17 @@ namespace osu.Desktop desktopWindow.CursorState |= CursorState.Hidden; desktopWindow.Title = Name; - desktopWindow.DragDrop += f => fileDrop(new[] { f }); + desktopWindow.DragDrop += f => + { + // on macOS, URL associations are handled via SDL_DROPFILE events. + if (f.StartsWith(OSU_PROTOCOL, StringComparison.Ordinal)) + { + HandleLink(f); + return; + } + + fileDrop(new[] { f }); + }; } protected override BatteryInfo CreateBatteryInfo() => new SDL2BatteryInfo(); From b254dbd7ca409e502b9d041f9c0c623ea3afd841 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Sun, 19 Mar 2023 17:37:49 +0100 Subject: [PATCH 2493/2991] Remove arbitrary extension limitation from drag and drop imports `OsuGameBase` already properly handles multiple extensions in the same import. --- osu.Desktop/OsuGameDesktop.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index b3f6370ccb..6b5c5b809b 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -151,10 +151,6 @@ namespace osu.Desktop { lock (importableFiles) { - string firstExtension = Path.GetExtension(filePaths.First()); - - if (filePaths.Any(f => Path.GetExtension(f) != firstExtension)) return; - importableFiles.AddRange(filePaths); Logger.Log($"Adding {filePaths.Length} files for import"); From 11f52d5bf4440d5012dbaff2167e921d7f2fd49c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 20 Mar 2023 14:01:35 +0900 Subject: [PATCH 2494/2991] Remove unused using statement --- osu.Desktop/OsuGameDesktop.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index 6b5c5b809b..f094785a5b 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Linq; using System.Reflection; using System.Runtime.Versioning; using System.Threading.Tasks; From 8557589a3542c7bc26969c9c8cbdac5f3a418ec5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 20 Mar 2023 15:28:13 +0900 Subject: [PATCH 2495/2991] Update resources --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index ce9cf37ec3..54d6533713 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -37,7 +37,7 @@ - + From 13a32b5246442bed162b1b4cefc873aa48750c78 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 20 Mar 2023 15:36:27 +0900 Subject: [PATCH 2496/2991] Move lock-in variable to `const` and document better --- osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs index 8cec65f515..4270a4df58 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs @@ -22,6 +22,13 @@ namespace osu.Game.Rulesets.Osu.UI /// private readonly List trackedTouches = new List(); + /// + /// The distance (in local pixels) that a touch must move before being considered a permanent tracking touch. + /// After this distance is covered, any extra touches on the screen will be considered as button inputs, unless + /// a new touch directly interacts with a hit circle. + /// + private const float distance_before_position_tracking_lock_in = 200; + private TrackedTouch? positionTrackingTouch; private readonly OsuInputManager osuInputManager; @@ -98,7 +105,7 @@ namespace osu.Game.Rulesets.Osu.UI } // ..or if the current position tracking touch was not a direct touch (and didn't travel across the screen too far). - if (!positionTrackingTouch.DirectTouch && positionTrackingTouch.DistanceTravelled < 200) + if (!positionTrackingTouch.DirectTouch && positionTrackingTouch.DistanceTravelled < distance_before_position_tracking_lock_in) { positionTrackingTouch = newTouch; return; @@ -160,9 +167,9 @@ namespace osu.Game.Rulesets.Osu.UI public readonly bool DirectTouch; /// - /// The total distance on screen travelled by this touch. + /// The total distance on screen travelled by this touch (in local pixels). /// - public double DistanceTravelled; + public float DistanceTravelled; public TrackedTouch(TouchSource source, OsuAction? action, bool directTouch) { From c056d5a6fb9f779e958b6eb1731ffa204a166600 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 20 Mar 2023 15:36:58 +0900 Subject: [PATCH 2497/2991] Reduce distance requirement for lock-in behaviour --- osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs index 4270a4df58..5277a1f7d6 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuTouchInputMapper.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.UI /// After this distance is covered, any extra touches on the screen will be considered as button inputs, unless /// a new touch directly interacts with a hit circle. /// - private const float distance_before_position_tracking_lock_in = 200; + private const float distance_before_position_tracking_lock_in = 100; private TrackedTouch? positionTrackingTouch; From fe91f85f6fe9afea0139408fc07c0b21d8dc93d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 20 Mar 2023 18:16:33 +0100 Subject: [PATCH 2498/2991] Reuse colour constants in fallback path --- .../Skinning/Argon/ManiaArgonSkinTransformer.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs index ca9cd83a63..dbea9c7c88 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs @@ -294,17 +294,17 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon switch (columnIndex % total_colours) { - case 0: return new Color4(255, 197, 40, 255); + case 0: return colour_yellow; - case 1: return new Color4(252, 109, 1, 255); + case 1: return colour_orange; - case 2: return new Color4(213, 35, 90, 255); + case 2: return colour_pink; - case 3: return new Color4(203, 60, 236, 255); + case 3: return colour_purple; - case 4: return new Color4(72, 198, 255, 255); + case 4: return colour_cyan; - case 5: return new Color4(100, 192, 92, 255); + case 5: return colour_green; default: throw new ArgumentOutOfRangeException(); } From 695ee39b87644f4bf62a52c41b80805b7b772dff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 20 Mar 2023 20:30:54 +0100 Subject: [PATCH 2499/2991] Privatise setter --- osu.Game/Screens/Select/FilterControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index 1bcc042f72..b44ca8ac04 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -252,7 +252,7 @@ namespace osu.Game.Screens.Select { private const float filter_text_size = 12; - public OsuSpriteText FilterText; + public OsuSpriteText FilterText { get; private set; } public FilterControlTextBox() { From ea8da69263ece422d6119dedc1471a8df4654a1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 20 Mar 2023 20:49:47 +0100 Subject: [PATCH 2500/2991] Fix importing beatmaps not changing count of visible beatmaps Reproduction steps: 1. Go to song select 2. Open beatmap listing 3. Import a beatmap that would fit the current filter criteria 4. The count of visible beatmaps does not change Fixed by updating the count on `BeatmapSetsChanged` too. --- osu.Game/Screens/Select/SongSelect.cs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 722119f82e..c5e914b461 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -162,15 +162,7 @@ namespace osu.Game.Screens.Select BleedBottom = Footer.HEIGHT, SelectionChanged = updateSelectedBeatmap, BeatmapSetsChanged = carouselBeatmapsLoaded, - FilterApplied = () => - { - FilterControl.InformationalText = - Carousel.CountDisplayed == 1 - // Intentionally not localised until we have proper support for this (see https://github.com/ppy/osu-framework/pull/4918 - // but also in this case we want support for formatting a number within a string). - ? $"{Carousel.CountDisplayed:#,0} matching beatmap" - : $"{Carousel.CountDisplayed:#,0} matching beatmaps"; - }, + FilterApplied = updateVisibleBeatmapCount, GetRecommendedBeatmap = s => recommender?.GetRecommendedBeatmap(s), }, c => carouselContainer.Child = c); @@ -837,6 +829,7 @@ namespace osu.Game.Screens.Select private void carouselBeatmapsLoaded() { bindBindables(); + updateVisibleBeatmapCount(); Carousel.AllowSelection = true; @@ -866,6 +859,15 @@ namespace osu.Game.Screens.Select } } + private void updateVisibleBeatmapCount() + { + FilterControl.InformationalText = Carousel.CountDisplayed == 1 + // Intentionally not localised until we have proper support for this (see https://github.com/ppy/osu-framework/pull/4918 + // but also in this case we want support for formatting a number within a string). + ? $"{Carousel.CountDisplayed:#,0} matching beatmap" + : $"{Carousel.CountDisplayed:#,0} matching beatmaps"; + } + private bool boundLocalBindables; private void bindBindables() From cc408470f4bafde7c8571171f0392437cc7d4b92 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Mar 2023 14:47:20 +0900 Subject: [PATCH 2501/2991] Add test coverage of second touch moving but not resulting in cursor movement --- osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs index d1880d7552..b2e4e07526 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs @@ -176,6 +176,14 @@ namespace osu.Game.Rulesets.Osu.Tests checkPressed(OsuAction.RightButton); // in this case, touch 2 should not become the positional tracking touch. checkPosition(TouchSource.Touch1); + + // even if the second touch moves on the screen, the original tracking touch is retained. + beginTouch(TouchSource.Touch2, new Vector2(0)); + beginTouch(TouchSource.Touch2, new Vector2(9999)); + beginTouch(TouchSource.Touch2, new Vector2(0)); + beginTouch(TouchSource.Touch2, new Vector2(9999)); + + checkPosition(TouchSource.Touch1); } [Test] From fb51221c2bb29e492fc09bb4f549bb3854d61432 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Mar 2023 21:25:50 +0900 Subject: [PATCH 2502/2991] Add test coverage of cyclic selection triggering when more than one item is selected --- .../Visual/Gameplay/TestSceneSkinEditor.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs index 35ba363f4b..119b753d70 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs @@ -126,6 +126,10 @@ namespace osu.Game.Tests.Visual.Gameplay }); AddAssert("Last two boxes selected", () => skinEditor.SelectedComponents, () => Is.EqualTo(new[] { box2, box3 })); + + // Test cyclic selection doesn't trigger in this state. + AddStep("click on black box stack", () => InputManager.Click(MouseButton.Left)); + AddAssert("Last two boxes still selected", () => skinEditor.SelectedComponents, () => Is.EqualTo(new[] { box2, box3 })); } [Test] @@ -164,6 +168,18 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("click on black box stack", () => InputManager.Click(MouseButton.Left)); AddAssert("Selection is black box 1", () => skinEditor.SelectedComponents.Single(), () => Is.EqualTo(blueprints[0].Item)); + + AddStep("select all boxes", () => + { + skinEditor.SelectedComponents.Clear(); + skinEditor.SelectedComponents.AddRange(targetContainer.Components.OfType().Skip(1)); + }); + + AddAssert("all boxes selected", () => skinEditor.SelectedComponents, () => Has.Count.EqualTo(2)); + AddStep("click on black box stack", () => InputManager.Click(MouseButton.Left)); + AddStep("click on black box stack", () => InputManager.Click(MouseButton.Left)); + AddStep("click on black box stack", () => InputManager.Click(MouseButton.Left)); + AddAssert("all boxes still selected", () => skinEditor.SelectedComponents, () => Has.Count.EqualTo(2)); } [TestCase(false)] From e31a90e0432928e487c25d0973d75555db68c262 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 21 Mar 2023 21:21:43 +0900 Subject: [PATCH 2503/2991] Don't cycle selection when more than one items are selected --- osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 143f343c7d..cb7c083d87 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -401,7 +401,7 @@ namespace osu.Game.Screens.Edit.Compose.Components return false; } - if (!wasDragStarted && selectedBlueprintAlreadySelectedOnMouseDown && AllowCyclicSelection) + if (!wasDragStarted && selectedBlueprintAlreadySelectedOnMouseDown && SelectedItems.Count == 1 && AllowCyclicSelection) { // If a click occurred and was handled by the currently selected blueprint but didn't result in a drag, // cycle between other blueprints which are also under the cursor. From df3ccdff9fed5b05188af319f19849656ac58975 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 20 Mar 2023 22:22:28 -0700 Subject: [PATCH 2504/2991] Add failing beatmap listing sort direction on criteria change test --- .../TestSceneBeatmapListingSortTabControl.cs | 26 ++++++++++++++++++- .../BeatmapListingSortTabControl.cs | 2 +- osu.Game/Overlays/OverlaySortTabControl.cs | 2 +- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSortTabControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSortTabControl.cs index 316035275f..dd7bf48791 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSortTabControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSortTabControl.cs @@ -14,10 +14,11 @@ using osu.Game.Graphics.Sprites; using osu.Game.Overlays; using osu.Game.Overlays.BeatmapListing; using osuTK; +using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { - public partial class TestSceneBeatmapListingSortTabControl : OsuTestScene + public partial class TestSceneBeatmapListingSortTabControl : OsuManualInputManagerTestScene { private readonly BeatmapListingSortTabControl control; @@ -111,6 +112,29 @@ namespace osu.Game.Tests.Visual.UserInterface resetUsesCriteriaOnCategory(SortCriteria.Updated, SearchCategory.Mine); } + [Test] + public void TestSortDirectionOnCriteriaChange() + { + AddStep("set category to leaderboard", () => control.Reset(SearchCategory.Leaderboard, false)); + AddAssert("sort direction is descending", () => control.SortDirection.Value == SortDirection.Descending); + + AddStep("click ranked sort button", () => + { + InputManager.MoveMouseTo(control.TabControl.ChildrenOfType().Single(s => s.Active.Value)); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("sort direction is ascending", () => control.SortDirection.Value == SortDirection.Ascending); + + AddStep("click first inactive sort button", () => + { + InputManager.MoveMouseTo(control.TabControl.ChildrenOfType().First(s => !s.Active.Value)); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("sort direction is descending", () => control.SortDirection.Value == SortDirection.Descending); + } + private void criteriaShowsOnCategory(bool expected, SortCriteria criteria, SearchCategory category) { AddAssert($"{criteria.ToString().ToLowerInvariant()} {(expected ? "shown" : "not shown")} on {category.ToString().ToLowerInvariant()}", () => diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs index 025738710f..79a2d01208 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs @@ -102,7 +102,7 @@ namespace osu.Game.Overlays.BeatmapListing }; } - private partial class BeatmapTabButton : TabButton + public partial class BeatmapTabButton : TabButton { public readonly Bindable SortDirection = new Bindable(); diff --git a/osu.Game/Overlays/OverlaySortTabControl.cs b/osu.Game/Overlays/OverlaySortTabControl.cs index 8af2ab3823..5c51f5e4d0 100644 --- a/osu.Game/Overlays/OverlaySortTabControl.cs +++ b/osu.Game/Overlays/OverlaySortTabControl.cs @@ -117,7 +117,7 @@ namespace osu.Game.Overlays } } - protected partial class TabButton : HeaderButton + public partial class TabButton : HeaderButton { public readonly BindableBool Active = new BindableBool(); From 3cd01ee621d6df6eda45374ed3765cfe3d074887 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 21 Mar 2023 14:49:39 -0700 Subject: [PATCH 2505/2991] Fix beatmap listing sort direction not resetting when changing criteria --- .../Overlays/BeatmapListing/BeatmapListingSortTabControl.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs index 79a2d01208..9cc4f8a34b 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs @@ -25,6 +25,8 @@ namespace osu.Game.Overlays.BeatmapListing if (currentParameters == null) Reset(SearchCategory.Leaderboard, false); + + Current.BindValueChanged(_ => SortDirection.Value = Overlays.SortDirection.Descending); } public void Reset(SearchCategory category, bool hasQuery) From 1478a26cc03beb5f90f53db1d61352de6cea65b4 Mon Sep 17 00:00:00 2001 From: Terochi Date: Tue, 21 Mar 2023 23:15:49 +0100 Subject: [PATCH 2506/2991] Addressed changes --- .../Gameplay/TestSceneSkinnableSound.cs | 5 +-- osu.Game/Skinning/PoolableSkinnableSample.cs | 45 ++----------------- 2 files changed, 5 insertions(+), 45 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs index cc82ffed2b..3f78dbfd96 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs @@ -107,15 +107,12 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("ensure sample loaded", () => skinnableSound.ChildrenOfType().Single().Name, () => Is.EqualTo(sample_lookup)); - AddStep("Change source", () => + AddStep("change source", () => { skinSource.OverridingSample = new SampleVirtual("new skin"); skinSource.TriggerSourceChanged(); }); - // Samples are nulled on source change immediately - AddUntilStep("wait for sample null", () => skinnableSound.ChildrenOfType().Count(), () => Is.Zero); - AddStep("start sample", () => skinnableSound.Play()); AddUntilStep("sample updated", () => skinnableSound.ChildrenOfType().Single().Name, () => Is.EqualTo("new skin")); } diff --git a/osu.Game/Skinning/PoolableSkinnableSample.cs b/osu.Game/Skinning/PoolableSkinnableSample.cs index 361c8688e7..eacb33f7d7 100644 --- a/osu.Game/Skinning/PoolableSkinnableSample.cs +++ b/osu.Game/Skinning/PoolableSkinnableSample.cs @@ -4,12 +4,10 @@ #nullable disable using System; -using System.Linq; using JetBrains.Annotations; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; -using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Containers; @@ -70,48 +68,21 @@ namespace osu.Game.Skinning updateSample(); } - protected override void LoadComplete() - { - base.LoadComplete(); - - CurrentSkin.SourceChanged += skinChangedImmediate; - } - - private void skinChangedImmediate() - { - // Clean up the previous sample immediately on a source change. - // This avoids a potential call to Play() of an already disposed sample (samples are disposed along with the skin, but SkinChanged is scheduled). - clearPreviousSamples(); - } - protected override void SkinChanged(ISkinSource skin) { base.SkinChanged(skin); updateSample(); } - /// - /// Whether this sample was playing before a skin source change. - /// - private bool wasPlaying; - - private void clearPreviousSamples() - { - // only run if the samples aren't already cleared. - // this ensures the "wasPlaying" state is stored correctly even if multiple clear calls are executed. - if (!sampleContainer.Any()) return; - - wasPlaying = Playing; - - sampleContainer.Clear(); - Sample = null; - } - private void updateSample() { if (sampleInfo == null) return; + bool wasPlaying = Playing; + + sampleContainer.Clear(); + var sample = CurrentSkin.GetSample(sampleInfo); if (sample == null) @@ -174,14 +145,6 @@ namespace osu.Game.Skinning } } - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - if (CurrentSkin.IsNotNull()) - CurrentSkin.SourceChanged -= skinChangedImmediate; - } - #region Re-expose AudioContainer public BindableNumber Volume => sampleContainer.Volume; From e1fb63e1f313943d058c820ca6a660d9342ca15f Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 20 Mar 2023 22:27:07 -0700 Subject: [PATCH 2507/2991] Move beatmap listing filter control to header --- .../BeatmapListing/BeatmapListingHeader.cs | 5 +++++ osu.Game/Overlays/BeatmapListingOverlay.cs | 14 +++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs index 76b6dec65b..3336c383ff 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs @@ -3,6 +3,7 @@ #nullable disable +using osu.Framework.Graphics; using osu.Game.Localisation; using osu.Game.Resources.Localisation.Web; @@ -10,8 +11,12 @@ namespace osu.Game.Overlays.BeatmapListing { public partial class BeatmapListingHeader : OverlayHeader { + public BeatmapListingFilterControl FilterControl { get; private set; } + protected override OverlayTitle CreateTitle() => new BeatmapListingTitle(); + protected override Drawable CreateContent() => FilterControl = new BeatmapListingFilterControl(); + private partial class BeatmapListingTitle : OverlayTitle { public BeatmapListingTitle() diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index 73961487ed..d2f39fde8e 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -43,7 +43,13 @@ namespace osu.Game.Overlays private Container panelTarget; private FillFlowContainer foundContent; - private BeatmapListingFilterControl filterControl; + + private BeatmapListingFilterControl filterControl => Header.FilterControl.With(f => + { + f.TypingStarted = onTypingStarted; + f.SearchStarted = onSearchStarted; + f.SearchFinished = onSearchFinished; + }); public BeatmapListingOverlay() : base(OverlayColourScheme.Blue) @@ -60,12 +66,6 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - filterControl = new BeatmapListingFilterControl - { - TypingStarted = onTypingStarted, - SearchStarted = onSearchStarted, - SearchFinished = onSearchFinished, - }, new Container { AutoSizeAxes = Axes.Y, From 74a15d742495d95fbb94ce2793e750802f67feef Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 20 Mar 2023 22:26:51 -0700 Subject: [PATCH 2508/2991] Fix overlay headers being blocked by loading layer --- osu.Game/Overlays/OnlineOverlay.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/OnlineOverlay.cs b/osu.Game/Overlays/OnlineOverlay.cs index 4fdf7cb2b6..f29a5719d8 100644 --- a/osu.Game/Overlays/OnlineOverlay.cs +++ b/osu.Game/Overlays/OnlineOverlay.cs @@ -3,6 +3,7 @@ #nullable disable +using System; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -22,6 +23,7 @@ namespace osu.Game.Overlays protected readonly OverlayScrollContainer ScrollFlow; protected readonly LoadingLayer Loading; + private readonly Container loadingContainer; private readonly Container content; protected OnlineOverlay(OverlayColourScheme colourScheme, bool requiresSignIn = true) @@ -65,10 +67,21 @@ namespace osu.Game.Overlays }, } }, - Loading = new LoadingLayer(true) + loadingContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Child = Loading = new LoadingLayer(true), + } }); base.Content.Add(mainContent); } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + loadingContainer.Padding = new MarginPadding { Top = Math.Max(0, Header.Height - ScrollFlow.Current) }; + } } } From d9571b6fc9700111a5ca3ee1433618e667cca766 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 21 Mar 2023 21:31:35 -0700 Subject: [PATCH 2509/2991] Move filter control property setters to `load()` --- osu.Game/Overlays/BeatmapListingOverlay.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index d2f39fde8e..f8784504b8 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -44,12 +44,7 @@ namespace osu.Game.Overlays private Container panelTarget; private FillFlowContainer foundContent; - private BeatmapListingFilterControl filterControl => Header.FilterControl.With(f => - { - f.TypingStarted = onTypingStarted; - f.SearchStarted = onSearchStarted; - f.SearchFinished = onSearchFinished; - }); + private BeatmapListingFilterControl filterControl => Header.FilterControl; public BeatmapListingOverlay() : base(OverlayColourScheme.Blue) @@ -88,6 +83,10 @@ namespace osu.Game.Overlays }, } }; + + filterControl.TypingStarted = onTypingStarted; + filterControl.SearchStarted = onSearchStarted; + filterControl.SearchFinished = onSearchFinished; } protected override void LoadComplete() From 425be20e462f32af5ca4a5103383a664f281315e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Mar 2023 14:13:42 +0900 Subject: [PATCH 2510/2991] Fix song select search textbox font size incorrectly having increased --- osu.Game/Screens/Select/FilterControl.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index b44ca8ac04..38520a85b7 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -257,6 +257,7 @@ namespace osu.Game.Screens.Select public FilterControlTextBox() { Height += filter_text_size; + TextContainer.Height *= (Height - filter_text_size) / Height; TextContainer.Margin = new MarginPadding { Bottom = filter_text_size }; } From 6f3bb85eaab77c727a64bffc415d56c853796aa7 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Wed, 22 Mar 2023 00:19:23 -0700 Subject: [PATCH 2511/2991] Always show down arrow on inactive sort buttons --- .../Overlays/BeatmapListing/BeatmapListingSortTabControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs index 9cc4f8a34b..2f290d05e9 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs @@ -138,7 +138,7 @@ namespace osu.Game.Overlays.BeatmapListing SortDirection.BindValueChanged(direction => { - icon.Icon = direction.NewValue == Overlays.SortDirection.Ascending ? FontAwesome.Solid.CaretUp : FontAwesome.Solid.CaretDown; + icon.Icon = direction.NewValue == Overlays.SortDirection.Ascending && Active.Value ? FontAwesome.Solid.CaretUp : FontAwesome.Solid.CaretDown; }, true); } From 9bc6b46e4e407704dddfe91ce2b043494825424a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Mar 2023 16:36:05 +0900 Subject: [PATCH 2512/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 4e580a6919..a62e28dca0 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -11,7 +11,7 @@ manifestmerger.jar - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index c08dc9ed8f..d5ff3fad56 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 8738979c57..25466f5426 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -16,6 +16,6 @@ iossimulator-x64 - + From 13be7097180551ff44c801ed219472d2d999c588 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 17 Mar 2023 19:29:34 +0900 Subject: [PATCH 2513/2991] Add basic renderer selection --- .../Settings/Sections/Graphics/RendererSettings.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index a5fdfdc105..08a62ff324 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -1,9 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Localisation; @@ -23,6 +22,12 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics // NOTE: Compatability mode omitted Children = new Drawable[] { + new SettingsEnumDropdown + { + LabelText = GraphicsSettingsStrings.Renderer, + Current = config.GetBindable(FrameworkSetting.Renderer), + Keywords = new[] { @"compatibility", @"directx" }, + }, // TODO: this needs to be a custom dropdown at some point new SettingsEnumDropdown { From 956fabb445aa22ec931750f20c5c78c7a80bab6c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 17 Mar 2023 20:28:26 +0900 Subject: [PATCH 2514/2991] Show restart notice when changing renderer --- .../Localisation/GraphicsSettingsStrings.cs | 11 ++++++++++ .../Sections/Graphics/RendererSettings.cs | 20 +++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/osu.Game/Localisation/GraphicsSettingsStrings.cs b/osu.Game/Localisation/GraphicsSettingsStrings.cs index 6e05929d81..422704514f 100644 --- a/osu.Game/Localisation/GraphicsSettingsStrings.cs +++ b/osu.Game/Localisation/GraphicsSettingsStrings.cs @@ -19,6 +19,11 @@ namespace osu.Game.Localisation /// public static LocalisableString RendererHeader => new TranslatableString(getKey(@"renderer_header"), @"Renderer"); + /// + /// "Renderer" + /// + public static LocalisableString Renderer => new TranslatableString(getKey(@"renderer"), @"Renderer"); + /// /// "Frame limiter" /// @@ -144,6 +149,12 @@ namespace osu.Game.Localisation /// public static LocalisableString Png => new TranslatableString(getKey(@"png_lossless"), @"PNG (lossless)"); + /// + /// "In order to change the renderer, the game will close. Please open it again." + /// + public static LocalisableString ChangeRendererConfirmation => + new TranslatableString(getKey(@"change_renderer_configuration"), @"In order to change the renderer, the game will close. Please open it again."); + private static string getKey(string key) => $"{prefix}:{key}"; } } diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index 08a62ff324..ba2691e41c 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -2,13 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Framework.Platform; using osu.Game.Configuration; using osu.Game.Localisation; +using osu.Game.Overlays.Dialog; namespace osu.Game.Overlays.Settings.Sections.Graphics { @@ -17,15 +17,16 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics protected override LocalisableString Header => GraphicsSettingsStrings.RendererHeader; [BackgroundDependencyLoader] - private void load(FrameworkConfigManager config, OsuConfigManager osuConfig) + private void load(FrameworkConfigManager config, OsuConfigManager osuConfig, IDialogOverlay dialogOverlay, OsuGame game, GameHost host) { - // NOTE: Compatability mode omitted + var renderer = config.GetBindable(FrameworkSetting.Renderer); + Children = new Drawable[] { new SettingsEnumDropdown { LabelText = GraphicsSettingsStrings.Renderer, - Current = config.GetBindable(FrameworkSetting.Renderer), + Current = renderer, Keywords = new[] { @"compatibility", @"directx" }, }, // TODO: this needs to be a custom dropdown at some point @@ -46,6 +47,17 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics Current = osuConfig.GetBindable(OsuSetting.ShowFpsDisplay) }, }; + + renderer.BindValueChanged(r => + { + if (r.NewValue == host.ResolvedRenderer) + return; + + dialogOverlay.Push(new ConfirmDialog(GraphicsSettingsStrings.ChangeRendererConfirmation, game.AttemptExit, () => + { + renderer.SetDefault(); + })); + }); } } } From aabe86dc26c90c90e1d9a5c0bd860bcf6d1b06fb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 17 Mar 2023 20:28:36 +0900 Subject: [PATCH 2515/2991] Limit renderers to those available for the current platform --- .../Overlays/Settings/Sections/Graphics/RendererSettings.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index ba2691e41c..80e5dd3843 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.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.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -27,6 +28,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics { LabelText = GraphicsSettingsStrings.Renderer, Current = renderer, + Items = host.GetPreferredRenderersForCurrentPlatform().OrderBy(t => t), Keywords = new[] { @"compatibility", @"directx" }, }, // TODO: this needs to be a custom dropdown at some point From 3050a16bf866895a9188e008f397b3e0262cea58 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 22 Mar 2023 16:56:35 +0900 Subject: [PATCH 2516/2991] Don't require a restart when selecting `Automatic` and startup setting was also automatic --- .../Settings/Sections/Graphics/RendererSettings.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index 80e5dd3843..4f24898bce 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -17,10 +17,13 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics { protected override LocalisableString Header => GraphicsSettingsStrings.RendererHeader; + private bool automaticRendererInUse; + [BackgroundDependencyLoader] private void load(FrameworkConfigManager config, OsuConfigManager osuConfig, IDialogOverlay dialogOverlay, OsuGame game, GameHost host) { var renderer = config.GetBindable(FrameworkSetting.Renderer); + automaticRendererInUse = renderer.Value == RendererType.Automatic; Children = new Drawable[] { @@ -55,6 +58,10 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics if (r.NewValue == host.ResolvedRenderer) return; + // Need to check startup renderer for the "automatic" case, as ResolvedRenderer above will track the final resolved renderer instead. + if (r.NewValue == RendererType.Automatic && automaticRendererInUse) + return; + dialogOverlay.Push(new ConfirmDialog(GraphicsSettingsStrings.ChangeRendererConfirmation, game.AttemptExit, () => { renderer.SetDefault(); From 8518d15b8daf8cd2cbb047054e8b2286c0f63493 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 23 Mar 2023 00:13:24 +0900 Subject: [PATCH 2517/2991] use endpoint --- .../Visual/Online/TestSceneChatOverlay.cs | 33 +++++++++++++++- .../Online/API/Requests/ChatReportRequest.cs | 38 +++++++++++++++++++ osu.Game/Overlays/Chat/ChatLine.cs | 2 +- osu.Game/Overlays/Chat/DrawableUsername.cs | 24 ++++++++++-- 4 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 osu.Game/Online/API/Requests/ChatReportRequest.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 48db5691ce..08337fbff9 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Collections.Generic; using System.Net; using System.Threading; +using System.Threading.Tasks; using JetBrains.Annotations; using NUnit.Framework; using osu.Framework.Allocation; @@ -32,6 +33,7 @@ using osu.Game.Overlays.Chat.ChannelList; using osuTK; using osuTK.Input; using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Overlays.Comments; namespace osu.Game.Tests.Visual.Online { @@ -55,6 +57,9 @@ namespace osu.Game.Tests.Visual.Online private int currentMessageId; + private DummyAPIAccess dummyAPI => (DummyAPIAccess)API; + private readonly ManualResetEventSlim requestLock = new ManualResetEventSlim(); + [SetUp] public void SetUp() => Schedule(() => { @@ -581,6 +586,8 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestChatReport() { + ChatReportRequest request = null; + AddStep("Show overlay with channel", () => { chatOverlay.Show(); @@ -590,6 +597,26 @@ namespace osu.Game.Tests.Visual.Online AddAssert("Overlay is visible", () => chatOverlay.State.Value == Visibility.Visible); waitForChannel1Visible(); + AddStep("Setup request handling", () => + { + requestLock.Reset(); + + dummyAPI.HandleRequest = r => + { + if (!(r is ChatReportRequest req)) + return false; + + Task.Run(() => + { + request = req; + requestLock.Wait(10000); + req.TriggerSuccess(); + }); + + return true; + }; + }); + AddStep("Show report popover", () => this.ChildrenOfType().First().ShowPopover()); AddStep("Try to report", () => @@ -599,7 +626,11 @@ namespace osu.Game.Tests.Visual.Online InputManager.Click(MouseButton.Left); }); - AddAssert("Report message sended", () => channelManager.CurrentChannel.Value.Messages.Any(x => x.Content.Contains("!report"))); + AddWaitStep("Wait", 3); + + AddAssert("Overlay closed", () => !this.ChildrenOfType().Any()); + AddStep("Complete request", () => requestLock.Set()); + AddUntilStep("Request sent", () => request != null); } private void joinTestChannel(int i) diff --git a/osu.Game/Online/API/Requests/ChatReportRequest.cs b/osu.Game/Online/API/Requests/ChatReportRequest.cs new file mode 100644 index 0000000000..00d314be68 --- /dev/null +++ b/osu.Game/Online/API/Requests/ChatReportRequest.cs @@ -0,0 +1,38 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Net.Http; +using osu.Framework.IO.Network; +using osu.Game.Online.Chat; +using osu.Game.Overlays.Chat; + +namespace osu.Game.Online.API.Requests; + +public class ChatReportRequest : APIRequest +{ + public readonly long? MessageId; + public readonly ChatReportReason Reason; + public readonly string Comment; + + public ChatReportRequest(long? id, ChatReportReason reason, string comment) + { + MessageId = id; + Reason = reason; + Comment = comment; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + req.Method = HttpMethod.Post; + + req.AddParameter(@"reportable_type", @"message"); + req.AddParameter(@"reportable_id", $"{MessageId}"); + req.AddParameter(@"reason", Reason.ToString()); + req.AddParameter(@"comments", Comment); + + return req; + } + + protected override string Target => @"reports"; +} diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index 70c3bf181c..0e69501ae9 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -92,7 +92,7 @@ namespace osu.Game.Overlays.Chat Font = OsuFont.GetFont(size: FontSize * 0.75f, weight: FontWeight.SemiBold, fixedWidth: true), AlwaysPresent = true, }, - drawableUsername = new DrawableUsername(message.Sender) + drawableUsername = new DrawableUsername(message) { Width = UsernameWidth, FontSize = FontSize, diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs index 640ce2eca6..c9b0b018e3 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -21,6 +21,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Localisation; using osu.Game.Online.API; +using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; using osu.Game.Resources.Localisation.Web; @@ -72,13 +73,15 @@ namespace osu.Game.Overlays.Chat private Bindable? currentChannel { get; set; } private readonly APIUser user; + private readonly Message message; private readonly OsuSpriteText drawableText; private readonly Drawable colouredDrawable; - public DrawableUsername(APIUser user) + public DrawableUsername(Message message) { - this.user = user; + this.message = message; + user = message.Sender; Action = openUserProfile; @@ -171,7 +174,8 @@ namespace osu.Game.Overlays.Chat })); } - items.Add(new OsuMenuItem("Report", MenuItemType.Destructive, this.ShowPopover)); + if (!user.Equals(api.LocalUser.Value)) + items.Add(new OsuMenuItem("Report", MenuItemType.Destructive, this.ShowPopover)); return items.ToArray(); } @@ -179,7 +183,19 @@ namespace osu.Game.Overlays.Chat private void report(ChatReportReason reason, string comments) { - chatManager?.PostMessage($"!report {user.Username} ({reason.GetDescription()}): {comments}"); + var request = new ChatReportRequest(message.Id, reason, comments); + + request.Failure += _ => Schedule(() => + { + currentChannel?.Value?.AddNewMessages(new ErrorMessage("Report failed to send, please retry")); + }); + + request.Success += () => Schedule(() => + { + currentChannel?.Value?.AddNewMessages(new InfoMessage("Report has been sent")); + }); + + api.Queue(request); } private void openUserChannel() From 85a924f0782ee04f48aae86224f09343f7b37979 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 23 Mar 2023 01:02:17 +0900 Subject: [PATCH 2518/2991] why merge problem? --- osu.Game/Overlays/Chat/DrawableUsername.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs index c9b0b018e3..25967003e9 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -163,8 +163,7 @@ namespace osu.Game.Overlays.Chat }; if (!user.Equals(api.LocalUser.Value)) - items.Add(new OsuMenuItem("Start Chat", MenuItemType.Standard, openUserChannel)); - items.Add(new OsuMenuItem(UsersStrings.CardSendMessage, MenuItemType.Standard, openUserChannel)); + items.Add(new OsuMenuItem(UsersStrings.CardSendMessage, MenuItemType.Standard, openUserChannel)); if (currentChannel?.Value != null) { From 26f2d9047d3238b4790613102e2d0500a18d69d9 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 23 Mar 2023 01:11:44 +0900 Subject: [PATCH 2519/2991] code style fix --- osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs | 1 - osu.Game/Online/API/Requests/ChatReportRequest.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 08337fbff9..5845ba3783 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -33,7 +33,6 @@ using osu.Game.Overlays.Chat.ChannelList; using osuTK; using osuTK.Input; using osu.Game.Graphics.UserInterfaceV2; -using osu.Game.Overlays.Comments; namespace osu.Game.Tests.Visual.Online { diff --git a/osu.Game/Online/API/Requests/ChatReportRequest.cs b/osu.Game/Online/API/Requests/ChatReportRequest.cs index 00d314be68..01cb455183 100644 --- a/osu.Game/Online/API/Requests/ChatReportRequest.cs +++ b/osu.Game/Online/API/Requests/ChatReportRequest.cs @@ -3,7 +3,6 @@ using System.Net.Http; using osu.Framework.IO.Network; -using osu.Game.Online.Chat; using osu.Game.Overlays.Chat; namespace osu.Game.Online.API.Requests; From ab6cfea5c71dded5fbd88ef4183943e7e25fbc74 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 23 Mar 2023 11:27:05 +0900 Subject: [PATCH 2520/2991] Revert old value instead of always using default Co-authored-by: cdwcgt --- .../Overlays/Settings/Sections/Graphics/RendererSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index 4f24898bce..45a6d35749 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -64,7 +64,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics dialogOverlay.Push(new ConfirmDialog(GraphicsSettingsStrings.ChangeRendererConfirmation, game.AttemptExit, () => { - renderer.SetDefault(); + renderer.Value = r.OldValue; })); }); } From 540b38dc2191691047b7ccf646c2b82541870233 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 23 Mar 2023 14:01:19 +0900 Subject: [PATCH 2521/2991] Fix tournament interface save button not usable after changing match progression/round --- osu.Game.Tournament/TournamentGameBase.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tournament/TournamentGameBase.cs b/osu.Game.Tournament/TournamentGameBase.cs index 7e19cb3aa5..634cc87a9f 100644 --- a/osu.Game.Tournament/TournamentGameBase.cs +++ b/osu.Game.Tournament/TournamentGameBase.cs @@ -332,13 +332,6 @@ namespace osu.Game.Tournament private void saveChanges() { - foreach (var r in ladder.Rounds) - r.Matches = ladder.Matches.Where(p => p.Round.Value == r).Select(p => p.ID).ToList(); - - ladder.Progressions = ladder.Matches.Where(p => p.Progression.Value != null).Select(p => new TournamentProgression(p.ID, p.Progression.Value.ID)).Concat( - ladder.Matches.Where(p => p.LosersProgression.Value != null).Select(p => new TournamentProgression(p.ID, p.LosersProgression.Value.ID, true))) - .ToList(); - // Serialise before opening stream for writing, so if there's a failure it will leave the file in the previous state. string serialisedLadder = GetSerialisedLadder(); @@ -349,6 +342,13 @@ namespace osu.Game.Tournament public string GetSerialisedLadder() { + foreach (var r in ladder.Rounds) + r.Matches = ladder.Matches.Where(p => p.Round.Value == r).Select(p => p.ID).ToList(); + + ladder.Progressions = ladder.Matches.Where(p => p.Progression.Value != null).Select(p => new TournamentProgression(p.ID, p.Progression.Value.ID)).Concat( + ladder.Matches.Where(p => p.LosersProgression.Value != null).Select(p => new TournamentProgression(p.ID, p.LosersProgression.Value.ID, true))) + .ToList(); + return JsonConvert.SerializeObject(ladder, new JsonSerializerSettings { From e6f1ec57a963cf4bdc16d8c186227dd18230d6d9 Mon Sep 17 00:00:00 2001 From: Terochi Date: Thu, 23 Mar 2023 18:46:48 +0100 Subject: [PATCH 2522/2991] Bring back and make use of `clearPreviousSamples()` --- osu.Game/Skinning/PoolableSkinnableSample.cs | 26 ++++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/osu.Game/Skinning/PoolableSkinnableSample.cs b/osu.Game/Skinning/PoolableSkinnableSample.cs index eacb33f7d7..76c2c4d7ec 100644 --- a/osu.Game/Skinning/PoolableSkinnableSample.cs +++ b/osu.Game/Skinning/PoolableSkinnableSample.cs @@ -4,6 +4,7 @@ #nullable disable using System; +using System.Linq; using JetBrains.Annotations; using osu.Framework.Audio; using osu.Framework.Audio.Sample; @@ -74,14 +75,29 @@ namespace osu.Game.Skinning updateSample(); } - private void updateSample() - { - if (sampleInfo == null) - return; + /// + /// Whether this sample was playing before a skin source change. + /// + private bool wasPlaying; - bool wasPlaying = Playing; + private void clearPreviousSamples() + { + // only run if the samples aren't already cleared. + // this ensures the "wasPlaying" state is stored correctly even if multiple clear calls are executed. + if (!sampleContainer.Any()) return; + + wasPlaying = Playing; sampleContainer.Clear(); + Sample = null; + } + + private void updateSample() + { + clearPreviousSamples(); + + if (sampleInfo == null) + return; var sample = CurrentSkin.GetSample(sampleInfo); From 450c5cef074b85b6f190b9ca05687937b044d776 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Fri, 24 Mar 2023 18:42:34 -0700 Subject: [PATCH 2523/2991] Add comment explaining loading container padding --- osu.Game/Overlays/OnlineOverlay.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/OnlineOverlay.cs b/osu.Game/Overlays/OnlineOverlay.cs index f29a5719d8..4d2c6bc9d0 100644 --- a/osu.Game/Overlays/OnlineOverlay.cs +++ b/osu.Game/Overlays/OnlineOverlay.cs @@ -81,6 +81,7 @@ namespace osu.Game.Overlays { base.UpdateAfterChildren(); + // don't block header by applying padding equal to the visible header height loadingContainer.Padding = new MarginPadding { Top = Math.Max(0, Header.Height - ScrollFlow.Current) }; } } From e1906a90eb8f6ea79140490304b06ee3453f1508 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 21 Mar 2023 13:23:08 -0700 Subject: [PATCH 2524/2991] Use `image@2x` from tournament banner api --- osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs | 1 + osu.Game/Users/TournamentBanner.cs | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs index a97c8aff66..4278c46d6a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs @@ -126,6 +126,7 @@ namespace osu.Game.Tests.Visual.Online Id = 13926, TournamentId = 35, ImageLowRes = "https://assets.ppy.sh/tournament-banners/official/owc2022/profile/winner_US.jpg", + Image = "https://assets.ppy.sh/tournament-banners/official/owc2022/profile/winner_US@2x.jpg", }, Badges = new[] { diff --git a/osu.Game/Users/TournamentBanner.cs b/osu.Game/Users/TournamentBanner.cs index 62e1913412..e7fada1eff 100644 --- a/osu.Game/Users/TournamentBanner.cs +++ b/osu.Game/Users/TournamentBanner.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.IO; using Newtonsoft.Json; namespace osu.Game.Users @@ -17,7 +16,7 @@ namespace osu.Game.Users [JsonProperty("image")] public string ImageLowRes = null!; - // TODO: remove when api returns @2x image link: https://github.com/ppy/osu-web/issues/9816 - public string Image => $@"{Path.ChangeExtension(ImageLowRes, null)}@2x{Path.GetExtension(ImageLowRes)}"; + [JsonProperty("image@2x")] + public string Image = null!; } } From eaef5ff2a3e0412036246eb6b4226a156bdbeaed Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 25 Mar 2023 22:13:51 -0700 Subject: [PATCH 2525/2991] Fix now playing playlist not highlighting selected item on initial open --- osu.Game/Overlays/Music/PlaylistItem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 00c5ce8002..4032af7651 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -75,7 +75,7 @@ namespace osu.Game.Overlays.Music selected = newSelected; updateSelectionState(false); - }); + }, true); updateSelectionState(true); }); From c803eb8e044424c601a585632755bf5f48f47834 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 26 Mar 2023 16:14:15 +0900 Subject: [PATCH 2526/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index a62e28dca0..bc382d8f97 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -11,7 +11,7 @@ manifestmerger.jar - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f8fc6ffda6..16f780d034 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 25466f5426..5d90119233 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -16,6 +16,6 @@ iossimulator-x64 - + From 27de3314fdfb89cec20e1d34d9d323354e3922c7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 26 Mar 2023 16:23:07 +0900 Subject: [PATCH 2527/2991] Remove iOS mouse handler code --- osu.iOS/IOSMouseSettings.cs | 36 ------------------------------------ osu.iOS/OsuGameIOS.cs | 15 --------------- 2 files changed, 51 deletions(-) delete mode 100644 osu.iOS/IOSMouseSettings.cs diff --git a/osu.iOS/IOSMouseSettings.cs b/osu.iOS/IOSMouseSettings.cs deleted file mode 100644 index f464bd93b8..0000000000 --- a/osu.iOS/IOSMouseSettings.cs +++ /dev/null @@ -1,36 +0,0 @@ -// 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.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Localisation; -using osu.Game.Configuration; -using osu.Game.Localisation; -using osu.Game.Overlays.Settings; - -namespace osu.iOS -{ - public partial class IOSMouseSettings : SettingsSubsection - { - protected override LocalisableString Header => MouseSettingsStrings.Mouse; - - [BackgroundDependencyLoader] - private void load(OsuConfigManager osuConfig) - { - Children = new Drawable[] - { - new SettingsCheckbox - { - LabelText = MouseSettingsStrings.DisableMouseWheelVolumeAdjust, - TooltipText = MouseSettingsStrings.DisableMouseWheelVolumeAdjustTooltip, - Current = osuConfig.GetBindable(OsuSetting.MouseDisableWheel), - }, - new SettingsCheckbox - { - LabelText = MouseSettingsStrings.DisableMouseButtons, - Current = osuConfig.GetBindable(OsuSetting.MouseDisableButtons), - }, - }; - } - } -} diff --git a/osu.iOS/OsuGameIOS.cs b/osu.iOS/OsuGameIOS.cs index 3e79bc6ad6..c49e6907ff 100644 --- a/osu.iOS/OsuGameIOS.cs +++ b/osu.iOS/OsuGameIOS.cs @@ -7,10 +7,7 @@ using System; using Foundation; using Microsoft.Maui.Devices; using osu.Framework.Graphics; -using osu.Framework.Input.Handlers; -using osu.Framework.iOS.Input; using osu.Game; -using osu.Game.Overlays.Settings; using osu.Game.Updater; using osu.Game.Utils; @@ -29,18 +26,6 @@ namespace osu.iOS // Because we have the home indicator (mostly) hidden we don't really care about drawing in this region. Edges.Bottom; - public override SettingsSubsection CreateSettingsSubsectionFor(InputHandler handler) - { - switch (handler) - { - case IOSMouseHandler: - return new IOSMouseSettings(); - - default: - return base.CreateSettingsSubsectionFor(handler); - } - } - private class IOSBatteryInfo : BatteryInfo { public override double? ChargeLevel => Battery.ChargeLevel; From 816eff1a87348e1b240dec34df0222868866fdf8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 26 Mar 2023 16:27:44 +0900 Subject: [PATCH 2528/2991] Update iOS startup code --- .../AppDelegate.cs | 17 ----------- .../Application.cs | 7 ++--- .../AppDelegate.cs | 17 ----------- .../Application.cs | 7 ++--- .../AppDelegate.cs | 17 ----------- .../Application.cs | 7 ++--- .../AppDelegate.cs | 17 ----------- .../Application.cs | 7 ++--- osu.Game.Tests.iOS/AppDelegate.cs | 16 ---------- osu.Game.Tests.iOS/Application.cs | 6 ++-- osu.iOS/AppDelegate.cs | 29 ------------------- osu.iOS/Application.cs | 6 ++-- 12 files changed, 16 insertions(+), 137 deletions(-) delete mode 100644 osu.Game.Rulesets.Catch.Tests.iOS/AppDelegate.cs delete mode 100644 osu.Game.Rulesets.Mania.Tests.iOS/AppDelegate.cs delete mode 100644 osu.Game.Rulesets.Osu.Tests.iOS/AppDelegate.cs delete mode 100644 osu.Game.Rulesets.Taiko.Tests.iOS/AppDelegate.cs delete mode 100644 osu.Game.Tests.iOS/AppDelegate.cs delete mode 100644 osu.iOS/AppDelegate.cs diff --git a/osu.Game.Rulesets.Catch.Tests.iOS/AppDelegate.cs b/osu.Game.Rulesets.Catch.Tests.iOS/AppDelegate.cs deleted file mode 100644 index 64ff3f7151..0000000000 --- a/osu.Game.Rulesets.Catch.Tests.iOS/AppDelegate.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -#nullable disable - -using Foundation; -using osu.Framework.iOS; -using osu.Game.Tests; - -namespace osu.Game.Rulesets.Catch.Tests.iOS -{ - [Register("AppDelegate")] - public class AppDelegate : GameAppDelegate - { - protected override Framework.Game CreateGame() => new OsuTestBrowser(); - } -} diff --git a/osu.Game.Rulesets.Catch.Tests.iOS/Application.cs b/osu.Game.Rulesets.Catch.Tests.iOS/Application.cs index 1fcb0aa427..d097c6a698 100644 --- a/osu.Game.Rulesets.Catch.Tests.iOS/Application.cs +++ b/osu.Game.Rulesets.Catch.Tests.iOS/Application.cs @@ -1,9 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using UIKit; +using osu.Framework.iOS; +using osu.Game.Tests; namespace osu.Game.Rulesets.Catch.Tests.iOS { @@ -11,7 +10,7 @@ namespace osu.Game.Rulesets.Catch.Tests.iOS { public static void Main(string[] args) { - UIApplication.Main(args, null, typeof(AppDelegate)); + GameApplication.Main(new OsuTestBrowser()); } } } diff --git a/osu.Game.Rulesets.Mania.Tests.iOS/AppDelegate.cs b/osu.Game.Rulesets.Mania.Tests.iOS/AppDelegate.cs deleted file mode 100644 index a528634f3b..0000000000 --- a/osu.Game.Rulesets.Mania.Tests.iOS/AppDelegate.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -#nullable disable - -using Foundation; -using osu.Framework.iOS; -using osu.Game.Tests; - -namespace osu.Game.Rulesets.Mania.Tests.iOS -{ - [Register("AppDelegate")] - public class AppDelegate : GameAppDelegate - { - protected override Framework.Game CreateGame() => new OsuTestBrowser(); - } -} diff --git a/osu.Game.Rulesets.Mania.Tests.iOS/Application.cs b/osu.Game.Rulesets.Mania.Tests.iOS/Application.cs index a508198f7f..75a5a73058 100644 --- a/osu.Game.Rulesets.Mania.Tests.iOS/Application.cs +++ b/osu.Game.Rulesets.Mania.Tests.iOS/Application.cs @@ -1,9 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using UIKit; +using osu.Framework.iOS; +using osu.Game.Tests; namespace osu.Game.Rulesets.Mania.Tests.iOS { @@ -11,7 +10,7 @@ namespace osu.Game.Rulesets.Mania.Tests.iOS { public static void Main(string[] args) { - UIApplication.Main(args, null, typeof(AppDelegate)); + GameApplication.Main(new OsuTestBrowser()); } } } diff --git a/osu.Game.Rulesets.Osu.Tests.iOS/AppDelegate.cs b/osu.Game.Rulesets.Osu.Tests.iOS/AppDelegate.cs deleted file mode 100644 index fa40a8536e..0000000000 --- a/osu.Game.Rulesets.Osu.Tests.iOS/AppDelegate.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -#nullable disable - -using Foundation; -using osu.Framework.iOS; -using osu.Game.Tests; - -namespace osu.Game.Rulesets.Osu.Tests.iOS -{ - [Register("AppDelegate")] - public class AppDelegate : GameAppDelegate - { - protected override Framework.Game CreateGame() => new OsuTestBrowser(); - } -} diff --git a/osu.Game.Rulesets.Osu.Tests.iOS/Application.cs b/osu.Game.Rulesets.Osu.Tests.iOS/Application.cs index 6ef29fa68e..f9059014a5 100644 --- a/osu.Game.Rulesets.Osu.Tests.iOS/Application.cs +++ b/osu.Game.Rulesets.Osu.Tests.iOS/Application.cs @@ -1,9 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using UIKit; +using osu.Framework.iOS; +using osu.Game.Tests; namespace osu.Game.Rulesets.Osu.Tests.iOS { @@ -11,7 +10,7 @@ namespace osu.Game.Rulesets.Osu.Tests.iOS { public static void Main(string[] args) { - UIApplication.Main(args, null, typeof(AppDelegate)); + GameApplication.Main(new OsuTestBrowser()); } } } diff --git a/osu.Game.Rulesets.Taiko.Tests.iOS/AppDelegate.cs b/osu.Game.Rulesets.Taiko.Tests.iOS/AppDelegate.cs deleted file mode 100644 index 385ba48707..0000000000 --- a/osu.Game.Rulesets.Taiko.Tests.iOS/AppDelegate.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -#nullable disable - -using Foundation; -using osu.Framework.iOS; -using osu.Game.Tests; - -namespace osu.Game.Rulesets.Taiko.Tests.iOS -{ - [Register("AppDelegate")] - public class AppDelegate : GameAppDelegate - { - protected override Framework.Game CreateGame() => new OsuTestBrowser(); - } -} diff --git a/osu.Game.Rulesets.Taiko.Tests.iOS/Application.cs b/osu.Game.Rulesets.Taiko.Tests.iOS/Application.cs index 0e3a953728..0b6a11d8c2 100644 --- a/osu.Game.Rulesets.Taiko.Tests.iOS/Application.cs +++ b/osu.Game.Rulesets.Taiko.Tests.iOS/Application.cs @@ -1,9 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using UIKit; +using osu.Framework.iOS; +using osu.Game.Tests; namespace osu.Game.Rulesets.Taiko.Tests.iOS { @@ -11,7 +10,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.iOS { public static void Main(string[] args) { - UIApplication.Main(args, null, typeof(AppDelegate)); + GameApplication.Main(new OsuTestBrowser()); } } } diff --git a/osu.Game.Tests.iOS/AppDelegate.cs b/osu.Game.Tests.iOS/AppDelegate.cs deleted file mode 100644 index b13027459f..0000000000 --- a/osu.Game.Tests.iOS/AppDelegate.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -#nullable disable - -using Foundation; -using osu.Framework.iOS; - -namespace osu.Game.Tests.iOS -{ - [Register("AppDelegate")] - public class AppDelegate : GameAppDelegate - { - protected override Framework.Game CreateGame() => new OsuTestBrowser(); - } -} diff --git a/osu.Game.Tests.iOS/Application.cs b/osu.Game.Tests.iOS/Application.cs index 4678be4fb8..e5df79f3de 100644 --- a/osu.Game.Tests.iOS/Application.cs +++ b/osu.Game.Tests.iOS/Application.cs @@ -1,9 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using UIKit; +using osu.Framework.iOS; namespace osu.Game.Tests.iOS { @@ -11,7 +9,7 @@ namespace osu.Game.Tests.iOS { public static void Main(string[] args) { - UIApplication.Main(args, null, typeof(AppDelegate)); + GameApplication.Main(new OsuTestBrowser()); } } } diff --git a/osu.iOS/AppDelegate.cs b/osu.iOS/AppDelegate.cs deleted file mode 100644 index 1d29d59fff..0000000000 --- a/osu.iOS/AppDelegate.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -#nullable disable - -using System.Threading.Tasks; -using Foundation; -using osu.Framework.iOS; -using UIKit; - -namespace osu.iOS -{ - [Register("AppDelegate")] - public class AppDelegate : GameAppDelegate - { - private OsuGameIOS game; - - protected override Framework.Game CreateGame() => game = new OsuGameIOS(); - - public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options) - { - if (url.IsFileUrl) - Task.Run(() => game.Import(url.Path)); - else - Task.Run(() => game.HandleLink(url.AbsoluteString)); - return true; - } - } -} diff --git a/osu.iOS/Application.cs b/osu.iOS/Application.cs index 64eb5c63f5..74bd58acb8 100644 --- a/osu.iOS/Application.cs +++ b/osu.iOS/Application.cs @@ -1,9 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using UIKit; +using osu.Framework.iOS; namespace osu.iOS { @@ -11,7 +9,7 @@ namespace osu.iOS { public static void Main(string[] args) { - UIApplication.Main(args, null, typeof(AppDelegate)); + GameApplication.Main(new OsuGameIOS()); } } } From e346b02ebf811f172bd7416db85bc0975406ccd9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 26 Mar 2023 20:09:35 +0900 Subject: [PATCH 2529/2991] Add display of current renderer --- osu.Game/Localisation/GraphicsSettingsStrings.cs | 5 +++++ .../Settings/Sections/Graphics/RendererSettings.cs | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game/Localisation/GraphicsSettingsStrings.cs b/osu.Game/Localisation/GraphicsSettingsStrings.cs index 422704514f..d35446af3d 100644 --- a/osu.Game/Localisation/GraphicsSettingsStrings.cs +++ b/osu.Game/Localisation/GraphicsSettingsStrings.cs @@ -24,6 +24,11 @@ namespace osu.Game.Localisation /// public static LocalisableString Renderer => new TranslatableString(getKey(@"renderer"), @"Renderer"); + /// + /// "Current renderer is "{0}"" + /// + public static LocalisableString CurrentRenderer(string arg0) => new TranslatableString(getKey(@"current_renderer"), @"Current renderer is ""{0}""", arg0); + /// /// "Frame limiter" /// diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index 45a6d35749..2a25939e08 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -4,6 +4,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; +using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Framework.Platform; @@ -25,9 +26,11 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics var renderer = config.GetBindable(FrameworkSetting.Renderer); automaticRendererInUse = renderer.Value == RendererType.Automatic; + SettingsEnumDropdown rendererDropdown; + Children = new Drawable[] { - new SettingsEnumDropdown + rendererDropdown = new SettingsEnumDropdown { LabelText = GraphicsSettingsStrings.Renderer, Current = renderer, @@ -67,6 +70,9 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics renderer.Value = r.OldValue; })); }); + + if (renderer.Value == RendererType.Automatic) + rendererDropdown.SetNoticeText(GraphicsSettingsStrings.CurrentRenderer(host.ResolvedRenderer.GetDescription())); } } } From 764361b3d3ae9e7c5276cb4ec861b98ae0b90fb5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 26 Mar 2023 20:14:33 +0900 Subject: [PATCH 2530/2991] Add special case to hide definitely non-working renderers on android --- .../Settings/Sections/Graphics/RendererSettings.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index 2a25939e08..4b5d2f5a7e 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Extensions; @@ -71,7 +72,13 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics })); }); - if (renderer.Value == RendererType.Automatic) + // TODO: remove this once we support SDL+android. + if (RuntimeInfo.OS == RuntimeInfo.Platform.Android) + { + rendererDropdown.Items = new[] { RendererType.Automatic, RendererType.OpenGLLegacy }; + rendererDropdown.SetNoticeText("New renderer support for android is coming soon!", true); + } + else if (renderer.Value == RendererType.Automatic) rendererDropdown.SetNoticeText(GraphicsSettingsStrings.CurrentRenderer(host.ResolvedRenderer.GetDescription())); } } From ba078e8357ef50d4a737a2e8f7366887e1bbd670 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 26 Mar 2023 20:29:30 +0900 Subject: [PATCH 2531/2991] Show "automatic" resolved renderer inline in dropdown instead --- .../Localisation/GraphicsSettingsStrings.cs | 5 --- .../Sections/Graphics/RendererSettings.cs | 33 ++++++++++++++++--- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/osu.Game/Localisation/GraphicsSettingsStrings.cs b/osu.Game/Localisation/GraphicsSettingsStrings.cs index d35446af3d..422704514f 100644 --- a/osu.Game/Localisation/GraphicsSettingsStrings.cs +++ b/osu.Game/Localisation/GraphicsSettingsStrings.cs @@ -24,11 +24,6 @@ namespace osu.Game.Localisation /// public static LocalisableString Renderer => new TranslatableString(getKey(@"renderer"), @"Renderer"); - /// - /// "Current renderer is "{0}"" - /// - public static LocalisableString CurrentRenderer(string arg0) => new TranslatableString(getKey(@"current_renderer"), @"Current renderer is ""{0}""", arg0); - /// /// "Frame limiter" /// diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index 4b5d2f5a7e..f007d45e8f 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -5,11 +5,11 @@ using System.Linq; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Configuration; -using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Framework.Platform; using osu.Game.Configuration; +using osu.Game.Graphics.UserInterface; using osu.Game.Localisation; using osu.Game.Overlays.Dialog; @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics Children = new Drawable[] { - rendererDropdown = new SettingsEnumDropdown + rendererDropdown = new RendererSettingsDropdown { LabelText = GraphicsSettingsStrings.Renderer, Current = renderer, @@ -78,8 +78,33 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics rendererDropdown.Items = new[] { RendererType.Automatic, RendererType.OpenGLLegacy }; rendererDropdown.SetNoticeText("New renderer support for android is coming soon!", true); } - else if (renderer.Value == RendererType.Automatic) - rendererDropdown.SetNoticeText(GraphicsSettingsStrings.CurrentRenderer(host.ResolvedRenderer.GetDescription())); + } + + private partial class RendererSettingsDropdown : SettingsEnumDropdown + { + protected override OsuDropdown CreateDropdown() => new RendererDropdown(); + + protected partial class RendererDropdown : DropdownControl + { + private RendererType hostResolvedRenderer; + private bool automaticRendererInUse; + + [BackgroundDependencyLoader] + private void load(FrameworkConfigManager config, GameHost host) + { + var renderer = config.GetBindable(FrameworkSetting.Renderer); + automaticRendererInUse = renderer.Value == RendererType.Automatic; + hostResolvedRenderer = host.ResolvedRenderer; + } + + protected override LocalisableString GenerateItemText(RendererType item) + { + if (item == RendererType.Automatic && automaticRendererInUse) + return $"{base.GenerateItemText(item)} ({hostResolvedRenderer})"; + + return base.GenerateItemText(item); + } + } } } } From bab93bed177bd85c52f7ea9928e1cda4c8733603 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 26 Mar 2023 20:43:28 +0900 Subject: [PATCH 2532/2991] Fix string interpolation and use `GetDescription` on renderer value --- .../Overlays/Settings/Sections/Graphics/RendererSettings.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index f007d45e8f..f9127fcd9a 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -5,6 +5,7 @@ using System.Linq; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Configuration; +using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Framework.Platform; @@ -100,7 +101,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics protected override LocalisableString GenerateItemText(RendererType item) { if (item == RendererType.Automatic && automaticRendererInUse) - return $"{base.GenerateItemText(item)} ({hostResolvedRenderer})"; + return LocalisableString.Interpolate($"{base.GenerateItemText(item)} ({hostResolvedRenderer.GetDescription()})"); return base.GenerateItemText(item); } From f3c174a7f2d5538d38daa4293c86677a1e324272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 26 Mar 2023 13:52:26 +0200 Subject: [PATCH 2533/2991] Fix test errors due to missing dependencies --- .../Overlays/Settings/Sections/Graphics/RendererSettings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index f9127fcd9a..ca21b15ff7 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics private bool automaticRendererInUse; [BackgroundDependencyLoader] - private void load(FrameworkConfigManager config, OsuConfigManager osuConfig, IDialogOverlay dialogOverlay, OsuGame game, GameHost host) + private void load(FrameworkConfigManager config, OsuConfigManager osuConfig, IDialogOverlay? dialogOverlay, OsuGame? game, GameHost host) { var renderer = config.GetBindable(FrameworkSetting.Renderer); automaticRendererInUse = renderer.Value == RendererType.Automatic; @@ -67,7 +67,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics if (r.NewValue == RendererType.Automatic && automaticRendererInUse) return; - dialogOverlay.Push(new ConfirmDialog(GraphicsSettingsStrings.ChangeRendererConfirmation, game.AttemptExit, () => + dialogOverlay?.Push(new ConfirmDialog(GraphicsSettingsStrings.ChangeRendererConfirmation, () => game?.AttemptExit(), () => { renderer.Value = r.OldValue; })); From 292486c25ac65f9ef3c7b92a77699bd773fde531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 26 Mar 2023 14:35:00 +0200 Subject: [PATCH 2534/2991] Use more resilient restore method --- .../Overlays/Settings/Sections/Graphics/RendererSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index ca21b15ff7..a4b0feb8bf 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -69,7 +69,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics dialogOverlay?.Push(new ConfirmDialog(GraphicsSettingsStrings.ChangeRendererConfirmation, () => game?.AttemptExit(), () => { - renderer.Value = r.OldValue; + renderer.Value = automaticRendererInUse ? RendererType.Automatic : host.ResolvedRenderer; })); }); From 898717231b333d744f5adb94263cc1faa466ae45 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Mar 2023 02:00:09 +0900 Subject: [PATCH 2535/2991] Hide vulkan renderer option for now We'll bring it back when it's more stable. --- .../Overlays/Settings/Sections/Graphics/RendererSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index a4b0feb8bf..a1f728ca87 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -36,7 +36,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics { LabelText = GraphicsSettingsStrings.Renderer, Current = renderer, - Items = host.GetPreferredRenderersForCurrentPlatform().OrderBy(t => t), + Items = host.GetPreferredRenderersForCurrentPlatform().OrderBy(t => t).Where(t => t != RendererType.Vulkan), Keywords = new[] { @"compatibility", @"directx" }, }, // TODO: this needs to be a custom dropdown at some point From 6924dc5c5066e761e00822c47a62f9999dbc69b8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Mar 2023 02:16:33 +0900 Subject: [PATCH 2536/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index bc382d8f97..927d66d93f 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -11,7 +11,7 @@ manifestmerger.jar - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 16f780d034..3de022e88d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 5d90119233..eb7ba24336 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -16,6 +16,6 @@ iossimulator-x64 - + From 3e0bbb24326ee0d0b4c6dae72ea86d423dc47bed Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 26 Mar 2023 16:03:21 -0700 Subject: [PATCH 2537/2991] Fix select beatmap button not highlighting when creating a multiplayer room using keyboard --- .../Match/MultiplayerMatchSettingsOverlay.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs index 207b9c378b..66acd6d1b0 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs @@ -73,11 +73,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match private OsuSpriteText typeLabel = null!; private LoadingLayer loadingLayer = null!; - public void SelectBeatmap() - { - if (matchSubScreen.IsCurrentScreen()) - matchSubScreen.Push(new MultiplayerMatchSongSelect(matchSubScreen.Room)); - } + public void SelectBeatmap() => selectBeatmapButton.TriggerClick(); [Resolved] private MultiplayerMatchSubScreen matchSubScreen { get; set; } = null!; @@ -97,6 +93,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match private IDisposable? applyingSettingsOperation; private Drawable playlistContainer = null!; private DrawableRoomPlaylist drawablePlaylist = null!; + private RoundedButton selectBeatmapButton = null!; public MatchSettings(Room room) { @@ -275,12 +272,16 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match RelativeSizeAxes = Axes.X, Height = DrawableRoomPlaylistItem.HEIGHT }, - new RoundedButton + selectBeatmapButton = new RoundedButton { RelativeSizeAxes = Axes.X, Height = 40, Text = "Select beatmap", - Action = SelectBeatmap + Action = () => + { + if (matchSubScreen.IsCurrentScreen()) + matchSubScreen.Push(new MultiplayerMatchSongSelect(matchSubScreen.Room)); + } } } } From 76a6f97fbb13aeb163818c1baed19422c30620be Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 26 Mar 2023 17:32:03 -0700 Subject: [PATCH 2538/2991] Fix wrong definition of a beatmap in first run setup --- osu.Game/Localisation/FirstRunSetupBeatmapScreenStrings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Localisation/FirstRunSetupBeatmapScreenStrings.cs b/osu.Game/Localisation/FirstRunSetupBeatmapScreenStrings.cs index 3a7fe4bb12..d822f4976f 100644 --- a/osu.Game/Localisation/FirstRunSetupBeatmapScreenStrings.cs +++ b/osu.Game/Localisation/FirstRunSetupBeatmapScreenStrings.cs @@ -15,9 +15,9 @@ namespace osu.Game.Localisation public static LocalisableString Header => new TranslatableString(getKey(@"header"), @"Obtaining Beatmaps"); /// - /// ""Beatmaps" are what we call playable levels. osu! doesn't come with any beatmaps pre-loaded. This step will help you get started on your beatmap collection." + /// ""Beatmaps" are what we call a set of playable levels. osu! doesn't come with any beatmaps pre-loaded. This step will help you get started on your beatmap collection." /// - public static LocalisableString Description => new TranslatableString(getKey(@"description"), @"""Beatmaps"" are what we call playable levels. osu! doesn't come with any beatmaps pre-loaded. This step will help you get started on your beatmap collection."); + public static LocalisableString Description => new TranslatableString(getKey(@"description"), @"""Beatmaps"" are what we call a set of playable levels. osu! doesn't come with any beatmaps pre-loaded. This step will help you get started on your beatmap collection."); /// /// "If you are a new player, we recommend playing through the tutorial to get accustomed to the gameplay." From 8b30c67580f34dd8375d473e4fa469b928339088 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 26 Mar 2023 18:01:48 -0700 Subject: [PATCH 2539/2991] Fix incorrect song select matching label by showing both beatmap and difficulty count for less ambiguity --- osu.Game/Screens/Select/BeatmapCarousel.cs | 7 ++++++- osu.Game/Screens/Select/SongSelect.cs | 9 ++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 68d3247275..dd3f13373d 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -64,7 +64,12 @@ namespace osu.Game.Screens.Select /// /// The total count of non-filtered beatmaps displayed. /// - public int CountDisplayed => beatmapSets.Where(s => !s.Filtered.Value).Sum(s => s.Beatmaps.Count(b => !b.Filtered.Value)); + public int CountDisplayedBeatmaps => beatmapSets.Where(s => !s.Filtered.Value).Sum(s => s.Beatmaps.Count(b => !b.Filtered.Value)); + + /// + /// The total count of non-filtered beatmap sets displayed. + /// + public int CountDisplayedSets => beatmapSets.Count(s => !s.Filtered.Value); /// /// The currently selected beatmap set. diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index c5e914b461..7191ff7c2a 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using Humanizer; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; @@ -861,11 +862,9 @@ namespace osu.Game.Screens.Select private void updateVisibleBeatmapCount() { - FilterControl.InformationalText = Carousel.CountDisplayed == 1 - // Intentionally not localised until we have proper support for this (see https://github.com/ppy/osu-framework/pull/4918 - // but also in this case we want support for formatting a number within a string). - ? $"{Carousel.CountDisplayed:#,0} matching beatmap" - : $"{Carousel.CountDisplayed:#,0} matching beatmaps"; + // Intentionally not localised until we have proper support for this (see https://github.com/ppy/osu-framework/pull/4918 + // but also in this case we want support for formatting a number within a string). + FilterControl.InformationalText = $"{"matching beatmap".ToQuantity(Carousel.CountDisplayedSets, "#,0")} ({"difficulty".ToQuantity(Carousel.CountDisplayedBeatmaps, "#,0")})"; } private bool boundLocalBindables; From b065689cf89b0771c7d117d67c36f9400942d3d7 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Mon, 27 Mar 2023 23:04:45 +0900 Subject: [PATCH 2540/2991] Limit the area of popover to DrawableChannel popover may be blocked by textBar --- osu.Game/Overlays/ChatOverlay.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 332ffa110a..96dbfe31f3 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -123,7 +123,7 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.Y, Width = side_bar_width, }, - new PopoverContainer + new Container { RelativeSizeAxes = Axes.Both, Anchor = Anchor.TopRight, @@ -135,9 +135,13 @@ namespace osu.Game.Overlays }, Children = new Drawable[] { - currentChannelContainer = new Container + new PopoverContainer { RelativeSizeAxes = Axes.Both, + Child = currentChannelContainer = new Container + { + RelativeSizeAxes = Axes.Both, + } }, loading = new LoadingLayer(true), channelListing = new ChannelListing From 3d032d0024bec4aa11c52725476025c92dbb9452 Mon Sep 17 00:00:00 2001 From: Mohammed Keyvanzadeh Date: Mon, 27 Mar 2023 18:10:32 +0330 Subject: [PATCH 2541/2991] github: update workflows and make tweaks - Update the GitHub Actions workflows to their latest versions. - Replace the usage of the deprecated `set-output` command with the new recommended way to set the output. - Format the YAML files. --- .github/ISSUE_TEMPLATE/config.yml | 19 +++--- .github/dependabot.yml | 88 ++++++++++++++-------------- .github/workflows/ci.yml | 46 +++++++-------- .github/workflows/diffcalc.yml | 29 +++++---- .github/workflows/report-nunit.yml | 23 ++++---- .github/workflows/sentry-release.yml | 4 +- 6 files changed, 104 insertions(+), 105 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 47a6a4c3d3..3f76831a81 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,12 +1,11 @@ blank_issues_enabled: false contact_links: - - name: Help - url: https://github.com/ppy/osu/discussions/categories/q-a - about: osu! not working as you'd expect? Not sure it's a bug? Check the Q&A section! - - name: Suggestions or feature request - url: https://github.com/ppy/osu/discussions/categories/ideas - about: Got something you think should change or be added? Search for or start a new discussion! - - name: osu!stable issues - url: https://github.com/ppy/osu-stable-issues - about: For osu!(stable) - ie. the current "live" game version, check out the dedicated repository. Note that this is for serious bug reports only, not tech support. - + - name: Help + url: https://github.com/ppy/osu/discussions/categories/q-a + about: osu! not working as you'd expect? Not sure it's a bug? Check the Q&A section! + - name: Suggestions or feature request + url: https://github.com/ppy/osu/discussions/categories/ideas + about: Got something you think should change or be added? Search for or start a new discussion! + - name: osu!stable issues + url: https://github.com/ppy/osu-stable-issues + about: For osu!(stable) - ie. the current "live" game version, check out the dedicated repository. Note that this is for serious bug reports only, not tech support. diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 814fc81f51..ed1c3cf658 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,46 +1,46 @@ version: 2 updates: -- package-ecosystem: nuget - directory: "/" - schedule: - interval: monthly - time: "17:00" - open-pull-requests-limit: 0 # disabled until https://github.com/dependabot/dependabot-core/issues/369 is resolved. - ignore: - - dependency-name: Microsoft.EntityFrameworkCore.Design - versions: - - "> 2.2.6" - - dependency-name: Microsoft.EntityFrameworkCore.Sqlite - versions: - - "> 2.2.6" - - dependency-name: Microsoft.EntityFrameworkCore.Sqlite.Core - versions: - - "> 2.2.6" - - dependency-name: Microsoft.Extensions.DependencyInjection - versions: - - ">= 5.a, < 6" - - dependency-name: NUnit3TestAdapter - versions: - - ">= 3.16.a, < 3.17" - - dependency-name: Microsoft.NET.Test.Sdk - versions: - - 16.9.1 - - dependency-name: Microsoft.Extensions.DependencyInjection - versions: - - 3.1.11 - - 3.1.12 - - dependency-name: Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson - versions: - - 3.1.11 - - dependency-name: Microsoft.NETCore.Targets - versions: - - 5.0.0 - - dependency-name: Microsoft.AspNetCore.SignalR.Protocols.MessagePack - versions: - - 5.0.2 - - dependency-name: NUnit - versions: - - 3.13.1 - - dependency-name: Microsoft.AspNetCore.SignalR.Client - versions: - - 3.1.11 + - package-ecosystem: nuget + directory: "/" + schedule: + interval: monthly + time: "17:00" + open-pull-requests-limit: 0 # disabled until https://github.com/dependabot/dependabot-core/issues/369 is resolved. + ignore: + - dependency-name: Microsoft.EntityFrameworkCore.Design + versions: + - "> 2.2.6" + - dependency-name: Microsoft.EntityFrameworkCore.Sqlite + versions: + - "> 2.2.6" + - dependency-name: Microsoft.EntityFrameworkCore.Sqlite.Core + versions: + - "> 2.2.6" + - dependency-name: Microsoft.Extensions.DependencyInjection + versions: + - ">= 5.a, < 6" + - dependency-name: NUnit3TestAdapter + versions: + - ">= 3.16.a, < 3.17" + - dependency-name: Microsoft.NET.Test.Sdk + versions: + - 16.9.1 + - dependency-name: Microsoft.Extensions.DependencyInjection + versions: + - 3.1.11 + - 3.1.12 + - dependency-name: Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson + versions: + - 3.1.11 + - dependency-name: Microsoft.NETCore.Targets + versions: + - 5.0.0 + - dependency-name: Microsoft.AspNetCore.SignalR.Protocols.MessagePack + versions: + - 5.0.2 + - dependency-name: NUnit + versions: + - 3.13.1 + - dependency-name: Microsoft.AspNetCore.SignalR.Client + versions: + - 3.1.11 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5c11f91994..742b428d1d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,17 +13,17 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 # FIXME: Tools won't run in .NET 6.0 unless you install 3.1.x LTS side by side. # https://itnext.io/how-to-support-multiple-net-sdks-in-github-actions-workflows-b988daa884e - name: Install .NET 3.1.x LTS - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v3 with: dotnet-version: "3.1.x" - name: Install .NET 6.0.x - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v3 with: dotnet-version: "6.0.x" @@ -59,28 +59,28 @@ jobs: run: dotnet jb inspectcode $(pwd)/osu.Desktop.slnf --no-build --output="inspectcodereport.xml" --caches-home="inspectcode" --verbosity=WARN - name: NVika - run: dotnet nvika parsereport "${{github.workspace}}/inspectcodereport.xml" --treatwarningsaserrors + run: dotnet nvika parsereport "${{ github.workspace }}/inspectcodereport.xml" --treatwarningsaserrors test: name: Test - runs-on: ${{matrix.os.fullname}} + runs-on: ${{ matrix.os.fullname }} env: - OSU_EXECUTION_MODE: ${{matrix.threadingMode}} + OSU_EXECUTION_MODE: ${{ matrix.threadingMode }} strategy: - fail-fast: false - matrix: - os: - - { prettyname: Windows, fullname: windows-latest } - - { prettyname: macOS, fullname: macos-latest } - - { prettyname: Linux, fullname: ubuntu-latest } - threadingMode: ['SingleThread', 'MultiThreaded'] + fail-fast: false + matrix: + os: + - { prettyname: Windows, fullname: windows-latest } + - { prettyname: macOS, fullname: macos-latest } + - { prettyname: Linux, fullname: ubuntu-latest } + threadingMode: ["SingleThread", "MultiThreaded"] timeout-minutes: 60 steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install .NET 6.0.x - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v3 with: dotnet-version: "6.0.x" @@ -88,17 +88,17 @@ jobs: run: dotnet build -c Debug -warnaserror osu.Desktop.slnf - name: Test - run: dotnet test $pwd/**/*.Tests/bin/Debug/*/*.Tests.dll --logger "trx;LogFileName=TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx" -- NUnit.ConsoleOut=0 + run: dotnet test $pwd/**/*.Tests/bin/Debug/*/*.Tests.dll --logger "trx;LogFileName=TestResults-${{ matrix.os.prettyname }}-${{ matrix.threadingMode }}.trx" -- NUnit.ConsoleOut=0 shell: pwsh # Attempt to upload results even if test fails. # https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#always - name: Upload Test Results - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 if: ${{ always() }} with: - name: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}} - path: ${{github.workspace}}/TestResults/TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx + name: osu-test-results-${{ matrix.os.prettyname }}-${{ matrix.threadingMode }} + path: ${{ github.workspace }}/TestResults/TestResults-${{ matrix.os.prettyname }}-${{ matrix.threadingMode }}.trx build-only-android: name: Build only (Android) @@ -106,10 +106,10 @@ jobs: timeout-minutes: 60 steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install .NET 6.0.x - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v3 with: dotnet-version: "6.0.x" @@ -125,10 +125,10 @@ jobs: timeout-minutes: 60 steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install .NET 6.0.x - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v3 with: dotnet-version: "6.0.x" diff --git a/.github/workflows/diffcalc.yml b/.github/workflows/diffcalc.yml index 9e11ab6663..b213d76794 100644 --- a/.github/workflows/diffcalc.yml +++ b/.github/workflows/diffcalc.yml @@ -2,12 +2,11 @@ # Usage: # !pp check 0 | Runs only the osu! ruleset. # !pp check 0 2 | Runs only the osu! and catch rulesets. -# name: Difficulty Calculation on: issue_comment: - types: [ created ] + types: [created] env: CONCURRENCY: 4 @@ -48,8 +47,8 @@ jobs: CONTINUE="no" fi - echo "::set-output name=continue::${CONTINUE}" - echo "::set-output name=matrix::${MATRIX_JSON}" + echo "continue=${CONTINUE}" >> $GITHUB_OUTPUT + echo "matrix=${MATRIX_JSON}" >> $GITHUB_OUTPUT diffcalc: name: Run runs-on: self-hosted @@ -80,34 +79,34 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - echo "::set-output name=branchname::$(curl -H "Authorization: token ${GITHUB_TOKEN}" ${{ github.event.issue.pull_request.url }} | jq '.head.ref' | sed 's/\"//g')" - echo "::set-output name=repo::$(curl -H "Authorization: token ${GITHUB_TOKEN}" ${{ github.event.issue.pull_request.url }} | jq '.head.repo.full_name' | sed 's/\"//g')" + echo "branchname=$(curl -H "Authorization: token ${GITHUB_TOKEN}" ${{ github.event.issue.pull_request.url }} | jq '.head.ref' | sed 's/\"//g')" >> $GITHUB_OUTPUT + echo "repo=$(curl -H "Authorization: token ${GITHUB_TOKEN}" ${{ github.event.issue.pull_request.url }} | jq '.head.repo.full_name' | sed 's/\"//g')" >> $GITHUB_OUTPUT # Checkout osu - name: Checkout osu (master) - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: - path: 'master/osu' + path: "master/osu" - name: Checkout osu (pr) - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: - path: 'pr/osu' + path: "pr/osu" repository: ${{ steps.upstreambranch.outputs.repo }} ref: ${{ steps.upstreambranch.outputs.branchname }} - name: Checkout osu-difficulty-calculator (master) - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: ppy/osu-difficulty-calculator - path: 'master/osu-difficulty-calculator' + path: "master/osu-difficulty-calculator" - name: Checkout osu-difficulty-calculator (pr) - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: ppy/osu-difficulty-calculator - path: 'pr/osu-difficulty-calculator' + path: "pr/osu-difficulty-calculator" - name: Install .NET 5.0.x - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v3 with: dotnet-version: "5.0.x" diff --git a/.github/workflows/report-nunit.yml b/.github/workflows/report-nunit.yml index 99e39f6f56..fee10aa487 100644 --- a/.github/workflows/report-nunit.yml +++ b/.github/workflows/report-nunit.yml @@ -2,6 +2,7 @@ # See: # * https://github.com/dorny/test-reporter#recommended-setup-for-public-repositories # * https://docs.github.com/en/actions/reference/authentication-in-a-workflow#permissions-for-the-github_token + name: Annotate CI run with test results on: workflow_run: @@ -18,21 +19,21 @@ jobs: runs-on: ubuntu-latest if: ${{ github.event.workflow_run.conclusion != 'cancelled' }} strategy: - fail-fast: false - matrix: - os: - - { prettyname: Windows } - - { prettyname: macOS } - - { prettyname: Linux } - threadingMode: ['SingleThread', 'MultiThreaded'] + fail-fast: false + matrix: + os: + - { prettyname: Windows } + - { prettyname: macOS } + - { prettyname: Linux } + threadingMode: ["SingleThread", "MultiThreaded"] timeout-minutes: 5 steps: - name: Annotate CI run with test results uses: dorny/test-reporter@v1.6.0 with: - artifact: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}} - name: Test Results (${{matrix.os.prettyname}}, ${{matrix.threadingMode}}) + artifact: osu-test-results-${{ matrix.os.prettyname }}-${{ matrix.threadingMode }} + name: Test Results (${{ matrix.os.prettyname }}, ${{ matrix.threadingMode }}) path: "*.trx" reporter: dotnet-trx - list-suites: 'failed' - list-tests: 'failed' + list-suites: "failed" + list-tests: "failed" diff --git a/.github/workflows/sentry-release.yml b/.github/workflows/sentry-release.yml index cce3f23e5f..001a63cc64 100644 --- a/.github/workflows/sentry-release.yml +++ b/.github/workflows/sentry-release.yml @@ -3,7 +3,7 @@ name: Add Release to Sentry on: push: tags: - - '*' + - "*" permissions: contents: read # to fetch code (actions/checkout) @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 From 433f9e53679f4595cf1b9b42da5e713981dcc95d Mon Sep 17 00:00:00 2001 From: Mohammed Keyvanzadeh Date: Mon, 27 Mar 2023 18:37:01 +0330 Subject: [PATCH 2542/2991] fixup! revert formatting changes --- .github/ISSUE_TEMPLATE/config.yml | 19 +++--- .github/dependabot.yml | 88 ++++++++++++++-------------- .github/workflows/ci.yml | 26 ++++---- .github/workflows/diffcalc.yml | 11 ++-- .github/workflows/report-nunit.yml | 23 ++++---- .github/workflows/sentry-release.yml | 2 +- 6 files changed, 85 insertions(+), 84 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 3f76831a81..47a6a4c3d3 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,11 +1,12 @@ blank_issues_enabled: false contact_links: - - name: Help - url: https://github.com/ppy/osu/discussions/categories/q-a - about: osu! not working as you'd expect? Not sure it's a bug? Check the Q&A section! - - name: Suggestions or feature request - url: https://github.com/ppy/osu/discussions/categories/ideas - about: Got something you think should change or be added? Search for or start a new discussion! - - name: osu!stable issues - url: https://github.com/ppy/osu-stable-issues - about: For osu!(stable) - ie. the current "live" game version, check out the dedicated repository. Note that this is for serious bug reports only, not tech support. + - name: Help + url: https://github.com/ppy/osu/discussions/categories/q-a + about: osu! not working as you'd expect? Not sure it's a bug? Check the Q&A section! + - name: Suggestions or feature request + url: https://github.com/ppy/osu/discussions/categories/ideas + about: Got something you think should change or be added? Search for or start a new discussion! + - name: osu!stable issues + url: https://github.com/ppy/osu-stable-issues + about: For osu!(stable) - ie. the current "live" game version, check out the dedicated repository. Note that this is for serious bug reports only, not tech support. + diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ed1c3cf658..814fc81f51 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,46 +1,46 @@ version: 2 updates: - - package-ecosystem: nuget - directory: "/" - schedule: - interval: monthly - time: "17:00" - open-pull-requests-limit: 0 # disabled until https://github.com/dependabot/dependabot-core/issues/369 is resolved. - ignore: - - dependency-name: Microsoft.EntityFrameworkCore.Design - versions: - - "> 2.2.6" - - dependency-name: Microsoft.EntityFrameworkCore.Sqlite - versions: - - "> 2.2.6" - - dependency-name: Microsoft.EntityFrameworkCore.Sqlite.Core - versions: - - "> 2.2.6" - - dependency-name: Microsoft.Extensions.DependencyInjection - versions: - - ">= 5.a, < 6" - - dependency-name: NUnit3TestAdapter - versions: - - ">= 3.16.a, < 3.17" - - dependency-name: Microsoft.NET.Test.Sdk - versions: - - 16.9.1 - - dependency-name: Microsoft.Extensions.DependencyInjection - versions: - - 3.1.11 - - 3.1.12 - - dependency-name: Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson - versions: - - 3.1.11 - - dependency-name: Microsoft.NETCore.Targets - versions: - - 5.0.0 - - dependency-name: Microsoft.AspNetCore.SignalR.Protocols.MessagePack - versions: - - 5.0.2 - - dependency-name: NUnit - versions: - - 3.13.1 - - dependency-name: Microsoft.AspNetCore.SignalR.Client - versions: - - 3.1.11 +- package-ecosystem: nuget + directory: "/" + schedule: + interval: monthly + time: "17:00" + open-pull-requests-limit: 0 # disabled until https://github.com/dependabot/dependabot-core/issues/369 is resolved. + ignore: + - dependency-name: Microsoft.EntityFrameworkCore.Design + versions: + - "> 2.2.6" + - dependency-name: Microsoft.EntityFrameworkCore.Sqlite + versions: + - "> 2.2.6" + - dependency-name: Microsoft.EntityFrameworkCore.Sqlite.Core + versions: + - "> 2.2.6" + - dependency-name: Microsoft.Extensions.DependencyInjection + versions: + - ">= 5.a, < 6" + - dependency-name: NUnit3TestAdapter + versions: + - ">= 3.16.a, < 3.17" + - dependency-name: Microsoft.NET.Test.Sdk + versions: + - 16.9.1 + - dependency-name: Microsoft.Extensions.DependencyInjection + versions: + - 3.1.11 + - 3.1.12 + - dependency-name: Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson + versions: + - 3.1.11 + - dependency-name: Microsoft.NETCore.Targets + versions: + - 5.0.0 + - dependency-name: Microsoft.AspNetCore.SignalR.Protocols.MessagePack + versions: + - 5.0.2 + - dependency-name: NUnit + versions: + - 3.13.1 + - dependency-name: Microsoft.AspNetCore.SignalR.Client + versions: + - 3.1.11 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 742b428d1d..e60e0a39ae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,21 +59,21 @@ jobs: run: dotnet jb inspectcode $(pwd)/osu.Desktop.slnf --no-build --output="inspectcodereport.xml" --caches-home="inspectcode" --verbosity=WARN - name: NVika - run: dotnet nvika parsereport "${{ github.workspace }}/inspectcodereport.xml" --treatwarningsaserrors + run: dotnet nvika parsereport "${{github.workspace}}/inspectcodereport.xml" --treatwarningsaserrors test: name: Test - runs-on: ${{ matrix.os.fullname }} + runs-on: ${{matrix.os.fullname}} env: - OSU_EXECUTION_MODE: ${{ matrix.threadingMode }} + OSU_EXECUTION_MODE: ${{matrix.threadingMode}} strategy: - fail-fast: false - matrix: - os: - - { prettyname: Windows, fullname: windows-latest } - - { prettyname: macOS, fullname: macos-latest } - - { prettyname: Linux, fullname: ubuntu-latest } - threadingMode: ["SingleThread", "MultiThreaded"] + fail-fast: false + matrix: + os: + - { prettyname: Windows, fullname: windows-latest } + - { prettyname: macOS, fullname: macos-latest } + - { prettyname: Linux, fullname: ubuntu-latest } + threadingMode: ['SingleThread', 'MultiThreaded'] timeout-minutes: 60 steps: - name: Checkout @@ -88,7 +88,7 @@ jobs: run: dotnet build -c Debug -warnaserror osu.Desktop.slnf - name: Test - run: dotnet test $pwd/**/*.Tests/bin/Debug/*/*.Tests.dll --logger "trx;LogFileName=TestResults-${{ matrix.os.prettyname }}-${{ matrix.threadingMode }}.trx" -- NUnit.ConsoleOut=0 + run: dotnet test $pwd/**/*.Tests/bin/Debug/*/*.Tests.dll --logger "trx;LogFileName=TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx" -- NUnit.ConsoleOut=0 shell: pwsh # Attempt to upload results even if test fails. @@ -97,8 +97,8 @@ jobs: uses: actions/upload-artifact@v3 if: ${{ always() }} with: - name: osu-test-results-${{ matrix.os.prettyname }}-${{ matrix.threadingMode }} - path: ${{ github.workspace }}/TestResults/TestResults-${{ matrix.os.prettyname }}-${{ matrix.threadingMode }}.trx + name: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}} + path: ${{github.workspace}}/TestResults/TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx build-only-android: name: Build only (Android) diff --git a/.github/workflows/diffcalc.yml b/.github/workflows/diffcalc.yml index b213d76794..2c6ec17e18 100644 --- a/.github/workflows/diffcalc.yml +++ b/.github/workflows/diffcalc.yml @@ -2,11 +2,12 @@ # Usage: # !pp check 0 | Runs only the osu! ruleset. # !pp check 0 2 | Runs only the osu! and catch rulesets. +# name: Difficulty Calculation on: issue_comment: - types: [created] + types: [ created ] env: CONCURRENCY: 4 @@ -86,11 +87,11 @@ jobs: - name: Checkout osu (master) uses: actions/checkout@v3 with: - path: "master/osu" + path: 'master/osu' - name: Checkout osu (pr) uses: actions/checkout@v3 with: - path: "pr/osu" + path: 'pr/osu' repository: ${{ steps.upstreambranch.outputs.repo }} ref: ${{ steps.upstreambranch.outputs.branchname }} @@ -98,12 +99,12 @@ jobs: uses: actions/checkout@v3 with: repository: ppy/osu-difficulty-calculator - path: "master/osu-difficulty-calculator" + path: 'master/osu-difficulty-calculator' - name: Checkout osu-difficulty-calculator (pr) uses: actions/checkout@v3 with: repository: ppy/osu-difficulty-calculator - path: "pr/osu-difficulty-calculator" + path: 'pr/osu-difficulty-calculator' - name: Install .NET 5.0.x uses: actions/setup-dotnet@v3 diff --git a/.github/workflows/report-nunit.yml b/.github/workflows/report-nunit.yml index fee10aa487..99e39f6f56 100644 --- a/.github/workflows/report-nunit.yml +++ b/.github/workflows/report-nunit.yml @@ -2,7 +2,6 @@ # See: # * https://github.com/dorny/test-reporter#recommended-setup-for-public-repositories # * https://docs.github.com/en/actions/reference/authentication-in-a-workflow#permissions-for-the-github_token - name: Annotate CI run with test results on: workflow_run: @@ -19,21 +18,21 @@ jobs: runs-on: ubuntu-latest if: ${{ github.event.workflow_run.conclusion != 'cancelled' }} strategy: - fail-fast: false - matrix: - os: - - { prettyname: Windows } - - { prettyname: macOS } - - { prettyname: Linux } - threadingMode: ["SingleThread", "MultiThreaded"] + fail-fast: false + matrix: + os: + - { prettyname: Windows } + - { prettyname: macOS } + - { prettyname: Linux } + threadingMode: ['SingleThread', 'MultiThreaded'] timeout-minutes: 5 steps: - name: Annotate CI run with test results uses: dorny/test-reporter@v1.6.0 with: - artifact: osu-test-results-${{ matrix.os.prettyname }}-${{ matrix.threadingMode }} - name: Test Results (${{ matrix.os.prettyname }}, ${{ matrix.threadingMode }}) + artifact: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}} + name: Test Results (${{matrix.os.prettyname}}, ${{matrix.threadingMode}}) path: "*.trx" reporter: dotnet-trx - list-suites: "failed" - list-tests: "failed" + list-suites: 'failed' + list-tests: 'failed' diff --git a/.github/workflows/sentry-release.yml b/.github/workflows/sentry-release.yml index 001a63cc64..ff4165c414 100644 --- a/.github/workflows/sentry-release.yml +++ b/.github/workflows/sentry-release.yml @@ -3,7 +3,7 @@ name: Add Release to Sentry on: push: tags: - - "*" + - '*' permissions: contents: read # to fetch code (actions/checkout) From 9426633a05c04c640666463fde89b20f07e96595 Mon Sep 17 00:00:00 2001 From: rrex971 <75212090+rrex971@users.noreply.github.com> Date: Mon, 27 Mar 2023 20:39:13 +0530 Subject: [PATCH 2543/2991] Allow AR and CS values below 1.0 for Catch the Beat Difficulty Adjustment mod --- osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index e59a0a0431..6efb415880 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.Mods public DifficultyBindable CircleSize { get; } = new DifficultyBindable { Precision = 0.1f, - MinValue = 1, + MinValue = 0, MaxValue = 10, ExtendedMaxValue = 11, ReadCurrentFromDifficulty = diff => diff.CircleSize, @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Catch.Mods public DifficultyBindable ApproachRate { get; } = new DifficultyBindable { Precision = 0.1f, - MinValue = 1, + MinValue = 0, MaxValue = 10, ExtendedMaxValue = 11, ReadCurrentFromDifficulty = diff => diff.ApproachRate, From f31e77dce5317b3beb82838e678c183536deb6d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 27 Mar 2023 18:08:06 +0200 Subject: [PATCH 2544/2991] Add direction switching to `TestSceneManiaPlayer` To test upscroll easier, and with all parts in conjunction. `ManiaSkinnableTestScene`s already had the capability to switch directions, but they did not show all parts together, which meant regressions were missed. --- .../TestSceneManiaPlayer.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneManiaPlayer.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneManiaPlayer.cs index 98046320cb..4e50fd924c 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneManiaPlayer.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneManiaPlayer.cs @@ -3,6 +3,9 @@ #nullable disable +using osu.Framework.Extensions.ObjectExtensions; +using osu.Game.Rulesets.Mania.Configuration; +using osu.Game.Rulesets.Mania.UI; using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Mania.Tests @@ -10,5 +13,19 @@ namespace osu.Game.Rulesets.Mania.Tests public partial class TestSceneManiaPlayer : PlayerTestScene { protected override Ruleset CreatePlayerRuleset() => new ManiaRuleset(); + + public override void SetUpSteps() + { + base.SetUpSteps(); + + AddStep("change direction to down", () => changeDirectionTo(ManiaScrollingDirection.Down)); + AddStep("change direction to up", () => changeDirectionTo(ManiaScrollingDirection.Up)); + } + + private void changeDirectionTo(ManiaScrollingDirection direction) + { + var rulesetConfig = (ManiaRulesetConfigManager)RulesetConfigs.GetConfigFor(new ManiaRuleset()).AsNonNull(); + rulesetConfig.SetValue(ManiaRulesetSetting.ScrollDirection, direction); + } } } From c54934cb45f361daaacbac7059b8139c655c6901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 27 Mar 2023 18:15:01 +0200 Subject: [PATCH 2545/2991] Fix hit lighting misalignment on argon skin with upscroll --- .../Skinning/Argon/ArgonHitExplosion.cs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitExplosion.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitExplosion.cs index 8e27b4abd7..fb38b536dc 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitExplosion.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitExplosion.cs @@ -43,8 +43,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon { largeFaint = new Container { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, RelativeSizeAxes = Axes.Both, Height = ArgonNotePiece.NOTE_ACCENT_RATIO, Masking = true, @@ -78,16 +76,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon private void onDirectionChanged(ValueChangedEvent direction) { - if (direction.NewValue == ScrollingDirection.Up) - { - Anchor = Anchor.TopCentre; - Y = ArgonNotePiece.NOTE_HEIGHT / 2; - } - else - { - Anchor = Anchor.BottomCentre; - Y = -ArgonNotePiece.NOTE_HEIGHT / 2; - } + Anchor = largeFaint.Anchor = largeFaint.Origin = direction.NewValue == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre; + Y = direction.NewValue == ScrollingDirection.Up ? ArgonNotePiece.NOTE_HEIGHT / 2 : -ArgonNotePiece.NOTE_HEIGHT / 2; } public void Animate(JudgementResult result) From 2b525b626c1e7a46c7402edbb4def3fa6d6a9581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 28 Mar 2023 06:22:00 +0200 Subject: [PATCH 2546/2991] Revert to previous conditional style --- .../Skinning/Argon/ArgonHitExplosion.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitExplosion.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitExplosion.cs index fb38b536dc..d490d3f944 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitExplosion.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonHitExplosion.cs @@ -76,8 +76,20 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon private void onDirectionChanged(ValueChangedEvent direction) { - Anchor = largeFaint.Anchor = largeFaint.Origin = direction.NewValue == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre; - Y = direction.NewValue == ScrollingDirection.Up ? ArgonNotePiece.NOTE_HEIGHT / 2 : -ArgonNotePiece.NOTE_HEIGHT / 2; + if (direction.NewValue == ScrollingDirection.Up) + { + Anchor = Anchor.TopCentre; + largeFaint.Anchor = Anchor.TopCentre; + largeFaint.Origin = Anchor.TopCentre; + Y = ArgonNotePiece.NOTE_HEIGHT / 2; + } + else + { + Anchor = Anchor.BottomCentre; + largeFaint.Anchor = Anchor.BottomCentre; + largeFaint.Origin = Anchor.BottomCentre; + Y = -ArgonNotePiece.NOTE_HEIGHT / 2; + } } public void Animate(JudgementResult result) From c742b3f0a8a10854ba73fc59c0f5a521c445a968 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Mar 2023 14:15:19 +0900 Subject: [PATCH 2547/2991] Update `DrawableRulesetDependencies` xmldoc to read more correctly --- osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs index 96b02ee4dc..5c031c5f08 100644 --- a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs +++ b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs @@ -25,21 +25,28 @@ namespace osu.Game.Rulesets.UI /// /// The texture store to be used for the ruleset. /// + /// + /// Reads textures from the "Textures" folder in ruleset resources. + /// If not available locally, lookups will fallback to the global texture store. + /// public TextureStore TextureStore { get; } /// /// The sample store to be used for the ruleset. /// /// - /// This is the local sample store pointing to the ruleset sample resources, - /// the cached sample store () retrieves from - /// this store and falls back to the parent store if this store doesn't have the requested sample. + /// Reads samples from the "Samples" folder in ruleset resources. + /// If not available locally, lookups will fallback to the global sample store. /// public ISampleStore SampleStore { get; } /// /// The shader manager to be used for the ruleset. /// + /// + /// Reads shaders from the "Shaders" folder in ruleset resources. + /// If not available locally, lookups will fallback to the global shader manager. + /// public ShaderManager ShaderManager { get; } /// From 5dfac02b11a3c5c70ee84f6787d5e355d4b1b7ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Mar 2023 14:15:38 +0900 Subject: [PATCH 2548/2991] Preload triangle shader on startup --- osu.Game/Screens/Loader.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index b70c1f7ddf..bee6207a35 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -130,6 +130,10 @@ namespace osu.Game.Screens loadTargets.Add(manager.Load(@"CursorTrail", FragmentShaderDescriptor.TEXTURE)); + loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, "TriangleBorder")); + + loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE)); + loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE)); } From 0d77ec013a936fd77b852837b7007229028f34bd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Mar 2023 14:53:08 +0900 Subject: [PATCH 2549/2991] Fix ruleset-local shader manager not correctly falling back to existing cached shaders --- .../UI/DrawableRulesetDependencies.cs | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs index 5c031c5f08..e6ee770e19 100644 --- a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs +++ b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs @@ -68,8 +68,7 @@ namespace osu.Game.Rulesets.UI SampleStore.PlaybackConcurrency = OsuGameBase.SAMPLE_CONCURRENCY; CacheAs(SampleStore = new FallbackSampleStore(SampleStore, parent.Get())); - ShaderManager = new ShaderManager(host.Renderer, new NamespacedResourceStore(resources, @"Shaders")); - CacheAs(ShaderManager = new FallbackShaderManager(host.Renderer, ShaderManager, parent.Get())); + CacheAs(ShaderManager = new RulesetShaderManager(host.Renderer, new NamespacedResourceStore(resources, @"Shaders"), parent.Get())); RulesetConfigManager = parent.Get().GetConfigFor(ruleset); if (RulesetConfigManager != null) @@ -197,24 +196,27 @@ namespace osu.Game.Rulesets.UI } } - private class FallbackShaderManager : ShaderManager + private class RulesetShaderManager : ShaderManager { - private readonly ShaderManager primary; - private readonly ShaderManager fallback; + private readonly ShaderManager parent; - public FallbackShaderManager(IRenderer renderer, ShaderManager primary, ShaderManager fallback) - : base(renderer, new ResourceStore()) + public RulesetShaderManager(IRenderer renderer, NamespacedResourceStore rulesetResources, ShaderManager parent) + : base(renderer, rulesetResources) { - this.primary = primary; - this.fallback = fallback; + this.parent = parent; } - public override byte[]? LoadRaw(string name) => primary.LoadRaw(name) ?? fallback.LoadRaw(name); - - protected override void Dispose(bool disposing) + public override IShader Load(string vertex, string fragment) { - base.Dispose(disposing); - if (primary.IsNotNull()) primary.Dispose(); + try + { + return base.Load(vertex, fragment); + } + catch + { + // Shader lookup is very non-standard. Rather than returning null on missing shaders, exceptions are thrown. + return parent.Load(vertex, fragment); + } } } } From 8c1df3c8d9d6c875d151f086035dc6b7d13ceb04 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Mar 2023 15:38:19 +0900 Subject: [PATCH 2550/2991] Fix web account registration not bypassing the URL warning --- osu.Game/Overlays/AccountCreation/ScreenEntry.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs index 2e20f83e9e..219cbe7eef 100644 --- a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs +++ b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs @@ -209,7 +209,7 @@ namespace osu.Game.Overlays.AccountCreation if (!string.IsNullOrEmpty(errors.Message)) passwordDescription.AddErrors(new[] { errors.Message }); - game.OpenUrlExternally($"{errors.Redirect}?username={usernameTextBox.Text}&email={emailTextBox.Text}"); + game.OpenUrlExternally($"{errors.Redirect}?username={usernameTextBox.Text}&email={emailTextBox.Text}", true); } } else From 45e3e3623b70c206a9889dd602186d895506d448 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Mar 2023 18:48:55 +0900 Subject: [PATCH 2551/2991] Fix spinners being selectable for too long after they fade in the editor The actual visual extension is only applied to `HitCircle`s (which does include slider start / end), and should not be applied to spinners in the first place. Addresses https://github.com/ppy/osu/discussions/22949. --- osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs index 3e161089cd..d6409279a4 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints protected override bool AlwaysShowWhenSelected => true; protected override bool ShouldBeAlive => base.ShouldBeAlive - || (ShowHitMarkers.Value && editorClock.CurrentTime >= Item.StartTime && editorClock.CurrentTime - Item.GetEndTime() < HitCircleOverlapMarker.FADE_OUT_EXTENSION); + || (DrawableObject is not DrawableSpinner && ShowHitMarkers.Value && editorClock.CurrentTime >= Item.StartTime && editorClock.CurrentTime - Item.GetEndTime() < HitCircleOverlapMarker.FADE_OUT_EXTENSION); protected OsuSelectionBlueprint(T hitObject) : base(hitObject) From 31df626f0ebe022884f2b5bd2bce49898661ec1d Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Tue, 28 Mar 2023 21:32:28 +0900 Subject: [PATCH 2552/2991] disable button when select other reason --- .../Graphics/UserInterfaceV2/ReportPopover.cs | 24 ++++++++++++------- osu.Game/Overlays/Chat/ReportChatPopover.cs | 6 ++++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs b/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs index 44af108ab1..46006402ad 100644 --- a/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs +++ b/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs @@ -24,8 +24,6 @@ namespace osu.Game.Graphics.UserInterfaceV2 private OsuEnumDropdown reasonDropdown = null!; private OsuTextBox commentsTextBox = null!; private RoundedButton submitButton = null!; - - public bool CanSubmitEmptyReason = false; public LocalisableString Header; protected ReportPopover(LocalisableString headerString) @@ -102,13 +100,21 @@ namespace osu.Game.Graphics.UserInterfaceV2 } }; - if (!CanSubmitEmptyReason) - { - commentsTextBox.Current.BindValueChanged(e => - { - submitButton.Enabled.Value = !string.IsNullOrWhiteSpace(e.NewValue); - }, true); - } + commentsTextBox.Current.BindValueChanged(_ => updateStatus()); + + reasonDropdown.Current.BindValueChanged(_ => updateStatus()); + + updateStatus(); + } + + private void updateStatus() + { + submitButton.Enabled.Value = !string.IsNullOrWhiteSpace(commentsTextBox.Current.Value) || CheckCanSubmitEmptyComment(reasonDropdown.Current.Value); + } + + protected virtual bool CheckCanSubmitEmptyComment(T reason) + { + return false; } } } diff --git a/osu.Game/Overlays/Chat/ReportChatPopover.cs b/osu.Game/Overlays/Chat/ReportChatPopover.cs index 79c3922795..de5f3268b8 100644 --- a/osu.Game/Overlays/Chat/ReportChatPopover.cs +++ b/osu.Game/Overlays/Chat/ReportChatPopover.cs @@ -12,7 +12,11 @@ namespace osu.Game.Overlays.Chat public ReportChatPopover(APIUser? user) : base(ReportStrings.UserTitle(user?.Username ?? @"Someone")) { - CanSubmitEmptyReason = true; + } + + protected override bool CheckCanSubmitEmptyComment(ChatReportReason reason) + { + return reason != ChatReportReason.Other; } } } From f01247f1ab75dfd7f9dc81200a569b3f114b4296 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Tue, 28 Mar 2023 21:39:42 +0900 Subject: [PATCH 2553/2991] test --- .../Visual/Online/TestSceneChatOverlay.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 5845ba3783..faf48ef854 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -618,6 +618,12 @@ namespace osu.Game.Tests.Visual.Online AddStep("Show report popover", () => this.ChildrenOfType().First().ShowPopover()); + AddStep("Set report reason to other", () => + { + var reason = this.ChildrenOfType>().Single(); + reason.Current.Value = ChatReportReason.Other; + }); + AddStep("Try to report", () => { var btn = this.ChildrenOfType().Single().ChildrenOfType().Single(); @@ -626,7 +632,21 @@ namespace osu.Game.Tests.Visual.Online }); AddWaitStep("Wait", 3); + AddAssert("Nothing happened", () => this.ChildrenOfType().Any()); + AddStep("Set report data", () => + { + var field = this.ChildrenOfType().Single().ChildrenOfType().Single(); + field.Current.Value = "test other"; + }); + AddStep("Try to report", () => + { + var btn = this.ChildrenOfType().Single().ChildrenOfType().Single(); + InputManager.MoveMouseTo(btn); + InputManager.Click(MouseButton.Left); + }); + + AddWaitStep("Wait", 3); AddAssert("Overlay closed", () => !this.ChildrenOfType().Any()); AddStep("Complete request", () => requestLock.Set()); AddUntilStep("Request sent", () => request != null); From 46ede27869efca77ec226081454cf682ad907a77 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Tue, 28 Mar 2023 22:24:05 +0900 Subject: [PATCH 2554/2991] add feature to adjust `ScalingContainer` background dim --- osu.Game/Configuration/OsuConfigManager.cs | 2 ++ .../Graphics/Containers/ScalingContainer.cs | 11 +++++++++-- .../Sections/Graphics/LayoutSettings.cs | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 70ad6bfc96..a06bfcc5f0 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -157,6 +157,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.Scaling, ScalingMode.Off); SetDefault(OsuSetting.SafeAreaConsiderations, true); + SetDefault(OsuSetting.ScalingMenuBackgroundDim, 0.9f, 0.5f, 1f); SetDefault(OsuSetting.ScalingSizeX, 0.8f, 0.2f, 1f); SetDefault(OsuSetting.ScalingSizeY, 0.8f, 0.2f, 1f); @@ -364,6 +365,7 @@ namespace osu.Game.Configuration ScalingPositionY, ScalingSizeX, ScalingSizeY, + ScalingMenuBackgroundDim, UIScale, IntroSequence, NotifyOnUsernameMentioned, diff --git a/osu.Game/Graphics/Containers/ScalingContainer.cs b/osu.Game/Graphics/Containers/ScalingContainer.cs index fb5c3e3b60..9c6830ce05 100644 --- a/osu.Game/Graphics/Containers/ScalingContainer.cs +++ b/osu.Game/Graphics/Containers/ScalingContainer.cs @@ -46,6 +46,8 @@ namespace osu.Game.Graphics.Containers private BackgroundScreenStack backgroundStack; + private Bindable scalingMenuBackgroundDim; + private RectangleF? customRect; private bool customRectIsRelativePosition; @@ -138,6 +140,9 @@ namespace osu.Game.Graphics.Containers safeAreaPadding = safeArea.SafeAreaPadding.GetBoundCopy(); safeAreaPadding.BindValueChanged(_ => Scheduler.AddOnce(updateSize)); + + scalingMenuBackgroundDim = config.GetBindable(OsuSetting.ScalingMenuBackgroundDim); + scalingMenuBackgroundDim.ValueChanged += _ => Scheduler.AddOnce(updateSize); } protected override void LoadComplete() @@ -148,7 +153,9 @@ namespace osu.Game.Graphics.Containers sizableContainer.FinishTransforms(); } - private bool requiresBackgroundVisible => (scalingMode.Value == ScalingMode.Everything || scalingMode.Value == ScalingMode.ExcludeOverlays) && (sizeX.Value != 1 || sizeY.Value != 1); + private bool requiresBackgroundVisible => (scalingMode.Value == ScalingMode.Everything || scalingMode.Value == ScalingMode.ExcludeOverlays) + && (sizeX.Value != 1 || sizeY.Value != 1) + && scalingMenuBackgroundDim.Value != 1f; private void updateSize() { @@ -161,7 +168,6 @@ namespace osu.Game.Graphics.Containers { AddInternal(backgroundStack = new BackgroundScreenStack { - Colour = OsuColour.Gray(0.1f), Alpha = 0, Depth = float.MaxValue }); @@ -170,6 +176,7 @@ namespace osu.Game.Graphics.Containers } backgroundStack.FadeIn(TRANSITION_DURATION); + backgroundStack.FadeColour(OsuColour.Gray(1.0f - scalingMenuBackgroundDim.Value), 800, Easing.OutQuint); } else backgroundStack?.FadeOut(TRANSITION_DURATION); diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 6465d62ef0..6dbaf27afc 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -30,6 +30,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics protected override LocalisableString Header => GraphicsSettingsStrings.LayoutHeader; private FillFlowContainer> scalingSettings = null!; + private SettingsSlider dimSlider = null!; private readonly Bindable currentDisplay = new Bindable(); private readonly IBindableList windowModes = new BindableList(); @@ -58,6 +59,8 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics private Bindable scalingSizeX = null!; private Bindable scalingSizeY = null!; + private Bindable scalingBackgroundDim = null!; + private const int transition_duration = 400; [BackgroundDependencyLoader] @@ -71,6 +74,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics scalingSizeY = osuConfig.GetBindable(OsuSetting.ScalingSizeY); scalingPositionX = osuConfig.GetBindable(OsuSetting.ScalingPositionX); scalingPositionY = osuConfig.GetBindable(OsuSetting.ScalingPositionY); + scalingBackgroundDim = osuConfig.GetBindable(OsuSetting.ScalingMenuBackgroundDim); if (window != null) { @@ -162,6 +166,13 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics KeyboardStep = 0.01f, DisplayAsPercentage = true }, + dimSlider = new SettingsSlider + { + LabelText = GameplaySettingsStrings.BackgroundDim, + Current = scalingBackgroundDim, + KeyboardStep = 0.01f, + DisplayAsPercentage = true + }, } }, }; @@ -219,6 +230,13 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics scalingSettings.AutoSizeAxes = scalingMode.Value != ScalingMode.Off ? Axes.Y : Axes.None; scalingSettings.ForEach(s => { + if (s == dimSlider) + { + s.TransferValueOnCommit = false; + s.CanBeShown.Value = scalingMode.Value == ScalingMode.Everything || scalingMode.Value == ScalingMode.ExcludeOverlays; + return; + } + s.TransferValueOnCommit = scalingMode.Value == ScalingMode.Everything; s.CanBeShown.Value = scalingMode.Value != ScalingMode.Off; }); From aad540629f4818f10310b56d5878c828196e7a80 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 29 Mar 2023 12:36:56 +0900 Subject: [PATCH 2555/2991] Remove duplicate load rule from `ShaderPrecompiler` --- osu.Game/Screens/Loader.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index bee6207a35..372cfe748e 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -133,8 +133,6 @@ namespace osu.Game.Screens loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, "TriangleBorder")); loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE)); - - loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE)); } protected virtual bool AllLoaded => loadTargets.All(s => s.IsLoaded); From 9b45591c2f92ae4a2cd45329557187b043751b1b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 29 Mar 2023 14:00:07 +0900 Subject: [PATCH 2556/2991] Add failing test coverage of saving failed replay causing progression to results --- .../Gameplay/TestSceneStoryboardWithOutro.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs index 0d88fb01a8..283866bef2 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboardWithOutro.cs @@ -13,6 +13,7 @@ using osu.Framework.Screens; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Configuration; +using osu.Game.Graphics.Containers; using osu.Game.Rulesets; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu; @@ -106,6 +107,26 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for fail overlay", () => Player.FailOverlay.State.Value == Visibility.Visible); } + [Test] + public void TestSaveFailedReplayWithStoryboardEndedDoesNotProgress() + { + CreateTest(() => + { + AddStep("fail on first judgement", () => currentFailConditions = (_, _) => true); + AddStep("set storyboard duration to 0s", () => currentStoryboardDuration = 0); + }); + AddUntilStep("storyboard ends", () => Player.GameplayClockContainer.CurrentTime >= currentStoryboardDuration); + AddUntilStep("wait for fail", () => Player.GameplayState.HasFailed); + + AddUntilStep("wait for fail overlay", () => Player.FailOverlay.State.Value == Visibility.Visible); + AddUntilStep("wait for button clickable", () => Player.ChildrenOfType().First().ChildrenOfType().First().Enabled.Value); + AddStep("click save button", () => Player.ChildrenOfType().First().ChildrenOfType().First().TriggerClick()); + + // Test a regression where importing the fail replay would cause progression to results screen in a failed state. + AddWaitStep("wait some", 10); + AddAssert("player is still current screen", () => Player.IsCurrentScreen()); + } + [Test] public void TestShowResultsFalse() { From a8bb2e33ac669b4c47b1c5b1e6b42c94f3a7bc32 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 29 Mar 2023 13:30:13 +0900 Subject: [PATCH 2557/2991] Ensure all preconditions are checked before progressing to results screen after storyboard ends --- osu.Game/Screens/Play/Player.cs | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 45a671fb89..3976e5059b 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -358,14 +358,10 @@ namespace osu.Game.Screens.Play ScoreProcessor.RevertResult(r); }; - DimmableStoryboard.HasStoryboardEnded.ValueChanged += storyboardEnded => - { - if (storyboardEnded.NewValue) - progressToResults(true); - }; + DimmableStoryboard.HasStoryboardEnded.ValueChanged += _ => scoreCompleted(); // Bind the judgement processors to ourselves - ScoreProcessor.HasCompleted.BindValueChanged(scoreCompletionChanged); + ScoreProcessor.HasCompleted.BindValueChanged(_ => scoreCompleted()); HealthProcessor.Failed += onFail; // Provide judgement processors to mods after they're loaded so that they're on the gameplay clock, @@ -706,8 +702,7 @@ namespace osu.Game.Screens.Play /// /// Handles changes in player state which may progress the completion of gameplay / this screen's lifetime. /// - /// Thrown if this method is called more than once without changing state. - private void scoreCompletionChanged(ValueChangedEvent completed) + private void scoreCompleted() { // If this player instance is in the middle of an exit, don't attempt any kind of state update. if (!this.IsCurrentScreen()) @@ -718,7 +713,7 @@ namespace osu.Game.Screens.Play // Currently, even if this scenario is hit, prepareScoreForDisplay has already been queued (and potentially run). // In scenarios where rewinding is possible (replay, spectating) this is a non-issue as no submission/import work is done, // but it still doesn't feel right that this exists here. - if (!completed.NewValue) + if (!ScoreProcessor.HasCompleted.Value) { resultsDisplayDelegate?.Cancel(); resultsDisplayDelegate = null; @@ -742,12 +737,12 @@ namespace osu.Game.Screens.Play if (!Configuration.ShowResults) return; - bool storyboardHasOutro = DimmableStoryboard.ContentDisplayed && !DimmableStoryboard.HasStoryboardEnded.Value; + bool storyboardStillRunning = DimmableStoryboard.ContentDisplayed && !DimmableStoryboard.HasStoryboardEnded.Value; - if (storyboardHasOutro) + // If the current beatmap has a storyboard, this method will be called again on storyboard completion. + // Alternatively, the user may press the outro skip button, forcing immediate display of the results screen. + if (storyboardStillRunning) { - // if the current beatmap has a storyboard, the progression to results will be handled by the storyboard ending - // or the user pressing the skip outro button. skipOutroOverlay.Show(); return; } From 4dd0c2c7a5eb3b0d57fbed9bdf4acf1bacb439e1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 29 Mar 2023 14:11:56 +0900 Subject: [PATCH 2558/2991] Add assert ensuring we don't ever get to the results screen with an F rank Intentionally an assertion as I want tests to fail, but I don't want this to cause crashes for an end user if it does happen to occur. --- osu.Game/Screens/Play/Player.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 3976e5059b..b8b3a8b5c0 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -788,6 +788,8 @@ namespace osu.Game.Screens.Play // This player instance may already be in the process of exiting. return; + Debug.Assert(ScoreProcessor.Rank.Value != ScoreRank.F); + this.Push(CreateResults(prepareScoreForDisplayTask.GetResultSafely())); }, Time.Current + delay, 50); From c7003434b2f1640e88443a536fac5b716f04bcbf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 29 Mar 2023 14:33:10 +0900 Subject: [PATCH 2559/2991] Fix localisation for audio device error containing incorrect newline escaping --- osu.Game/Localisation/NotificationsStrings.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/osu.Game/Localisation/NotificationsStrings.cs b/osu.Game/Localisation/NotificationsStrings.cs index 6a9793b20c..5e2600bc50 100644 --- a/osu.Game/Localisation/NotificationsStrings.cs +++ b/osu.Game/Localisation/NotificationsStrings.cs @@ -50,16 +50,18 @@ namespace osu.Game.Localisation public static LocalisableString NoAutoplayMod => new TranslatableString(getKey(@"no_autoplay_mod"), @"The current ruleset doesn't have an autoplay mod available!"); /// - /// "osu! doesn't seem to be able to play audio correctly.\n\nPlease try changing your audio device to a working setting." + /// "osu! doesn't seem to be able to play audio correctly. + /// + /// Please try changing your audio device to a working setting." /// - public static LocalisableString AudioPlaybackIssue => new TranslatableString(getKey(@"audio_playback_issue"), - @"osu! doesn't seem to be able to play audio correctly.\n\nPlease try changing your audio device to a working setting."); + public static LocalisableString AudioPlaybackIssue => new TranslatableString(getKey(@"audio_playback_issue"), @"osu! doesn't seem to be able to play audio correctly. + +Please try changing your audio device to a working setting."); /// /// "The score overlay is currently disabled. You can toggle this by pressing {0}." /// - public static LocalisableString ScoreOverlayDisabled(LocalisableString arg0) => new TranslatableString(getKey(@"score_overlay_disabled"), - @"The score overlay is currently disabled. You can toggle this by pressing {0}.", arg0); + public static LocalisableString ScoreOverlayDisabled(LocalisableString arg0) => new TranslatableString(getKey(@"score_overlay_disabled"), @"The score overlay is currently disabled. You can toggle this by pressing {0}.", arg0); private static string getKey(string key) => $@"{prefix}:{key}"; } From 72c5c9848f8761c719ca1fa22ecc6f784019d0ff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 29 Mar 2023 14:44:42 +0900 Subject: [PATCH 2560/2991] Always use `LocalisableString` fallbacks when deploying debug and viewing english This allows changes to `xxxStrings.cs` files to immediately reflect in the UI, which is (at least for me) an expectation. --- osu.Game/Localisation/ResourceManagerLocalisationStore.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Localisation/ResourceManagerLocalisationStore.cs b/osu.Game/Localisation/ResourceManagerLocalisationStore.cs index d2ff783413..50a450c101 100644 --- a/osu.Game/Localisation/ResourceManagerLocalisationStore.cs +++ b/osu.Game/Localisation/ResourceManagerLocalisationStore.cs @@ -11,6 +11,7 @@ using System.Linq; using System.Resources; using System.Threading; using System.Threading.Tasks; +using osu.Framework.Development; using osu.Framework.Localisation; namespace osu.Game.Localisation @@ -65,6 +66,11 @@ namespace osu.Game.Localisation if (manager == null) return null; + // When running a debug build and in viewing english culture, use the fallbacks rather than osu-resources baked strings. + // This is what a developer expects to see when making changes to `xxxStrings.cs` files. + if (DebugUtils.IsDebugBuild && EffectiveCulture.Name == @"en") + return null; + try { return manager.GetString(key, EffectiveCulture); From 836c884aaed7c97925a7c4f8279192a053ebb8fa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 29 Mar 2023 18:03:21 +0900 Subject: [PATCH 2561/2991] Fix circle-size based scale being applied twice to caught fruit Closes #22968. --- osu.Game.Rulesets.Catch/UI/Catcher.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 1c52c092ec..ab754e51f7 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -136,6 +136,7 @@ namespace osu.Game.Rulesets.Catch.UI Origin = Anchor.TopCentre; Size = new Vector2(BASE_SIZE); + if (difficulty != null) Scale = calculateScale(difficulty); @@ -333,8 +334,11 @@ namespace osu.Game.Rulesets.Catch.UI base.Update(); var scaleFromDirection = new Vector2((int)VisualDirection, 1); + body.Scale = scaleFromDirection; - caughtObjectContainer.Scale = hitExplosionContainer.Scale = flipCatcherPlate ? scaleFromDirection : Vector2.One; + // Inverse of catcher scale is applied here, as catcher gets scaled by circle size and so do the incoming fruit. + caughtObjectContainer.Scale = (1 / Scale.X) * (flipCatcherPlate ? scaleFromDirection : Vector2.One); + hitExplosionContainer.Scale = flipCatcherPlate ? scaleFromDirection : Vector2.One; // Correct overshooting. if ((hyperDashDirection > 0 && hyperDashTargetPosition < X) || From e85c28031e2348f0f4e71eafe3d1fe13ba4305fc Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 29 Mar 2023 22:55:25 +0900 Subject: [PATCH 2562/2991] change weird name --- osu.Game/Configuration/OsuConfigManager.cs | 4 ++-- osu.Game/Graphics/Containers/ScalingContainer.cs | 2 +- .../Overlays/Settings/Sections/Graphics/LayoutSettings.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index a06bfcc5f0..1e7d3cf84f 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -157,7 +157,7 @@ namespace osu.Game.Configuration SetDefault(OsuSetting.Scaling, ScalingMode.Off); SetDefault(OsuSetting.SafeAreaConsiderations, true); - SetDefault(OsuSetting.ScalingMenuBackgroundDim, 0.9f, 0.5f, 1f); + SetDefault(OsuSetting.ScalingBackgroundDim, 0.9f, 0.5f, 1f); SetDefault(OsuSetting.ScalingSizeX, 0.8f, 0.2f, 1f); SetDefault(OsuSetting.ScalingSizeY, 0.8f, 0.2f, 1f); @@ -365,7 +365,7 @@ namespace osu.Game.Configuration ScalingPositionY, ScalingSizeX, ScalingSizeY, - ScalingMenuBackgroundDim, + ScalingBackgroundDim, UIScale, IntroSequence, NotifyOnUsernameMentioned, diff --git a/osu.Game/Graphics/Containers/ScalingContainer.cs b/osu.Game/Graphics/Containers/ScalingContainer.cs index 9c6830ce05..8b0450b71c 100644 --- a/osu.Game/Graphics/Containers/ScalingContainer.cs +++ b/osu.Game/Graphics/Containers/ScalingContainer.cs @@ -141,7 +141,7 @@ namespace osu.Game.Graphics.Containers safeAreaPadding = safeArea.SafeAreaPadding.GetBoundCopy(); safeAreaPadding.BindValueChanged(_ => Scheduler.AddOnce(updateSize)); - scalingMenuBackgroundDim = config.GetBindable(OsuSetting.ScalingMenuBackgroundDim); + scalingMenuBackgroundDim = config.GetBindable(OsuSetting.ScalingBackgroundDim); scalingMenuBackgroundDim.ValueChanged += _ => Scheduler.AddOnce(updateSize); } diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 6dbaf27afc..895ae1ed89 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -74,7 +74,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics scalingSizeY = osuConfig.GetBindable(OsuSetting.ScalingSizeY); scalingPositionX = osuConfig.GetBindable(OsuSetting.ScalingPositionX); scalingPositionY = osuConfig.GetBindable(OsuSetting.ScalingPositionY); - scalingBackgroundDim = osuConfig.GetBindable(OsuSetting.ScalingMenuBackgroundDim); + scalingBackgroundDim = osuConfig.GetBindable(OsuSetting.ScalingBackgroundDim); if (window != null) { From 19b7036b95eeac979f75850feb19b2a5a1a97ce2 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 29 Mar 2023 22:56:35 +0900 Subject: [PATCH 2563/2991] use same same duration negligence in migrating code --- osu.Game/Graphics/Containers/ScalingContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/ScalingContainer.cs b/osu.Game/Graphics/Containers/ScalingContainer.cs index 8b0450b71c..bd52c8bb32 100644 --- a/osu.Game/Graphics/Containers/ScalingContainer.cs +++ b/osu.Game/Graphics/Containers/ScalingContainer.cs @@ -176,7 +176,7 @@ namespace osu.Game.Graphics.Containers } backgroundStack.FadeIn(TRANSITION_DURATION); - backgroundStack.FadeColour(OsuColour.Gray(1.0f - scalingMenuBackgroundDim.Value), 800, Easing.OutQuint); + backgroundStack.FadeColour(OsuColour.Gray(1.0f - scalingMenuBackgroundDim.Value), TRANSITION_DURATION, Easing.OutQuint); } else backgroundStack?.FadeOut(TRANSITION_DURATION); From 5d395e6d37f6247430e57c3ede359cad4c729b64 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 29 Mar 2023 22:59:54 +0900 Subject: [PATCH 2564/2991] move to ctor --- .../Overlays/Settings/Sections/Graphics/LayoutSettings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 895ae1ed89..523b1237fa 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -171,7 +171,8 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics LabelText = GameplaySettingsStrings.BackgroundDim, Current = scalingBackgroundDim, KeyboardStep = 0.01f, - DisplayAsPercentage = true + DisplayAsPercentage = true, + TransferValueOnCommit = false }, } }, @@ -232,7 +233,6 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics { if (s == dimSlider) { - s.TransferValueOnCommit = false; s.CanBeShown.Value = scalingMode.Value == ScalingMode.Everything || scalingMode.Value == ScalingMode.ExcludeOverlays; return; } From b25a59fd14ddac89f688e2bed48b6aef944b416d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 31 Mar 2023 02:30:04 +0900 Subject: [PATCH 2565/2991] Rename `scoreCompleted` -> `checkScoreCompleted` to reflect the fact it doesn't always succeed --- osu.Game/Screens/Play/Player.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index b8b3a8b5c0..c4b52136b9 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -358,10 +358,10 @@ namespace osu.Game.Screens.Play ScoreProcessor.RevertResult(r); }; - DimmableStoryboard.HasStoryboardEnded.ValueChanged += _ => scoreCompleted(); + DimmableStoryboard.HasStoryboardEnded.ValueChanged += _ => checkScoreCompleted(); // Bind the judgement processors to ourselves - ScoreProcessor.HasCompleted.BindValueChanged(_ => scoreCompleted()); + ScoreProcessor.HasCompleted.BindValueChanged(_ => checkScoreCompleted()); HealthProcessor.Failed += onFail; // Provide judgement processors to mods after they're loaded so that they're on the gameplay clock, @@ -702,7 +702,7 @@ namespace osu.Game.Screens.Play /// /// Handles changes in player state which may progress the completion of gameplay / this screen's lifetime. /// - private void scoreCompleted() + private void checkScoreCompleted() { // If this player instance is in the middle of an exit, don't attempt any kind of state update. if (!this.IsCurrentScreen()) From 796cd9c916d8c9643b569986e106afa554584a6a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 31 Mar 2023 02:36:17 +0900 Subject: [PATCH 2566/2991] Rewrite comment explaining early return on `checkScoreCompleted` given new usages --- osu.Game/Screens/Play/Player.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index c4b52136b9..eb33bf43d6 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -708,11 +708,13 @@ namespace osu.Game.Screens.Play if (!this.IsCurrentScreen()) return; - // Special case to handle rewinding post-completion. This is the only way already queued forward progress can be cancelled. - // TODO: Investigate whether this can be moved to a RewindablePlayer subclass or similar. - // Currently, even if this scenario is hit, prepareScoreForDisplay has already been queued (and potentially run). - // In scenarios where rewinding is possible (replay, spectating) this is a non-issue as no submission/import work is done, - // but it still doesn't feel right that this exists here. + // Handle cases of arriving at this method when not in a completed state. + // - When a storyboard completion triggered this call earlier than gameplay finishes. + // - When a replay has been rewound before a queued resultsDisplayDelegate has run. + // + // Currently, even if this scenario is hit, prepareAndImportScoreAsync has already been queued (and potentially run). + // In the scenarios above, this is a non-issue, but it still feels a bit convoluted to have to cancel in this method. + // Maybe this can be improved with further refactoring. if (!ScoreProcessor.HasCompleted.Value) { resultsDisplayDelegate?.Cancel(); From db71db84915aa219e96aa50f67fcae9599a132b4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 31 Mar 2023 13:07:14 +0900 Subject: [PATCH 2567/2991] Update README bounty/compensation section in line with changes applied to osu-web --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f3f025fa10..eb2fe6d0eb 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ When it comes to contributing to the project, the two main things you can do to If you wish to help with localisation efforts, head over to [crowdin](https://crowdin.com/project/osu-web). -For those interested, we love to reward quality contributions via [bounties](https://docs.google.com/spreadsheets/d/1jNXfj_S3Pb5PErA-czDdC9DUu4IgUbe1Lt8E7CYUJuE/view?&rm=minimal#gid=523803337), paid out via PayPal or osu!supporter tags. Don't hesitate to [request a bounty](https://docs.google.com/forms/d/e/1FAIpQLSet_8iFAgPMG526pBZ2Kic6HSh7XPM3fE8xPcnWNkMzINDdYg/viewform) for your work on this project. +We love to reward quality contributions. If you have made a large contribution, or are a regular contributor, you are welcome to [submit an expense via opencollective](https://opencollective.com/ppy/expenses/new). If you have any questions, feel free to [reach out to peppy](mailto:pe@ppy.sh) before doing so. ## Licence From d5b8a45541703f3a469cf866f92c75755334183b Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 31 Mar 2023 16:20:16 +0900 Subject: [PATCH 2568/2991] Always use fallback strings for English MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Localisation/ResourceManagerLocalisationStore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Localisation/ResourceManagerLocalisationStore.cs b/osu.Game/Localisation/ResourceManagerLocalisationStore.cs index 50a450c101..1a05bec41a 100644 --- a/osu.Game/Localisation/ResourceManagerLocalisationStore.cs +++ b/osu.Game/Localisation/ResourceManagerLocalisationStore.cs @@ -68,7 +68,7 @@ namespace osu.Game.Localisation // When running a debug build and in viewing english culture, use the fallbacks rather than osu-resources baked strings. // This is what a developer expects to see when making changes to `xxxStrings.cs` files. - if (DebugUtils.IsDebugBuild && EffectiveCulture.Name == @"en") + if (EffectiveCulture.Name == @"en") return null; try From 28f31ef37968134a61a59255f7ea2037ae413644 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 31 Mar 2023 16:23:37 +0900 Subject: [PATCH 2569/2991] Adjust comment slightly --- osu.Game/Localisation/ResourceManagerLocalisationStore.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Localisation/ResourceManagerLocalisationStore.cs b/osu.Game/Localisation/ResourceManagerLocalisationStore.cs index 1a05bec41a..8551a140bd 100644 --- a/osu.Game/Localisation/ResourceManagerLocalisationStore.cs +++ b/osu.Game/Localisation/ResourceManagerLocalisationStore.cs @@ -66,8 +66,8 @@ namespace osu.Game.Localisation if (manager == null) return null; - // When running a debug build and in viewing english culture, use the fallbacks rather than osu-resources baked strings. - // This is what a developer expects to see when making changes to `xxxStrings.cs` files. + // When using the English culture, prefer the fallbacks rather than osu-resources baked strings. + // They are guaranteed to be up-to-date, and is also what a developer expects to see when making changes to `xxxStrings.cs` files. if (EffectiveCulture.Name == @"en") return null; From 4b7d44c329dd12fd97651492edf0b1b0d58d0fcf Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 31 Mar 2023 16:23:56 +0900 Subject: [PATCH 2570/2991] Remove unused using --- osu.Game/Localisation/ResourceManagerLocalisationStore.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Localisation/ResourceManagerLocalisationStore.cs b/osu.Game/Localisation/ResourceManagerLocalisationStore.cs index 8551a140bd..3fa86c188c 100644 --- a/osu.Game/Localisation/ResourceManagerLocalisationStore.cs +++ b/osu.Game/Localisation/ResourceManagerLocalisationStore.cs @@ -11,7 +11,6 @@ using System.Linq; using System.Resources; using System.Threading; using System.Threading.Tasks; -using osu.Framework.Development; using osu.Framework.Localisation; namespace osu.Game.Localisation From 7f9bf09e0396f7b76f78b55ebaaf995c21d245c4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 2 Apr 2023 20:07:31 +0900 Subject: [PATCH 2571/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 927d66d93f..9b26526b9a 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -11,7 +11,7 @@ manifestmerger.jar - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 3de022e88d..6c10137a92 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index eb7ba24336..25fad5eaa3 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -16,6 +16,6 @@ iossimulator-x64 - + From 0f0dd9f2dcdb731ac3e33d4c9a416ce3a3952a95 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 2 Apr 2023 20:07:33 +0900 Subject: [PATCH 2572/2991] Update resources --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 6c10137a92..640f72c7da 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -37,7 +37,7 @@ - + From cf5acbf66eb5b0ff872eef50ff78f5409d4111a8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 2 Apr 2023 20:16:14 +0900 Subject: [PATCH 2573/2991] Update usage of `SupportedWindowModes` --- osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 6465d62ef0..a40156cf6d 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -75,7 +75,6 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics if (window != null) { currentDisplay.BindTo(window.CurrentDisplayBindable); - windowModes.BindTo(window.SupportedWindowModes); window.DisplaysChanged += onDisplaysChanged; } @@ -87,7 +86,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics windowModeDropdown = new SettingsDropdown { LabelText = GraphicsSettingsStrings.ScreenMode, - ItemSource = windowModes, + Items = window?.SupportedWindowModes, Current = config.GetBindable(FrameworkSetting.WindowMode), }, displayDropdown = new DisplaySettingsDropdown From e66569b394848348d62dd654af716afd69eae1b9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 2 Apr 2023 21:04:44 +0900 Subject: [PATCH 2574/2991] Update ruleset dependency tests in line with nullable changes --- .../Testing/TestSceneRulesetDependencies.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs b/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs index f1533a32b9..a5a83d7231 100644 --- a/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs +++ b/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using NUnit.Framework; @@ -51,9 +49,11 @@ namespace osu.Game.Tests.Testing [Test] public void TestRetrieveShader() { - AddAssert("ruleset shaders retrieved", () => - Dependencies.Get().LoadRaw(@"sh_TestVertex.vs") != null && - Dependencies.Get().LoadRaw(@"sh_TestFragment.fs") != null); + AddStep("ruleset shaders retrieved without error", () => + { + Dependencies.Get().LoadRaw(@"sh_TestVertex.vs"); + Dependencies.Get().LoadRaw(@"sh_TestFragment.fs"); + }); } [Test] @@ -76,12 +76,12 @@ namespace osu.Game.Tests.Testing } public override IResourceStore CreateResourceStore() => new NamespacedResourceStore(TestResources.GetStore(), @"Resources"); - public override IRulesetConfigManager CreateConfig(SettingsStore settings) => new TestRulesetConfigManager(); + public override IRulesetConfigManager CreateConfig(SettingsStore? settings) => new TestRulesetConfigManager(); public override IEnumerable GetModsFor(ModType type) => Array.Empty(); - public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList mods = null) => null; - public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => null; - public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => null; + public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList? mods = null) => null!; + public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => null!; + public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => null!; } private class TestRulesetConfigManager : IRulesetConfigManager From 4c2b7e7788823978d8f82f9f006395ce3d06892c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 2 Apr 2023 21:05:20 +0900 Subject: [PATCH 2575/2991] Fix random inspection showing up only in CI --- osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs index 7b26640e50..1a44262ef8 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs @@ -55,7 +55,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu set => valueText.Text = value.ToLocalisableString("N0"); } - public CountSection(LocalisableString header) + protected CountSection(LocalisableString header) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; From 2cf863636632887cc7c6029b81dd45b3cad6b10a Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 2 Apr 2023 22:25:58 +0900 Subject: [PATCH 2576/2991] show guest diff author in `BeatmapPicker` --- .../Online/TestSceneBeatmapSetOverlay.cs | 73 ++++++++++++++++++- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 30 +++++++- 2 files changed, 101 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 5d13421195..3090ff6c49 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -14,6 +14,7 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Testing; using osu.Game.Beatmaps.Drawables; +using osu.Game.Graphics.Containers; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; @@ -26,7 +27,7 @@ using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Tests.Visual.Online { - public partial class TestSceneBeatmapSetOverlay : OsuTestScene + public partial class TestSceneBeatmapSetOverlay : OsuManualInputManagerTestScene { private readonly TestBeatmapSetOverlay overlay; @@ -281,6 +282,22 @@ namespace osu.Game.Tests.Visual.Online AddAssert(@"type is correct", () => type == lookupType.ToString()); } + [Test] + public void TestBeatmapSetWithGuestDIff() + { + AddStep("show map", () => overlay.ShowBeatmapSet(createBeatmapSetWithGuestDiff())); + AddStep("Move mouse to host diff", () => + { + InputManager.MoveMouseTo(overlay.ChildrenOfType().ElementAt(0)); + }); + AddAssert("Guset mapper information not show", () => !overlay.ChildrenOfType().Single().ChildrenOfType().Any()); + AddStep("move mouse to guest diff", () => + { + InputManager.MoveMouseTo(overlay.ChildrenOfType().ElementAt(1)); + }); + AddAssert("Guset mapper information show", () => overlay.ChildrenOfType().Single().ChildrenOfType().Any()); + } + private APIBeatmapSet createManyDifficultiesBeatmapSet() { var set = getBeatmapSet(); @@ -320,6 +337,60 @@ namespace osu.Game.Tests.Visual.Online return beatmapSet; } + private APIBeatmapSet createBeatmapSetWithGuestDiff() + { + var set = getBeatmapSet(); + + var beatmaps = new List(); + + var guestUser = new APIUser + { + Username = @"BanchoBot", + Id = 3, + }; + + set.RelatedUsers = new[] + { + set.Author, guestUser + }; + + beatmaps.Add(new APIBeatmap + { + OnlineID = 1145, + DifficultyName = "Host Diff", + RulesetID = Ruleset.Value.OnlineID, + StarRating = 1.4, + OverallDifficulty = 3.5f, + AuthorID = set.AuthorID, + FailTimes = new APIFailTimes + { + Fails = Enumerable.Range(1, 100).Select(j => j % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(j => j % 12 - 6).ToArray(), + }, + Status = BeatmapOnlineStatus.Graveyard + }); + + beatmaps.Add(new APIBeatmap + { + OnlineID = 1919, + DifficultyName = "Guest Diff", + RulesetID = Ruleset.Value.OnlineID, + StarRating = 8.1, + OverallDifficulty = 3.5f, + AuthorID = 3, + FailTimes = new APIFailTimes + { + Fails = Enumerable.Range(1, 100).Select(j => j % 12 - 6).ToArray(), + Retries = Enumerable.Range(-2, 100).Select(j => j % 12 - 6).ToArray(), + }, + Status = BeatmapOnlineStatus.Graveyard + }); + + set.Beatmaps = beatmaps.ToArray(); + + return set; + } + private void downloadAssert(bool shown) { AddAssert($"is download button {(shown ? "shown" : "hidden")}", () => overlay.Header.HeaderContent.DownloadButtonsVisible == shown); diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 585e0dd1a2..7dc3fc665f 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -31,6 +31,7 @@ namespace osu.Game.Overlays.BeatmapSet private const float tile_spacing = 2; private readonly OsuSpriteText version, starRating, starRatingText; + public readonly FillFlowContainer GuestMapperContainer; private readonly FillFlowContainer starRatingContainer; private readonly Statistic plays, favourites; @@ -88,6 +89,12 @@ namespace osu.Game.Overlays.BeatmapSet Origin = Anchor.BottomLeft, Font = OsuFont.GetFont(size: 17, weight: FontWeight.Bold) }, + GuestMapperContainer = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + }, starRatingContainer = new FillFlowContainer { Anchor = Anchor.BottomLeft, @@ -198,11 +205,32 @@ namespace osu.Game.Overlays.BeatmapSet updateDifficultyButtons(); } - private void showBeatmap(IBeatmapInfo? beatmapInfo) + private void showBeatmap(APIBeatmap? beatmapInfo) { + GuestMapperContainer.Clear(); + + if (beatmapInfo != null && beatmapSet?.Author.OnlineID != beatmapInfo.AuthorID) + { + if (BeatmapSet?.RelatedUsers?.Single(u => u.OnlineID == beatmapInfo.AuthorID) is APIUser user) + GuestMapperContainer.Child = getGueatMapper(user); + } + version.Text = beatmapInfo?.DifficultyName ?? string.Empty; } + private Drawable getGueatMapper(APIUser user) + { + return new LinkFlowContainer(s => + { + s.Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 15); + }).With(d => + { + d.AutoSizeAxes = Axes.Both; + d.AddText("mapped by "); + d.AddUserLink(user); + }); + } + private void updateDifficultyButtons() { Difficulties.Children.ToList().ForEach(diff => diff.State = diff.Beatmap == Beatmap.Value ? DifficultySelectorState.Selected : DifficultySelectorState.NotSelected); From d949ef3ca4cf0891f6dff2bc02b9a38c9ee9687c Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 2 Apr 2023 22:53:15 +0900 Subject: [PATCH 2577/2991] make `guestMapperContainer` private tests don't use it --- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 7dc3fc665f..61bfd97f3c 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.BeatmapSet private const float tile_spacing = 2; private readonly OsuSpriteText version, starRating, starRatingText; - public readonly FillFlowContainer GuestMapperContainer; + private readonly FillFlowContainer guestMapperContainer; private readonly FillFlowContainer starRatingContainer; private readonly Statistic plays, favourites; @@ -89,7 +89,7 @@ namespace osu.Game.Overlays.BeatmapSet Origin = Anchor.BottomLeft, Font = OsuFont.GetFont(size: 17, weight: FontWeight.Bold) }, - GuestMapperContainer = new FillFlowContainer + guestMapperContainer = new FillFlowContainer { AutoSizeAxes = Axes.Both, Anchor = Anchor.BottomLeft, @@ -207,12 +207,12 @@ namespace osu.Game.Overlays.BeatmapSet private void showBeatmap(APIBeatmap? beatmapInfo) { - GuestMapperContainer.Clear(); + guestMapperContainer.Clear(); if (beatmapInfo != null && beatmapSet?.Author.OnlineID != beatmapInfo.AuthorID) { if (BeatmapSet?.RelatedUsers?.Single(u => u.OnlineID == beatmapInfo.AuthorID) is APIUser user) - GuestMapperContainer.Child = getGueatMapper(user); + guestMapperContainer.Child = getGueatMapper(user); } version.Text = beatmapInfo?.DifficultyName ?? string.Empty; From 1e0b64c9e8c408e27f039c47c67327d33a79bd38 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 2 Apr 2023 23:07:39 +0900 Subject: [PATCH 2578/2991] Update framework (again) --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 9b26526b9a..eb9a7e60df 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -11,7 +11,7 @@ manifestmerger.jar - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 640f72c7da..ec33eff5eb 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 25fad5eaa3..096c4d52ab 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -16,6 +16,6 @@ iossimulator-x64 - + From c3a6a581693efda04f913462f216960b19bedd5e Mon Sep 17 00:00:00 2001 From: Susko3 Date: Sun, 2 Apr 2023 19:23:18 +0200 Subject: [PATCH 2579/2991] Fix window mode dropdown not showing --- .../Overlays/Settings/Sections/Graphics/LayoutSettings.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index a40156cf6d..2765d2b437 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -32,7 +32,6 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics private FillFlowContainer> scalingSettings = null!; private readonly Bindable currentDisplay = new Bindable(); - private readonly IBindableList windowModes = new BindableList(); private Bindable scalingMode = null!; private Bindable sizeFullscreen = null!; @@ -87,6 +86,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics { LabelText = GraphicsSettingsStrings.ScreenMode, Items = window?.SupportedWindowModes, + CanBeShown = { Value = window?.SupportedWindowModes.Count() > 1 }, Current = config.GetBindable(FrameworkSetting.WindowMode), }, displayDropdown = new DisplaySettingsDropdown @@ -180,8 +180,6 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics updateScreenModeWarning(); }, true); - windowModes.BindCollectionChanged((_, _) => updateDisplaySettingsVisibility()); - currentDisplay.BindValueChanged(display => Schedule(() => { resolutions.RemoveRange(1, resolutions.Count - 1); @@ -235,7 +233,6 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics private void updateDisplaySettingsVisibility() { - windowModeDropdown.CanBeShown.Value = windowModes.Count > 1; resolutionDropdown.CanBeShown.Value = resolutions.Count > 1 && windowModeDropdown.Current.Value == WindowMode.Fullscreen; displayDropdown.CanBeShown.Value = displayDropdown.Items.Count() > 1; safeAreaConsiderationsCheckbox.CanBeShown.Value = host.Window?.SafeAreaPadding.Value.Total != Vector2.Zero; From 63ea17f10e7661bafe2c2c978ab20ac9fbd9e789 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 2 Apr 2023 18:15:00 -0700 Subject: [PATCH 2580/2991] Update comment vote pill in line with web --- osu.Game/Overlays/Comments/VotePill.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Comments/VotePill.cs b/osu.Game/Overlays/Comments/VotePill.cs index 6cfa5cb9e8..dd418a9e58 100644 --- a/osu.Game/Overlays/Comments/VotePill.cs +++ b/osu.Game/Overlays/Comments/VotePill.cs @@ -132,11 +132,10 @@ namespace osu.Game.Overlays.Comments }, sideNumber = new OsuSpriteText { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreRight, + Anchor = Anchor.TopCentre, + Origin = Anchor.BottomCentre, Text = "+1", Font = OsuFont.GetFont(size: 14), - Margin = new MarginPadding { Right = 3 }, Alpha = 0, }, votesCounter = new OsuSpriteText @@ -189,7 +188,7 @@ namespace osu.Game.Overlays.Comments else sideNumber.FadeTo(IsHovered ? 1 : 0); - borderContainer.BorderThickness = IsHovered ? 3 : 0; + borderContainer.BorderThickness = IsHovered ? 2 : 0; } private void onHoverAction() From 8932668f77c46d358da083a8f5d2dce2d9a9c3af Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Apr 2023 10:31:47 +0900 Subject: [PATCH 2581/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index eb9a7e60df..4b89e82729 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -11,7 +11,7 @@ manifestmerger.jar - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index ec33eff5eb..b9c6c1df9d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 096c4d52ab..083d8192ea 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -16,6 +16,6 @@ iossimulator-x64 - + From 7a0edabd5dc557680b06b5e51f4628da9c08879f Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 2 Apr 2023 17:11:19 -0700 Subject: [PATCH 2582/2991] Normalise overlay horizontal padding const --- osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs | 6 +++--- osu.Game/Overlays/BeatmapSet/Info.cs | 2 +- osu.Game/Overlays/BeatmapSetOverlay.cs | 1 - osu.Game/Overlays/Changelog/ChangelogBuild.cs | 4 +--- osu.Game/Overlays/Changelog/ChangelogListing.cs | 2 +- osu.Game/Overlays/Profile/Header/BadgeHeaderContainer.cs | 2 +- osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs | 2 +- osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs | 4 ++-- osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs | 2 +- osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs | 2 +- osu.Game/Overlays/Profile/ProfileHeader.cs | 2 +- osu.Game/Overlays/Profile/ProfileSection.cs | 4 ++-- osu.Game/Overlays/Rankings/CountryFilter.cs | 2 +- osu.Game/Overlays/Rankings/SpotlightSelector.cs | 2 +- osu.Game/Overlays/Rankings/Tables/RankingsTable.cs | 3 +-- osu.Game/Overlays/UserProfileOverlay.cs | 4 +--- osu.Game/Overlays/WaveOverlayContainer.cs | 2 ++ 17 files changed, 21 insertions(+), 25 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs index 26e6b1f158..7ff8352054 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs @@ -97,8 +97,8 @@ namespace osu.Game.Overlays.BeatmapSet Padding = new MarginPadding { Vertical = BeatmapSetOverlay.Y_PADDING, - Left = BeatmapSetOverlay.X_PADDING, - Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH, + Left = WaveOverlayContainer.HORIZONTAL_PADDING, + Right = WaveOverlayContainer.HORIZONTAL_PADDING + BeatmapSetOverlay.RIGHT_WIDTH, }, Children = new Drawable[] { @@ -170,7 +170,7 @@ namespace osu.Game.Overlays.BeatmapSet Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Top = BeatmapSetOverlay.Y_PADDING, Right = BeatmapSetOverlay.X_PADDING }, + Margin = new MarginPadding { Top = BeatmapSetOverlay.Y_PADDING, Right = WaveOverlayContainer.HORIZONTAL_PADDING }, Direction = FillDirection.Vertical, Spacing = new Vector2(10), Children = new Drawable[] diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 58739eb471..8758b9c5cf 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -55,7 +55,7 @@ namespace osu.Game.Overlays.BeatmapSet new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = 15, Horizontal = BeatmapSetOverlay.X_PADDING }, + Padding = new MarginPadding { Top = 15, Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING }, Children = new Drawable[] { new Container diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 237ce22767..873336bb6e 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -25,7 +25,6 @@ namespace osu.Game.Overlays { public partial class BeatmapSetOverlay : OnlineOverlay { - public const float X_PADDING = 40; public const float Y_PADDING = 25; public const float RIGHT_WIDTH = 275; diff --git a/osu.Game/Overlays/Changelog/ChangelogBuild.cs b/osu.Game/Overlays/Changelog/ChangelogBuild.cs index 96d5203d14..08978ac2ab 100644 --- a/osu.Game/Overlays/Changelog/ChangelogBuild.cs +++ b/osu.Game/Overlays/Changelog/ChangelogBuild.cs @@ -18,8 +18,6 @@ namespace osu.Game.Overlays.Changelog { public partial class ChangelogBuild : FillFlowContainer { - public const float HORIZONTAL_PADDING = 70; - public Action SelectBuild; protected readonly APIChangelogBuild Build; @@ -33,7 +31,7 @@ namespace osu.Game.Overlays.Changelog RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; Direction = FillDirection.Vertical; - Padding = new MarginPadding { Horizontal = HORIZONTAL_PADDING }; + Padding = new MarginPadding { Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING }; Children = new Drawable[] { diff --git a/osu.Game/Overlays/Changelog/ChangelogListing.cs b/osu.Game/Overlays/Changelog/ChangelogListing.cs index d7c9ff67fe..4b784c7a28 100644 --- a/osu.Game/Overlays/Changelog/ChangelogListing.cs +++ b/osu.Game/Overlays/Changelog/ChangelogListing.cs @@ -64,7 +64,7 @@ namespace osu.Game.Overlays.Changelog { RelativeSizeAxes = Axes.X, Height = 1, - Padding = new MarginPadding { Horizontal = ChangelogBuild.HORIZONTAL_PADDING }, + Padding = new MarginPadding { Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING }, Margin = new MarginPadding { Top = 30 }, Child = new Box { diff --git a/osu.Game/Overlays/Profile/Header/BadgeHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BadgeHeaderContainer.cs index 508041eb76..24be6ce2f5 100644 --- a/osu.Game/Overlays/Profile/Header/BadgeHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BadgeHeaderContainer.cs @@ -50,7 +50,7 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Spacing = new Vector2(10, 10), - Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Top = 10 }, + Padding = new MarginPadding { Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING, Top = 10 }, } }; } diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 1e80257a57..08a816930e 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -55,7 +55,7 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, - Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + Padding = new MarginPadding { Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING, Vertical = 10 }, Spacing = new Vector2(0, 10), Children = new Drawable[] { diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 0dab4d582d..cafee7ea85 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -39,7 +39,7 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.Y, Direction = FillDirection.Horizontal, Padding = new MarginPadding { Vertical = 10 }, - Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }, + Margin = new MarginPadding { Left = WaveOverlayContainer.HORIZONTAL_PADDING }, Spacing = new Vector2(10, 0), Children = new Drawable[] { @@ -62,7 +62,7 @@ namespace osu.Game.Overlays.Profile.Header Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Right = UserProfileOverlay.CONTENT_X_MARGIN }, + Margin = new MarginPadding { Right = WaveOverlayContainer.HORIZONTAL_PADDING }, Children = new Drawable[] { levelBadge = new LevelBadge diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 1cc3aae735..1f35f39b49 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -30,7 +30,7 @@ namespace osu.Game.Overlays.Profile.Header { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + Padding = new MarginPadding { Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING, Vertical = 10 }, Child = new GridContainer { RelativeSizeAxes = Axes.X, diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 2f4f49788f..d04329430b 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -83,7 +83,7 @@ namespace osu.Game.Overlays.Profile.Header Direction = FillDirection.Horizontal, Padding = new MarginPadding { - Left = UserProfileOverlay.CONTENT_X_MARGIN, + Left = WaveOverlayContainer.HORIZONTAL_PADDING, Vertical = vertical_padding }, Height = content_height + 2 * vertical_padding, diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 363eb5d58e..80d48ae09e 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Profile public ProfileHeader() { - ContentSidePadding = UserProfileOverlay.CONTENT_X_MARGIN; + ContentSidePadding = WaveOverlayContainer.HORIZONTAL_PADDING; TabControl.AddItem(LayoutStrings.HeaderUsersShow); diff --git a/osu.Game/Overlays/Profile/ProfileSection.cs b/osu.Game/Overlays/Profile/ProfileSection.cs index 4ac86924f8..a8a240ddde 100644 --- a/osu.Game/Overlays/Profile/ProfileSection.cs +++ b/osu.Game/Overlays/Profile/ProfileSection.cs @@ -67,7 +67,7 @@ namespace osu.Game.Overlays.Profile AutoSizeAxes = Axes.Both, Margin = new MarginPadding { - Horizontal = UserProfileOverlay.CONTENT_X_MARGIN - outer_gutter_width, + Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING - outer_gutter_width, Top = 20, Bottom = 20, }, @@ -97,7 +97,7 @@ namespace osu.Game.Overlays.Profile RelativeSizeAxes = Axes.X, Padding = new MarginPadding { - Horizontal = UserProfileOverlay.CONTENT_X_MARGIN - outer_gutter_width, + Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING - outer_gutter_width, Bottom = 20 } }, diff --git a/osu.Game/Overlays/Rankings/CountryFilter.cs b/osu.Game/Overlays/Rankings/CountryFilter.cs index e27fa7c7bd..525816f8fd 100644 --- a/osu.Game/Overlays/Rankings/CountryFilter.cs +++ b/osu.Game/Overlays/Rankings/CountryFilter.cs @@ -54,7 +54,7 @@ namespace osu.Game.Overlays.Rankings Origin = Anchor.CentreLeft, Direction = FillDirection.Horizontal, Spacing = new Vector2(10, 0), - Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }, + Margin = new MarginPadding { Left = WaveOverlayContainer.HORIZONTAL_PADDING }, Children = new Drawable[] { new OsuSpriteText diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index 31273e3b01..190da04a5d 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -63,7 +63,7 @@ namespace osu.Game.Overlays.Rankings { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN }, + Padding = new MarginPadding { Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING }, Child = new FillFlowContainer { RelativeSizeAxes = Axes.X, diff --git a/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs b/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs index affd9a2c44..27d894cdc2 100644 --- a/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs @@ -23,7 +23,6 @@ namespace osu.Game.Overlays.Rankings.Tables public abstract partial class RankingsTable : TableContainer { protected const int TEXT_SIZE = 12; - private const float horizontal_inset = 20; private const float row_height = 32; private const float row_spacing = 3; private const int items_per_page = 50; @@ -39,7 +38,7 @@ namespace osu.Game.Overlays.Rankings.Tables RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - Padding = new MarginPadding { Horizontal = horizontal_inset }; + Padding = new MarginPadding { Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING }; RowSize = new Dimension(GridSizeMode.Absolute, row_height + row_spacing); } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index c5f8a820ea..d1fe877e55 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -45,8 +45,6 @@ namespace osu.Game.Overlays [Resolved] private RulesetStore rulesets { get; set; } = null!; - public const float CONTENT_X_MARGIN = 50; - public UserProfileOverlay() : base(OverlayColourScheme.Pink) { @@ -184,7 +182,7 @@ namespace osu.Game.Overlays public ProfileSectionTabControl() { Height = 40; - Padding = new MarginPadding { Horizontal = CONTENT_X_MARGIN }; + Padding = new MarginPadding { Horizontal = HORIZONTAL_PADDING }; TabContainer.Spacing = new Vector2(20); } diff --git a/osu.Game/Overlays/WaveOverlayContainer.cs b/osu.Game/Overlays/WaveOverlayContainer.cs index d25f6a9ae5..00474cc0d8 100644 --- a/osu.Game/Overlays/WaveOverlayContainer.cs +++ b/osu.Game/Overlays/WaveOverlayContainer.cs @@ -22,6 +22,8 @@ namespace osu.Game.Overlays protected override string PopInSampleName => "UI/wave-pop-in"; + public const float HORIZONTAL_PADDING = 50; + protected WaveOverlayContainer() { AddInternal(Waves = new WaveContainer From af389b1107367207fd42cbef0b30d0f23175d541 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 2 Apr 2023 17:12:27 -0700 Subject: [PATCH 2583/2991] Replace all hardcoded 50 horizontal padding with const --- osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs | 2 +- osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs | 4 ++-- osu.Game/Overlays/Comments/CommentsContainer.cs | 4 ++-- osu.Game/Overlays/Comments/CommentsHeader.cs | 2 +- osu.Game/Overlays/Comments/TotalCommentsCounter.cs | 2 +- osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs | 2 +- osu.Game/Overlays/News/Displays/ArticleListing.cs | 2 +- osu.Game/Overlays/OverlayHeader.cs | 2 +- osu.Game/Overlays/OverlaySidebar.cs | 2 +- osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs | 2 +- osu.Game/Overlays/Wiki/WikiArticlePage.cs | 2 +- osu.Game/Overlays/WikiOverlay.cs | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 9eb04d9cc5..6d89313979 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -116,7 +116,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, - Padding = new MarginPadding { Horizontal = 50 }, + Padding = new MarginPadding { Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING }, Margin = new MarginPadding { Vertical = 20 }, Children = new Drawable[] { diff --git a/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs b/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs index 04526eb7ba..4aded1dd59 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Changelog Padding = new MarginPadding { Vertical = 20, - Horizontal = 50, + Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING, }; } @@ -79,7 +79,7 @@ namespace osu.Game.Overlays.Changelog Direction = FillDirection.Vertical, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Padding = new MarginPadding { Right = 50 + image_container_width }, + Padding = new MarginPadding { Right = WaveOverlayContainer.HORIZONTAL_PADDING + image_container_width }, Children = new Drawable[] { new OsuSpriteText diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index c4e4700674..2a873690a7 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -99,7 +99,7 @@ namespace osu.Game.Overlays.Comments { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = 50, Vertical = 20 }, + Padding = new MarginPadding { Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING, Vertical = 20 }, Children = new Drawable[] { avatar = new UpdateableAvatar(api.LocalUser.Value) @@ -393,7 +393,7 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Margin = new MarginPadding { Left = 50 }, + Margin = new MarginPadding { Left = WaveOverlayContainer.HORIZONTAL_PADDING }, Text = CommentsStrings.Empty } }); diff --git a/osu.Game/Overlays/Comments/CommentsHeader.cs b/osu.Game/Overlays/Comments/CommentsHeader.cs index e6d44e618b..0ae1f839a1 100644 --- a/osu.Game/Overlays/Comments/CommentsHeader.cs +++ b/osu.Game/Overlays/Comments/CommentsHeader.cs @@ -41,7 +41,7 @@ namespace osu.Game.Overlays.Comments new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = 50 }, + Padding = new MarginPadding { Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING }, Children = new Drawable[] { new OverlaySortTabControl diff --git a/osu.Game/Overlays/Comments/TotalCommentsCounter.cs b/osu.Game/Overlays/Comments/TotalCommentsCounter.cs index 38928f6f3d..2065f7a76b 100644 --- a/osu.Game/Overlays/Comments/TotalCommentsCounter.cs +++ b/osu.Game/Overlays/Comments/TotalCommentsCounter.cs @@ -32,7 +32,7 @@ namespace osu.Game.Overlays.Comments Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, - Margin = new MarginPadding { Left = 50 }, + Margin = new MarginPadding { Left = WaveOverlayContainer.HORIZONTAL_PADDING }, Spacing = new Vector2(5, 0), Children = new Drawable[] { diff --git a/osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs b/osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs index 73fab6d62b..a40993ae05 100644 --- a/osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs +++ b/osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs @@ -129,7 +129,7 @@ namespace osu.Game.Overlays.Dashboard.Friends { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = 50 } + Padding = new MarginPadding { Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING } }, loading = new LoadingLayer(true) } diff --git a/osu.Game/Overlays/News/Displays/ArticleListing.cs b/osu.Game/Overlays/News/Displays/ArticleListing.cs index b6ce16ae7d..4fc9dde156 100644 --- a/osu.Game/Overlays/News/Displays/ArticleListing.cs +++ b/osu.Game/Overlays/News/Displays/ArticleListing.cs @@ -43,7 +43,7 @@ namespace osu.Game.Overlays.News.Displays { Vertical = 20, Left = 30, - Right = 50 + Right = WaveOverlayContainer.HORIZONTAL_PADDING }; InternalChild = new FillFlowContainer diff --git a/osu.Game/Overlays/OverlayHeader.cs b/osu.Game/Overlays/OverlayHeader.cs index f28d40c429..93de463204 100644 --- a/osu.Game/Overlays/OverlayHeader.cs +++ b/osu.Game/Overlays/OverlayHeader.cs @@ -89,7 +89,7 @@ namespace osu.Game.Overlays } }); - ContentSidePadding = 50; + ContentSidePadding = WaveOverlayContainer.HORIZONTAL_PADDING; } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/OverlaySidebar.cs b/osu.Game/Overlays/OverlaySidebar.cs index b8c0032e87..93e5e83ffc 100644 --- a/osu.Game/Overlays/OverlaySidebar.cs +++ b/osu.Game/Overlays/OverlaySidebar.cs @@ -55,7 +55,7 @@ namespace osu.Game.Overlays Padding = new MarginPadding { Vertical = 20, - Left = 50, + Left = WaveOverlayContainer.HORIZONTAL_PADDING, Right = 30 }, Child = CreateContent() diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index cafee7ea85..d964364510 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -77,7 +77,7 @@ namespace osu.Game.Overlays.Profile.Header Origin = Anchor.CentreRight, Width = 200, Height = 6, - Margin = new MarginPadding { Right = 50 }, + Margin = new MarginPadding { Right = WaveOverlayContainer.HORIZONTAL_PADDING }, Child = new LevelProgressBar { RelativeSizeAxes = Axes.Both, diff --git a/osu.Game/Overlays/Wiki/WikiArticlePage.cs b/osu.Game/Overlays/Wiki/WikiArticlePage.cs index 6c1dbe3181..342a395871 100644 --- a/osu.Game/Overlays/Wiki/WikiArticlePage.cs +++ b/osu.Game/Overlays/Wiki/WikiArticlePage.cs @@ -56,7 +56,7 @@ namespace osu.Game.Overlays.Wiki { Vertical = 20, Left = 30, - Right = 50, + Right = WaveOverlayContainer.HORIZONTAL_PADDING, }, OnAddHeading = sidebar.AddEntry, } diff --git a/osu.Game/Overlays/WikiOverlay.cs b/osu.Game/Overlays/WikiOverlay.cs index 88dc2cd7a4..2444aa4fa2 100644 --- a/osu.Game/Overlays/WikiOverlay.cs +++ b/osu.Game/Overlays/WikiOverlay.cs @@ -145,7 +145,7 @@ namespace osu.Game.Overlays Padding = new MarginPadding { Vertical = 20, - Horizontal = 50, + Horizontal = HORIZONTAL_PADDING, }, }); } From 436f1e4ae40fb980447672a5f2ad69a41ce61243 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 2 Apr 2023 20:45:09 -0700 Subject: [PATCH 2584/2991] Replace other hardcoded horizontal padding with const - Also add overlay stream item padding const and account for it --- .../Overlays/BeatmapListing/BeatmapListingSearchControl.cs | 2 +- osu.Game/Overlays/Changelog/ChangelogHeader.cs | 2 +- osu.Game/Overlays/Comments/CommentsContainer.cs | 2 +- osu.Game/Overlays/Comments/DrawableComment.cs | 2 +- osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs | 2 +- osu.Game/Overlays/OverlayStreamItem.cs | 4 +++- 6 files changed, 8 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs index 23de1cf76d..3fa0fc7a77 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs @@ -107,7 +107,7 @@ namespace osu.Game.Overlays.BeatmapListing Padding = new MarginPadding { Vertical = 20, - Horizontal = 40, + Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING, }, Child = new FillFlowContainer { diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index 54ada24987..e9be67e977 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -93,7 +93,7 @@ namespace osu.Game.Overlays.Changelog AutoSizeAxes = Axes.Y, Padding = new MarginPadding { - Horizontal = 65, + Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING - ChangelogUpdateStreamItem.PADDING, Vertical = 20 }, Child = Streams = new ChangelogUpdateStreamControl { Current = currentStream }, diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 2a873690a7..24536fe460 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -152,7 +152,7 @@ namespace osu.Game.Overlays.Comments ShowDeleted = { BindTarget = ShowDeleted }, Margin = new MarginPadding { - Horizontal = 70, + Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING, Vertical = 10 } }, diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 397dd46cdc..a710406548 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -537,7 +537,7 @@ namespace osu.Game.Overlays.Comments { return new MarginPadding { - Horizontal = 70, + Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING, Vertical = 15 }; } diff --git a/osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs b/osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs index a40993ae05..e3accfd2ad 100644 --- a/osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs +++ b/osu.Game/Overlays/Dashboard/Friends/FriendDisplay.cs @@ -79,7 +79,7 @@ namespace osu.Game.Overlays.Dashboard.Friends Padding = new MarginPadding { Top = 20, - Horizontal = 45 + Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING - FriendsOnlineStatusItem.PADDING }, Child = onlineStreamControl = new FriendOnlineStreamControl(), } diff --git a/osu.Game/Overlays/OverlayStreamItem.cs b/osu.Game/Overlays/OverlayStreamItem.cs index 9b18e5cccf..45181c13e4 100644 --- a/osu.Game/Overlays/OverlayStreamItem.cs +++ b/osu.Game/Overlays/OverlayStreamItem.cs @@ -39,12 +39,14 @@ namespace osu.Game.Overlays private FillFlowContainer text; private ExpandingBar expandingBar; + public const float PADDING = 5; + protected OverlayStreamItem(T value) : base(value) { Height = 50; Width = 90; - Margin = new MarginPadding(5); + Margin = new MarginPadding(PADDING); } [BackgroundDependencyLoader] From 247d426c8a61cebe24693bf0124798483bea7239 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 2 Apr 2023 17:14:31 -0700 Subject: [PATCH 2585/2991] Add horizontal padding to currently playing search textbox --- osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs index 1540aa8fbb..5047992c8b 100644 --- a/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs +++ b/osu.Game/Overlays/Dashboard/CurrentlyPlayingDisplay.cs @@ -60,7 +60,7 @@ namespace osu.Game.Overlays.Dashboard new Container { RelativeSizeAxes = Axes.X, - Padding = new MarginPadding(padding), + Padding = new MarginPadding { Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING, Vertical = padding }, Child = searchTextBox = new BasicSearchTextBox { RelativeSizeAxes = Axes.X, From a097433cb121f6315166cd8e9914efb9dc0347ea Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Apr 2023 14:56:29 +0900 Subject: [PATCH 2586/2991] Fix overlay toggle keys working during disabled activation modes Closes #23104. --- osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs | 13 +++++++++++++ osu.Game/Overlays/Toolbar/Toolbar.cs | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs index aef6f9ade0..22c7bb64b2 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs @@ -114,6 +114,19 @@ namespace osu.Game.Tests.Visual.Menus } } + [TestCase(OverlayActivation.All)] + [TestCase(OverlayActivation.Disabled)] + public void TestButtonKeyboardInputRespectsOverlayActivation(OverlayActivation mode) + { + AddStep($"set activation mode to {mode}", () => toolbar.OverlayActivationMode.Value = mode); + AddStep("hide toolbar", () => toolbar.Hide()); + + if (mode == OverlayActivation.Disabled) + AddAssert("check buttons not accepting input", () => InputManager.NonPositionalInputQueue.OfType().Count(), () => Is.Zero); + else + AddAssert("check buttons accepting input", () => InputManager.NonPositionalInputQueue.OfType().Count(), () => Is.Not.Zero); + } + [TestCase(OverlayActivation.All)] [TestCase(OverlayActivation.Disabled)] public void TestRespectsOverlayActivation(OverlayActivation mode) diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index f21ef0ee98..93294a9d30 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -42,7 +42,7 @@ namespace osu.Game.Overlays.Toolbar protected readonly IBindable OverlayActivationMode = new Bindable(OverlayActivation.All); // Toolbar and its components need keyboard input even when hidden. - public override bool PropagateNonPositionalInputSubTree => true; + public override bool PropagateNonPositionalInputSubTree => OverlayActivationMode.Value != OverlayActivation.Disabled; public Toolbar() { From 6239789188c94561aaae96b6932fd67ee9ad5a4c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Apr 2023 15:37:10 +0900 Subject: [PATCH 2587/2991] Fix missing using statements in multiple test scenes --- osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs | 1 + osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 7bc789ecc4..eecead5415 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -8,6 +8,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Framework.Timing; using osu.Game.Configuration; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs index 9d8d82108d..7bbfc6a62b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs @@ -10,6 +10,8 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; using osu.Framework.Timing; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; From 7011928d86e7ed83f3e7d8839d8e1acc0a878267 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Apr 2023 18:04:33 +0900 Subject: [PATCH 2588/2991] Fix abysmal debug performance due to try-catch logic in `DrawableRulesetDependencies` --- .../UI/DrawableRulesetDependencies.cs | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs index e6ee770e19..1d5fcc634e 100644 --- a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs +++ b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs @@ -206,17 +206,26 @@ namespace osu.Game.Rulesets.UI this.parent = parent; } + // When the debugger is attached, exceptions are expensive. + // Manually work around this by caching failed lookups and falling back straight to parent. + private readonly HashSet<(string, string)> failedLookups = new HashSet<(string, string)>(); + public override IShader Load(string vertex, string fragment) { - try + if (!failedLookups.Contains((vertex, fragment))) { - return base.Load(vertex, fragment); - } - catch - { - // Shader lookup is very non-standard. Rather than returning null on missing shaders, exceptions are thrown. - return parent.Load(vertex, fragment); + try + { + return base.Load(vertex, fragment); + } + catch + { + // Shader lookup is very non-standard. Rather than returning null on missing shaders, exceptions are thrown. + failedLookups.Add((vertex, fragment)); + } } + + return parent.Load(vertex, fragment); } } } From be79ea1c10eacfe4e759e2fd2fcdeeaf92280c6c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Apr 2023 18:14:58 +0900 Subject: [PATCH 2589/2991] Remove left/right click based placement in taiko editor and respect sample selection --- .../Edit/Blueprints/HitPlacementBlueprint.cs | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs index 0a1f5380b5..d47a50b94d 100644 --- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs @@ -35,20 +35,8 @@ namespace osu.Game.Rulesets.Taiko.Edit.Blueprints protected override bool OnMouseDown(MouseDownEvent e) { - switch (e.Button) - { - case MouseButton.Left: - HitObject.Type = HitType.Centre; - EndPlacement(true); - return true; - - case MouseButton.Right: - HitObject.Type = HitType.Rim; - EndPlacement(true); - return true; - } - - return false; + EndPlacement(true); + return true; } public override void UpdateTimeAndPosition(SnapResult result) From 51240ed46b0fbec450b74c7513cf3737a997cad9 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Mon, 3 Apr 2023 19:51:22 +0900 Subject: [PATCH 2590/2991] typo --- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 61bfd97f3c..59be9414fd 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -212,13 +212,13 @@ namespace osu.Game.Overlays.BeatmapSet if (beatmapInfo != null && beatmapSet?.Author.OnlineID != beatmapInfo.AuthorID) { if (BeatmapSet?.RelatedUsers?.Single(u => u.OnlineID == beatmapInfo.AuthorID) is APIUser user) - guestMapperContainer.Child = getGueatMapper(user); + guestMapperContainer.Child = getGuestMapper(user); } version.Text = beatmapInfo?.DifficultyName ?? string.Empty; } - private Drawable getGueatMapper(APIUser user) + private Drawable getGuestMapper(APIUser user) { return new LinkFlowContainer(s => { From 41c01d3929279865a1e542c7aa556bc3dad1d44d Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Mon, 3 Apr 2023 20:07:21 +0900 Subject: [PATCH 2591/2991] nullable condition --- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 59be9414fd..67348959a6 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -211,21 +211,18 @@ namespace osu.Game.Overlays.BeatmapSet if (beatmapInfo != null && beatmapSet?.Author.OnlineID != beatmapInfo.AuthorID) { - if (BeatmapSet?.RelatedUsers?.Single(u => u.OnlineID == beatmapInfo.AuthorID) is APIUser user) guestMapperContainer.Child = getGuestMapper(user); + APIUser? user = BeatmapSet?.RelatedUsers?.Single(u => u.OnlineID == beatmapInfo?.AuthorID); + if (user != null) } version.Text = beatmapInfo?.DifficultyName ?? string.Empty; } - private Drawable getGuestMapper(APIUser user) + private void getGuestMapper(APIUser user) { - return new LinkFlowContainer(s => + guestMapperContainer.With(d => { - s.Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 15); - }).With(d => - { - d.AutoSizeAxes = Axes.Both; d.AddText("mapped by "); d.AddUserLink(user); }); From 735b48679e2d4cd025590d84e7bd84a6712b08ab Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Mon, 3 Apr 2023 20:09:49 +0900 Subject: [PATCH 2592/2991] use `LinkFlowContainer` directly --- .../Visual/Online/TestSceneBeatmapSetOverlay.cs | 5 +++-- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 11 ++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 3090ff6c49..37f7b7623b 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -15,6 +15,7 @@ using System.Linq; using osu.Framework.Testing; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; @@ -290,12 +291,12 @@ namespace osu.Game.Tests.Visual.Online { InputManager.MoveMouseTo(overlay.ChildrenOfType().ElementAt(0)); }); - AddAssert("Guset mapper information not show", () => !overlay.ChildrenOfType().Single().ChildrenOfType().Any()); + AddAssert("Guset mapper information not show", () => overlay.ChildrenOfType().Single().ChildrenOfType().All(s => s.Text != "BanchoBot")); AddStep("move mouse to guest diff", () => { InputManager.MoveMouseTo(overlay.ChildrenOfType().ElementAt(1)); }); - AddAssert("Guset mapper information show", () => overlay.ChildrenOfType().Single().ChildrenOfType().Any()); + AddAssert("Guset mapper information show", () => overlay.ChildrenOfType().Single().ChildrenOfType().Any(s => s.Text == "BanchoBot")); } private APIBeatmapSet createManyDifficultiesBeatmapSet() diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 67348959a6..3689599a6f 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.BeatmapSet private const float tile_spacing = 2; private readonly OsuSpriteText version, starRating, starRatingText; - private readonly FillFlowContainer guestMapperContainer; + private readonly LinkFlowContainer guestMapperContainer; private readonly FillFlowContainer starRatingContainer; private readonly Statistic plays, favourites; @@ -89,7 +89,8 @@ namespace osu.Game.Overlays.BeatmapSet Origin = Anchor.BottomLeft, Font = OsuFont.GetFont(size: 17, weight: FontWeight.Bold) }, - guestMapperContainer = new FillFlowContainer + guestMapperContainer = new LinkFlowContainer(s => + s.Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 15)) { AutoSizeAxes = Axes.Both, Anchor = Anchor.BottomLeft, @@ -209,11 +210,11 @@ namespace osu.Game.Overlays.BeatmapSet { guestMapperContainer.Clear(); - if (beatmapInfo != null && beatmapSet?.Author.OnlineID != beatmapInfo.AuthorID) + if (beatmapInfo != null && beatmapInfo.AuthorID != beatmapSet?.AuthorID) { - guestMapperContainer.Child = getGuestMapper(user); - APIUser? user = BeatmapSet?.RelatedUsers?.Single(u => u.OnlineID == beatmapInfo?.AuthorID); + APIUser? user = BeatmapSet?.RelatedUsers?.Single(u => u.OnlineID == beatmapInfo.AuthorID); if (user != null) + getGuestMapper(user); } version.Text = beatmapInfo?.DifficultyName ?? string.Empty; From 9dd30e4b4cb87a783c3e3f121b0238716137e252 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Mon, 3 Apr 2023 20:24:38 +0900 Subject: [PATCH 2593/2991] condition fix --- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 3689599a6f..63bb122cb6 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -210,9 +210,9 @@ namespace osu.Game.Overlays.BeatmapSet { guestMapperContainer.Clear(); - if (beatmapInfo != null && beatmapInfo.AuthorID != beatmapSet?.AuthorID) + if (beatmapInfo?.AuthorID != beatmapSet?.AuthorID) { - APIUser? user = BeatmapSet?.RelatedUsers?.Single(u => u.OnlineID == beatmapInfo.AuthorID); + APIUser? user = BeatmapSet?.RelatedUsers?.SingleOrDefault(u => u.OnlineID == beatmapInfo?.AuthorID); if (user != null) getGuestMapper(user); } From 9e0277b2fd85c825cb35e9cf47a1f4313db12656 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Tue, 4 Apr 2023 00:19:14 +0900 Subject: [PATCH 2594/2991] useless using --- osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 37f7b7623b..9e46738305 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -14,7 +14,6 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Testing; using osu.Game.Beatmaps.Drawables; -using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Online.API; using osu.Game.Online.API.Requests; From ed07c0640b4edca4424103fdadd45e9044dc8976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 3 Apr 2023 20:13:59 +0200 Subject: [PATCH 2595/2991] Remove unused using directive --- osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs index d47a50b94d..67206fcd8f 100644 --- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs @@ -8,7 +8,6 @@ using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.UI; using osuTK; -using osuTK.Input; namespace osu.Game.Rulesets.Taiko.Edit.Blueprints { From f42a463479d94480aefaf0189adddeafe0df3965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 3 Apr 2023 20:14:17 +0200 Subject: [PATCH 2596/2991] Remove `#nullable disable` May as well that we're here... --- .../Edit/Blueprints/HitPlacementBlueprint.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs index 67206fcd8f..f152c98a2e 100644 --- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Input.Events; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Taiko.Objects; From f9ebdadfe8da725e41f3fd4cd86a21a832457c7e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 4 Apr 2023 18:53:25 +0900 Subject: [PATCH 2597/2991] Move right-side editor toolbox to base `HitObjectComposer` Move right-side editor toolbox to base `HitObjectComposer` --- .../Edit/CatchHitObjectComposer.cs | 1 - .../Edit/DistancedHitObjectComposer.cs | 53 ++++++------------- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 22 +++++++- 3 files changed, 37 insertions(+), 39 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index ea5f54a775..cd8894753f 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -48,7 +48,6 @@ namespace osu.Game.Rulesets.Catch.Edit private void load() { // todo: enable distance spacing once catch supports applying it to its existing distance snap grid implementation. - RightSideToolboxContainer.Alpha = 0; DistanceSpacingMultiplier.Disabled = true; LayerBelowRuleset.Add(new PlayfieldBorder diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index 0df481737e..aa47b4f424 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -11,8 +11,6 @@ using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; @@ -47,8 +45,6 @@ namespace osu.Game.Rulesets.Edit IBindable IDistanceSnapProvider.DistanceSpacingMultiplier => DistanceSpacingMultiplier; - protected ExpandingToolboxContainer RightSideToolboxContainer { get; private set; } - private ExpandableSlider> distanceSpacingSlider; private ExpandableButton currentDistanceSpacingButton; @@ -67,47 +63,29 @@ namespace osu.Game.Rulesets.Edit [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - AddInternal(new Container + RightToolbox.Add(new EditorToolboxGroup("snapping") { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, + Alpha = DistanceSpacingMultiplier.Disabled ? 0 : 1, Children = new Drawable[] { - new Box + distanceSpacingSlider = new ExpandableSlider> { - Colour = colourProvider.Background5, - RelativeSizeAxes = Axes.Both, + KeyboardStep = adjust_step, + // Manual binding in LoadComplete to handle one-way event flow. + Current = DistanceSpacingMultiplier.GetUnboundCopy(), }, - RightSideToolboxContainer = new ExpandingToolboxContainer(130, 250) + currentDistanceSpacingButton = new ExpandableButton { - Alpha = DistanceSpacingMultiplier.Disabled ? 0 : 1, - Child = new EditorToolboxGroup("snapping") + Action = () => { - Children = new Drawable[] - { - distanceSpacingSlider = new ExpandableSlider> - { - KeyboardStep = adjust_step, - // Manual binding in LoadComplete to handle one-way event flow. - Current = DistanceSpacingMultiplier.GetUnboundCopy(), - }, - currentDistanceSpacingButton = new ExpandableButton - { - Action = () => - { - (HitObject before, HitObject after)? objects = getObjectsOnEitherSideOfCurrentTime(); + (HitObject before, HitObject after)? objects = getObjectsOnEitherSideOfCurrentTime(); - Debug.Assert(objects != null); + Debug.Assert(objects != null); - DistanceSpacingMultiplier.Value = ReadCurrentDistanceSnap(objects.Value.before, objects.Value.after); - DistanceSnapToggle.Value = TernaryState.True; - }, - RelativeSizeAxes = Axes.X, - } - } - } + DistanceSpacingMultiplier.Value = ReadCurrentDistanceSnap(objects.Value.before, objects.Value.after); + DistanceSnapToggle.Value = TernaryState.True; + }, + RelativeSizeAxes = Axes.X, } } }); @@ -261,7 +239,8 @@ namespace osu.Game.Rulesets.Edit public virtual float GetBeatSnapDistanceAt(HitObject referenceObject, bool useReferenceSliderVelocity = true) { - return (float)(100 * (useReferenceSliderVelocity ? referenceObject.DifficultyControlPoint.SliderVelocity : 1) * EditorBeatmap.Difficulty.SliderMultiplier * 1 / BeatSnapProvider.BeatDivisor); + return (float)(100 * (useReferenceSliderVelocity ? referenceObject.DifficultyControlPoint.SliderVelocity : 1) * EditorBeatmap.Difficulty.SliderMultiplier * 1 + / BeatSnapProvider.BeatDivisor); } public virtual float DurationToDistance(HitObject referenceObject, double duration) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index aee86fd942..c2250b1cd5 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -60,6 +60,10 @@ namespace osu.Game.Rulesets.Edit protected ComposeBlueprintContainer BlueprintContainer { get; private set; } + protected ExpandingToolboxContainer LeftToolbox { get; private set; } + + protected ExpandingToolboxContainer RightToolbox { get; private set; } + private DrawableEditorRulesetWrapper drawableRulesetWrapper; protected readonly Container LayerBelowRuleset = new Container { RelativeSizeAxes = Axes.Both }; @@ -131,7 +135,7 @@ namespace osu.Game.Rulesets.Edit Colour = colourProvider.Background5, RelativeSizeAxes = Axes.Both, }, - new ExpandingToolboxContainer(60, 200) + LeftToolbox = new ExpandingToolboxContainer(60, 200) { Children = new Drawable[] { @@ -153,6 +157,22 @@ namespace osu.Game.Rulesets.Edit }, } }, + new Container + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Children = new Drawable[] + { + new Box + { + Colour = colourProvider.Background5, + RelativeSizeAxes = Axes.Both, + }, + RightToolbox = new ExpandingToolboxContainer(130, 250) + } + } }; toolboxCollection.Items = CompositionTools From c356c163fa3b86597090751e1e4dcc3bb9598d86 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 4 Apr 2023 19:03:45 +0900 Subject: [PATCH 2598/2991] Add hit object inspector view --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 98 +++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index c2250b1cd5..9f5663747c 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -18,12 +18,15 @@ using osu.Framework.Input.Events; using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Configuration; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Overlays; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Screens.Edit; @@ -33,6 +36,7 @@ using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Compose.Components; using osuTK; using osuTK.Input; +using FontWeight = osu.Game.Graphics.FontWeight; namespace osu.Game.Rulesets.Edit { @@ -77,6 +81,14 @@ namespace osu.Game.Rulesets.Edit private IBindable hasTiming; private Bindable autoSeekOnPlacement; + [Resolved] + private EditorBeatmap beatmap { get; set; } + + [Resolved] + private OverlayColourProvider colours { get; set; } + + private OsuTextFlowContainer inspectorText; + protected HitObjectComposer(Ruleset ruleset) : base(ruleset) { @@ -171,6 +183,16 @@ namespace osu.Game.Rulesets.Edit RelativeSizeAxes = Axes.Both, }, RightToolbox = new ExpandingToolboxContainer(130, 250) + { + Child = new EditorToolboxGroup("inspector") + { + Child = inspectorText = new OsuTextFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + } + }, + } } } }; @@ -212,6 +234,13 @@ namespace osu.Game.Rulesets.Edit }); } + protected override void Update() + { + base.Update(); + + updateInspectorText(); + } + public override Playfield Playfield => drawableRulesetWrapper.Playfield; public override IEnumerable HitObjects => drawableRulesetWrapper.Playfield.AllHitObjects; @@ -289,6 +318,75 @@ namespace osu.Game.Rulesets.Edit return base.OnKeyDown(e); } + private void updateInspectorText() + { + if (beatmap.SelectedHitObjects.Count != 1) + { + inspectorText.Clear(); + return; + } + + var selected = beatmap.SelectedHitObjects.Single(); + + inspectorText.Clear(); + + addHeader("Time"); + addValue($"{selected.StartTime:#,0.##}ms"); + + switch (selected) + { + case IHasPosition pos: + addHeader("Position"); + addValue($"x:{pos.X:#,0.##} y:{pos.Y:#,0.##}"); + break; + + case IHasXPosition x: + addHeader("Position"); + + addValue($"x:{x.X:#,0.##} "); + break; + + case IHasYPosition y: + addHeader("Position"); + + addValue($"y:{y.Y:#,0.##}"); + break; + } + + if (selected is IHasDistance distance) + { + addHeader("Distance"); + addValue($"{distance.Distance:#,0.##}px"); + } + + if (selected is IHasRepeats repeats) + { + addHeader("Repeats"); + addValue($"{repeats.RepeatCount:#,0.##}"); + } + + if (selected is IHasDuration duration) + { + addHeader("End Time"); + addValue($"{duration.EndTime:#,0.##}ms"); + addHeader("Duration"); + addValue($"{duration.Duration:#,0.##}ms"); + } + + void addHeader(string header) => inspectorText.AddParagraph($"{header}: ", s => + { + s.Padding = new MarginPadding { Top = 2 }; + s.Font = s.Font.With(size: 12); + s.Colour = colours.Content2; + }); + + void addValue(string value) => inspectorText.AddParagraph(value, s => + { + s.Font = s.Font.With(weight: FontWeight.SemiBold); + s.Colour = colours.Content1; + }); + } + private bool checkLeftToggleFromKey(Key key, out int index) { if (key < Key.Number1 || key > Key.Number9) From b0d57616679c01c8d6ac73000ceb034331ff2cc1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 4 Apr 2023 19:05:50 +0900 Subject: [PATCH 2599/2991] Add object type --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 9f5663747c..753667eb4a 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -10,6 +10,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.EnumExtensions; +using osu.Framework.Extensions.TypeExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -330,6 +331,9 @@ namespace osu.Game.Rulesets.Edit inspectorText.Clear(); + addHeader("Type"); + addValue($"{selected.GetType().ReadableName()}"); + addHeader("Time"); addValue($"{selected.StartTime:#,0.##}ms"); From 195b5fc3f182adfb7ffa68a98102571f635eda0b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 4 Apr 2023 19:11:48 +0900 Subject: [PATCH 2600/2991] Add view for selections of size != 1 --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 103 +++++++++++--------- 1 file changed, 59 insertions(+), 44 deletions(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 753667eb4a..b4c8c7798e 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -321,62 +321,77 @@ namespace osu.Game.Rulesets.Edit private void updateInspectorText() { - if (beatmap.SelectedHitObjects.Count != 1) - { - inspectorText.Clear(); - return; - } - - var selected = beatmap.SelectedHitObjects.Single(); - inspectorText.Clear(); - addHeader("Type"); - addValue($"{selected.GetType().ReadableName()}"); - - addHeader("Time"); - addValue($"{selected.StartTime:#,0.##}ms"); - - switch (selected) + switch (beatmap.SelectedHitObjects.Count) { - case IHasPosition pos: - addHeader("Position"); - addValue($"x:{pos.X:#,0.##} y:{pos.Y:#,0.##}"); + case 0: + addHeader("No selection"); break; - case IHasXPosition x: - addHeader("Position"); + case 1: + var selected = beatmap.SelectedHitObjects.Single(); + + addHeader("Type"); + addValue($"{selected.GetType().ReadableName()}"); + + addHeader("Time"); + addValue($"{selected.StartTime:#,0.##}ms"); + + switch (selected) + { + case IHasPosition pos: + addHeader("Position"); + addValue($"x:{pos.X:#,0.##} y:{pos.Y:#,0.##}"); + break; + + case IHasXPosition x: + addHeader("Position"); + + addValue($"x:{x.X:#,0.##} "); + break; + + case IHasYPosition y: + addHeader("Position"); + + addValue($"y:{y.Y:#,0.##}"); + break; + } + + if (selected is IHasDistance distance) + { + addHeader("Distance"); + addValue($"{distance.Distance:#,0.##}px"); + } + + if (selected is IHasRepeats repeats) + { + addHeader("Repeats"); + addValue($"{repeats.RepeatCount:#,0.##}"); + } + + if (selected is IHasDuration duration) + { + addHeader("End Time"); + addValue($"{duration.EndTime:#,0.##}ms"); + addHeader("Duration"); + addValue($"{duration.Duration:#,0.##}ms"); + } - addValue($"x:{x.X:#,0.##} "); break; - case IHasYPosition y: - addHeader("Position"); + default: + addHeader("Selected Objects"); + addValue($"{beatmap.SelectedHitObjects.Count:#,0.##}"); - addValue($"y:{y.Y:#,0.##}"); + addHeader("Start Time"); + addValue($"{beatmap.SelectedHitObjects.Min(o => o.StartTime):#,0.##}"); + + addHeader("End Time"); + addValue($"{beatmap.SelectedHitObjects.Max(o => o.GetEndTime()):#,0.##}"); break; } - if (selected is IHasDistance distance) - { - addHeader("Distance"); - addValue($"{distance.Distance:#,0.##}px"); - } - - if (selected is IHasRepeats repeats) - { - addHeader("Repeats"); - addValue($"{repeats.RepeatCount:#,0.##}"); - } - - if (selected is IHasDuration duration) - { - addHeader("End Time"); - addValue($"{duration.EndTime:#,0.##}ms"); - addHeader("Duration"); - addValue($"{duration.Duration:#,0.##}ms"); - } - void addHeader(string header) => inspectorText.AddParagraph($"{header}: ", s => { s.Padding = new MarginPadding { Top = 2 }; From 4aed483005abf9eaf9ad3f73197cdfad6fa2f051 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 4 Apr 2023 19:14:30 +0900 Subject: [PATCH 2601/2991] Tidy up dependency resolution --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 25 +++++++++------------ 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index b4c8c7798e..b28dfdf3f0 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -63,6 +63,9 @@ namespace osu.Game.Rulesets.Edit [Resolved] protected IBeatSnapProvider BeatSnapProvider { get; private set; } + [Resolved] + private OverlayColourProvider colourProvider { get; set; } + protected ComposeBlueprintContainer BlueprintContainer { get; private set; } protected ExpandingToolboxContainer LeftToolbox { get; private set; } @@ -82,12 +85,6 @@ namespace osu.Game.Rulesets.Edit private IBindable hasTiming; private Bindable autoSeekOnPlacement; - [Resolved] - private EditorBeatmap beatmap { get; set; } - - [Resolved] - private OverlayColourProvider colours { get; set; } - private OsuTextFlowContainer inspectorText; protected HitObjectComposer(Ruleset ruleset) @@ -99,7 +96,7 @@ namespace osu.Game.Rulesets.Edit dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider, OsuConfigManager config) + private void load(OsuConfigManager config) { autoSeekOnPlacement = config.GetBindable(OsuSetting.EditorAutoSeekOnPlacement); @@ -323,14 +320,14 @@ namespace osu.Game.Rulesets.Edit { inspectorText.Clear(); - switch (beatmap.SelectedHitObjects.Count) + switch (EditorBeatmap.SelectedHitObjects.Count) { case 0: addHeader("No selection"); break; case 1: - var selected = beatmap.SelectedHitObjects.Single(); + var selected = EditorBeatmap.SelectedHitObjects.Single(); addHeader("Type"); addValue($"{selected.GetType().ReadableName()}"); @@ -382,13 +379,13 @@ namespace osu.Game.Rulesets.Edit default: addHeader("Selected Objects"); - addValue($"{beatmap.SelectedHitObjects.Count:#,0.##}"); + addValue($"{EditorBeatmap.SelectedHitObjects.Count:#,0.##}"); addHeader("Start Time"); - addValue($"{beatmap.SelectedHitObjects.Min(o => o.StartTime):#,0.##}"); + addValue($"{EditorBeatmap.SelectedHitObjects.Min(o => o.StartTime):#,0.##}"); addHeader("End Time"); - addValue($"{beatmap.SelectedHitObjects.Max(o => o.GetEndTime()):#,0.##}"); + addValue($"{EditorBeatmap.SelectedHitObjects.Max(o => o.GetEndTime()):#,0.##}"); break; } @@ -396,13 +393,13 @@ namespace osu.Game.Rulesets.Edit { s.Padding = new MarginPadding { Top = 2 }; s.Font = s.Font.With(size: 12); - s.Colour = colours.Content2; + s.Colour = colourProvider.Content2; }); void addValue(string value) => inspectorText.AddParagraph(value, s => { s.Font = s.Font.With(weight: FontWeight.SemiBold); - s.Colour = colours.Content1; + s.Colour = colourProvider.Content1; }); } From 3209b092702aaa78c376422de632d48c86792d65 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 4 Apr 2023 19:17:14 +0900 Subject: [PATCH 2602/2991] Move inspector into own file --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 107 +-------------- osu.Game/Rulesets/Edit/HitObjectInspector.cs | 132 +++++++++++++++++++ 2 files changed, 133 insertions(+), 106 deletions(-) create mode 100644 osu.Game/Rulesets/Edit/HitObjectInspector.cs diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index b28dfdf3f0..653861c11c 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -10,7 +10,6 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.EnumExtensions; -using osu.Framework.Extensions.TypeExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -19,15 +18,12 @@ using osu.Framework.Input.Events; using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Configuration; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; using osu.Game.Overlays; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI.Scrolling; using osu.Game.Screens.Edit; @@ -37,7 +33,6 @@ using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Compose.Components; using osuTK; using osuTK.Input; -using FontWeight = osu.Game.Graphics.FontWeight; namespace osu.Game.Rulesets.Edit { @@ -85,8 +80,6 @@ namespace osu.Game.Rulesets.Edit private IBindable hasTiming; private Bindable autoSeekOnPlacement; - private OsuTextFlowContainer inspectorText; - protected HitObjectComposer(Ruleset ruleset) : base(ruleset) { @@ -184,11 +177,7 @@ namespace osu.Game.Rulesets.Edit { Child = new EditorToolboxGroup("inspector") { - Child = inspectorText = new OsuTextFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - } + Child = new HitObjectInspector() }, } } @@ -232,13 +221,6 @@ namespace osu.Game.Rulesets.Edit }); } - protected override void Update() - { - base.Update(); - - updateInspectorText(); - } - public override Playfield Playfield => drawableRulesetWrapper.Playfield; public override IEnumerable HitObjects => drawableRulesetWrapper.Playfield.AllHitObjects; @@ -316,93 +298,6 @@ namespace osu.Game.Rulesets.Edit return base.OnKeyDown(e); } - private void updateInspectorText() - { - inspectorText.Clear(); - - switch (EditorBeatmap.SelectedHitObjects.Count) - { - case 0: - addHeader("No selection"); - break; - - case 1: - var selected = EditorBeatmap.SelectedHitObjects.Single(); - - addHeader("Type"); - addValue($"{selected.GetType().ReadableName()}"); - - addHeader("Time"); - addValue($"{selected.StartTime:#,0.##}ms"); - - switch (selected) - { - case IHasPosition pos: - addHeader("Position"); - addValue($"x:{pos.X:#,0.##} y:{pos.Y:#,0.##}"); - break; - - case IHasXPosition x: - addHeader("Position"); - - addValue($"x:{x.X:#,0.##} "); - break; - - case IHasYPosition y: - addHeader("Position"); - - addValue($"y:{y.Y:#,0.##}"); - break; - } - - if (selected is IHasDistance distance) - { - addHeader("Distance"); - addValue($"{distance.Distance:#,0.##}px"); - } - - if (selected is IHasRepeats repeats) - { - addHeader("Repeats"); - addValue($"{repeats.RepeatCount:#,0.##}"); - } - - if (selected is IHasDuration duration) - { - addHeader("End Time"); - addValue($"{duration.EndTime:#,0.##}ms"); - addHeader("Duration"); - addValue($"{duration.Duration:#,0.##}ms"); - } - - break; - - default: - addHeader("Selected Objects"); - addValue($"{EditorBeatmap.SelectedHitObjects.Count:#,0.##}"); - - addHeader("Start Time"); - addValue($"{EditorBeatmap.SelectedHitObjects.Min(o => o.StartTime):#,0.##}"); - - addHeader("End Time"); - addValue($"{EditorBeatmap.SelectedHitObjects.Max(o => o.GetEndTime()):#,0.##}"); - break; - } - - void addHeader(string header) => inspectorText.AddParagraph($"{header}: ", s => - { - s.Padding = new MarginPadding { Top = 2 }; - s.Font = s.Font.With(size: 12); - s.Colour = colourProvider.Content2; - }); - - void addValue(string value) => inspectorText.AddParagraph(value, s => - { - s.Font = s.Font.With(weight: FontWeight.SemiBold); - s.Colour = colourProvider.Content1; - }); - } - private bool checkLeftToggleFromKey(Key key, out int index) { if (key < Key.Number1 || key > Key.Number9) diff --git a/osu.Game/Rulesets/Edit/HitObjectInspector.cs b/osu.Game/Rulesets/Edit/HitObjectInspector.cs new file mode 100644 index 0000000000..a6837b24f2 --- /dev/null +++ b/osu.Game/Rulesets/Edit/HitObjectInspector.cs @@ -0,0 +1,132 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +#nullable disable +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Extensions.TypeExtensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Overlays; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; +using osu.Game.Screens.Edit; + +namespace osu.Game.Rulesets.Edit +{ + internal partial class HitObjectInspector : CompositeDrawable + { + private OsuTextFlowContainer inspectorText; + + [Resolved] + protected EditorBeatmap EditorBeatmap { get; private set; } + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } + + [BackgroundDependencyLoader] + private void load() + { + InternalChild = inspectorText = new OsuTextFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + }; + } + + protected override void Update() + { + base.Update(); + updateInspectorText(); + } + + private void updateInspectorText() + { + inspectorText.Clear(); + + switch (EditorBeatmap.SelectedHitObjects.Count) + { + case 0: + addHeader("No selection"); + break; + + case 1: + var selected = EditorBeatmap.SelectedHitObjects.Single(); + + addHeader("Type"); + addValue($"{selected.GetType().ReadableName()}"); + + addHeader("Time"); + addValue($"{selected.StartTime:#,0.##}ms"); + + switch (selected) + { + case IHasPosition pos: + addHeader("Position"); + addValue($"x:{pos.X:#,0.##} y:{pos.Y:#,0.##}"); + break; + + case IHasXPosition x: + addHeader("Position"); + + addValue($"x:{x.X:#,0.##} "); + break; + + case IHasYPosition y: + addHeader("Position"); + + addValue($"y:{y.Y:#,0.##}"); + break; + } + + if (selected is IHasDistance distance) + { + addHeader("Distance"); + addValue($"{distance.Distance:#,0.##}px"); + } + + if (selected is IHasRepeats repeats) + { + addHeader("Repeats"); + addValue($"{repeats.RepeatCount:#,0.##}"); + } + + if (selected is IHasDuration duration) + { + addHeader("End Time"); + addValue($"{duration.EndTime:#,0.##}ms"); + addHeader("Duration"); + addValue($"{duration.Duration:#,0.##}ms"); + } + + break; + + default: + addHeader("Selected Objects"); + addValue($"{EditorBeatmap.SelectedHitObjects.Count:#,0.##}"); + + addHeader("Start Time"); + addValue($"{EditorBeatmap.SelectedHitObjects.Min(o => o.StartTime):#,0.##}"); + + addHeader("End Time"); + addValue($"{EditorBeatmap.SelectedHitObjects.Max(o => o.GetEndTime()):#,0.##}"); + break; + } + + void addHeader(string header) => inspectorText.AddParagraph($"{header}: ", s => + { + s.Padding = new MarginPadding { Top = 2 }; + s.Font = s.Font.With(size: 12); + s.Colour = colourProvider.Content2; + }); + + void addValue(string value) => inspectorText.AddParagraph(value, s => + { + s.Font = s.Font.With(weight: FontWeight.SemiBold); + s.Colour = colourProvider.Content1; + }); + } + } +} From f07d859532cc8906c298fddc59e187be1b3b2fd7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 4 Apr 2023 19:31:33 +0900 Subject: [PATCH 2603/2991] Optimise how often we update the display --- osu.Game/Rulesets/Edit/HitObjectInspector.cs | 24 +++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectInspector.cs b/osu.Game/Rulesets/Edit/HitObjectInspector.cs index a6837b24f2..71a3202f8d 100644 --- a/osu.Game/Rulesets/Edit/HitObjectInspector.cs +++ b/osu.Game/Rulesets/Edit/HitObjectInspector.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. -#nullable disable using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.TypeExtensions; @@ -18,17 +17,20 @@ namespace osu.Game.Rulesets.Edit { internal partial class HitObjectInspector : CompositeDrawable { - private OsuTextFlowContainer inspectorText; + private OsuTextFlowContainer inspectorText = null!; [Resolved] - protected EditorBeatmap EditorBeatmap { get; private set; } + protected EditorBeatmap EditorBeatmap { get; private set; } = null!; [Resolved] - private OverlayColourProvider colourProvider { get; set; } + private OverlayColourProvider colourProvider { get; set; } = null!; [BackgroundDependencyLoader] private void load() { + AutoSizeAxes = Axes.Y; + RelativeSizeAxes = Axes.X; + InternalChild = inspectorText = new OsuTextFlowContainer { RelativeSizeAxes = Axes.X, @@ -36,10 +38,13 @@ namespace osu.Game.Rulesets.Edit }; } - protected override void Update() + protected override void LoadComplete() { - base.Update(); - updateInspectorText(); + base.LoadComplete(); + + EditorBeatmap.SelectedHitObjects.CollectionChanged += (_, _) => updateInspectorText(); + EditorBeatmap.TransactionBegan += updateInspectorText; + EditorBeatmap.TransactionEnded += updateInspectorText; } private void updateInspectorText() @@ -49,7 +54,7 @@ namespace osu.Game.Rulesets.Edit switch (EditorBeatmap.SelectedHitObjects.Count) { case 0: - addHeader("No selection"); + addValue("No selection"); break; case 1: @@ -115,6 +120,9 @@ namespace osu.Game.Rulesets.Edit break; } + if (EditorBeatmap.TransactionActive) + Scheduler.AddDelayed(updateInspectorText, 100); + void addHeader(string header) => inspectorText.AddParagraph($"{header}: ", s => { s.Padding = new MarginPadding { Top = 2 }; From 7d9327f3e209665dd13e08020dcb053dc05671ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 4 Apr 2023 18:40:10 +0200 Subject: [PATCH 2604/2991] Only allow hit placement when left mouse is clicked --- .../Edit/Blueprints/HitPlacementBlueprint.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs index f152c98a2e..8b1a4f688c 100644 --- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/HitPlacementBlueprint.cs @@ -6,6 +6,7 @@ using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.UI; using osuTK; +using osuTK.Input; namespace osu.Game.Rulesets.Taiko.Edit.Blueprints { @@ -32,6 +33,9 @@ namespace osu.Game.Rulesets.Taiko.Edit.Blueprints protected override bool OnMouseDown(MouseDownEvent e) { + if (e.Button != MouseButton.Left) + return false; + EndPlacement(true); return true; } From 9c8b25e0348cc2b9be66c22b0d4f4b46f6b880a8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 5 Apr 2023 13:45:24 +0900 Subject: [PATCH 2605/2991] Fix display not always updating when expected by updating on a schedule --- osu.Game/Rulesets/Edit/HitObjectInspector.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectInspector.cs b/osu.Game/Rulesets/Edit/HitObjectInspector.cs index 71a3202f8d..1870476ca0 100644 --- a/osu.Game/Rulesets/Edit/HitObjectInspector.cs +++ b/osu.Game/Rulesets/Edit/HitObjectInspector.cs @@ -106,6 +106,9 @@ namespace osu.Game.Rulesets.Edit addValue($"{duration.Duration:#,0.##}ms"); } + // I'd hope there's a better way to do this, but I don't want to bind to each and every property above to watch for changes. + // This is a good middle-ground for the time being. + Scheduler.AddDelayed(updateInspectorText, 250); break; default: @@ -120,9 +123,6 @@ namespace osu.Game.Rulesets.Edit break; } - if (EditorBeatmap.TransactionActive) - Scheduler.AddDelayed(updateInspectorText, 100); - void addHeader(string header) => inspectorText.AddParagraph($"{header}: ", s => { s.Padding = new MarginPadding { Top = 2 }; From e5d57a65c9d651419e750fb4f7a9038366651ea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 5 Apr 2023 19:47:25 +0200 Subject: [PATCH 2606/2991] Fix incorrect indent --- osu.Game/Rulesets/UI/RulesetInputManager.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index 8b3d62034a..2ae54a3afe 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -166,10 +166,10 @@ namespace osu.Game.Rulesets.UI keyCounter.SetReceptor(receptor); keyCounter.AddRange(KeyBindingContainer.DefaultKeyBindings - .Select(b => b.GetAction()) - .Distinct() - .OrderBy(action => action) - .Select(action => new KeyCounterActionTrigger(action))); + .Select(b => b.GetAction()) + .Distinct() + .OrderBy(action => action) + .Select(action => new KeyCounterActionTrigger(action))); } private partial class ActionReceptor : KeyCounterDisplay.Receptor, IKeyBindingHandler From 02c6126be7807833ba9583006ae6eba54f21d68a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 5 Apr 2023 20:53:54 +0200 Subject: [PATCH 2607/2991] Ensure storyboards are enabled in existing epilepsy warning tests --- osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index 2ea27c2fef..0c7991e0ca 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -45,6 +45,9 @@ namespace osu.Game.Tests.Visual.Gameplay [Resolved] private SessionStatics sessionStatics { get; set; } + [Resolved] + private OsuConfigManager config { get; set; } + [Cached(typeof(INotificationOverlay))] private readonly NotificationOverlay notificationOverlay; @@ -317,6 +320,7 @@ namespace osu.Game.Tests.Visual.Gameplay saveVolumes(); setFullVolume(); + AddStep("enable storyboards", () => config.SetValue(OsuSetting.ShowStoryboard, true)); AddStep("change epilepsy warning", () => epilepsyWarning = warning); AddStep("load dummy beatmap", () => resetPlayer(false)); @@ -339,6 +343,7 @@ namespace osu.Game.Tests.Visual.Gameplay saveVolumes(); setFullVolume(); + AddStep("enable storyboards", () => config.SetValue(OsuSetting.ShowStoryboard, true)); AddStep("set epilepsy warning", () => epilepsyWarning = true); AddStep("load dummy beatmap", () => resetPlayer(false)); From 6df7614b9df0ed26479d147b6c193d1ea7f6a0b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 5 Apr 2023 20:56:50 +0200 Subject: [PATCH 2608/2991] Add tests for suppressing epilepsy warning when storyboard disabled --- .../Visual/Gameplay/TestScenePlayerLoader.cs | 19 ++++++++++++++++++- osu.Game/Screens/Play/PlayerLoader.cs | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index 0c7991e0ca..dbd1ce1f6e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -337,6 +337,23 @@ namespace osu.Game.Tests.Visual.Gameplay restoreVolumes(); } + [Test] + public void TestEpilepsyWarningWithDisabledStoryboard() + { + saveVolumes(); + setFullVolume(); + + AddStep("disable storyboards", () => config.SetValue(OsuSetting.ShowStoryboard, false)); + AddStep("change epilepsy warning", () => epilepsyWarning = true); + AddStep("load dummy beatmap", () => resetPlayer(false)); + + AddUntilStep("wait for current", () => loader.IsCurrentScreen()); + + AddUntilStep("epilepsy warning absent", () => getWarning() == null); + + restoreVolumes(); + } + [Test] public void TestEpilepsyWarningEarlyExit() { @@ -454,7 +471,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("click notification", () => notification.TriggerClick()); } - private EpilepsyWarning getWarning() => loader.ChildrenOfType().SingleOrDefault(); + private EpilepsyWarning getWarning() => loader.ChildrenOfType().SingleOrDefault(w => w.IsAlive); private partial class TestPlayerLoader : PlayerLoader { diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index be4229ade9..30ae5ee5aa 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -489,6 +489,7 @@ namespace osu.Game.Screens.Play { // This goes hand-in-hand with the restoration of low pass filter in contentOut(). this.TransformBindableTo(volumeAdjustment, 0, CONTENT_OUT_DURATION, Easing.OutCubic); + epilepsyWarning?.Expire(); } pushSequence.Schedule(() => From ed565b1e5905c47e3ab512c50f1894626999289c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 6 Apr 2023 11:40:04 +0300 Subject: [PATCH 2609/2991] Fix SampleStore isn't being disposed --- osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs index 1d5fcc634e..76d84000f1 100644 --- a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs +++ b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs @@ -98,7 +98,7 @@ namespace osu.Game.Rulesets.UI isDisposed = true; - if (ShaderManager.IsNotNull()) SampleStore.Dispose(); + if (SampleStore.IsNotNull()) SampleStore.Dispose(); if (TextureStore.IsNotNull()) TextureStore.Dispose(); if (ShaderManager.IsNotNull()) ShaderManager.Dispose(); } From ad717d2368270b7cb04f7d4d3b70c2cc5d860fea Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Apr 2023 23:39:36 +0900 Subject: [PATCH 2610/2991] Fix scheduled calls piling up during transactions --- osu.Game/Rulesets/Edit/HitObjectInspector.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectInspector.cs b/osu.Game/Rulesets/Edit/HitObjectInspector.cs index 1870476ca0..02270d4662 100644 --- a/osu.Game/Rulesets/Edit/HitObjectInspector.cs +++ b/osu.Game/Rulesets/Edit/HitObjectInspector.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.TypeExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Threading; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Overlays; @@ -47,9 +48,13 @@ namespace osu.Game.Rulesets.Edit EditorBeatmap.TransactionEnded += updateInspectorText; } + private ScheduledDelegate? rollingTextUpdate; + private void updateInspectorText() { inspectorText.Clear(); + rollingTextUpdate?.Cancel(); + rollingTextUpdate = null; switch (EditorBeatmap.SelectedHitObjects.Count) { @@ -108,7 +113,7 @@ namespace osu.Game.Rulesets.Edit // I'd hope there's a better way to do this, but I don't want to bind to each and every property above to watch for changes. // This is a good middle-ground for the time being. - Scheduler.AddDelayed(updateInspectorText, 250); + rollingTextUpdate ??= Scheduler.AddDelayed(updateInspectorText, 250); break; default: From f1de560d5717ad17588640f5745c7e801f7dfd72 Mon Sep 17 00:00:00 2001 From: Micha Lehmann Date: Sat, 8 Apr 2023 00:50:31 +0200 Subject: [PATCH 2611/2991] Snap editor selection rotation when holding shift --- .../Components/SelectionBoxRotationHandle.cs | 62 ++++++++++++++++--- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs index 0f702e1c49..04eaf6c491 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs @@ -16,6 +16,8 @@ using osu.Framework.Localisation; using osuTK; using osuTK.Graphics; +using Key = osuTK.Input.Key; + namespace osu.Game.Screens.Edit.Compose.Components { public partial class SelectionBoxRotationHandle : SelectionBoxDragHandle, IHasTooltip @@ -26,6 +28,8 @@ namespace osu.Game.Screens.Edit.Compose.Components private SpriteIcon icon; + private const float snapStep = 15; + private float rawCumulativeRotation = 0; private readonly Bindable cumulativeRotation = new Bindable(); [Resolved] @@ -74,21 +78,38 @@ namespace osu.Game.Screens.Edit.Compose.Components { base.OnDrag(e); - float instantaneousAngle = convertDragEventToAngleOfRotation(e); - cumulativeRotation.Value += instantaneousAngle; + rawCumulativeRotation += convertDragEventToAngleOfRotation(e); - if (cumulativeRotation.Value < -180) - cumulativeRotation.Value += 360; - else if (cumulativeRotation.Value > 180) - cumulativeRotation.Value -= 360; + applyRotation(shouldSnap: e.ShiftPressed); + } - HandleRotate?.Invoke(instantaneousAngle); + protected override bool OnKeyDown(KeyDownEvent e) + { + base.OnKeyDown(e); + + if (cumulativeRotation.Value != null && (e.Key == Key.ShiftLeft || e.Key == Key.ShiftRight)) + { + applyRotation(shouldSnap: true); + } + + return true; + } + + protected override void OnKeyUp(KeyUpEvent e) + { + base.OnKeyUp(e); + + if (cumulativeRotation.Value != null && (e.Key == Key.ShiftLeft || e.Key == Key.ShiftRight)) + { + applyRotation(shouldSnap: false); + } } protected override void OnDragEnd(DragEndEvent e) { base.OnDragEnd(e); cumulativeRotation.Value = null; + rawCumulativeRotation = 0; } private float convertDragEventToAngleOfRotation(DragEvent e) @@ -100,6 +121,33 @@ namespace osu.Game.Screens.Edit.Compose.Components return (endAngle - startAngle) * 180 / MathF.PI; } + private void applyRotation(bool shouldSnap) + { + float oldRotation = cumulativeRotation.Value ?? 0; + + if (shouldSnap) + { + cumulativeRotation.Value = snap(rawCumulativeRotation, snapStep); + } + else + { + cumulativeRotation.Value = rawCumulativeRotation; + } + + if (cumulativeRotation.Value < -180) + cumulativeRotation.Value += 360; + else if (cumulativeRotation.Value > 180) + cumulativeRotation.Value -= 360; + + HandleRotate?.Invoke((float)cumulativeRotation.Value - oldRotation); + } + + private float snap(float value, float step) + { + float floor = MathF.Floor(value / step) * step; + return value - floor < step / 2f ? floor : floor + step; + } + private void updateTooltipText() { TooltipText = cumulativeRotation.Value?.ToLocalisableString("0.0°") ?? default; From c827c2810b99cae4a725023f69e85652dbd8fde3 Mon Sep 17 00:00:00 2001 From: Micha Lehmann Date: Sat, 8 Apr 2023 01:28:28 +0200 Subject: [PATCH 2612/2991] Improve editor selection rotation value wrapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes two issues the previous algorithm had: 1. A half-turn rotation used to show up as -180°. 2. Rotating more than 180° in one drag event would overwhelm it and cause the value to go outside its range. This comes at the cost of a negligible performance hit, since a division (modulo) is performed instead of just addition/subtraction. --- .../Edit/Compose/Components/SelectionBoxRotationHandle.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs index 04eaf6c491..4990a522f8 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs @@ -134,10 +134,7 @@ namespace osu.Game.Screens.Edit.Compose.Components cumulativeRotation.Value = rawCumulativeRotation; } - if (cumulativeRotation.Value < -180) - cumulativeRotation.Value += 360; - else if (cumulativeRotation.Value > 180) - cumulativeRotation.Value -= 360; + cumulativeRotation.Value = (cumulativeRotation.Value - 180) % 360 + 180; HandleRotate?.Invoke((float)cumulativeRotation.Value - oldRotation); } From f72dd86b4251123400048ed2b9474ba69d25ef57 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 8 Apr 2023 10:40:36 +0900 Subject: [PATCH 2613/2991] Fix code quality issues and avoid updating bindable twice per operation --- .../Components/SelectionBoxRotationHandle.cs | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs index 4990a522f8..5a1587eea6 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs @@ -15,7 +15,6 @@ using osu.Framework.Input.Events; using osu.Framework.Localisation; using osuTK; using osuTK.Graphics; - using Key = osuTK.Input.Key; namespace osu.Game.Screens.Edit.Compose.Components @@ -28,8 +27,8 @@ namespace osu.Game.Screens.Edit.Compose.Components private SpriteIcon icon; - private const float snapStep = 15; - private float rawCumulativeRotation = 0; + private const float snap_step = 15; + private readonly Bindable cumulativeRotation = new Bindable(); [Resolved] @@ -66,6 +65,8 @@ namespace osu.Game.Screens.Edit.Compose.Components icon.FadeColour(!IsHeld && IsHovered ? Color4.White : Color4.Black, TRANSFORM_DURATION, Easing.OutQuint); } + private float rawCumulativeRotation; + protected override bool OnDragStart(DragStartEvent e) { bool handle = base.OnDragStart(e); @@ -125,17 +126,10 @@ namespace osu.Game.Screens.Edit.Compose.Components { float oldRotation = cumulativeRotation.Value ?? 0; - if (shouldSnap) - { - cumulativeRotation.Value = snap(rawCumulativeRotation, snapStep); - } - else - { - cumulativeRotation.Value = rawCumulativeRotation; - } - - cumulativeRotation.Value = (cumulativeRotation.Value - 180) % 360 + 180; + float newRotation = shouldSnap ? snap(rawCumulativeRotation, snap_step) : rawCumulativeRotation; + newRotation = (newRotation - 180) % 360 + 180; + cumulativeRotation.Value = newRotation; HandleRotate?.Invoke((float)cumulativeRotation.Value - oldRotation); } From ed208ef12739ff03fa18fefc15036a7594601739 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Fri, 7 Apr 2023 21:10:37 -0700 Subject: [PATCH 2614/2991] Fix more typos and adjust font size to match web --- osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs | 6 +++--- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 9e46738305..4838f42043 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -286,16 +286,16 @@ namespace osu.Game.Tests.Visual.Online public void TestBeatmapSetWithGuestDIff() { AddStep("show map", () => overlay.ShowBeatmapSet(createBeatmapSetWithGuestDiff())); - AddStep("Move mouse to host diff", () => + AddStep("move mouse to host diff", () => { InputManager.MoveMouseTo(overlay.ChildrenOfType().ElementAt(0)); }); - AddAssert("Guset mapper information not show", () => overlay.ChildrenOfType().Single().ChildrenOfType().All(s => s.Text != "BanchoBot")); + AddAssert("guest mapper information not shown", () => overlay.ChildrenOfType().Single().ChildrenOfType().All(s => s.Text != "BanchoBot")); AddStep("move mouse to guest diff", () => { InputManager.MoveMouseTo(overlay.ChildrenOfType().ElementAt(1)); }); - AddAssert("Guset mapper information show", () => overlay.ChildrenOfType().Single().ChildrenOfType().Any(s => s.Text == "BanchoBot")); + AddAssert("guest mapper information shown", () => overlay.ChildrenOfType().Single().ChildrenOfType().Any(s => s.Text == "BanchoBot")); } private APIBeatmapSet createManyDifficultiesBeatmapSet() diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 63bb122cb6..d527d4cc9a 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -90,11 +90,12 @@ namespace osu.Game.Overlays.BeatmapSet Font = OsuFont.GetFont(size: 17, weight: FontWeight.Bold) }, guestMapperContainer = new LinkFlowContainer(s => - s.Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 15)) + s.Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 11)) { AutoSizeAxes = Axes.Both, Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, + Margin = new MarginPadding { Bottom = 1 }, }, starRatingContainer = new FillFlowContainer { From a86a968faca0168128a0ddb432e8dfd590e93c17 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Fri, 7 Apr 2023 21:16:36 -0700 Subject: [PATCH 2615/2991] Use public `BeatmapSet` to match other usages --- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index d527d4cc9a..27e671ded0 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -211,7 +211,7 @@ namespace osu.Game.Overlays.BeatmapSet { guestMapperContainer.Clear(); - if (beatmapInfo?.AuthorID != beatmapSet?.AuthorID) + if (beatmapInfo?.AuthorID != BeatmapSet?.AuthorID) { APIUser? user = BeatmapSet?.RelatedUsers?.SingleOrDefault(u => u.OnlineID == beatmapInfo?.AuthorID); if (user != null) From 580d5745c0197dbd73c3103ba78b7485ea19fcd6 Mon Sep 17 00:00:00 2001 From: Micha Lehmann Date: Sat, 8 Apr 2023 14:15:49 +0200 Subject: [PATCH 2616/2991] Add "(snapped)" to the tooltip when snap-rotating in the editor --- osu.Game/Localisation/EditorStrings.cs | 10 ++++++++++ .../Compose/Components/SelectionBoxRotationHandle.cs | 12 +++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/osu.Game/Localisation/EditorStrings.cs b/osu.Game/Localisation/EditorStrings.cs index f4e23ae7cb..beddcfd44e 100644 --- a/osu.Game/Localisation/EditorStrings.cs +++ b/osu.Game/Localisation/EditorStrings.cs @@ -99,6 +99,16 @@ namespace osu.Game.Localisation /// public static LocalisableString TimelineTicks => new TranslatableString(getKey(@"timeline_ticks"), @"Ticks"); + /// + /// "0.0°" + /// + public static LocalisableString RotationFormatUnsnapped => new TranslatableString(getKey(@"rotation_format_unsnapped"), @"0.0°"); + + /// + /// "0.0° (snapped)" + /// + public static LocalisableString RotationFormatSnapped => new TranslatableString(getKey(@"rotation_format_snapped"), @"0.0° (snapped)"); + private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs index 5a1587eea6..8d0e20e4ac 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs @@ -13,6 +13,7 @@ using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Framework.Localisation; +using osu.Game.Localisation; using osuTK; using osuTK.Graphics; using Key = osuTK.Input.Key; @@ -56,7 +57,6 @@ namespace osu.Game.Screens.Edit.Compose.Components protected override void LoadComplete() { base.LoadComplete(); - cumulativeRotation.BindValueChanged(_ => updateTooltipText(), true); } protected override void UpdateHoverState() @@ -130,7 +130,10 @@ namespace osu.Game.Screens.Edit.Compose.Components newRotation = (newRotation - 180) % 360 + 180; cumulativeRotation.Value = newRotation; - HandleRotate?.Invoke((float)cumulativeRotation.Value - oldRotation); + + HandleRotate?.Invoke(newRotation - oldRotation); + string tooltipFormat = shouldSnap ? EditorStrings.RotationFormatSnapped.ToString() : EditorStrings.RotationFormatUnsnapped.ToString(); + TooltipText = newRotation.ToLocalisableString(tooltipFormat); } private float snap(float value, float step) @@ -138,10 +141,5 @@ namespace osu.Game.Screens.Edit.Compose.Components float floor = MathF.Floor(value / step) * step; return value - floor < step / 2f ? floor : floor + step; } - - private void updateTooltipText() - { - TooltipText = cumulativeRotation.Value?.ToLocalisableString("0.0°") ?? default; - } } } From 3c4a25e53f3459aa6ef3e1a9182769b02dd3b966 Mon Sep 17 00:00:00 2001 From: Micha Lehmann Date: Sat, 8 Apr 2023 14:28:52 +0200 Subject: [PATCH 2617/2991] Fix tooltip text not resetting when ending an editor rotation --- .../Edit/Compose/Components/SelectionBoxRotationHandle.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs index 8d0e20e4ac..09898f1f2f 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs @@ -111,6 +111,7 @@ namespace osu.Game.Screens.Edit.Compose.Components base.OnDragEnd(e); cumulativeRotation.Value = null; rawCumulativeRotation = 0; + TooltipText = default; } private float convertDragEventToAngleOfRotation(DragEvent e) From a1fc4def1dca5791a6cbe0dd44a3badb244718f6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 8 Apr 2023 22:18:07 +0900 Subject: [PATCH 2618/2991] Remove redundant method override --- .../Edit/Compose/Components/SelectionBoxRotationHandle.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs index 09898f1f2f..fb86cb4a01 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs @@ -54,11 +54,6 @@ namespace osu.Game.Screens.Edit.Compose.Components }); } - protected override void LoadComplete() - { - base.LoadComplete(); - } - protected override void UpdateHoverState() { base.UpdateHoverState(); From 8d2e852ffd2bf8b8d76b4b4132ce3b4aa067e468 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 8 Apr 2023 22:18:29 +0900 Subject: [PATCH 2619/2991] Fix overbearing key down handling --- .../Compose/Components/SelectionBoxRotationHandle.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs index fb86cb4a01..73da837d03 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs @@ -81,24 +81,21 @@ namespace osu.Game.Screens.Edit.Compose.Components protected override bool OnKeyDown(KeyDownEvent e) { - base.OnKeyDown(e); - - if (cumulativeRotation.Value != null && (e.Key == Key.ShiftLeft || e.Key == Key.ShiftRight)) + if (IsDragged && (e.Key == Key.ShiftLeft || e.Key == Key.ShiftRight)) { applyRotation(shouldSnap: true); + return true; } - return true; + return base.OnKeyDown(e); } protected override void OnKeyUp(KeyUpEvent e) { base.OnKeyUp(e); - if (cumulativeRotation.Value != null && (e.Key == Key.ShiftLeft || e.Key == Key.ShiftRight)) - { + if (IsDragged && (e.Key == Key.ShiftLeft || e.Key == Key.ShiftRight)) applyRotation(shouldSnap: false); - } } protected override void OnDragEnd(DragEndEvent e) From 13b522e825b6f1b2f1d7e843bd8fa2421f41d482 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 9 Apr 2023 21:54:26 +0900 Subject: [PATCH 2620/2991] repair usage of CancellationToken Co-Authored-By: n0099 --- osu.Game/Database/LegacyModelExporter.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 6f2fe90957..e8fc25ab84 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -60,7 +60,7 @@ namespace osu.Game.Database /// If specified CancellationToken, then use it. Otherwise use PostNotification's CancellationToken. /// /// - public async Task ExportAsync(TModel model, CancellationToken? cancellationToken = null) + public async Task ExportAsync(TModel model, CancellationToken cancellationToken = default) { // check if the model is being exporting already if (!exporting_models.Contains(model)) @@ -93,7 +93,8 @@ namespace osu.Game.Database { using (var stream = exportStorage.CreateFileSafely(filename)) { - success = await ExportToStreamAsync(model, stream, notification, cancellationToken ?? notification.CancellationToken).ConfigureAwait(false); + success = await ExportToStreamAsync(model, stream, notification, + cancellationToken == CancellationToken.None ? notification.CancellationToken : cancellationToken).ConfigureAwait(false); } } catch (OperationCanceledException) From 1f4da35c8d75e77d3eadca6bbf7624cf2b63331c Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 9 Apr 2023 22:11:52 +0900 Subject: [PATCH 2621/2991] notification nullable fix --- osu.Game/Database/LegacyArchiveExporter.cs | 12 ++++++++---- osu.Game/Database/LegacyModelExporter.cs | 9 +++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/osu.Game/Database/LegacyArchiveExporter.cs b/osu.Game/Database/LegacyArchiveExporter.cs index 1af8c454c1..35f09189c9 100644 --- a/osu.Game/Database/LegacyArchiveExporter.cs +++ b/osu.Game/Database/LegacyArchiveExporter.cs @@ -25,7 +25,7 @@ namespace osu.Game.Database { } - protected override void ExportToStream(TModel model, Stream outputStream, ProgressNotification notification, CancellationToken cancellationToken = default) + protected override void ExportToStream(TModel model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default) => exportZipArchive(model, outputStream, notification, cancellationToken); /// @@ -35,7 +35,7 @@ namespace osu.Game.Database /// The output stream to export to. /// The notification will displayed to the user /// The Cancellation token that can cancel the exporting. - private void exportZipArchive(TModel model, Stream outputStream, ProgressNotification notification, CancellationToken cancellationToken = default) + private void exportZipArchive(TModel model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default) { try { @@ -67,8 +67,12 @@ namespace osu.Game.Database } i++; - notification.Progress = i / model.Files.Count(); - notification.Text = $"Exporting... ({i}/{model.Files.Count()})"; + + if (notification != null) + { + notification.Progress = i / model.Files.Count(); + notification.Text = $"Exporting... ({i}/{model.Files.Count()})"; + } } } catch (ObjectDisposedException) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index e8fc25ab84..0f09c2c19b 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -105,6 +105,7 @@ namespace osu.Game.Database // cleanup if export is failed or canceled. if (!success) { + notification.State = ProgressNotificationState.Cancelled; exportStorage.Delete(filename); } else @@ -129,27 +130,23 @@ namespace osu.Game.Database /// Whether the export was successful public Task ExportToStreamAsync(TModel model, Stream stream, ProgressNotification? notification = null, CancellationToken cancellationToken = default) { - ProgressNotification notify = notification ?? new ProgressNotification(); - Guid id = model.ID; return Task.Run(() => { realmAccess.Run(r => { TModel refetchModel = r.Find(id); - ExportToStream(refetchModel, stream, notify, cancellationToken); + ExportToStream(refetchModel, stream, notification, cancellationToken); }); }, cancellationToken).ContinueWith(t => { if (cancellationToken.IsCancellationRequested) { - notify.State = ProgressNotificationState.Cancelled; return false; } if (t.IsFaulted) { - notify.State = ProgressNotificationState.Cancelled; Logger.Error(t.Exception, "An error occurred while exporting", LoggingTarget.Database); return false; } @@ -165,6 +162,6 @@ namespace osu.Game.Database /// The output stream to export to. /// The notification will displayed to the user /// The Cancellation token that can cancel the exporting. - protected abstract void ExportToStream(TModel model, Stream outputStream, ProgressNotification notification, CancellationToken cancellationToken = default); + protected abstract void ExportToStream(TModel model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default); } } From de21b4a2f73dfd6ee9278148b88b1f8ab92ca5af Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 9 Apr 2023 22:15:00 +0900 Subject: [PATCH 2622/2991] use Live Use RealmAccess only when needed --- osu.Game.Tests/Skins/IO/ImportSkinTest.cs | 9 ++--- osu.Game/Beatmaps/BeatmapManager.cs | 4 +-- osu.Game/Database/LegacyArchiveExporter.cs | 4 +-- osu.Game/Database/LegacyBeatmapExporter.cs | 4 +-- osu.Game/Database/LegacyModelExporter.cs | 36 ++++++++++++------- osu.Game/Database/LegacyScoreExporter.cs | 5 ++- osu.Game/Database/LegacySkinExporter.cs | 3 +- .../Overlays/Settings/Sections/SkinSection.cs | 2 +- osu.Game/Scoring/ScoreManager.cs | 4 +-- osu.Game/Skinning/SkinManager.cs | 6 ++-- 10 files changed, 42 insertions(+), 35 deletions(-) diff --git a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs index 726ff74d7f..8043c01d2d 100644 --- a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs +++ b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs @@ -119,10 +119,7 @@ namespace osu.Game.Tests.Skins.IO var import1 = await loadSkinIntoOsu(osu, new ImportTask(createOskWithIni("name 1", "author 1"), "custom.osk")); assertCorrectMetadata(import1, "name 1 [custom]", "author 1", osu); - await import1.PerformRead(async s => - { - await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get()).ExportToStreamAsync(s, exportStream); - }); + await new LegacySkinExporter(osu.Dependencies.Get()).ExportToStreamAsync(import1, exportStream); string exportFilename = import1.GetDisplayString(); @@ -203,7 +200,7 @@ namespace osu.Game.Tests.Skins.IO Assert.IsFalse(s.Protected); Assert.AreEqual(typeof(ArgonSkin), s.CreateInstance(skinManager).GetType()); - await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get()).ExportToStreamAsync(s, exportStream); + await new LegacySkinExporter(osu.Dependencies.Get()).ExportToStreamAsync(skinManager.CurrentSkinInfo.Value, exportStream); Assert.Greater(exportStream.Length, 0); }); @@ -236,7 +233,7 @@ namespace osu.Game.Tests.Skins.IO Assert.IsFalse(s.Protected); Assert.AreEqual(typeof(DefaultLegacySkin), s.CreateInstance(skinManager).GetType()); - await new LegacySkinExporter(osu.Dependencies.Get(), osu.Dependencies.Get()).ExportToStreamAsync(s, exportStream); + await new LegacySkinExporter(osu.Dependencies.Get()).ExportToStreamAsync(skinManager.CurrentSkinInfo.Value, exportStream); Assert.Greater(exportStream.Length, 0); }); diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index d3bf8081b1..877a0c7667 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -79,7 +79,7 @@ namespace osu.Game.Beatmaps workingBeatmapCache = CreateWorkingBeatmapCache(audioManager, gameResources, userResources, defaultBeatmap, host); - beatmapExporter = new LegacyBeatmapExporter(storage, realm) + beatmapExporter = new LegacyBeatmapExporter(storage) { PostNotification = obj => PostNotification?.Invoke(obj) }; @@ -400,7 +400,7 @@ namespace osu.Game.Beatmaps public Task?> ImportAsUpdate(ProgressNotification notification, ImportTask importTask, BeatmapSetInfo original) => beatmapImporter.ImportAsUpdate(notification, importTask, original); - public Task Export(BeatmapSetInfo beatmap) => beatmapExporter.ExportAsync(beatmap); + public Task Export(BeatmapSetInfo beatmap) => beatmapExporter.ExportAsync(beatmap, Realm); private void updateHashAndMarkDirty(BeatmapSetInfo setInfo) { diff --git a/osu.Game/Database/LegacyArchiveExporter.cs b/osu.Game/Database/LegacyArchiveExporter.cs index 35f09189c9..297139a20e 100644 --- a/osu.Game/Database/LegacyArchiveExporter.cs +++ b/osu.Game/Database/LegacyArchiveExporter.cs @@ -20,8 +20,8 @@ namespace osu.Game.Database public abstract class LegacyArchiveExporter : LegacyModelExporter where TModel : RealmObject, IHasNamedFiles, IHasGuidPrimaryKey { - protected LegacyArchiveExporter(Storage storage, RealmAccess realm) - : base(storage, realm) + protected LegacyArchiveExporter(Storage storage) + : base(storage) { } diff --git a/osu.Game/Database/LegacyBeatmapExporter.cs b/osu.Game/Database/LegacyBeatmapExporter.cs index 107b91a234..e89d3da8c7 100644 --- a/osu.Game/Database/LegacyBeatmapExporter.cs +++ b/osu.Game/Database/LegacyBeatmapExporter.cs @@ -8,8 +8,8 @@ namespace osu.Game.Database { public class LegacyBeatmapExporter : LegacyArchiveExporter { - public LegacyBeatmapExporter(Storage storage, RealmAccess realm) - : base(storage, realm) + public LegacyBeatmapExporter(Storage storage) + : base(storage) { } diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 0f09c2c19b..58606cb5fa 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -31,24 +31,35 @@ namespace osu.Game.Database private readonly Storage exportStorage; protected virtual string GetFilename(TModel item) => item.GetDisplayString(); - private readonly RealmAccess realmAccess; - public Action? PostNotification { get; set; } // Store the model being exporting. - private static readonly List exporting_models = new List(); + private static readonly List> exporting_models = new List>(); /// /// Construct exporter. /// Create a new exporter for each export, otherwise it will cause confusing notifications. /// /// Storage for storing exported files. Basically it is used to provide export stream - /// The RealmAccess used to provide the exported file. - protected LegacyModelExporter(Storage storage, RealmAccess realm) + protected LegacyModelExporter(Storage storage) { exportStorage = storage.GetStorageForDirectory(@"exports"); UserFileStorage = storage.GetStorageForDirectory(@"files"); - realmAccess = realm; + } + + /// + /// Export the model to default folder. + /// + /// The model should export. + /// Realm that convert model to Live. + /// + /// The Cancellation token that can cancel the exporting. + /// If specified CancellationToken, then use it. Otherwise use PostNotification's CancellationToken. + /// + /// + public Task ExportAsync(TModel model, RealmAccess realm, CancellationToken cancellationToken = default) + { + return ExportAsync(model.ToLive(realm), cancellationToken); } /// @@ -60,7 +71,7 @@ namespace osu.Game.Database /// If specified CancellationToken, then use it. Otherwise use PostNotification's CancellationToken. /// /// - public async Task ExportAsync(TModel model, CancellationToken cancellationToken = default) + public async Task ExportAsync(Live model, CancellationToken cancellationToken = default) { // check if the model is being exporting already if (!exporting_models.Contains(model)) @@ -73,7 +84,8 @@ namespace osu.Game.Database return false; } - string itemFilename = GetFilename(model).GetValidFilename(); + string itemFilename = model.PerformRead(s => GetFilename(s).GetValidFilename()); + IEnumerable existingExports = exportStorage .GetFiles(string.Empty, $"{itemFilename}*{FileExtension}") @@ -128,15 +140,13 @@ namespace osu.Game.Database /// The notification will displayed to the user /// The Cancellation token that can cancel the exporting. /// Whether the export was successful - public Task ExportToStreamAsync(TModel model, Stream stream, ProgressNotification? notification = null, CancellationToken cancellationToken = default) + public Task ExportToStreamAsync(Live model, Stream stream, ProgressNotification? notification = null, CancellationToken cancellationToken = default) { - Guid id = model.ID; return Task.Run(() => { - realmAccess.Run(r => + model.PerformRead(s => { - TModel refetchModel = r.Find(id); - ExportToStream(refetchModel, stream, notification, cancellationToken); + ExportToStream(s, stream, notification, cancellationToken); }); }, cancellationToken).ContinueWith(t => { diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index ef55ffdd96..bd7d273a64 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -13,8 +13,7 @@ namespace osu.Game.Database { public class LegacyScoreExporter : LegacyModelExporter { - public LegacyScoreExporter(Storage storage, RealmAccess realm) - : base(storage, realm) + public LegacyScoreExporter(Storage storage) : base(storage) { } @@ -28,7 +27,7 @@ namespace osu.Game.Database protected override string FileExtension => ".osr"; - protected override void ExportToStream(ScoreInfo model, Stream stream, ProgressNotification notification, CancellationToken cancellationToken = default) + protected override void ExportToStream(ScoreInfo model, Stream stream, ProgressNotification? notification, CancellationToken cancellationToken = default) { var file = model.Files.SingleOrDefault(); if (file == null) diff --git a/osu.Game/Database/LegacySkinExporter.cs b/osu.Game/Database/LegacySkinExporter.cs index d3e6a2f0f4..2a531203bc 100644 --- a/osu.Game/Database/LegacySkinExporter.cs +++ b/osu.Game/Database/LegacySkinExporter.cs @@ -8,8 +8,7 @@ namespace osu.Game.Database { public class LegacySkinExporter : LegacyArchiveExporter { - public LegacySkinExporter(Storage storage, RealmAccess realm) - : base(storage, realm) + public LegacySkinExporter(Storage storage) : base(storage) { } diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index df5d7e0c27..5382eac675 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -159,7 +159,7 @@ namespace osu.Game.Overlays.Settings.Sections { try { - skins.CurrentSkinInfo.Value.PerformRead(s => skins.ExportSkin(s)); + skins.ExportCurrentSkin(); } catch (Exception e) { diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index 3201fec696..5e432b6a96 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -50,7 +50,7 @@ namespace osu.Game.Scoring PostNotification = obj => PostNotification?.Invoke(obj) }; - scoreExporter = new LegacyScoreExporter(storage, realm) + scoreExporter = new LegacyScoreExporter(storage) { PostNotification = obj => PostNotification?.Invoke(obj) }; @@ -193,7 +193,7 @@ namespace osu.Game.Scoring public Task>> Import(ProgressNotification notification, ImportTask[] tasks, ImportParameters parameters = default) => scoreImporter.Import(notification, tasks); - public Task Export(ScoreInfo score) => scoreExporter.ExportAsync(score); + public Task Export(ScoreInfo score) => scoreExporter.ExportAsync(score, Realm); public Task> ImportAsUpdate(ProgressNotification notification, ImportTask task, ScoreInfo original) => scoreImporter.ImportAsUpdate(notification, task, original); diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index 1a76ec8623..45536e04eb 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -123,7 +123,7 @@ namespace osu.Game.Skinning SourceChanged?.Invoke(); }; - skinExporter = new LegacySkinExporter(storage, realm) + skinExporter = new LegacySkinExporter(storage) { PostNotification = obj => PostNotification?.Invoke(obj) }; @@ -305,7 +305,9 @@ namespace osu.Game.Skinning public Task> Import(ImportTask task, ImportParameters parameters = default, CancellationToken cancellationToken = default) => skinImporter.Import(task, parameters, cancellationToken); - public Task ExportSkin(SkinInfo skin) => skinExporter.ExportAsync(skin); + public Task ExportCurrentSkin() => ExportSkin(CurrentSkinInfo.Value); + + public Task ExportSkin(Live skin) => skinExporter.ExportAsync(skin); #endregion From 49193a2bdd950aab1a0d4183ce75b47e97050512 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 9 Apr 2023 22:25:47 +0900 Subject: [PATCH 2623/2991] CompletionText Co-Authored-By: Dean Herbert --- osu.Game/Database/LegacyModelExporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 58606cb5fa..a61d9fd582 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -122,7 +122,7 @@ namespace osu.Game.Database } else { - notification.CompletionText = "Export Complete, Click to open the folder"; + notification.CompletionText = $"Exported {itemFilename}! Click to view."; notification.CompletionClickAction = () => exportStorage.PresentFileExternally(filename); notification.State = ProgressNotificationState.Completed; } From fc55b96e776401b8b35737a49ba07ff309a0eef6 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 9 Apr 2023 14:27:42 +0900 Subject: [PATCH 2624/2991] remove `CompletionText` in Constructor this will never used Co-Authored-By: Dean Herbert --- osu.Game/Database/LegacyModelExporter.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index a61d9fd582..975809b9a7 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -97,7 +97,6 @@ namespace osu.Game.Database { State = ProgressNotificationState.Active, Text = "Exporting...", - CompletionText = "Export completed" }; PostNotification?.Invoke(notification); From 5d64c1b7bfd7fd5ce51a2df503735a4f794b9517 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 9 Apr 2023 15:09:18 +0900 Subject: [PATCH 2625/2991] exception handling --- osu.Game/Database/LegacyModelExporter.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 1c5d6b4813..7904be7f4f 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -124,8 +124,15 @@ namespace osu.Game.Database cancellationToken == CancellationToken.None ? notification.CancellationToken : cancellationToken).ConfigureAwait(false); } } - catch (OperationCanceledException) + catch { + notification.State = ProgressNotificationState.Cancelled; + throw; + } + finally + { + // Determines whether to export repeatedly, so he must be removed from the list at the end whether there is a error. + exporting_models.Remove(model); } // cleanup if export is failed or canceled. @@ -141,7 +148,6 @@ namespace osu.Game.Database notification.State = ProgressNotificationState.Completed; } - exporting_models.Remove(model); return success; } @@ -171,7 +177,7 @@ namespace osu.Game.Database if (t.IsFaulted) { Logger.Error(t.Exception, "An error occurred while exporting", LoggingTarget.Database); - return false; + throw t.Exception!; } return true; From 52fc6de13f0be2f624e1a26be301f3f4e0c6c39e Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 9 Apr 2023 15:12:15 +0900 Subject: [PATCH 2626/2991] merge fix wtf? --- osu.Game.Tests/Database/LegacyExporterTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Database/LegacyExporterTest.cs b/osu.Game.Tests/Database/LegacyExporterTest.cs index d41b3a5017..2f92ec1a4c 100644 --- a/osu.Game.Tests/Database/LegacyExporterTest.cs +++ b/osu.Game.Tests/Database/LegacyExporterTest.cs @@ -110,9 +110,9 @@ namespace osu.Game.Tests.Database public override string ToString() => Filename; } - private class TestLegacyExporter : LegacyExporter + private class TestLegacyModelExporter : LegacyModelExporter { - public TestLegacyExporter(Storage storage) + public TestLegacyModelExporter(Storage storage) : base(storage) { } From def6da98fc8760c63efe8208241eea0c25dfd880 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 9 Apr 2023 15:40:40 +0900 Subject: [PATCH 2627/2991] fix test in #22653 --- osu.Game.Tests/Database/LegacyExporterTest.cs | 96 +++++++++++++------ 1 file changed, 66 insertions(+), 30 deletions(-) diff --git a/osu.Game.Tests/Database/LegacyExporterTest.cs b/osu.Game.Tests/Database/LegacyExporterTest.cs index 2f92ec1a4c..c25e14d2ef 100644 --- a/osu.Game.Tests/Database/LegacyExporterTest.cs +++ b/osu.Game.Tests/Database/LegacyExporterTest.cs @@ -1,19 +1,26 @@ // 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.IO; +using System.Threading; +using System.Threading.Tasks; using NUnit.Framework; +using osu.Framework.Extensions; using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Platform; using osu.Framework.Testing; using osu.Game.Database; +using osu.Game.Overlays.Notifications; +using Realms; namespace osu.Game.Tests.Database { [TestFixture] - public class LegacyExporterTest + public class LegacyModelExporterTest { - private TestLegacyExporter legacyExporter = null!; + private TestLegacyModelExporter legacyExporter = null!; private TemporaryNativeStorage storage = null!; private const string short_filename = "normal file name"; @@ -25,15 +32,15 @@ namespace osu.Game.Tests.Database public void SetUp() { storage = new TemporaryNativeStorage("export-storage"); - legacyExporter = new TestLegacyExporter(storage); + legacyExporter = new TestLegacyModelExporter(storage); } [Test] public void ExportFileWithNormalNameTest() { - var item = new TestPathInfo(short_filename); + var item = new TestRealmObject(short_filename); - Assert.That(item.Filename.Length, Is.LessThan(TestLegacyExporter.MAX_FILENAME_LENGTH)); + Assert.That(item.Filename.Length, Is.LessThan(TestLegacyModelExporter.MAX_FILENAME_LENGTH)); exportItemAndAssert(item, short_filename); } @@ -41,9 +48,9 @@ namespace osu.Game.Tests.Database [Test] public void ExportFileWithNormalNameMultipleTimesTest() { - var item = new TestPathInfo(short_filename); + var item = new TestRealmObject(short_filename); - Assert.That(item.Filename.Length, Is.LessThan(TestLegacyExporter.MAX_FILENAME_LENGTH)); + Assert.That(item.Filename.Length, Is.LessThan(TestLegacyModelExporter.MAX_FILENAME_LENGTH)); //Export multiple times for (int i = 0; i < 100; i++) @@ -56,24 +63,24 @@ namespace osu.Game.Tests.Database [Test] public void ExportFileWithSuperLongNameTest() { - int expectedLength = TestLegacyExporter.MAX_FILENAME_LENGTH - (legacyExporter.GetExtension().Length); + int expectedLength = TestLegacyModelExporter.MAX_FILENAME_LENGTH - (legacyExporter.GetExtension().Length); string expectedName = long_filename.Remove(expectedLength); - var item = new TestPathInfo(long_filename); + var item = new TestRealmObject(long_filename); - Assert.That(item.Filename.Length, Is.GreaterThan(TestLegacyExporter.MAX_FILENAME_LENGTH)); + Assert.That(item.Filename.Length, Is.GreaterThan(TestLegacyModelExporter.MAX_FILENAME_LENGTH)); exportItemAndAssert(item, expectedName); } [Test] public void ExportFileWithSuperLongNameMultipleTimesTest() { - int expectedLength = TestLegacyExporter.MAX_FILENAME_LENGTH - (legacyExporter.GetExtension().Length); + int expectedLength = TestLegacyModelExporter.MAX_FILENAME_LENGTH - (legacyExporter.GetExtension().Length); string expectedName = long_filename.Remove(expectedLength); - var item = new TestPathInfo(long_filename); + var item = new TestRealmObject(long_filename); - Assert.That(item.Filename.Length, Is.GreaterThan(TestLegacyExporter.MAX_FILENAME_LENGTH)); + Assert.That(item.Filename.Length, Is.GreaterThan(TestLegacyModelExporter.MAX_FILENAME_LENGTH)); //Export multiple times for (int i = 0; i < 100; i++) @@ -83,9 +90,14 @@ namespace osu.Game.Tests.Database } } - private void exportItemAndAssert(IHasNamedFiles item, string expectedName) + private void exportItemAndAssert(TestRealmObject item, string expectedName) { - Assert.DoesNotThrow(() => legacyExporter.Export(item)); + // ReSharper disable once AsyncVoidLambda + Assert.DoesNotThrow(() => + { + Task t = Task.Run(() => legacyExporter.ExportAsync(new TestRealmLive(item))); + t.WaitSafely(); + }); Assert.That(storage.Exists($"exports/{expectedName}{legacyExporter.GetExtension()}"), Is.True); } @@ -96,21 +108,7 @@ namespace osu.Game.Tests.Database storage.Dispose(); } - private class TestPathInfo : IHasNamedFiles - { - public string Filename { get; } - - public IEnumerable Files { get; } = new List(); - - public TestPathInfo(string filename) - { - Filename = filename; - } - - public override string ToString() => Filename; - } - - private class TestLegacyModelExporter : LegacyModelExporter + private class TestLegacyModelExporter : LegacyModelExporter { public TestLegacyModelExporter(Storage storage) : base(storage) @@ -119,7 +117,45 @@ namespace osu.Game.Tests.Database public string GetExtension() => FileExtension; + protected override void ExportToStream(TestRealmObject model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default) + { + } + protected override string FileExtension => ".test"; } + + private class TestRealmObject : RealmObject, IHasNamedFiles, IHasGuidPrimaryKey + { + public Guid ID => throw new NotImplementedException(); + public string Filename { get; } + + public IEnumerable Files { get; } = new List(); + + public TestRealmObject(string filename) + { + Filename = filename; + } + + public override string ToString() => Filename; + } + + private class TestRealmLive : Live + { + public override void PerformRead(Action perform) => perform(Value); + + public override TReturn PerformRead(Func perform) => perform(Value); + + public override void PerformWrite(Action perform) => throw new NotImplementedException(); + + public override bool IsManaged => throw new NotImplementedException(); + + public override TestRealmObject Value { get; } + + public TestRealmLive(TestRealmObject model) + : base(Guid.Empty) + { + Value = model; + } + } } } From dd690891175a8597e72005782965c762052a5672 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Sun, 9 Apr 2023 15:43:18 +0900 Subject: [PATCH 2628/2991] code quality --- .../{LegacyExporterTest.cs => LegacyModelExporterTest.cs} | 1 - osu.Game/Database/LegacyModelExporter.cs | 2 +- osu.Game/Database/LegacyScoreExporter.cs | 3 ++- osu.Game/Database/LegacySkinExporter.cs | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) rename osu.Game.Tests/Database/{LegacyExporterTest.cs => LegacyModelExporterTest.cs} (99%) diff --git a/osu.Game.Tests/Database/LegacyExporterTest.cs b/osu.Game.Tests/Database/LegacyModelExporterTest.cs similarity index 99% rename from osu.Game.Tests/Database/LegacyExporterTest.cs rename to osu.Game.Tests/Database/LegacyModelExporterTest.cs index c25e14d2ef..27059c3058 100644 --- a/osu.Game.Tests/Database/LegacyExporterTest.cs +++ b/osu.Game.Tests/Database/LegacyModelExporterTest.cs @@ -92,7 +92,6 @@ namespace osu.Game.Tests.Database private void exportItemAndAssert(TestRealmObject item, string expectedName) { - // ReSharper disable once AsyncVoidLambda Assert.DoesNotThrow(() => { Task t = Task.Run(() => legacyExporter.ExportAsync(new TestRealmLive(item))); diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyModelExporter.cs index 7904be7f4f..0e4fefae5c 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyModelExporter.cs @@ -107,7 +107,7 @@ namespace osu.Game.Database .GetFiles(string.Empty, $"{itemFilename}*{FileExtension}") .Concat(exportStorage.GetDirectories(string.Empty)); string filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); - bool success = false; + bool success; ProgressNotification notification = new ProgressNotification { diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index bd7d273a64..e7473c963b 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -13,7 +13,8 @@ namespace osu.Game.Database { public class LegacyScoreExporter : LegacyModelExporter { - public LegacyScoreExporter(Storage storage) : base(storage) + public LegacyScoreExporter(Storage storage) + : base(storage) { } diff --git a/osu.Game/Database/LegacySkinExporter.cs b/osu.Game/Database/LegacySkinExporter.cs index 2a531203bc..4775a54c13 100644 --- a/osu.Game/Database/LegacySkinExporter.cs +++ b/osu.Game/Database/LegacySkinExporter.cs @@ -8,7 +8,8 @@ namespace osu.Game.Database { public class LegacySkinExporter : LegacyArchiveExporter { - public LegacySkinExporter(Storage storage) : base(storage) + public LegacySkinExporter(Storage storage) + : base(storage) { } From c9234829762667d18272bf187885b0804ee51c1d Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 10 Apr 2023 13:31:48 +0900 Subject: [PATCH 2629/2991] Add progressive score multiplier for DT --- .../Mods/CatchModDoubleTime.cs | 1 - .../Mods/ManiaModDoubleTime.cs | 1 - osu.Game.Rulesets.Osu/Mods/OsuModDoubleTime.cs | 1 - .../Mods/TaikoModDoubleTime.cs | 1 - osu.Game/Rulesets/Mods/ModDoubleTime.cs | 17 +++++++++++++++++ 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDoubleTime.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDoubleTime.cs index 57c06e1cd1..83db9f665b 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDoubleTime.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDoubleTime.cs @@ -7,6 +7,5 @@ namespace osu.Game.Rulesets.Catch.Mods { public class CatchModDoubleTime : ModDoubleTime { - public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.06 : 1; } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs index a302f95966..f4b9cf3b88 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs @@ -7,6 +7,5 @@ namespace osu.Game.Rulesets.Mania.Mods { public class ManiaModDoubleTime : ModDoubleTime { - public override double ScoreMultiplier => 1; } } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDoubleTime.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDoubleTime.cs index 700a3f44bc..5569df8d95 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDoubleTime.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDoubleTime.cs @@ -7,6 +7,5 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModDoubleTime : ModDoubleTime { - public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.12 : 1; } } diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModDoubleTime.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModDoubleTime.cs index 89581c57bd..e517439ba4 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModDoubleTime.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModDoubleTime.cs @@ -7,6 +7,5 @@ namespace osu.Game.Rulesets.Taiko.Mods { public class TaikoModDoubleTime : ModDoubleTime { - public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.12 : 1; } } diff --git a/osu.Game/Rulesets/Mods/ModDoubleTime.cs b/osu.Game/Rulesets/Mods/ModDoubleTime.cs index 9e4469bf25..733610c040 100644 --- a/osu.Game/Rulesets/Mods/ModDoubleTime.cs +++ b/osu.Game/Rulesets/Mods/ModDoubleTime.cs @@ -24,5 +24,22 @@ namespace osu.Game.Rulesets.Mods MaxValue = 2, Precision = 0.01, }; + + public override double ScoreMultiplier + { + get + { + // Round to the nearest multiple of 0.1. + double value = (int)(SpeedChange.Value * 10) / 10.0; + + // Offset back to 0. + value -= 1; + + // Each 0.1 multiple changes score multiplier by 0.02. + value /= 5; + + return 1 + value; + } + } } } From 15f6bc155eb49f1fca344e6901d5ec12b8480201 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 10 Apr 2023 13:35:48 +0900 Subject: [PATCH 2630/2991] Add progressive score multiplier for HT --- osu.Game.Rulesets.Catch/Mods/CatchModHalfTime.cs | 1 - osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs | 1 - osu.Game.Rulesets.Osu/Mods/OsuModHalfTime.cs | 1 - osu.Game.Rulesets.Taiko/Mods/TaikoModHalfTime.cs | 1 - osu.Game/Rulesets/Mods/ModHalfTime.cs | 14 ++++++++++++++ 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModHalfTime.cs b/osu.Game.Rulesets.Catch/Mods/CatchModHalfTime.cs index ce06b841aa..3afb8c3d89 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModHalfTime.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModHalfTime.cs @@ -7,6 +7,5 @@ namespace osu.Game.Rulesets.Catch.Mods { public class CatchModHalfTime : ModHalfTime { - public override double ScoreMultiplier => 0.3; } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs index 014954dd60..8d48e3acde 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs @@ -7,6 +7,5 @@ namespace osu.Game.Rulesets.Mania.Mods { public class ManiaModHalfTime : ModHalfTime { - public override double ScoreMultiplier => 0.5; } } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHalfTime.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHalfTime.cs index 4769e7660b..bf65a6c9d3 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHalfTime.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHalfTime.cs @@ -7,6 +7,5 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModHalfTime : ModHalfTime { - public override double ScoreMultiplier => 0.3; } } diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModHalfTime.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModHalfTime.cs index 68d6305fbf..9ef6fe8649 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModHalfTime.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModHalfTime.cs @@ -7,6 +7,5 @@ namespace osu.Game.Rulesets.Taiko.Mods { public class TaikoModHalfTime : ModHalfTime { - public override double ScoreMultiplier => 0.3; } } diff --git a/osu.Game/Rulesets/Mods/ModHalfTime.cs b/osu.Game/Rulesets/Mods/ModHalfTime.cs index 7d858dca6f..06c7750035 100644 --- a/osu.Game/Rulesets/Mods/ModHalfTime.cs +++ b/osu.Game/Rulesets/Mods/ModHalfTime.cs @@ -24,5 +24,19 @@ namespace osu.Game.Rulesets.Mods MaxValue = 0.99, Precision = 0.01, }; + + public override double ScoreMultiplier + { + get + { + // Round to the nearest multiple of 0.1. + double value = (int)(SpeedChange.Value * 10) / 10.0; + + // Offset back to 0. + value -= 1; + + return 1 + value; + } + } } } From bfb7ead6898424220bc63c73db34397462eba685 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 9 Apr 2023 22:04:07 -0700 Subject: [PATCH 2631/2991] Add failing text box beatmap difficulty count test --- .../Visual/SongSelect/TestScenePlaySongSelect.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index feab86d3ee..a103cf759f 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -1068,6 +1068,21 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("options disabled", () => !songSelect.ChildrenOfType().Single().Enabled.Value); } + [Test] + public void TestTextBoxBeatmapDifficultyCount() + { + createSongSelect(); + + AddAssert("0 matching shown", () => songSelect.ChildrenOfType().Single().InformationalText == "0 matching beatmaps"); + + addRulesetImportStep(0); + + AddAssert("3 matching shown", () => songSelect.ChildrenOfType().Single().InformationalText == "3 matching beatmaps"); + AddStep("delete all beatmaps", () => manager.Delete()); + AddUntilStep("wait for no beatmap", () => Beatmap.IsDefault); + AddAssert("0 matching shown", () => songSelect.ChildrenOfType().Single().InformationalText == "0 matching beatmaps"); + } + private void waitForInitialSelection() { AddUntilStep("wait for initial selection", () => !Beatmap.IsDefault); From 7f5b99c91b3dad9985bb6e0aaca0d8ad8d1ba84e Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Fri, 7 Apr 2023 22:32:12 -0700 Subject: [PATCH 2632/2991] Fix song select beatmap difficulty count not updating when deleting --- osu.Game/Screens/Select/BeatmapCarousel.cs | 7 +++++++ osu.Game/Screens/Select/SongSelect.cs | 1 + 2 files changed, 8 insertions(+) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 68d3247275..36fc01613e 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -49,6 +49,11 @@ namespace osu.Game.Screens.Select /// public Action? BeatmapSetsChanged; + /// + /// Triggered when the deleted change. + /// + public Action? DeletedBeatmapSetsChanged; + /// /// Triggered after filter conditions have finished being applied to the model hierarchy. /// @@ -353,6 +358,8 @@ namespace osu.Game.Screens.Select if (!Scroll.UserScrolling) ScrollToSelected(true); + + DeletedBeatmapSetsChanged?.Invoke(); }); public void UpdateBeatmapSet(BeatmapSetInfo beatmapSet) => Schedule(() => diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index c5e914b461..41cbfea0fc 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -162,6 +162,7 @@ namespace osu.Game.Screens.Select BleedBottom = Footer.HEIGHT, SelectionChanged = updateSelectedBeatmap, BeatmapSetsChanged = carouselBeatmapsLoaded, + DeletedBeatmapSetsChanged = updateVisibleBeatmapCount, FilterApplied = updateVisibleBeatmapCount, GetRecommendedBeatmap = s => recommender?.GetRecommendedBeatmap(s), }, c => carouselContainer.Child = c); From ad51f880e04a39cfddfb70f08ab87e08448a9096 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 10 Apr 2023 17:49:29 +0900 Subject: [PATCH 2633/2991] Remove overrides on DC/NC mods --- osu.Game.Rulesets.Catch/Mods/CatchModDaycore.cs | 1 - osu.Game.Rulesets.Catch/Mods/CatchModNightcore.cs | 1 - osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs | 1 - osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs | 1 - osu.Game.Rulesets.Osu/Mods/OsuModDaycore.cs | 1 - osu.Game.Rulesets.Osu/Mods/OsuModNightcore.cs | 1 - osu.Game.Rulesets.Taiko/Mods/TaikoModDaycore.cs | 1 - osu.Game.Rulesets.Taiko/Mods/TaikoModNightcore.cs | 1 - 8 files changed, 8 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDaycore.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDaycore.cs index cae19e9468..180cb98ed7 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDaycore.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDaycore.cs @@ -7,6 +7,5 @@ namespace osu.Game.Rulesets.Catch.Mods { public class CatchModDaycore : ModDaycore { - public override double ScoreMultiplier => 0.3; } } diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModNightcore.cs b/osu.Game.Rulesets.Catch/Mods/CatchModNightcore.cs index 9e38913be7..c537897439 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModNightcore.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModNightcore.cs @@ -8,6 +8,5 @@ namespace osu.Game.Rulesets.Catch.Mods { public class CatchModNightcore : ModNightcore { - public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.06 : 1; } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs index bec0a6a1d3..309393b664 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs @@ -7,6 +7,5 @@ namespace osu.Game.Rulesets.Mania.Mods { public class ManiaModDaycore : ModDaycore { - public override double ScoreMultiplier => 0.5; } } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs index 4cc712060c..748725af9f 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs @@ -8,6 +8,5 @@ namespace osu.Game.Rulesets.Mania.Mods { public class ManiaModNightcore : ModNightcore { - public override double ScoreMultiplier => 1; } } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDaycore.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDaycore.cs index 371dfe6a1a..1de6b9ce55 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDaycore.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDaycore.cs @@ -7,6 +7,5 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModDaycore : ModDaycore { - public override double ScoreMultiplier => 0.3; } } diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModNightcore.cs b/osu.Game.Rulesets.Osu/Mods/OsuModNightcore.cs index b7838ebaa7..661cc948c5 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModNightcore.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModNightcore.cs @@ -8,6 +8,5 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModNightcore : ModNightcore { - public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.12 : 1; } } diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModDaycore.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModDaycore.cs index 84aa5e6bba..f442435d9c 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModDaycore.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModDaycore.cs @@ -7,6 +7,5 @@ namespace osu.Game.Rulesets.Taiko.Mods { public class TaikoModDaycore : ModDaycore { - public override double ScoreMultiplier => 0.3; } } diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModNightcore.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModNightcore.cs index 7cb14635ff..ad5da3d601 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModNightcore.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModNightcore.cs @@ -8,6 +8,5 @@ namespace osu.Game.Rulesets.Taiko.Mods { public class TaikoModNightcore : ModNightcore { - public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.12 : 1; } } From 641415ca3263fdff295402f965a5562c309ea8f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 10 Apr 2023 14:05:32 +0200 Subject: [PATCH 2634/2991] Unify displayed duration format for single/multiple selection --- osu.Game/Rulesets/Edit/HitObjectInspector.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectInspector.cs b/osu.Game/Rulesets/Edit/HitObjectInspector.cs index 02270d4662..d0a022744f 100644 --- a/osu.Game/Rulesets/Edit/HitObjectInspector.cs +++ b/osu.Game/Rulesets/Edit/HitObjectInspector.cs @@ -121,10 +121,10 @@ namespace osu.Game.Rulesets.Edit addValue($"{EditorBeatmap.SelectedHitObjects.Count:#,0.##}"); addHeader("Start Time"); - addValue($"{EditorBeatmap.SelectedHitObjects.Min(o => o.StartTime):#,0.##}"); + addValue($"{EditorBeatmap.SelectedHitObjects.Min(o => o.StartTime):#,0.##}ms"); addHeader("End Time"); - addValue($"{EditorBeatmap.SelectedHitObjects.Max(o => o.GetEndTime()):#,0.##}"); + addValue($"{EditorBeatmap.SelectedHitObjects.Max(o => o.GetEndTime()):#,0.##}ms"); break; } From 60358c720392264ab4b1c51bbca89aa72710300d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 10 Apr 2023 14:13:53 +0200 Subject: [PATCH 2635/2991] Perform first inspector text update immediately Provides better and more consistent initial state for the inspector. --- osu.Game/Rulesets/Edit/HitObjectInspector.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Rulesets/Edit/HitObjectInspector.cs b/osu.Game/Rulesets/Edit/HitObjectInspector.cs index d0a022744f..977d00ede2 100644 --- a/osu.Game/Rulesets/Edit/HitObjectInspector.cs +++ b/osu.Game/Rulesets/Edit/HitObjectInspector.cs @@ -46,6 +46,7 @@ namespace osu.Game.Rulesets.Edit EditorBeatmap.SelectedHitObjects.CollectionChanged += (_, _) => updateInspectorText(); EditorBeatmap.TransactionBegan += updateInspectorText; EditorBeatmap.TransactionEnded += updateInspectorText; + updateInspectorText(); } private ScheduledDelegate? rollingTextUpdate; From 6fec476147b04d30be33bcba642c262fd6a8c811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 10 Apr 2023 14:55:30 +0200 Subject: [PATCH 2636/2991] Simplify snap implementation --- .../Edit/Compose/Components/SelectionBoxRotationHandle.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs index 73da837d03..bee768ad50 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs @@ -129,10 +129,6 @@ namespace osu.Game.Screens.Edit.Compose.Components TooltipText = newRotation.ToLocalisableString(tooltipFormat); } - private float snap(float value, float step) - { - float floor = MathF.Floor(value / step) * step; - return value - floor < step / 2f ? floor : floor + step; - } + private float snap(float value, float step) => MathF.Round(value / step) * step; } } From 73bd0feef58ed190df4317b507a9a4cae882fa53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 10 Apr 2023 15:03:33 +0200 Subject: [PATCH 2637/2991] Fix incorrectly implemented localisation --- osu.Game/Localisation/EditorStrings.cs | 8 ++++---- .../Edit/Compose/Components/SelectionBoxRotationHandle.cs | 4 +--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/osu.Game/Localisation/EditorStrings.cs b/osu.Game/Localisation/EditorStrings.cs index beddcfd44e..7c9b52275d 100644 --- a/osu.Game/Localisation/EditorStrings.cs +++ b/osu.Game/Localisation/EditorStrings.cs @@ -100,14 +100,14 @@ namespace osu.Game.Localisation public static LocalisableString TimelineTicks => new TranslatableString(getKey(@"timeline_ticks"), @"Ticks"); /// - /// "0.0°" + /// "{0:0.0}°" /// - public static LocalisableString RotationFormatUnsnapped => new TranslatableString(getKey(@"rotation_format_unsnapped"), @"0.0°"); + public static LocalisableString RotationUnsnapped(float newRotation) => new TranslatableString(getKey(@"rotation_unsnapped"), @"{0:0.0}°", newRotation); /// - /// "0.0° (snapped)" + /// "{0:0.0}° (snapped)" /// - public static LocalisableString RotationFormatSnapped => new TranslatableString(getKey(@"rotation_format_snapped"), @"0.0° (snapped)"); + public static LocalisableString RotationSnapped(float newRotation) => new TranslatableString(getKey(@"rotation_snapped"), @"{0:0.0}° (snapped)", newRotation); private static string getKey(string key) => $@"{prefix}:{key}"; } diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs index bee768ad50..305f5bf3c4 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs @@ -7,7 +7,6 @@ using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.EnumExtensions; -using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Sprites; @@ -125,8 +124,7 @@ namespace osu.Game.Screens.Edit.Compose.Components cumulativeRotation.Value = newRotation; HandleRotate?.Invoke(newRotation - oldRotation); - string tooltipFormat = shouldSnap ? EditorStrings.RotationFormatSnapped.ToString() : EditorStrings.RotationFormatUnsnapped.ToString(); - TooltipText = newRotation.ToLocalisableString(tooltipFormat); + TooltipText = shouldSnap ? EditorStrings.RotationSnapped(newRotation) : EditorStrings.RotationUnsnapped(newRotation); } private float snap(float value, float step) => MathF.Round(value / step) * step; From 11fd93a2baec751af641692664cbf3387871839d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 10 Apr 2023 15:19:54 +0200 Subject: [PATCH 2638/2991] Inline disturbing `getGuestMapper()` method Disturbing because name suggests pure method, but it is in fact `void` and also performs side effects by about the most confusing means possible. --- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 27e671ded0..104f861df7 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -214,22 +214,17 @@ namespace osu.Game.Overlays.BeatmapSet if (beatmapInfo?.AuthorID != BeatmapSet?.AuthorID) { APIUser? user = BeatmapSet?.RelatedUsers?.SingleOrDefault(u => u.OnlineID == beatmapInfo?.AuthorID); + if (user != null) - getGuestMapper(user); + { + guestMapperContainer.AddText("mapped by "); + guestMapperContainer.AddUserLink(user); + } } version.Text = beatmapInfo?.DifficultyName ?? string.Empty; } - private void getGuestMapper(APIUser user) - { - guestMapperContainer.With(d => - { - d.AddText("mapped by "); - d.AddUserLink(user); - }); - } - private void updateDifficultyButtons() { Difficulties.Children.ToList().ForEach(diff => diff.State = diff.Beatmap == Beatmap.Value ? DifficultySelectorState.Selected : DifficultySelectorState.NotSelected); From 6e08105e2c37656801dda1d0583525a549f049e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 10 Apr 2023 15:27:10 +0200 Subject: [PATCH 2639/2991] Remove usage of "diff" vernacular --- .../Visual/Online/TestSceneBeatmapSetOverlay.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 4838f42043..a27c4ddad2 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -283,15 +283,15 @@ namespace osu.Game.Tests.Visual.Online } [Test] - public void TestBeatmapSetWithGuestDIff() + public void TestBeatmapSetWithGuestDifficulty() { - AddStep("show map", () => overlay.ShowBeatmapSet(createBeatmapSetWithGuestDiff())); - AddStep("move mouse to host diff", () => + AddStep("show map", () => overlay.ShowBeatmapSet(createBeatmapSetWithGuestDifficulty())); + AddStep("move mouse to host difficulty", () => { InputManager.MoveMouseTo(overlay.ChildrenOfType().ElementAt(0)); }); AddAssert("guest mapper information not shown", () => overlay.ChildrenOfType().Single().ChildrenOfType().All(s => s.Text != "BanchoBot")); - AddStep("move mouse to guest diff", () => + AddStep("move mouse to guest difficulty", () => { InputManager.MoveMouseTo(overlay.ChildrenOfType().ElementAt(1)); }); @@ -337,7 +337,7 @@ namespace osu.Game.Tests.Visual.Online return beatmapSet; } - private APIBeatmapSet createBeatmapSetWithGuestDiff() + private APIBeatmapSet createBeatmapSetWithGuestDifficulty() { var set = getBeatmapSet(); From c7dea717931631e02ef80c5222b6eed2b96e458c Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 10 Apr 2023 11:26:18 -0700 Subject: [PATCH 2640/2991] Use existing `BeatmapSetsChanged` action --- osu.Game/Screens/Select/BeatmapCarousel.cs | 7 +------ osu.Game/Screens/Select/SongSelect.cs | 1 - 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 36fc01613e..d6359dd62e 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -49,11 +49,6 @@ namespace osu.Game.Screens.Select /// public Action? BeatmapSetsChanged; - /// - /// Triggered when the deleted change. - /// - public Action? DeletedBeatmapSetsChanged; - /// /// Triggered after filter conditions have finished being applied to the model hierarchy. /// @@ -359,7 +354,7 @@ namespace osu.Game.Screens.Select if (!Scroll.UserScrolling) ScrollToSelected(true); - DeletedBeatmapSetsChanged?.Invoke(); + BeatmapSetsChanged?.Invoke(); }); public void UpdateBeatmapSet(BeatmapSetInfo beatmapSet) => Schedule(() => diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 41cbfea0fc..c5e914b461 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -162,7 +162,6 @@ namespace osu.Game.Screens.Select BleedBottom = Footer.HEIGHT, SelectionChanged = updateSelectedBeatmap, BeatmapSetsChanged = carouselBeatmapsLoaded, - DeletedBeatmapSetsChanged = updateVisibleBeatmapCount, FilterApplied = updateVisibleBeatmapCount, GetRecommendedBeatmap = s => recommender?.GetRecommendedBeatmap(s), }, c => carouselContainer.Child = c); From f80de08f24e5176bc1d3bb79b994e1e1717d059d Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 10 Apr 2023 11:28:23 -0700 Subject: [PATCH 2641/2991] Adjust `BeatmapSetsChanged` xmldoc Co-Authored-By: Dean Herbert --- 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 d6359dd62e..6ba9843f7b 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -45,7 +45,7 @@ namespace osu.Game.Screens.Select public float BleedBottom { get; set; } /// - /// Triggered when the loaded change and are completely loaded. + /// Triggered when finish loading, or are subsequently changed. /// public Action? BeatmapSetsChanged; From d0cbe206a949452c6bb4a0116470babc95aa9b36 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 10 Apr 2023 23:37:29 -0700 Subject: [PATCH 2642/2991] Revert back to one number with "matching beatmap difficulties" label --- .../Visual/SongSelect/TestScenePlaySongSelect.cs | 6 +++--- osu.Game/Screens/Select/BeatmapCarousel.cs | 7 +------ osu.Game/Screens/Select/SongSelect.cs | 2 +- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index a103cf759f..c9a7cf37a8 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -1073,14 +1073,14 @@ namespace osu.Game.Tests.Visual.SongSelect { createSongSelect(); - AddAssert("0 matching shown", () => songSelect.ChildrenOfType().Single().InformationalText == "0 matching beatmaps"); + AddAssert("0 matching shown", () => songSelect.ChildrenOfType().Single().InformationalText == "0 matching beatmap difficulties"); addRulesetImportStep(0); - AddAssert("3 matching shown", () => songSelect.ChildrenOfType().Single().InformationalText == "3 matching beatmaps"); + AddAssert("3 matching shown", () => songSelect.ChildrenOfType().Single().InformationalText == "3 matching beatmap difficulties"); AddStep("delete all beatmaps", () => manager.Delete()); AddUntilStep("wait for no beatmap", () => Beatmap.IsDefault); - AddAssert("0 matching shown", () => songSelect.ChildrenOfType().Single().InformationalText == "0 matching beatmaps"); + AddAssert("0 matching shown", () => songSelect.ChildrenOfType().Single().InformationalText == "0 matching beatmap difficulties"); } private void waitForInitialSelection() diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index d5ddc375b7..6ba9843f7b 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -64,12 +64,7 @@ namespace osu.Game.Screens.Select /// /// The total count of non-filtered beatmaps displayed. /// - public int CountDisplayedBeatmaps => beatmapSets.Where(s => !s.Filtered.Value).Sum(s => s.Beatmaps.Count(b => !b.Filtered.Value)); - - /// - /// The total count of non-filtered beatmap sets displayed. - /// - public int CountDisplayedSets => beatmapSets.Count(s => !s.Filtered.Value); + public int CountDisplayed => beatmapSets.Where(s => !s.Filtered.Value).Sum(s => s.Beatmaps.Count(b => !b.Filtered.Value)); /// /// The currently selected beatmap set. diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 7191ff7c2a..09ccee3717 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -864,7 +864,7 @@ namespace osu.Game.Screens.Select { // Intentionally not localised until we have proper support for this (see https://github.com/ppy/osu-framework/pull/4918 // but also in this case we want support for formatting a number within a string). - FilterControl.InformationalText = $"{"matching beatmap".ToQuantity(Carousel.CountDisplayedSets, "#,0")} ({"difficulty".ToQuantity(Carousel.CountDisplayedBeatmaps, "#,0")})"; + FilterControl.InformationalText = $"{"matching beatmap difficulty".ToQuantity(Carousel.CountDisplayed, "#,0")}"; } private bool boundLocalBindables; From 0cc92ce5f926d91978c8903d3883fa70c61cf4c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 11 Apr 2023 17:51:01 +0200 Subject: [PATCH 2643/2991] Add failing test case Covering nested object reverts not firing the parent's `RevertResult` event in accordance with what the xmldoc of the event states. --- .../Gameplay/TestScenePoolingRuleset.cs | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePoolingRuleset.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePoolingRuleset.cs index 0469df1de3..d16f51f36e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePoolingRuleset.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePoolingRuleset.cs @@ -164,6 +164,36 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("all results reverted", () => playfield.JudgedObjects.Count, () => Is.EqualTo(0)); } + [Test] + public void TestRevertNestedObjects() + { + ManualClock clock = null; + + var beatmap = new Beatmap(); + beatmap.HitObjects.Add(new TestHitObjectWithNested { Duration = 40 }); + + createTest(beatmap, 10, () => new FramedClock(clock = new ManualClock())); + + AddStep("skip to middle of object", () => clock.CurrentTime = (beatmap.HitObjects[0].StartTime + beatmap.HitObjects[0].GetEndTime()) / 2); + AddAssert("2 objects judged", () => playfield.JudgedObjects.Count, () => Is.EqualTo(2)); + + AddStep("skip to before end of object", () => clock.CurrentTime = beatmap.HitObjects[0].GetEndTime() - 1); + AddAssert("3 objects judged", () => playfield.JudgedObjects.Count, () => Is.EqualTo(3)); + + DrawableHitObject drawableHitObject = null; + HashSet revertedHitObjects = new HashSet(); + + AddStep("retrieve drawable hit object", () => drawableHitObject = playfield.ChildrenOfType().Single()); + AddStep("set up revert tracking", () => + { + revertedHitObjects.Clear(); + drawableHitObject.OnRevertResult += (ho, _) => revertedHitObjects.Add(ho.HitObject); + }); + AddStep("skip back to object start", () => clock.CurrentTime = beatmap.HitObjects[0].StartTime); + AddAssert("3 reverts fired", () => revertedHitObjects, () => Has.Count.EqualTo(3)); + AddAssert("no objects judged", () => playfield.JudgedObjects.Count, () => Is.EqualTo(0)); + } + [Test] public void TestApplyHitResultOnKilled() { @@ -258,6 +288,8 @@ namespace osu.Game.Tests.Visual.Gameplay { RegisterPool(poolSize); RegisterPool(poolSize); + RegisterPool(poolSize); + RegisterPool(poolSize); } protected override HitObjectLifetimeEntry CreateLifetimeEntry(HitObject hitObject) => new TestHitObjectLifetimeEntry(hitObject); @@ -388,6 +420,120 @@ namespace osu.Game.Tests.Visual.Gameplay } } + private class TestHitObjectWithNested : TestHitObject + { + protected override void CreateNestedHitObjects(CancellationToken cancellationToken) + { + base.CreateNestedHitObjects(cancellationToken); + + for (int i = 0; i < 3; ++i) + AddNested(new NestedHitObject { StartTime = (float)Duration * (i + 1) / 4 }); + } + } + + private class NestedHitObject : ConvertHitObject + { + } + + private partial class DrawableTestHitObjectWithNested : DrawableHitObject + { + private Container nestedContainer; + + public DrawableTestHitObjectWithNested() + : base(null) + { + } + + [BackgroundDependencyLoader] + private void load() + { + AddRangeInternal(new Drawable[] + { + new Circle + { + RelativeSizeAxes = Axes.Both, + Colour = Colour4.Red + }, + nestedContainer = new Container + { + RelativeSizeAxes = Axes.Both + } + }); + } + + protected override void OnApply() + { + base.OnApply(); + + Size = new Vector2(200, 50); + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + } + + protected override void AddNestedHitObject(DrawableHitObject hitObject) + { + base.AddNestedHitObject(hitObject); + nestedContainer.Add(hitObject); + } + + protected override void ClearNestedHitObjects() + { + base.ClearNestedHitObjects(); + nestedContainer.Clear(false); + } + + protected override void CheckForResult(bool userTriggered, double timeOffset) + { + base.CheckForResult(userTriggered, timeOffset); + if (timeOffset >= 0) + ApplyResult(r => r.Type = r.Judgement.MaxResult); + } + } + + private partial class DrawableNestedHitObject : DrawableHitObject + { + public DrawableNestedHitObject() + : this(null) + { + } + + public DrawableNestedHitObject(NestedHitObject hitObject) + : base(hitObject) + { + Size = new Vector2(15); + Colour = Colour4.White; + RelativePositionAxes = Axes.Both; + Origin = Anchor.Centre; + } + + [BackgroundDependencyLoader] + private void load() + { + AddInternal(new Circle + { + RelativeSizeAxes = Axes.Both, + }); + } + + protected override void OnApply() + { + base.OnApply(); + + X = (float)((HitObject.StartTime - ParentHitObject!.HitObject.StartTime) / (ParentHitObject.HitObject.GetEndTime() - ParentHitObject.HitObject.StartTime)); + Y = 0.5f; + + LifetimeStart = ParentHitObject.LifetimeStart; + LifetimeEnd = ParentHitObject.LifetimeEnd; + } + + protected override void CheckForResult(bool userTriggered, double timeOffset) + { + base.CheckForResult(userTriggered, timeOffset); + if (timeOffset >= 0) + ApplyResult(r => r.Type = r.Judgement.MaxResult); + } + } + #endregion } } From db86ced4b4077f042af4e865c8bad859c3cfff23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 11 Apr 2023 17:59:33 +0200 Subject: [PATCH 2644/2991] Invoke `RevertResult` on parent DHO when nested DHO is reverted The behaviour described above was removed in 812a4b412a2c1b13a1e1215a00f863ef6fd83e45, thus henceforth contradicting `RevertResult`'s xmldoc. As it is relied on by some external rulesets, bring it back to unbreak them. --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 0c50f8341a..f6c3452e48 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -239,6 +239,7 @@ namespace osu.Game.Rulesets.Objects.Drawables OnNestedDrawableCreated?.Invoke(drawableNested); drawableNested.OnNewResult += onNewResult; + drawableNested.OnRevertResult += onNestedRevertResult; drawableNested.ApplyCustomUpdateState += onApplyCustomUpdateState; // This is only necessary for non-pooled DHOs. For pooled DHOs, this is handled inside GetPooledDrawableRepresentation(). @@ -312,6 +313,7 @@ namespace osu.Game.Rulesets.Objects.Drawables foreach (var obj in nestedHitObjects) { obj.OnNewResult -= onNewResult; + obj.OnRevertResult -= onNestedRevertResult; obj.ApplyCustomUpdateState -= onApplyCustomUpdateState; } @@ -376,6 +378,8 @@ namespace osu.Game.Rulesets.Objects.Drawables OnRevertResult?.Invoke(this, Result); } + private void onNestedRevertResult(DrawableHitObject drawableHitObject, JudgementResult result) => OnRevertResult?.Invoke(drawableHitObject, result); + private void onApplyCustomUpdateState(DrawableHitObject drawableHitObject, ArmedState state) => ApplyCustomUpdateState?.Invoke(drawableHitObject, state); private void onDefaultsApplied(HitObject hitObject) From e72f103c1759e61c3afa7080f962c639265996c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 11 Apr 2023 21:42:55 +0200 Subject: [PATCH 2645/2991] Do not look up metadata for locally-modified beatmaps on save --- osu.Game/Beatmaps/BeatmapImporter.cs | 6 ++--- osu.Game/Beatmaps/BeatmapManager.cs | 15 ++++++++--- .../Beatmaps/BeatmapOnlineChangeIngest.cs | 2 +- osu.Game/Beatmaps/BeatmapUpdater.cs | 13 +++++----- osu.Game/Beatmaps/MetadataLookupScope.cs | 26 +++++++++++++++++++ osu.Game/OsuGameBase.cs | 2 +- 6 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 osu.Game/Beatmaps/MetadataLookupScope.cs diff --git a/osu.Game/Beatmaps/BeatmapImporter.cs b/osu.Game/Beatmaps/BeatmapImporter.cs index 4752a88199..4731a70753 100644 --- a/osu.Game/Beatmaps/BeatmapImporter.cs +++ b/osu.Game/Beatmaps/BeatmapImporter.cs @@ -35,7 +35,7 @@ namespace osu.Game.Beatmaps protected override string[] HashableFileTypes => new[] { ".osu" }; - public Action<(BeatmapSetInfo beatmapSet, bool isBatch)>? ProcessBeatmap { private get; set; } + public ProcessBeatmapDelegate? ProcessBeatmap { private get; set; } public BeatmapImporter(Storage storage, RealmAccess realm) : base(storage, realm) @@ -59,7 +59,7 @@ namespace osu.Game.Beatmaps first.PerformRead(s => { // Re-run processing even in this case. We might have outdated metadata. - ProcessBeatmap?.Invoke((s, false)); + ProcessBeatmap?.Invoke(s, MetadataLookupScope.OnlineFirst); }); return first; } @@ -206,7 +206,7 @@ namespace osu.Game.Beatmaps protected override void PostImport(BeatmapSetInfo model, Realm realm, ImportParameters parameters) { base.PostImport(model, realm, parameters); - ProcessBeatmap?.Invoke((model, parameters.Batch)); + ProcessBeatmap?.Invoke(model, parameters.Batch ? MetadataLookupScope.LocalCacheFirst : MetadataLookupScope.OnlineFirst); } private void validateOnlineIds(BeatmapSetInfo beatmapSet, Realm realm) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index ad56bbbc3a..cab49b7d69 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -42,7 +42,7 @@ namespace osu.Game.Beatmaps private readonly WorkingBeatmapCache workingBeatmapCache; - public Action<(BeatmapSetInfo beatmapSet, bool isBatch)>? ProcessBeatmap { private get; set; } + public ProcessBeatmapDelegate? ProcessBeatmap { private get; set; } public override bool PauseImports { @@ -72,7 +72,7 @@ namespace osu.Game.Beatmaps BeatmapTrackStore = audioManager.GetTrackStore(userResources); beatmapImporter = CreateBeatmapImporter(storage, realm); - beatmapImporter.ProcessBeatmap = args => ProcessBeatmap?.Invoke(args); + beatmapImporter.ProcessBeatmap = (beatmapSet, scope) => ProcessBeatmap?.Invoke(beatmapSet, scope); beatmapImporter.PostNotification = obj => PostNotification?.Invoke(obj); workingBeatmapCache = CreateWorkingBeatmapCache(audioManager, gameResources, userResources, defaultBeatmap, host); @@ -454,7 +454,9 @@ namespace osu.Game.Beatmaps if (transferCollections) beatmapInfo.TransferCollectionReferences(r, oldMd5Hash); - ProcessBeatmap?.Invoke((liveBeatmapSet, false)); + // do not look up metadata. + // this is a locally-modified set now, so looking up metadata is busy work at best and harmful at worst. + ProcessBeatmap?.Invoke(liveBeatmapSet, MetadataLookupScope.None); }); } @@ -542,4 +544,11 @@ namespace osu.Game.Beatmaps public override string HumanisedModelName => "beatmap"; } + + /// + /// Delegate type for beatmap processing callbacks. + /// + /// The beatmap set to be processed. + /// The scope to use when looking up metadata. + public delegate void ProcessBeatmapDelegate(BeatmapSetInfo beatmapSet, MetadataLookupScope lookupScope); } diff --git a/osu.Game/Beatmaps/BeatmapOnlineChangeIngest.cs b/osu.Game/Beatmaps/BeatmapOnlineChangeIngest.cs index 98aefd75d3..b160043820 100644 --- a/osu.Game/Beatmaps/BeatmapOnlineChangeIngest.cs +++ b/osu.Game/Beatmaps/BeatmapOnlineChangeIngest.cs @@ -36,7 +36,7 @@ namespace osu.Game.Beatmaps var matchingSet = r.All().FirstOrDefault(s => s.OnlineID == id); if (matchingSet != null) - beatmapUpdater.Queue(matchingSet.ToLive(realm), true); + beatmapUpdater.Queue(matchingSet.ToLive(realm), MetadataLookupScope.OnlineFirst); } }); } diff --git a/osu.Game/Beatmaps/BeatmapUpdater.cs b/osu.Game/Beatmaps/BeatmapUpdater.cs index d7b1fac7b3..af9f32f834 100644 --- a/osu.Game/Beatmaps/BeatmapUpdater.cs +++ b/osu.Game/Beatmaps/BeatmapUpdater.cs @@ -42,24 +42,25 @@ namespace osu.Game.Beatmaps /// Queue a beatmap for background processing. /// /// The managed beatmap set to update. A transaction will be opened to apply changes. - /// Whether metadata from an online source should be preferred. If true, the local cache will be skipped to ensure the freshest data state possible. - public void Queue(Live beatmapSet, bool preferOnlineFetch = false) + /// The preferred scope to use for metadata lookup. + public void Queue(Live beatmapSet, MetadataLookupScope lookupScope = MetadataLookupScope.LocalCacheFirst) { Logger.Log($"Queueing change for local beatmap {beatmapSet}"); - Task.Factory.StartNew(() => beatmapSet.PerformRead(b => Process(b, preferOnlineFetch)), default, TaskCreationOptions.HideScheduler | TaskCreationOptions.RunContinuationsAsynchronously, updateScheduler); + Task.Factory.StartNew(() => beatmapSet.PerformRead(b => Process(b, lookupScope)), default, TaskCreationOptions.HideScheduler | TaskCreationOptions.RunContinuationsAsynchronously, updateScheduler); } /// /// Run all processing on a beatmap immediately. /// /// The managed beatmap set to update. A transaction will be opened to apply changes. - /// Whether metadata from an online source should be preferred. If true, the local cache will be skipped to ensure the freshest data state possible. - public void Process(BeatmapSetInfo beatmapSet, bool preferOnlineFetch = false) => beatmapSet.Realm.Write(r => + /// The preferred scope to use for metadata lookup. + public void Process(BeatmapSetInfo beatmapSet, MetadataLookupScope lookupScope = MetadataLookupScope.LocalCacheFirst) => beatmapSet.Realm.Write(r => { // Before we use below, we want to invalidate. workingBeatmapCache.Invalidate(beatmapSet); - metadataLookup.Update(beatmapSet, preferOnlineFetch); + if (lookupScope != MetadataLookupScope.None) + metadataLookup.Update(beatmapSet, lookupScope == MetadataLookupScope.OnlineFirst); foreach (var beatmap in beatmapSet.Beatmaps) { diff --git a/osu.Game/Beatmaps/MetadataLookupScope.cs b/osu.Game/Beatmaps/MetadataLookupScope.cs new file mode 100644 index 0000000000..e1fbedc26a --- /dev/null +++ b/osu.Game/Beatmaps/MetadataLookupScope.cs @@ -0,0 +1,26 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Beatmaps +{ + /// + /// Determines which sources (if any at all) should be queried in which order for a beatmap's metadata. + /// + public enum MetadataLookupScope + { + /// + /// Do not attempt to look up the beatmap metadata either in the local cache or online. + /// + None, + + /// + /// Try the local metadata cache first before querying online sources. + /// + LocalCacheFirst, + + /// + /// Query online sources immediately. + /// + OnlineFirst + } +} diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 8f27e5dc53..34e31b0d61 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -310,7 +310,7 @@ namespace osu.Game base.Content.Add(new BeatmapOnlineChangeIngest(beatmapUpdater, realm, metadataClient)); - BeatmapManager.ProcessBeatmap = args => beatmapUpdater.Process(args.beatmapSet, !args.isBatch); + BeatmapManager.ProcessBeatmap = (beatmapSet, scope) => beatmapUpdater.Process(beatmapSet, scope); dependencies.Cache(userCache = new UserLookupCache()); base.Content.Add(userCache); From fbb15fff26ad91ceeccf9facc030fd6e6b503b1c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Apr 2023 23:03:16 +0900 Subject: [PATCH 2646/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 4b89e82729..a93b450ebb 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -11,7 +11,7 @@ manifestmerger.jar - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b9c6c1df9d..0ec65f4daf 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 083d8192ea..3862ddacdb 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -16,6 +16,6 @@ iossimulator-x64 - + From c3f3b8db7c8c6e32d10066650eb89f4933d3d94f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Apr 2023 23:09:46 +0900 Subject: [PATCH 2647/2991] Update resources --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 0ec65f4daf..578b8512e7 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -37,7 +37,7 @@ - + From c0a25144cf458a979348ac8637087eb33428d3a4 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Tue, 18 Apr 2023 11:31:56 +0900 Subject: [PATCH 2648/2991] Apply changes to custom ShaderManager --- .../TestSceneDrawableRulesetDependencies.cs | 2 +- .../Testing/TestSceneRulesetDependencies.cs | 4 ++-- .../UI/DrawableRulesetDependencies.cs | 22 +++---------------- 3 files changed, 6 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs b/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs index f8248e88bb..6639b6dd68 100644 --- a/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs +++ b/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs @@ -164,7 +164,7 @@ namespace osu.Game.Tests.Rulesets this.parentManager = parentManager; } - public override byte[] LoadRaw(string name) => parentManager.LoadRaw(name); + public override byte[] GetRawData(string fileName) => parentManager.GetRawData(fileName); public bool IsDisposed { get; private set; } diff --git a/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs b/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs index a5a83d7231..585a3f95e7 100644 --- a/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs +++ b/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs @@ -51,8 +51,8 @@ namespace osu.Game.Tests.Testing { AddStep("ruleset shaders retrieved without error", () => { - Dependencies.Get().LoadRaw(@"sh_TestVertex.vs"); - Dependencies.Get().LoadRaw(@"sh_TestFragment.fs"); + Dependencies.Get().GetRawData(@"sh_TestVertex.vs"); + Dependencies.Get().GetRawData(@"sh_TestFragment.fs"); }); } diff --git a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs index 76d84000f1..e34289c968 100644 --- a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs +++ b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs @@ -206,27 +206,11 @@ namespace osu.Game.Rulesets.UI this.parent = parent; } - // When the debugger is attached, exceptions are expensive. - // Manually work around this by caching failed lookups and falling back straight to parent. - private readonly HashSet<(string, string)> failedLookups = new HashSet<(string, string)>(); + public override IShader? GetCachedShader(string vertex, string fragment) => base.GetCachedShader(vertex, fragment) ?? parent.GetCachedShader(vertex, fragment); - public override IShader Load(string vertex, string fragment) - { - if (!failedLookups.Contains((vertex, fragment))) - { - try - { - return base.Load(vertex, fragment); - } - catch - { - // Shader lookup is very non-standard. Rather than returning null on missing shaders, exceptions are thrown. - failedLookups.Add((vertex, fragment)); - } - } + public override IShaderPart? GetCachedShaderPart(string name) => base.GetCachedShaderPart(name) ?? parent.GetCachedShaderPart(name); - return parent.Load(vertex, fragment); - } + public override byte[]? GetRawData(string fileName) => base.GetRawData(fileName) ?? parent.GetRawData(fileName); } } } From 16df92f405cf466c21459189b9c90689d3b23ca7 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 17 Apr 2023 20:59:02 -0700 Subject: [PATCH 2649/2991] Fix sets not being plural --- osu.Game/Localisation/FirstRunSetupBeatmapScreenStrings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Localisation/FirstRunSetupBeatmapScreenStrings.cs b/osu.Game/Localisation/FirstRunSetupBeatmapScreenStrings.cs index d822f4976f..a77ee066e4 100644 --- a/osu.Game/Localisation/FirstRunSetupBeatmapScreenStrings.cs +++ b/osu.Game/Localisation/FirstRunSetupBeatmapScreenStrings.cs @@ -15,9 +15,9 @@ namespace osu.Game.Localisation public static LocalisableString Header => new TranslatableString(getKey(@"header"), @"Obtaining Beatmaps"); /// - /// ""Beatmaps" are what we call a set of playable levels. osu! doesn't come with any beatmaps pre-loaded. This step will help you get started on your beatmap collection." + /// ""Beatmaps" are what we call sets of playable levels. osu! doesn't come with any beatmaps pre-loaded. This step will help you get started on your beatmap collection." /// - public static LocalisableString Description => new TranslatableString(getKey(@"description"), @"""Beatmaps"" are what we call a set of playable levels. osu! doesn't come with any beatmaps pre-loaded. This step will help you get started on your beatmap collection."); + public static LocalisableString Description => new TranslatableString(getKey(@"description"), @"""Beatmaps"" are what we call sets of playable levels. osu! doesn't come with any beatmaps pre-loaded. This step will help you get started on your beatmap collection."); /// /// "If you are a new player, we recommend playing through the tutorial to get accustomed to the gameplay." From c80a25328d2d5dc0fb8b1d7f710ee275db247e33 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 17 Apr 2023 20:59:41 -0700 Subject: [PATCH 2650/2991] Shorten label to just "matches" --- osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs | 6 +++--- osu.Game/Screens/Select/SongSelect.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index c9a7cf37a8..f094d40caa 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -1073,14 +1073,14 @@ namespace osu.Game.Tests.Visual.SongSelect { createSongSelect(); - AddAssert("0 matching shown", () => songSelect.ChildrenOfType().Single().InformationalText == "0 matching beatmap difficulties"); + AddAssert("0 matching shown", () => songSelect.ChildrenOfType().Single().InformationalText == "0 matches"); addRulesetImportStep(0); - AddAssert("3 matching shown", () => songSelect.ChildrenOfType().Single().InformationalText == "3 matching beatmap difficulties"); + AddAssert("3 matching shown", () => songSelect.ChildrenOfType().Single().InformationalText == "3 matches"); AddStep("delete all beatmaps", () => manager.Delete()); AddUntilStep("wait for no beatmap", () => Beatmap.IsDefault); - AddAssert("0 matching shown", () => songSelect.ChildrenOfType().Single().InformationalText == "0 matching beatmap difficulties"); + AddAssert("0 matching shown", () => songSelect.ChildrenOfType().Single().InformationalText == "0 matches"); } private void waitForInitialSelection() diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 09ccee3717..4d6a5398c5 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -864,7 +864,7 @@ namespace osu.Game.Screens.Select { // Intentionally not localised until we have proper support for this (see https://github.com/ppy/osu-framework/pull/4918 // but also in this case we want support for formatting a number within a string). - FilterControl.InformationalText = $"{"matching beatmap difficulty".ToQuantity(Carousel.CountDisplayed, "#,0")}"; + FilterControl.InformationalText = $"{"match".ToQuantity(Carousel.CountDisplayed, "#,0")}"; } private bool boundLocalBindables; From 760ef1014587638fb2b3eb3a022136cb0d07f396 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Apr 2023 00:04:21 +0900 Subject: [PATCH 2651/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 4b89e82729..3ede0b85da 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -11,7 +11,7 @@ manifestmerger.jar - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b9c6c1df9d..6e8b642abf 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 083d8192ea..127994c670 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -16,6 +16,6 @@ iossimulator-x64 - + From 776c4cfaad00d1f9f99cfa70792022f68002c5b0 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Wed, 19 Apr 2023 18:34:35 -0700 Subject: [PATCH 2652/2991] Ensure `selected` field is correct in `updateSelectionState()` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Bartłomiej Dach --- osu.Game/Overlays/Music/PlaylistItem.cs | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 4032af7651..4a39cc06c8 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -56,7 +56,7 @@ namespace osu.Game.Overlays.Music var artist = new RomanisableString(metadata.ArtistUnicode, metadata.Artist); titlePart = text.AddText(title, sprite => sprite.Font = OsuFont.GetFont(weight: FontWeight.Regular)); - titlePart.DrawablePartsRecreated += _ => updateSelectionState(true); + titlePart.DrawablePartsRecreated += _ => updateSelectionState(SelectedSet.Value, instant: true); text.AddText(@" "); // to separate the title from the artist. text.AddText(artist, sprite => @@ -66,25 +66,22 @@ namespace osu.Game.Overlays.Music sprite.Padding = new MarginPadding { Top = 1 }; }); - SelectedSet.BindValueChanged(set => - { - bool newSelected = set.NewValue?.Equals(Model) == true; - - if (newSelected == selected) - return; - - selected = newSelected; - updateSelectionState(false); - }, true); - - updateSelectionState(true); + SelectedSet.BindValueChanged(set => updateSelectionState(set.NewValue, instant: false)); + updateSelectionState(SelectedSet.Value, instant: true); }); } private bool selected; - private void updateSelectionState(bool instant) + private void updateSelectionState(Live selectedSet, bool instant) { + bool newSelected = selectedSet?.Equals(Model) == true; + + if (newSelected == selected && !instant) // instant updates should forcibly set correct state regardless of previous state. + return; + + selected = newSelected; + foreach (Drawable s in titlePart.Drawables) s.FadeColour(selected ? colours.Yellow : Color4.White, instant ? 0 : FADE_DURATION); } From 9f4b1f0f242a95ab2df2e77e2f2670ae5f846364 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Apr 2023 14:30:01 +0900 Subject: [PATCH 2653/2991] Always round editor rotation to integer values --- .../Edit/Compose/Components/SelectionBoxRotationHandle.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs index 305f5bf3c4..c2a3f12efd 100644 --- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs +++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs @@ -118,7 +118,7 @@ namespace osu.Game.Screens.Edit.Compose.Components { float oldRotation = cumulativeRotation.Value ?? 0; - float newRotation = shouldSnap ? snap(rawCumulativeRotation, snap_step) : rawCumulativeRotation; + float newRotation = shouldSnap ? snap(rawCumulativeRotation, snap_step) : MathF.Round(rawCumulativeRotation); newRotation = (newRotation - 180) % 360 + 180; cumulativeRotation.Value = newRotation; From 1066dfcbf6bddb1378652b22d1d9922f6d4e5eb7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Apr 2023 14:35:12 +0900 Subject: [PATCH 2654/2991] Change default beat divisor to 4 This matches stable, and is a much saner default value. Will apply to new beatmaps and also beatmaps which don't specify a snap value in the `.osu` file. --- osu.Game/Beatmaps/BeatmapInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 3208598f56..63e878b80d 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -167,7 +167,7 @@ namespace osu.Game.Beatmaps /// public double DistanceSpacing { get; set; } = 1.0; - public int BeatDivisor { get; set; } + public int BeatDivisor { get; set; } = 4; public int GridSize { get; set; } From b62de5514c532a3c2df5ef4c311eb5b273578050 Mon Sep 17 00:00:00 2001 From: Haspamelodica Date: Fri, 21 Apr 2023 02:10:24 +0200 Subject: [PATCH 2655/2991] Fixed video importing bug #23259 --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 2 +- osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs | 2 +- osu.Game/OsuGameBase.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index cab49b7d69..6af6a25579 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -368,7 +368,7 @@ namespace osu.Game.Beatmaps // user requested abort return; - var video = b.Files.FirstOrDefault(f => OsuGameBase.VIDEO_EXTENSIONS.Any(ex => f.Filename.EndsWith(ex, StringComparison.Ordinal))); + var video = b.Files.FirstOrDefault(f => OsuGameBase.VIDEO_EXTENSIONS.Any(ex => f.Filename.EndsWith(ex, StringComparison.OrdinalIgnoreCase))); if (video != null) { diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index a9bdd21b64..0e3a62e8fa 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -369,7 +369,7 @@ namespace osu.Game.Beatmaps.Formats // Some very old beatmaps had incorrect type specifications for their backgrounds (ie. using 1 for VIDEO // instead of 0 for BACKGROUND). To handle this gracefully, check the file extension against known supported // video extensions and handle similar to a background if it doesn't match. - if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(filename))) + if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(filename).ToUpperInvariant())) { beatmap.BeatmapInfo.Metadata.BackgroundFile = filename; } diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index f8308fe431..2eb496a798 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -114,7 +114,7 @@ namespace osu.Game.Beatmaps.Formats // // This avoids potential weird crashes when ffmpeg attempts to parse an image file as a video // (see https://github.com/ppy/osu/issues/22829#issuecomment-1465552451). - if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(path))) + if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(path).ToUpperInvariant())) break; storyboard.GetLayer("Video").Add(new StoryboardVideo(path, offset)); diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs b/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs index 37e15c6127..825b1a5636 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs @@ -70,7 +70,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 { get { - if (OsuGameBase.VIDEO_EXTENSIONS.Contains(File.Extension)) + if (OsuGameBase.VIDEO_EXTENSIONS.Contains(File.Extension.ToUpperInvariant())) return FontAwesome.Regular.FileVideo; switch (File.Extension) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 34e31b0d61..2ab6c24af7 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -71,7 +71,7 @@ namespace osu.Game [Cached(typeof(OsuGameBase))] public partial class OsuGameBase : Framework.Game, ICanAcceptFiles, IBeatSyncProvider { - public static readonly string[] VIDEO_EXTENSIONS = { ".mp4", ".mov", ".avi", ".flv", ".mpg", ".wmv", ".m4v" }; + public static readonly string[] VIDEO_EXTENSIONS = { ".MP4", ".MOV", ".AVI", ".FLV", ".MPG", ".WMV", ".M4V" }; public const string OSU_PROTOCOL = "osu://"; From e90660c1a48c7eb46447348756ca2b976ca1bbf6 Mon Sep 17 00:00:00 2001 From: Haspamelodica Date: Fri, 21 Apr 2023 02:35:28 +0200 Subject: [PATCH 2656/2991] Switched to lowercase --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 2 +- osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs | 2 +- osu.Game/OsuGameBase.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 0e3a62e8fa..ef1dbc0488 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -369,7 +369,7 @@ namespace osu.Game.Beatmaps.Formats // Some very old beatmaps had incorrect type specifications for their backgrounds (ie. using 1 for VIDEO // instead of 0 for BACKGROUND). To handle this gracefully, check the file extension against known supported // video extensions and handle similar to a background if it doesn't match. - if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(filename).ToUpperInvariant())) + if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(filename).ToLowerInvariant())) { beatmap.BeatmapInfo.Metadata.BackgroundFile = filename; } diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 2eb496a798..df5d3edb55 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -114,7 +114,7 @@ namespace osu.Game.Beatmaps.Formats // // This avoids potential weird crashes when ffmpeg attempts to parse an image file as a video // (see https://github.com/ppy/osu/issues/22829#issuecomment-1465552451). - if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(path).ToUpperInvariant())) + if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(path).ToLowerInvariant())) break; storyboard.GetLayer("Video").Add(new StoryboardVideo(path, offset)); diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs b/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs index 825b1a5636..7097102335 100644 --- a/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs +++ b/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs @@ -70,7 +70,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 { get { - if (OsuGameBase.VIDEO_EXTENSIONS.Contains(File.Extension.ToUpperInvariant())) + if (OsuGameBase.VIDEO_EXTENSIONS.Contains(File.Extension.ToLowerInvariant())) return FontAwesome.Regular.FileVideo; switch (File.Extension) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 2ab6c24af7..34e31b0d61 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -71,7 +71,7 @@ namespace osu.Game [Cached(typeof(OsuGameBase))] public partial class OsuGameBase : Framework.Game, ICanAcceptFiles, IBeatSyncProvider { - public static readonly string[] VIDEO_EXTENSIONS = { ".MP4", ".MOV", ".AVI", ".FLV", ".MPG", ".WMV", ".M4V" }; + public static readonly string[] VIDEO_EXTENSIONS = { ".mp4", ".mov", ".avi", ".flv", ".mpg", ".wmv", ".m4v" }; public const string OSU_PROTOCOL = "osu://"; From e9fb836e9ccfbd6690ffcf5c6974e2d125a5fb80 Mon Sep 17 00:00:00 2001 From: Haspamelodica Date: Fri, 21 Apr 2023 03:24:11 +0200 Subject: [PATCH 2657/2991] Added tests for video backgrounds --- .../Formats/LegacyBeatmapDecoderTest.cs | 31 +++++++++++++++ .../Formats/LegacyStoryboardDecoderTest.cs | 38 ++++++++++++++++++- .../video-with-lowercase-extension.osb | 5 +++ .../video-with-uppercase-extension.osb | 5 +++ 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Tests/Resources/video-with-lowercase-extension.osb create mode 100644 osu.Game.Tests/Resources/video-with-uppercase-extension.osb diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 518981980b..5979f6785e 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -21,6 +21,7 @@ using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Skinning; +using osu.Game.Storyboards; using osu.Game.Tests.Resources; using osuTK; using osuTK.Graphics; @@ -160,6 +161,36 @@ namespace osu.Game.Tests.Beatmaps.Formats } } + [Test] + public void TestDecodeVideoWithLowercaseExtension() + { + var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; + + using (var resStream = TestResources.OpenResource("video-with-lowercase-extension.osb")) + using (var stream = new LineBufferedReader(resStream)) + { + var beatmap = decoder.Decode(stream); + var metadata = beatmap.Metadata; + + Assert.AreEqual("BG.jpg", metadata.BackgroundFile); + } + } + + [Test] + public void TestDecodeVideoWithUppercaseExtension() + { + var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; + + using (var resStream = TestResources.OpenResource("video-with-uppercase-extension.osb")) + using (var stream = new LineBufferedReader(resStream)) + { + var beatmap = decoder.Decode(stream); + var metadata = beatmap.Metadata; + + Assert.AreEqual("BG.jpg", metadata.BackgroundFile); + } + } + [Test] public void TestDecodeImageSpecifiedAsVideo() { diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs index 3a776ac225..1bfe134610 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs @@ -169,6 +169,40 @@ namespace osu.Game.Tests.Beatmaps.Formats } } + [Test] + public void TestDecodeVideoWithLowercaseExtension() + { + var decoder = new LegacyStoryboardDecoder(); + + using (var resStream = TestResources.OpenResource("video-with-lowercase-extension.osb")) + using (var stream = new LineBufferedReader(resStream)) + { + var storyboard = decoder.Decode(stream); + + StoryboardLayer video = storyboard.Layers.Single(l => l.Name == "Video"); + Assert.That(video.Elements.Count, Is.EqualTo(1)); + + Assert.AreEqual("Video.avi", ((StoryboardVideo)video.Elements[0]).Path); + } + } + + [Test] + public void TestDecodeVideoWithUppercaseExtension() + { + var decoder = new LegacyStoryboardDecoder(); + + using (var resStream = TestResources.OpenResource("video-with-uppercase-extension.osb")) + using (var stream = new LineBufferedReader(resStream)) + { + var storyboard = decoder.Decode(stream); + + StoryboardLayer video = storyboard.Layers.Single(l => l.Name == "Video"); + Assert.That(video.Elements.Count, Is.EqualTo(1)); + + Assert.AreEqual("Video.AVI", ((StoryboardVideo)video.Elements[0]).Path); + } + } + [Test] public void TestDecodeImageSpecifiedAsVideo() { @@ -179,8 +213,8 @@ namespace osu.Game.Tests.Beatmaps.Formats { var storyboard = decoder.Decode(stream); - StoryboardLayer foreground = storyboard.Layers.Single(l => l.Name == "Video"); - Assert.That(foreground.Elements.Count, Is.Zero); + StoryboardLayer video = storyboard.Layers.Single(l => l.Name == "Video"); + Assert.That(video.Elements.Count, Is.Zero); } } diff --git a/osu.Game.Tests/Resources/video-with-lowercase-extension.osb b/osu.Game.Tests/Resources/video-with-lowercase-extension.osb new file mode 100644 index 0000000000..eec09722ed --- /dev/null +++ b/osu.Game.Tests/Resources/video-with-lowercase-extension.osb @@ -0,0 +1,5 @@ +osu file format v14 + +[Events] +0,0,"BG.jpg",0,0 +Video,0,"Video.avi",0,0 diff --git a/osu.Game.Tests/Resources/video-with-uppercase-extension.osb b/osu.Game.Tests/Resources/video-with-uppercase-extension.osb new file mode 100644 index 0000000000..3834a547f2 --- /dev/null +++ b/osu.Game.Tests/Resources/video-with-uppercase-extension.osb @@ -0,0 +1,5 @@ +osu file format v14 + +[Events] +0,0,"BG.jpg",0,0 +Video,0,"Video.AVI",0,0 From 3166f88c17a291724f03b2bb53ca96413864a443 Mon Sep 17 00:00:00 2001 From: Haspamelodica Date: Fri, 21 Apr 2023 10:11:47 +0200 Subject: [PATCH 2658/2991] Removed unneccessary using directive --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 5979f6785e..d898650b66 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -21,7 +21,6 @@ using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Skinning; -using osu.Game.Storyboards; using osu.Game.Tests.Resources; using osuTK; using osuTK.Graphics; From 847b63066b9e08255026c3c530ebb5acab9ab5a4 Mon Sep 17 00:00:00 2001 From: Terochi Date: Fri, 21 Apr 2023 21:46:03 +0200 Subject: [PATCH 2659/2991] fix --- osu.Game.Rulesets.Catch/UI/Catcher.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index ab754e51f7..7787dd80c1 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -418,10 +418,13 @@ namespace osu.Game.Rulesets.Catch.UI private void clearPlate(DroppedObjectAnimation animation) { - var droppedObjects = caughtObjectContainer.Children.Select(getDroppedObject).ToArray(); + var caughtObjects = caughtObjectContainer.Children.ToArray(); caughtObjectContainer.Clear(false); + //use the already returned PoolableDrawables for new objects + var droppedObjects = caughtObjects.Select(getDroppedObject).ToArray(); + droppedObjectTarget.AddRange(droppedObjects); foreach (var droppedObject in droppedObjects) @@ -430,13 +433,11 @@ namespace osu.Game.Rulesets.Catch.UI private void removeFromPlate(CaughtObject caughtObject, DroppedObjectAnimation animation) { - var droppedObject = getDroppedObject(caughtObject); - caughtObjectContainer.Remove(caughtObject, false); - droppedObjectTarget.Add(droppedObject); + droppedObjectTarget.Add(getDroppedObject(caughtObject)); - applyDropAnimation(droppedObject, animation); + applyDropAnimation(caughtObject, animation); } private void applyDropAnimation(Drawable d, DroppedObjectAnimation animation) @@ -456,6 +457,8 @@ namespace osu.Game.Rulesets.Catch.UI break; } + //define lifetime start for dropped objects to be disposed correctly when rewinding replay + d.LifetimeStart = Clock.CurrentTime; d.Expire(); } From bb1ed387ef29958bcc8f8006cebfad2ead9dc8c8 Mon Sep 17 00:00:00 2001 From: Terochi Date: Sat, 22 Apr 2023 10:54:50 +0200 Subject: [PATCH 2660/2991] fixed missed bit and comments --- osu.Game.Rulesets.Catch/UI/Catcher.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 7787dd80c1..f77dab56c8 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -422,7 +422,7 @@ namespace osu.Game.Rulesets.Catch.UI caughtObjectContainer.Clear(false); - //use the already returned PoolableDrawables for new objects + // Use the already returned PoolableDrawables for new objects var droppedObjects = caughtObjects.Select(getDroppedObject).ToArray(); droppedObjectTarget.AddRange(droppedObjects); @@ -435,9 +435,11 @@ namespace osu.Game.Rulesets.Catch.UI { caughtObjectContainer.Remove(caughtObject, false); - droppedObjectTarget.Add(getDroppedObject(caughtObject)); + var droppedObject = getDroppedObject(caughtObject); - applyDropAnimation(caughtObject, animation); + droppedObjectTarget.Add(droppedObject); + + applyDropAnimation(droppedObject, animation); } private void applyDropAnimation(Drawable d, DroppedObjectAnimation animation) @@ -457,7 +459,7 @@ namespace osu.Game.Rulesets.Catch.UI break; } - //define lifetime start for dropped objects to be disposed correctly when rewinding replay + // Define lifetime start for dropped objects to be disposed correctly when rewinding replay d.LifetimeStart = Clock.CurrentTime; d.Expire(); } From 56ab029a58eeff34f1f976fb956b7f042d8c79df Mon Sep 17 00:00:00 2001 From: Hy0tic Date: Sat, 22 Apr 2023 13:30:08 -0400 Subject: [PATCH 2661/2991] fix issue where multipler does not update when adjusting speed for preset mod --- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 16602db4be..d611fd3c0b 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -252,7 +252,7 @@ namespace osu.Game.Overlays.Mods if (AllowCustomisation) { - modSettingChangeTracker = new ModSettingChangeTracker(val.NewValue); + modSettingChangeTracker = new ModSettingChangeTracker(SelectedMods.Value); modSettingChangeTracker.SettingChanged += _ => updateMultiplier(); } }, true); From 3919400be2c0d2dddc287ca8bda36677dfb029fe Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Apr 2023 14:28:56 +0900 Subject: [PATCH 2662/2991] Apply NRT to some storyboard classes --- osu.Game/Storyboards/StoryboardAnimation.cs | 2 -- osu.Game/Storyboards/StoryboardSprite.cs | 13 +++++-------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/osu.Game/Storyboards/StoryboardAnimation.cs b/osu.Game/Storyboards/StoryboardAnimation.cs index 16deac8e9e..1a4b6bb923 100644 --- a/osu.Game/Storyboards/StoryboardAnimation.cs +++ b/osu.Game/Storyboards/StoryboardAnimation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osuTK; using osu.Framework.Graphics; using osu.Game.Storyboards.Drawables; diff --git a/osu.Game/Storyboards/StoryboardSprite.cs b/osu.Game/Storyboards/StoryboardSprite.cs index 5b7b194be7..0c28d7bce1 100644 --- a/osu.Game/Storyboards/StoryboardSprite.cs +++ b/osu.Game/Storyboards/StoryboardSprite.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Graphics; using osu.Game.Storyboards.Drawables; using osuTK; @@ -114,7 +111,7 @@ namespace osu.Game.Storyboards public virtual Drawable CreateDrawable() => new DrawableStoryboardSprite(this); - public void ApplyTransforms(Drawable drawable, IEnumerable> triggeredGroups = null) + public void ApplyTransforms(Drawable drawable, IEnumerable>? triggeredGroups = null) { // For performance reasons, we need to apply the commands in order by start time. Not doing so will cause many functions to be interleaved, resulting in O(n^2) complexity. // To achieve this, commands are "generated" as pairs of (command, initFunc, transformFunc) and batched into a contiguous list @@ -156,7 +153,7 @@ namespace osu.Game.Storyboards foreach (var command in commands) { - DrawablePropertyInitializer initFunc = null; + DrawablePropertyInitializer? initFunc = null; if (!initialized) { @@ -169,7 +166,7 @@ namespace osu.Game.Storyboards } } - private IEnumerable.TypedCommand> getCommands(CommandTimelineSelector timelineSelector, IEnumerable> triggeredGroups) + private IEnumerable.TypedCommand> getCommands(CommandTimelineSelector timelineSelector, IEnumerable>? triggeredGroups) { var commands = TimelineGroup.GetCommands(timelineSelector); foreach (var loop in loops) @@ -198,11 +195,11 @@ namespace osu.Game.Storyboards { public double StartTime => command.StartTime; - private readonly DrawablePropertyInitializer initializeProperty; + private readonly DrawablePropertyInitializer? initializeProperty; private readonly DrawableTransformer transform; private readonly CommandTimeline.TypedCommand command; - public GeneratedCommand([NotNull] CommandTimeline.TypedCommand command, [CanBeNull] DrawablePropertyInitializer initializeProperty, [NotNull] DrawableTransformer transform) + public GeneratedCommand(CommandTimeline.TypedCommand command, DrawablePropertyInitializer? initializeProperty, DrawableTransformer transform) { this.command = command; this.initializeProperty = initializeProperty; From dce0c5fac815b4334a921b81989baf2d06e3c57c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Apr 2023 15:14:32 +0900 Subject: [PATCH 2663/2991] Add test coverage of expected behaviour for playback of loops with no explicit end time --- .../Formats/LegacyStoryboardDecoderTest.cs | 19 +++++++++++++++++++ .../animation-loop-no-explicit-end-time.osb | 6 ++++++ 2 files changed, 25 insertions(+) create mode 100644 osu.Game.Tests/Resources/animation-loop-no-explicit-end-time.osb diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs index 3a776ac225..17e94a8b5f 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs @@ -95,6 +95,25 @@ namespace osu.Game.Tests.Beatmaps.Formats } } + [Test] + public void TestLoopWithoutExplicitFadeOut() + { + var decoder = new LegacyStoryboardDecoder(); + + using (var resStream = TestResources.OpenResource("animation-loop-no-explicit-end-time.osb")) + using (var stream = new LineBufferedReader(resStream)) + { + var storyboard = decoder.Decode(stream); + + StoryboardLayer background = storyboard.Layers.Single(l => l.Depth == 3); + Assert.AreEqual(1, background.Elements.Count); + + Assert.AreEqual(2000, background.Elements[0].StartTime); + Assert.AreEqual(2000, (background.Elements[0] as StoryboardAnimation)?.EarliestTransformTime); + Assert.AreEqual(12000, (background.Elements[0] as StoryboardAnimation)?.GetEndTime()); + } + } + [Test] public void TestCorrectAnimationStartTime() { diff --git a/osu.Game.Tests/Resources/animation-loop-no-explicit-end-time.osb b/osu.Game.Tests/Resources/animation-loop-no-explicit-end-time.osb new file mode 100644 index 0000000000..7afaa445df --- /dev/null +++ b/osu.Game.Tests/Resources/animation-loop-no-explicit-end-time.osb @@ -0,0 +1,6 @@ +[Events] +//Storyboard Layer 0 (Background) +Animation,Background,Centre,"img.jpg",320,240,2,150,LoopForever + F,0,2000,,0,1 + L,2000,10 + F,18,0,1000,1,0 From e330052852a8692c769ed2152a5980a16679b576 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Apr 2023 15:22:11 +0900 Subject: [PATCH 2664/2991] Add second definition of `EndTime` for storyboard elements to account for loops in lifetime --- .../Beatmaps/Formats/LegacyStoryboardDecoderTest.cs | 4 +++- .../Background/TestSceneBackgroundScreenDefault.cs | 1 + .../Storyboards/IStoryboardElementWithDuration.cs | 8 ++++++++ osu.Game/Storyboards/StoryboardSprite.cs | 13 +++++++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs index 17e94a8b5f..f78825ffb1 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs @@ -110,7 +110,9 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(2000, background.Elements[0].StartTime); Assert.AreEqual(2000, (background.Elements[0] as StoryboardAnimation)?.EarliestTransformTime); - Assert.AreEqual(12000, (background.Elements[0] as StoryboardAnimation)?.GetEndTime()); + + Assert.AreEqual(3000, (background.Elements[0] as StoryboardAnimation)?.GetEndTime()); + Assert.AreEqual(12000, (background.Elements[0] as StoryboardAnimation)?.EndTimeForDisplay); } } diff --git a/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs b/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs index fbdaad1cd8..8f4250799e 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs @@ -311,6 +311,7 @@ namespace osu.Game.Tests.Visual.Background public bool IsDrawable => true; public double StartTime => double.MinValue; public double EndTime => double.MaxValue; + public double EndTimeForDisplay => double.MaxValue; public Drawable CreateDrawable() => new DrawableTestStoryboardElement(); } diff --git a/osu.Game/Storyboards/IStoryboardElementWithDuration.cs b/osu.Game/Storyboards/IStoryboardElementWithDuration.cs index c8daeb3b3d..9eed139ad4 100644 --- a/osu.Game/Storyboards/IStoryboardElementWithDuration.cs +++ b/osu.Game/Storyboards/IStoryboardElementWithDuration.cs @@ -12,9 +12,17 @@ namespace osu.Game.Storyboards { /// /// The time at which the ends. + /// This is consumed to extend the length of a storyboard to ensure all visuals are played to completion. /// double EndTime { get; } + /// + /// The time this element displays until. + /// This is used for lifetime purposes, and includes long playing animations which don't necessarily extend + /// a storyboard's play time. + /// + double EndTimeForDisplay { get; } + /// /// The duration of the StoryboardElement. /// diff --git a/osu.Game/Storyboards/StoryboardSprite.cs b/osu.Game/Storyboards/StoryboardSprite.cs index 0c28d7bce1..982185d51b 100644 --- a/osu.Game/Storyboards/StoryboardSprite.cs +++ b/osu.Game/Storyboards/StoryboardSprite.cs @@ -81,6 +81,19 @@ namespace osu.Game.Storyboards } } + public double EndTimeForDisplay + { + get + { + double latestEndTime = TimelineGroup.EndTime; + + foreach (var l in loops) + latestEndTime = Math.Max(latestEndTime, l.StartTime + l.CommandsDuration * l.TotalIterations); + + return latestEndTime; + } + } + public bool HasCommands => TimelineGroup.HasCommands || loops.Any(l => l.HasCommands); private delegate void DrawablePropertyInitializer(Drawable drawable, T value); From a4c6850ab2e64fc2a195744af8b02fd6c61a4726 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Tue, 25 Apr 2023 11:34:09 +0200 Subject: [PATCH 2665/2991] made the SampleControlPoint and DifficultyControlPoint obsolete --- .../Legacy/DistanceObjectPatternGenerator.cs | 11 ++-- osu.Game.Rulesets.Osu/Objects/Slider.cs | 32 +++++++--- .../Beatmaps/TaikoBeatmapConverter.cs | 11 ++-- .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 3 + osu.Game/Rulesets/Objects/HitObject.cs | 61 ++++++++++++------- .../Rulesets/Objects/Legacy/ConvertSlider.cs | 15 ++++- .../Objects/Types/IHasSliderVelocity.cs | 15 +++++ 7 files changed, 105 insertions(+), 43 deletions(-) create mode 100644 osu.Game/Rulesets/Objects/Types/IHasSliderVelocity.cs diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 2bdd0e16ad..9e031c2b4d 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -49,15 +49,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy Debug.Assert(distanceData != null); TimingControlPoint timingPoint = beatmap.ControlPointInfo.TimingPointAt(hitObject.StartTime); - DifficultyControlPoint difficultyPoint = hitObject.DifficultyControlPoint; double beatLength; -#pragma warning disable 618 - if (difficultyPoint is LegacyBeatmapDecoder.LegacyDifficultyControlPoint legacyDifficultyPoint) -#pragma warning restore 618 - beatLength = timingPoint.BeatLength * legacyDifficultyPoint.BpmMultiplier; + if (hitObject.LegacyBpmMultiplier.HasValue) + beatLength = timingPoint.BeatLength * hitObject.LegacyBpmMultiplier.Value; + else if (hitObject is IHasSliderVelocity hasSliderVelocity) + beatLength = timingPoint.BeatLength / hasSliderVelocity.SliderVelocity; else - beatLength = timingPoint.BeatLength / difficultyPoint.SliderVelocity; + beatLength = timingPoint.BeatLength; SpanCount = repeatsData?.SpanCount() ?? 1; StartTime = (int)Math.Round(hitObject.StartTime); diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 6c2be8a49a..6952033aec 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -8,6 +8,7 @@ using osu.Game.Rulesets.Objects.Types; using System.Collections.Generic; using osu.Game.Rulesets.Objects; using System.Linq; +using System.Text.Json.Serialization; using System.Threading; using Newtonsoft.Json; using osu.Framework.Caching; @@ -15,13 +16,14 @@ using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Formats; +using osu.Game.Beatmaps.Legacy; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Osu.Objects { - public class Slider : OsuHitObject, IHasPathWithRepeats + public class Slider : OsuHitObject, IHasPathWithRepeats, IHasSliderVelocity { public double EndTime => StartTime + this.SpanCount() * Path.Distance / Velocity; @@ -134,6 +136,13 @@ namespace osu.Game.Rulesets.Osu.Objects /// public bool OnlyJudgeNestedObjects = true; + public double SliderVelocity { get; set; } = 1; + + /// + /// Whether to generate ticks on this . + /// + public bool GenerateTicks = true; + [JsonIgnore] public SliderHeadCircle HeadCircle { get; protected set; } @@ -151,15 +160,24 @@ namespace osu.Game.Rulesets.Osu.Objects base.ApplyDefaultsToSelf(controlPointInfo, difficulty); TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); -#pragma warning disable 618 - var legacyDifficultyPoint = DifficultyControlPoint as LegacyBeatmapDecoder.LegacyDifficultyControlPoint; -#pragma warning restore 618 - double scoringDistance = BASE_SCORING_DISTANCE * difficulty.SliderMultiplier * DifficultyControlPoint.SliderVelocity; - bool generateTicks = legacyDifficultyPoint?.GenerateTicks ?? true; + double scoringDistance = BASE_SCORING_DISTANCE * difficulty.SliderMultiplier * SliderVelocity; Velocity = scoringDistance / timingPoint.BeatLength; - TickDistance = generateTicks ? (scoringDistance / difficulty.SliderTickRate * TickDistanceMultiplier) : double.PositiveInfinity; + TickDistance = GenerateTicks ? (scoringDistance / difficulty.SliderTickRate * TickDistanceMultiplier) : double.PositiveInfinity; + } + + protected override void ApplyLegacyInfoToSelf(ControlPointInfo controlPointInfo, IBeatmapDifficultyInfo difficulty) + { + base.ApplyLegacyInfoToSelf(controlPointInfo, difficulty); + + DifficultyControlPoint difficultyControlPoint = controlPointInfo is LegacyControlPointInfo legacyInfo ? legacyInfo.DifficultyPointAt(StartTime) : DifficultyControlPoint.DEFAULT; +#pragma warning disable 618 + var legacyDifficultyPoint = difficultyControlPoint as LegacyBeatmapDecoder.LegacyDifficultyControlPoint; +#pragma warning restore 618 + + SliderVelocity = difficultyControlPoint.SliderVelocity; + GenerateTicks = legacyDifficultyPoint?.GenerateTicks ?? true; } protected override void CreateNestedHitObjects(CancellationToken cancellationToken) diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 6a35e9376b..362ddccaf1 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -177,15 +177,14 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps double distance = distanceData.Distance * spans * LegacyBeatmapEncoder.LEGACY_TAIKO_VELOCITY_MULTIPLIER; TimingControlPoint timingPoint = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime); - DifficultyControlPoint difficultyPoint = obj.DifficultyControlPoint; double beatLength; -#pragma warning disable 618 - if (difficultyPoint is LegacyBeatmapDecoder.LegacyDifficultyControlPoint legacyDifficultyPoint) -#pragma warning restore 618 - beatLength = timingPoint.BeatLength * legacyDifficultyPoint.BpmMultiplier; + if (obj.LegacyBpmMultiplier.HasValue) + beatLength = timingPoint.BeatLength * obj.LegacyBpmMultiplier.Value; + else if (obj is IHasSliderVelocity hasSliderVelocity) + beatLength = timingPoint.BeatLength / hasSliderVelocity.SliderVelocity; else - beatLength = timingPoint.BeatLength / difficultyPoint.SliderVelocity; + beatLength = timingPoint.BeatLength; double sliderScoringPointDistance = osu_base_scoring_distance * beatmap.Difficulty.SliderMultiplier / beatmap.Difficulty.SliderTickRate; diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index a9bdd21b64..c17eea0e85 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -85,7 +85,10 @@ namespace osu.Game.Beatmaps.Formats this.beatmap.HitObjects = this.beatmap.HitObjects.OrderBy(h => h.StartTime).ToList(); foreach (var hitObject in this.beatmap.HitObjects) + { + hitObject.ApplyLegacyInfo(this.beatmap.ControlPointInfo, this.beatmap.Difficulty); hitObject.ApplyDefaults(this.beatmap.ControlPointInfo, this.beatmap.Difficulty); + } } /// diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 25f538d211..aea564a4b9 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -16,6 +16,7 @@ using osu.Framework.Lists; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Legacy; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Types; @@ -80,6 +81,12 @@ namespace osu.Game.Rulesets.Objects public SampleControlPoint SampleControlPoint = SampleControlPoint.DEFAULT; public DifficultyControlPoint DifficultyControlPoint = DifficultyControlPoint.DEFAULT; + /// + /// Legacy BPM multiplier that introduces floating-point errors for rulesets that depend on it. + /// DO NOT USE THIS UNLESS 100% SURE. + /// + public double? LegacyBpmMultiplier { get; private set; } + /// /// Whether this is in Kiai time. /// @@ -105,25 +112,6 @@ namespace osu.Game.Rulesets.Objects /// The cancellation token. public void ApplyDefaults(ControlPointInfo controlPointInfo, IBeatmapDifficultyInfo difficulty, CancellationToken cancellationToken = default) { - var legacyInfo = controlPointInfo as LegacyControlPointInfo; - - if (legacyInfo != null) - DifficultyControlPoint = (DifficultyControlPoint)legacyInfo.DifficultyPointAt(StartTime).DeepClone(); - else if (ReferenceEquals(DifficultyControlPoint, DifficultyControlPoint.DEFAULT)) - DifficultyControlPoint = new DifficultyControlPoint(); - - DifficultyControlPoint.Time = StartTime; - - ApplyDefaultsToSelf(controlPointInfo, difficulty); - - // This is done here after ApplyDefaultsToSelf as we may require custom defaults to be applied to have an accurate end time. - if (legacyInfo != null) - SampleControlPoint = (SampleControlPoint)legacyInfo.SamplePointAt(this.GetEndTime() + control_point_leniency).DeepClone(); - else if (ReferenceEquals(SampleControlPoint, SampleControlPoint.DEFAULT)) - SampleControlPoint = new SampleControlPoint(); - - SampleControlPoint.Time = this.GetEndTime() + control_point_leniency; - nestedHitObjects.Clear(); CreateNestedHitObjects(cancellationToken); @@ -164,9 +152,6 @@ namespace osu.Game.Rulesets.Objects foreach (var nested in nestedHitObjects) nested.StartTime += offset; - - DifficultyControlPoint.Time = time.NewValue; - SampleControlPoint.Time = this.GetEndTime() + control_point_leniency; } } @@ -178,6 +163,38 @@ namespace osu.Game.Rulesets.Objects HitWindows?.SetDifficulty(difficulty.OverallDifficulty); } + /// + /// Applies legacy information to this HitObject. + /// This method gets called at the end of before applying defaults. + /// + /// The control points. + /// The difficulty settings to use. + /// The cancellation token. + public void ApplyLegacyInfo(ControlPointInfo controlPointInfo, IBeatmapDifficultyInfo difficulty, CancellationToken cancellationToken = default) + { + var legacyInfo = controlPointInfo as LegacyControlPointInfo; + + DifficultyControlPoint difficultyControlPoint = legacyInfo != null ? legacyInfo.DifficultyPointAt(StartTime) : DifficultyControlPoint.DEFAULT; +#pragma warning disable 618 + if (difficultyControlPoint is LegacyBeatmapDecoder.LegacyDifficultyControlPoint legacyDifficultyControlPoint) +#pragma warning restore 618 + LegacyBpmMultiplier = legacyDifficultyControlPoint.BpmMultiplier; + + ApplyLegacyInfoToSelf(controlPointInfo, difficulty); + + // This is done here after ApplyLegacyInfoToSelf as we may require custom defaults to be applied to have an accurate end time. + SampleControlPoint sampleControlPoint = legacyInfo != null ? legacyInfo.SamplePointAt(this.GetEndTime() + control_point_leniency) : SampleControlPoint.DEFAULT; + + foreach (var hitSampleInfo in Samples) + { + sampleControlPoint.ApplyTo(hitSampleInfo); + } + } + + protected virtual void ApplyLegacyInfoToSelf(ControlPointInfo controlPointInfo, IBeatmapDifficultyInfo difficulty) + { + } + protected virtual void CreateNestedHitObjects(CancellationToken cancellationToken) { } diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index bd2713a7d1..11e1f0beae 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -9,10 +9,11 @@ using Newtonsoft.Json; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Beatmaps.Legacy; namespace osu.Game.Rulesets.Objects.Legacy { - internal abstract class ConvertSlider : ConvertHitObject, IHasPathWithRepeats, IHasLegacyLastTickOffset + internal abstract class ConvertSlider : ConvertHitObject, IHasPathWithRepeats, IHasLegacyLastTickOffset, IHasSliderVelocity { /// /// Scoring distance with a speed-adjusted beat length of 1 second. @@ -40,17 +41,27 @@ namespace osu.Game.Rulesets.Objects.Legacy public double Velocity = 1; + public double SliderVelocity { get; set; } = 1; + protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, IBeatmapDifficultyInfo difficulty) { base.ApplyDefaultsToSelf(controlPointInfo, difficulty); TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); - double scoringDistance = base_scoring_distance * difficulty.SliderMultiplier * DifficultyControlPoint.SliderVelocity; + double scoringDistance = base_scoring_distance * difficulty.SliderMultiplier * SliderVelocity; Velocity = scoringDistance / timingPoint.BeatLength; } + protected override void ApplyLegacyInfoToSelf(ControlPointInfo controlPointInfo, IBeatmapDifficultyInfo difficulty) + { + base.ApplyLegacyInfoToSelf(controlPointInfo, difficulty); + + DifficultyControlPoint difficultyControlPoint = controlPointInfo is LegacyControlPointInfo legacyInfo ? legacyInfo.DifficultyPointAt(StartTime) : DifficultyControlPoint.DEFAULT; + SliderVelocity = difficultyControlPoint.SliderVelocity; + } + public double LegacyLastTickOffset => 36; } } diff --git a/osu.Game/Rulesets/Objects/Types/IHasSliderVelocity.cs b/osu.Game/Rulesets/Objects/Types/IHasSliderVelocity.cs new file mode 100644 index 0000000000..a7195dab4b --- /dev/null +++ b/osu.Game/Rulesets/Objects/Types/IHasSliderVelocity.cs @@ -0,0 +1,15 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Rulesets.Objects.Types; + +/// +/// A HitObject that has a slider velocity multiplier. +/// +public interface IHasSliderVelocity +{ + /// + /// The slider velocity multiplier. + /// + double SliderVelocity { get; set; } +} From ea1e6e9798b7773bdf130febf4026edbd1caac52 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Tue, 25 Apr 2023 12:12:46 +0200 Subject: [PATCH 2666/2991] Add LegacyContext --- .../Legacy/DistanceObjectPatternGenerator.cs | 5 +- osu.Game.Rulesets.Osu/Objects/Slider.cs | 13 +-- .../Beatmaps/TaikoBeatmapConverter.cs | 5 +- .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 16 +++- osu.Game/Beatmaps/Legacy/LegacyContext.cs | 32 +++++++ osu.Game/Context/IContext.cs | 10 +++ osu.Game/Context/IHasContext.cs | 88 +++++++++++++++++++ osu.Game/Rulesets/Objects/HitObject.cs | 15 +--- 8 files changed, 155 insertions(+), 29 deletions(-) create mode 100644 osu.Game/Beatmaps/Legacy/LegacyContext.cs create mode 100644 osu.Game/Context/IContext.cs create mode 100644 osu.Game/Context/IHasContext.cs diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 9e031c2b4d..b3a68269f7 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -15,6 +15,7 @@ using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Formats; +using osu.Game.Beatmaps.Legacy; using osu.Game.Utils; namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy @@ -51,8 +52,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy TimingControlPoint timingPoint = beatmap.ControlPointInfo.TimingPointAt(hitObject.StartTime); double beatLength; - if (hitObject.LegacyBpmMultiplier.HasValue) - beatLength = timingPoint.BeatLength * hitObject.LegacyBpmMultiplier.Value; + if (hitObject.HasContext()) + beatLength = timingPoint.BeatLength * hitObject.GetContext().BpmMultiplier; else if (hitObject is IHasSliderVelocity hasSliderVelocity) beatLength = timingPoint.BeatLength / hasSliderVelocity.SliderVelocity; else diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 6952033aec..4010218f6e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -138,11 +138,6 @@ namespace osu.Game.Rulesets.Osu.Objects public double SliderVelocity { get; set; } = 1; - /// - /// Whether to generate ticks on this . - /// - public bool GenerateTicks = true; - [JsonIgnore] public SliderHeadCircle HeadCircle { get; protected set; } @@ -162,9 +157,10 @@ namespace osu.Game.Rulesets.Osu.Objects TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); double scoringDistance = BASE_SCORING_DISTANCE * difficulty.SliderMultiplier * SliderVelocity; + bool generateTicks = !HasContext() || GetContext().GenerateTicks; Velocity = scoringDistance / timingPoint.BeatLength; - TickDistance = GenerateTicks ? (scoringDistance / difficulty.SliderTickRate * TickDistanceMultiplier) : double.PositiveInfinity; + TickDistance = generateTicks ? (scoringDistance / difficulty.SliderTickRate * TickDistanceMultiplier) : double.PositiveInfinity; } protected override void ApplyLegacyInfoToSelf(ControlPointInfo controlPointInfo, IBeatmapDifficultyInfo difficulty) @@ -172,12 +168,7 @@ namespace osu.Game.Rulesets.Osu.Objects base.ApplyLegacyInfoToSelf(controlPointInfo, difficulty); DifficultyControlPoint difficultyControlPoint = controlPointInfo is LegacyControlPointInfo legacyInfo ? legacyInfo.DifficultyPointAt(StartTime) : DifficultyControlPoint.DEFAULT; -#pragma warning disable 618 - var legacyDifficultyPoint = difficultyControlPoint as LegacyBeatmapDecoder.LegacyDifficultyControlPoint; -#pragma warning restore 618 - SliderVelocity = difficultyControlPoint.SliderVelocity; - GenerateTicks = legacyDifficultyPoint?.GenerateTicks ?? true; } protected override void CreateNestedHitObjects(CancellationToken cancellationToken) diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 362ddccaf1..ef73ffd517 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -16,6 +16,7 @@ using JetBrains.Annotations; using osu.Game.Audio; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Formats; +using osu.Game.Beatmaps.Legacy; namespace osu.Game.Rulesets.Taiko.Beatmaps { @@ -179,8 +180,8 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps TimingControlPoint timingPoint = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime); double beatLength; - if (obj.LegacyBpmMultiplier.HasValue) - beatLength = timingPoint.BeatLength * obj.LegacyBpmMultiplier.Value; + if (obj.HasContext()) + beatLength = timingPoint.BeatLength * obj.GetContext().BpmMultiplier; else if (obj is IHasSliderVelocity hasSliderVelocity) beatLength = timingPoint.BeatLength / hasSliderVelocity.SliderVelocity; else diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index c17eea0e85..6f948e4d23 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -15,6 +15,7 @@ using osu.Game.Beatmaps.Legacy; using osu.Game.Beatmaps.Timing; using osu.Game.IO; using osu.Game.Rulesets; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Legacy; namespace osu.Game.Beatmaps.Formats @@ -86,11 +87,24 @@ namespace osu.Game.Beatmaps.Formats foreach (var hitObject in this.beatmap.HitObjects) { - hitObject.ApplyLegacyInfo(this.beatmap.ControlPointInfo, this.beatmap.Difficulty); + applyLegacyInfoToHitObject(hitObject); hitObject.ApplyDefaults(this.beatmap.ControlPointInfo, this.beatmap.Difficulty); } } + private void applyLegacyInfoToHitObject(HitObject hitObject) + { + var legacyInfo = beatmap.ControlPointInfo as LegacyControlPointInfo; + + DifficultyControlPoint difficultyControlPoint = legacyInfo != null ? legacyInfo.DifficultyPointAt(hitObject.StartTime) : DifficultyControlPoint.DEFAULT; +#pragma warning disable 618 + if (difficultyControlPoint is LegacyDifficultyControlPoint legacyDifficultyControlPoint) +#pragma warning restore 618 + hitObject.SetContext(new LegacyContext(legacyDifficultyControlPoint.BpmMultiplier, legacyDifficultyControlPoint.GenerateTicks)); + + hitObject.ApplyLegacyInfo(beatmap.ControlPointInfo, beatmap.Difficulty); + } + /// /// Some `BeatmapInfo` members have default values that differ from the default values used by stable. /// In addition, legacy beatmaps will sometimes not contain some configuration keys, in which case diff --git a/osu.Game/Beatmaps/Legacy/LegacyContext.cs b/osu.Game/Beatmaps/Legacy/LegacyContext.cs new file mode 100644 index 0000000000..eeb02bdcb7 --- /dev/null +++ b/osu.Game/Beatmaps/Legacy/LegacyContext.cs @@ -0,0 +1,32 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Context; + +namespace osu.Game.Beatmaps.Legacy; + +public class LegacyContext : IContext +{ + public LegacyContext(double bpmMultiplier, bool generateTicks) + { + BpmMultiplier = bpmMultiplier; + GenerateTicks = generateTicks; + } + + /// + /// Legacy BPM multiplier that introduces floating-point errors for rulesets that depend on it. + /// DO NOT USE THIS UNLESS 100% SURE. + /// + public double BpmMultiplier { get; } + + /// + /// Whether or not slider ticks should be generated at this control point. + /// This exists for backwards compatibility with maps that abuse NaN slider velocity behavior on osu!stable (e.g. /b/2628991). + /// + public bool GenerateTicks { get; } + + public IContext Copy() + { + return new LegacyContext(BpmMultiplier, GenerateTicks); + } +} diff --git a/osu.Game/Context/IContext.cs b/osu.Game/Context/IContext.cs new file mode 100644 index 0000000000..f70cdea9f8 --- /dev/null +++ b/osu.Game/Context/IContext.cs @@ -0,0 +1,10 @@ +namespace osu.Game.Context; + +public interface IContext +{ + /// + /// Makes a deep copy of this context. + /// + /// The deep copy of this context. + public IContext Copy(); +} diff --git a/osu.Game/Context/IHasContext.cs b/osu.Game/Context/IHasContext.cs new file mode 100644 index 0000000000..bee81ea555 --- /dev/null +++ b/osu.Game/Context/IHasContext.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; + +namespace osu.Game.Context +{ + public abstract class ContextContainer + { + /// + /// The contexts of this container. + /// The objects always have the type of their key. + /// + private readonly Dictionary contexts; + + protected ContextContainer() + { + contexts = new Dictionary(); + } + + /// + /// Checks whether this object has the context with type T. + /// + /// The type to check the context of. + /// Whether the context object with type T exists in this object. + public bool HasContext() where T : IContext + { + return contexts.ContainsKey(typeof(T)); + } + + /// + /// Gets the context with type T. + /// + /// The type to get the context of. + /// If the context does not exist in this hit object. + /// The context object with type T. + public T GetContext() where T : IContext + { + return (T)contexts[typeof(T)]; + } + + /// + /// Tries to get the context with type T. + /// + /// The found context with type T. + /// The type to get the context of. + /// Whether the context exists in this object. + public bool TryGetContext(out T context) where T : IContext + { + if (contexts.TryGetValue(typeof(T), out var context2)) + { + context = (T)context2; + return true; + } + + context = default!; + return false; + } + + /// + /// Sets the context object of type T. + /// + /// The context type to set. + /// The context object to store in this object. + public void SetContext(T context) where T : IContext + { + contexts[typeof(T)] = context; + } + + /// + /// Removes the context of type T from this object. + /// + /// The type to remove the context of. + /// Whether a context was removed. + public bool RemoveContext() where T : IContext + { + return RemoveContext(typeof(T)); + } + + /// + /// Removes the context of type T from this object. + /// + /// The type to remove the context of. + /// Whether a context was removed. + public bool RemoveContext(Type t) + { + return contexts.Remove(t); + } + } +} diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index aea564a4b9..fb7a5739b4 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -18,6 +18,7 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Legacy; +using osu.Game.Context; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Scoring; @@ -30,7 +31,7 @@ namespace osu.Game.Rulesets.Objects /// HitObjects may contain more properties for which you should be checking through the IHas* types. /// /// - public class HitObject + public class HitObject : ContextContainer { /// /// A small adjustment to the start time of control points to account for rounding/precision errors. @@ -81,12 +82,6 @@ namespace osu.Game.Rulesets.Objects public SampleControlPoint SampleControlPoint = SampleControlPoint.DEFAULT; public DifficultyControlPoint DifficultyControlPoint = DifficultyControlPoint.DEFAULT; - /// - /// Legacy BPM multiplier that introduces floating-point errors for rulesets that depend on it. - /// DO NOT USE THIS UNLESS 100% SURE. - /// - public double? LegacyBpmMultiplier { get; private set; } - /// /// Whether this is in Kiai time. /// @@ -174,12 +169,6 @@ namespace osu.Game.Rulesets.Objects { var legacyInfo = controlPointInfo as LegacyControlPointInfo; - DifficultyControlPoint difficultyControlPoint = legacyInfo != null ? legacyInfo.DifficultyPointAt(StartTime) : DifficultyControlPoint.DEFAULT; -#pragma warning disable 618 - if (difficultyControlPoint is LegacyBeatmapDecoder.LegacyDifficultyControlPoint legacyDifficultyControlPoint) -#pragma warning restore 618 - LegacyBpmMultiplier = legacyDifficultyControlPoint.BpmMultiplier; - ApplyLegacyInfoToSelf(controlPointInfo, difficulty); // This is done here after ApplyLegacyInfoToSelf as we may require custom defaults to be applied to have an accurate end time. From 891b87a5ff97e9eaeb7a0de15472217e97b2540c Mon Sep 17 00:00:00 2001 From: OliBomby Date: Tue, 25 Apr 2023 12:52:21 +0200 Subject: [PATCH 2667/2991] remove ApplyLegacyInfo method --- osu.Game.Rulesets.Osu/Objects/Slider.cs | 8 ----- .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 36 ++++++++++++++++--- osu.Game/Rulesets/Objects/HitObject.cs | 26 -------------- .../Rulesets/Objects/Legacy/ConvertSlider.cs | 8 ----- 4 files changed, 32 insertions(+), 46 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 4010218f6e..a90d60cd1b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -163,14 +163,6 @@ namespace osu.Game.Rulesets.Osu.Objects TickDistance = generateTicks ? (scoringDistance / difficulty.SliderTickRate * TickDistanceMultiplier) : double.PositiveInfinity; } - protected override void ApplyLegacyInfoToSelf(ControlPointInfo controlPointInfo, IBeatmapDifficultyInfo difficulty) - { - base.ApplyLegacyInfoToSelf(controlPointInfo, difficulty); - - DifficultyControlPoint difficultyControlPoint = controlPointInfo is LegacyControlPointInfo legacyInfo ? legacyInfo.DifficultyPointAt(StartTime) : DifficultyControlPoint.DEFAULT; - SliderVelocity = difficultyControlPoint.SliderVelocity; - } - protected override void CreateNestedHitObjects(CancellationToken cancellationToken) { base.CreateNestedHitObjects(cancellationToken); diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 6f948e4d23..dad23df282 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -17,6 +17,7 @@ using osu.Game.IO; using osu.Game.Rulesets; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Legacy; +using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Beatmaps.Formats { @@ -27,6 +28,11 @@ namespace osu.Game.Beatmaps.Formats /// public const int EARLY_VERSION_TIMING_OFFSET = 24; + /// + /// A small adjustment to the start time of control points to account for rounding/precision errors. + /// + private const double control_point_leniency = 1; + internal static RulesetStore RulesetStore; private Beatmap beatmap; @@ -87,12 +93,11 @@ namespace osu.Game.Beatmaps.Formats foreach (var hitObject in this.beatmap.HitObjects) { - applyLegacyInfoToHitObject(hitObject); - hitObject.ApplyDefaults(this.beatmap.ControlPointInfo, this.beatmap.Difficulty); + applyLegacyInfoAndDefaults(hitObject); } } - private void applyLegacyInfoToHitObject(HitObject hitObject) + private void applyLegacyInfoAndDefaults(HitObject hitObject) { var legacyInfo = beatmap.ControlPointInfo as LegacyControlPointInfo; @@ -102,7 +107,30 @@ namespace osu.Game.Beatmaps.Formats #pragma warning restore 618 hitObject.SetContext(new LegacyContext(legacyDifficultyControlPoint.BpmMultiplier, legacyDifficultyControlPoint.GenerateTicks)); - hitObject.ApplyLegacyInfo(beatmap.ControlPointInfo, beatmap.Difficulty); + if (hitObject is IHasSliderVelocity hasSliderVelocity) + hasSliderVelocity.SliderVelocity = difficultyControlPoint.SliderVelocity; + + hitObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.Difficulty); + + SampleControlPoint sampleControlPoint = legacyInfo != null ? legacyInfo.SamplePointAt(hitObject.GetEndTime() + control_point_leniency) : SampleControlPoint.DEFAULT; + + foreach (var hitSampleInfo in hitObject.Samples) + { + sampleControlPoint.ApplyTo(hitSampleInfo); + } + + if (hitObject is not IHasRepeats hasRepeats) return; + + for (int i = 0; i < hasRepeats.NodeSamples.Count; i++) + { + double time = hitObject.StartTime + i * hasRepeats.Duration / hasRepeats.SpanCount() + control_point_leniency; + sampleControlPoint = legacyInfo != null ? legacyInfo.SamplePointAt(time) : SampleControlPoint.DEFAULT; + + foreach (var hitSampleInfo in hasRepeats.NodeSamples[i]) + { + sampleControlPoint.ApplyTo(hitSampleInfo); + } + } } /// diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index fb7a5739b4..2298a7ef12 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -158,32 +158,6 @@ namespace osu.Game.Rulesets.Objects HitWindows?.SetDifficulty(difficulty.OverallDifficulty); } - /// - /// Applies legacy information to this HitObject. - /// This method gets called at the end of before applying defaults. - /// - /// The control points. - /// The difficulty settings to use. - /// The cancellation token. - public void ApplyLegacyInfo(ControlPointInfo controlPointInfo, IBeatmapDifficultyInfo difficulty, CancellationToken cancellationToken = default) - { - var legacyInfo = controlPointInfo as LegacyControlPointInfo; - - ApplyLegacyInfoToSelf(controlPointInfo, difficulty); - - // This is done here after ApplyLegacyInfoToSelf as we may require custom defaults to be applied to have an accurate end time. - SampleControlPoint sampleControlPoint = legacyInfo != null ? legacyInfo.SamplePointAt(this.GetEndTime() + control_point_leniency) : SampleControlPoint.DEFAULT; - - foreach (var hitSampleInfo in Samples) - { - sampleControlPoint.ApplyTo(hitSampleInfo); - } - } - - protected virtual void ApplyLegacyInfoToSelf(ControlPointInfo controlPointInfo, IBeatmapDifficultyInfo difficulty) - { - } - protected virtual void CreateNestedHitObjects(CancellationToken cancellationToken) { } diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index 11e1f0beae..47aabf1599 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -54,14 +54,6 @@ namespace osu.Game.Rulesets.Objects.Legacy Velocity = scoringDistance / timingPoint.BeatLength; } - protected override void ApplyLegacyInfoToSelf(ControlPointInfo controlPointInfo, IBeatmapDifficultyInfo difficulty) - { - base.ApplyLegacyInfoToSelf(controlPointInfo, difficulty); - - DifficultyControlPoint difficultyControlPoint = controlPointInfo is LegacyControlPointInfo legacyInfo ? legacyInfo.DifficultyPointAt(StartTime) : DifficultyControlPoint.DEFAULT; - SliderVelocity = difficultyControlPoint.SliderVelocity; - } - public double LegacyLastTickOffset => 36; } } From bf1951fc38200c8372df7ada3ce19bc8c4a9443a Mon Sep 17 00:00:00 2001 From: OliBomby Date: Tue, 25 Apr 2023 12:54:45 +0200 Subject: [PATCH 2668/2991] Fix incorrect xmldoc --- osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs index c454439c5c..6cd4d74a31 100644 --- a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs @@ -30,7 +30,7 @@ namespace osu.Game.Beatmaps.ControlPoints public readonly Bindable SampleBankBindable = new Bindable(DEFAULT_BANK) { Default = DEFAULT_BANK }; /// - /// The speed multiplier at this control point. + /// The default sample bank at this control point. /// public string SampleBank { @@ -39,7 +39,7 @@ namespace osu.Game.Beatmaps.ControlPoints } /// - /// The default sample bank at this control point. + /// The default sample volume at this control point. /// public readonly BindableInt SampleVolumeBindable = new BindableInt(100) { From 97910d6be6b96bcb56d77d8489f41f80cd58f1b4 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Tue, 25 Apr 2023 13:06:37 +0200 Subject: [PATCH 2669/2991] remove unused directives --- osu.Game.Rulesets.Osu/Objects/Slider.cs | 1 - osu.Game/Rulesets/Objects/HitObject.cs | 2 -- osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs | 1 - 3 files changed, 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index a90d60cd1b..73ac184c57 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -15,7 +15,6 @@ using osu.Framework.Caching; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Legacy; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu.Judgements; diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 2298a7ef12..0502610eab 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -16,8 +16,6 @@ using osu.Framework.Lists; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Beatmaps.Formats; -using osu.Game.Beatmaps.Legacy; using osu.Game.Context; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Types; diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index 47aabf1599..f602cbac09 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -9,7 +9,6 @@ using Newtonsoft.Json; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Beatmaps.Legacy; namespace osu.Game.Rulesets.Objects.Legacy { From dd2c289ce96ed4c874f901476bef18e0c4657a6c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Apr 2023 20:22:12 +0900 Subject: [PATCH 2670/2991] Remove pointless default value --- osu.Game/Screens/Play/ArgonKeyCounter.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Play/ArgonKeyCounter.cs b/osu.Game/Screens/Play/ArgonKeyCounter.cs index 70fe2e3a65..a978f001d5 100644 --- a/osu.Game/Screens/Play/ArgonKeyCounter.cs +++ b/osu.Game/Screens/Play/ArgonKeyCounter.cs @@ -56,7 +56,6 @@ namespace osu.Game.Screens.Play Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, Font = OsuFont.Torus.With(size: count_font_size * scale_factor, weight: FontWeight.Bold), - Text = "0" }, }; From 76309586330690aee88bfc4b7f6ac6b70cdbf751 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Apr 2023 20:24:36 +0900 Subject: [PATCH 2671/2991] Stop using `Drawable.Name` to convey actual UI information --- osu.Game/Screens/Play/ArgonKeyCounter.cs | 2 +- osu.Game/Screens/Play/HUD/DefaultKeyCounter.cs | 2 +- osu.Game/Screens/Play/HUD/KeyCounter.cs | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/ArgonKeyCounter.cs b/osu.Game/Screens/Play/ArgonKeyCounter.cs index a978f001d5..6818b30823 100644 --- a/osu.Game/Screens/Play/ArgonKeyCounter.cs +++ b/osu.Game/Screens/Play/ArgonKeyCounter.cs @@ -49,7 +49,7 @@ namespace osu.Game.Screens.Play Position = new Vector2(0, -13) * scale_factor, Font = OsuFont.Torus.With(size: name_font_size * scale_factor, weight: FontWeight.Bold), Colour = colours.Blue0, - Text = Name + Text = Trigger.Name }, countText = new OsuSpriteText { diff --git a/osu.Game/Screens/Play/HUD/DefaultKeyCounter.cs b/osu.Game/Screens/Play/HUD/DefaultKeyCounter.cs index 69a3e53dfc..f7ac72035f 100644 --- a/osu.Game/Screens/Play/HUD/DefaultKeyCounter.cs +++ b/osu.Game/Screens/Play/HUD/DefaultKeyCounter.cs @@ -57,7 +57,7 @@ namespace osu.Game.Screens.Play.HUD { new OsuSpriteText { - Text = Name, + Text = Trigger.Name, Font = OsuFont.Numeric.With(size: 12), Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Screens/Play/HUD/KeyCounter.cs b/osu.Game/Screens/Play/HUD/KeyCounter.cs index 2a4ab1993a..7cdd6b025f 100644 --- a/osu.Game/Screens/Play/HUD/KeyCounter.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounter.cs @@ -54,8 +54,6 @@ namespace osu.Game.Screens.Play.HUD Trigger.OnActivate += Activate; Trigger.OnDeactivate += Deactivate; - - Name = trigger.Name; } private void increment() From 0c3a01595362d1e995dfe46d7fbd0d1c4bd8c814 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Apr 2023 21:37:17 +0900 Subject: [PATCH 2672/2991] Fix key counter test not testing the full binding of `IsCounting` --- .../Visual/Gameplay/TestSceneKeyCounter.cs | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs index 1e35c24e97..aabc25d660 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs @@ -19,21 +19,21 @@ namespace osu.Game.Tests.Visual.Gameplay { public TestSceneKeyCounter() { - KeyCounterDisplay kc = new DefaultKeyCounterDisplay + KeyCounterDisplay defaultDisplay = new DefaultKeyCounterDisplay { Origin = Anchor.Centre, Anchor = Anchor.Centre, Position = new Vector2(0, 72.7f) }; - KeyCounterDisplay argonKc = new ArgonKeyCounterDisplay + KeyCounterDisplay argonDisplay = new ArgonKeyCounterDisplay { Origin = Anchor.Centre, Anchor = Anchor.Centre, Position = new Vector2(0, -72.7f) }; - kc.AddRange(new InputTrigger[] + defaultDisplay.AddRange(new InputTrigger[] { new KeyCounterKeyboardTrigger(Key.X), new KeyCounterKeyboardTrigger(Key.X), @@ -41,7 +41,7 @@ namespace osu.Game.Tests.Visual.Gameplay new KeyCounterMouseTrigger(MouseButton.Right), }); - argonKc.AddRange(new InputTrigger[] + argonDisplay.AddRange(new InputTrigger[] { new KeyCounterKeyboardTrigger(Key.X), new KeyCounterKeyboardTrigger(Key.X), @@ -49,32 +49,29 @@ namespace osu.Game.Tests.Visual.Gameplay new KeyCounterMouseTrigger(MouseButton.Right), }); - var testCounter = (DefaultKeyCounter)kc.Counters.First(); + var testCounter = (DefaultKeyCounter)defaultDisplay.Counters.First(); AddStep("Add random", () => { Key key = (Key)((int)Key.A + RNG.Next(26)); - kc.Add(new KeyCounterKeyboardTrigger(key)); - argonKc.Add(new KeyCounterKeyboardTrigger(key)); + defaultDisplay.Add(new KeyCounterKeyboardTrigger(key)); + argonDisplay.Add(new KeyCounterKeyboardTrigger(key)); }); - Key testKey = ((KeyCounterKeyboardTrigger)kc.Counters.First().Trigger).Key; - - void addPressKeyStep() - { - AddStep($"Press {testKey} key", () => InputManager.Key(testKey)); - } + Key testKey = ((KeyCounterKeyboardTrigger)defaultDisplay.Counters.First().Trigger).Key; addPressKeyStep(); AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses.Value == 1); addPressKeyStep(); AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses.Value == 2); - AddStep("Disable counting", () => testCounter.IsCounting.Value = false); + AddStep("Disable counting", () => defaultDisplay.IsCounting.Value = false); addPressKeyStep(); AddAssert($"Check {testKey} count has not changed", () => testCounter.CountPresses.Value == 2); - Add(kc); - Add(argonKc); + Add(defaultDisplay); + Add(argonDisplay); + + void addPressKeyStep() => AddStep($"Press {testKey} key", () => InputManager.Key(testKey)); } } } From 0a861ffcee21bae0b235b88b2455e1f2d3bfe2d6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Apr 2023 21:22:55 +0900 Subject: [PATCH 2673/2991] Restructure key counters to use a common flow --- .../Screens/Play/ArgonKeyCounterDisplay.cs | 14 ++++----- .../Play/HUD/DefaultKeyCounterDisplay.cs | 29 +++++++++---------- .../Screens/Play/HUD/KeyCounterDisplay.cs | 8 +++-- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/osu.Game/Screens/Play/ArgonKeyCounterDisplay.cs b/osu.Game/Screens/Play/ArgonKeyCounterDisplay.cs index a62ac3d39a..984c2a7287 100644 --- a/osu.Game/Screens/Play/ArgonKeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/ArgonKeyCounterDisplay.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.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Screens.Play.HUD; @@ -13,13 +12,11 @@ namespace osu.Game.Screens.Play { private const int duration = 100; - private readonly FillFlowContainer keyFlow; - - public override IEnumerable Counters => keyFlow; + protected override FillFlowContainer KeyFlow { get; } public ArgonKeyCounterDisplay() { - InternalChild = keyFlow = new FillFlowContainer + InternalChild = KeyFlow = new FillFlowContainer { Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, @@ -32,13 +29,12 @@ namespace osu.Game.Screens.Play { base.Update(); - Size = keyFlow.Size; + Size = KeyFlow.Size; } - public override void Add(InputTrigger trigger) => - keyFlow.Add(new ArgonKeyCounter(trigger)); + protected override KeyCounter CreateCounter(InputTrigger trigger) => new ArgonKeyCounter(trigger); protected override void UpdateVisibility() - => keyFlow.FadeTo(AlwaysVisible.Value || ConfigVisibility.Value ? 1 : 0, duration); + => KeyFlow.FadeTo(AlwaysVisible.Value || ConfigVisibility.Value ? 1 : 0, duration); } } diff --git a/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs index 14d7f56093..e459574243 100644 --- a/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs @@ -1,7 +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.Collections.Generic; +using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osuTK.Graphics; @@ -13,13 +13,11 @@ namespace osu.Game.Screens.Play.HUD private const int duration = 100; private const double key_fade_time = 80; - private readonly FillFlowContainer keyFlow; - - public override IEnumerable Counters => keyFlow; + protected override FillFlowContainer KeyFlow { get; } public DefaultKeyCounterDisplay() { - InternalChild = keyFlow = new FillFlowContainer + InternalChild = KeyFlow = new FillFlowContainer { Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, @@ -33,20 +31,19 @@ namespace osu.Game.Screens.Play.HUD // Don't use autosize as it will shrink to zero when KeyFlow is hidden. // In turn this can cause the display to be masked off screen and never become visible again. - Size = keyFlow.Size; + Size = KeyFlow.Size; } - public override void Add(InputTrigger trigger) => - keyFlow.Add(new DefaultKeyCounter(trigger) - { - FadeTime = key_fade_time, - KeyDownTextColor = KeyDownTextColor, - KeyUpTextColor = KeyUpTextColor, - }); + protected override KeyCounter CreateCounter(InputTrigger trigger) => new DefaultKeyCounter(trigger) + { + FadeTime = key_fade_time, + KeyDownTextColor = KeyDownTextColor, + KeyUpTextColor = KeyUpTextColor, + }; protected override void UpdateVisibility() => // Isolate changing visibility of the key counters from fading this component. - keyFlow.FadeTo(AlwaysVisible.Value || ConfigVisibility.Value ? 1 : 0, duration); + KeyFlow.FadeTo(AlwaysVisible.Value || ConfigVisibility.Value ? 1 : 0, duration); private Color4 keyDownTextColor = Color4.DarkGray; @@ -58,7 +55,7 @@ namespace osu.Game.Screens.Play.HUD if (value != keyDownTextColor) { keyDownTextColor = value; - foreach (var child in keyFlow) + foreach (var child in KeyFlow.Cast()) child.KeyDownTextColor = value; } } @@ -74,7 +71,7 @@ namespace osu.Game.Screens.Play.HUD if (value != keyUpTextColor) { keyUpTextColor = value; - foreach (var child in keyFlow) + foreach (var child in KeyFlow.Cast()) child.KeyUpTextColor = value; } } diff --git a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs index 49c0da6793..e218155af2 100644 --- a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs @@ -29,7 +29,9 @@ namespace osu.Game.Screens.Play.HUD /// /// The s contained in this . /// - public abstract IEnumerable Counters { get; } + public IEnumerable Counters => KeyFlow; + + protected abstract FillFlowContainer KeyFlow { get; } /// /// Whether the actions reported by all s within this should be counted. @@ -53,13 +55,15 @@ namespace osu.Game.Screens.Play.HUD /// /// Add a to this display. /// - public abstract void Add(InputTrigger trigger); + public void Add(InputTrigger trigger) => KeyFlow.Add(CreateCounter(trigger)); /// /// Add a range of to this display. /// public void AddRange(IEnumerable triggers) => triggers.ForEach(Add); + protected abstract KeyCounter CreateCounter(InputTrigger trigger); + [BackgroundDependencyLoader] private void load(OsuConfigManager config) { From 6b4032e34b57fba897a4f8906a9097c6543acb30 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Apr 2023 21:31:39 +0900 Subject: [PATCH 2674/2991] Add missing binding of `IsCounting` with contained counters --- osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs index e218155af2..05427d3a32 100644 --- a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs @@ -55,7 +55,14 @@ namespace osu.Game.Screens.Play.HUD /// /// Add a to this display. /// - public void Add(InputTrigger trigger) => KeyFlow.Add(CreateCounter(trigger)); + public void Add(InputTrigger trigger) + { + var keyCounter = CreateCounter(trigger); + + KeyFlow.Add(keyCounter); + + IsCounting.BindTo(keyCounter.IsCounting); + } /// /// Add a range of to this display. From e08d7daffd7c5f582f98a43cad3f2fd2d64829bc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 25 Apr 2023 21:43:14 +0900 Subject: [PATCH 2675/2991] Don't show decimal point in tooltip --- osu.Game/Localisation/EditorStrings.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Localisation/EditorStrings.cs b/osu.Game/Localisation/EditorStrings.cs index 7c9b52275d..20258b9c35 100644 --- a/osu.Game/Localisation/EditorStrings.cs +++ b/osu.Game/Localisation/EditorStrings.cs @@ -100,14 +100,14 @@ namespace osu.Game.Localisation public static LocalisableString TimelineTicks => new TranslatableString(getKey(@"timeline_ticks"), @"Ticks"); /// - /// "{0:0.0}°" + /// "{0:0}°" /// - public static LocalisableString RotationUnsnapped(float newRotation) => new TranslatableString(getKey(@"rotation_unsnapped"), @"{0:0.0}°", newRotation); + public static LocalisableString RotationUnsnapped(float newRotation) => new TranslatableString(getKey(@"rotation_unsnapped"), @"{0:0}°", newRotation); /// - /// "{0:0.0}° (snapped)" + /// "{0:0}° (snapped)" /// - public static LocalisableString RotationSnapped(float newRotation) => new TranslatableString(getKey(@"rotation_snapped"), @"{0:0.0}° (snapped)", newRotation); + public static LocalisableString RotationSnapped(float newRotation) => new TranslatableString(getKey(@"rotation_snapped"), @"{0:0}° (snapped)", newRotation); private static string getKey(string key) => $@"{prefix}:{key}"; } From c37875bee824e8c00bbc0d07273dbd98cbef5930 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Tue, 25 Apr 2023 15:53:36 +0200 Subject: [PATCH 2676/2991] remove hitobject SampleControlPoint usage from LegacyBeatmapEncoder --- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 072e442dea..04786cc9fb 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -92,7 +92,7 @@ namespace osu.Game.Beatmaps.Formats writer.WriteLine(FormattableString.Invariant($"AudioLeadIn: {beatmap.BeatmapInfo.AudioLeadIn}")); writer.WriteLine(FormattableString.Invariant($"PreviewTime: {beatmap.Metadata.PreviewTime}")); writer.WriteLine(FormattableString.Invariant($"Countdown: {(int)beatmap.BeatmapInfo.Countdown}")); - writer.WriteLine(FormattableString.Invariant($"SampleSet: {toLegacySampleBank((beatmap.HitObjects.FirstOrDefault()?.SampleControlPoint ?? SampleControlPoint.DEFAULT).SampleBank)}")); + writer.WriteLine(FormattableString.Invariant($"SampleSet: {toLegacySampleBank(((beatmap.ControlPointInfo as LegacyControlPointInfo)?.SamplePoints?.FirstOrDefault() ?? SampleControlPoint.DEFAULT).SampleBank)}")); writer.WriteLine(FormattableString.Invariant($"StackLeniency: {beatmap.BeatmapInfo.StackLeniency}")); writer.WriteLine(FormattableString.Invariant($"Mode: {onlineRulesetID}")); writer.WriteLine(FormattableString.Invariant($"LetterboxInBreaks: {(beatmap.BeatmapInfo.LetterboxInBreaks ? '1' : '0')}")); @@ -268,7 +268,12 @@ namespace osu.Game.Beatmaps.Formats { foreach (var hitObject in hitObjects) { - yield return hitObject.SampleControlPoint; + if (hitObject.Samples.Count > 0) + { + int volume = hitObject.Samples.Max(o => o.Volume); + int customIndex = hitObject.Samples.OfType().Max(o => o.CustomSampleBank); + yield return new LegacyBeatmapDecoder.LegacySampleControlPoint { Time = hitObject.GetEndTime(), SampleVolume = volume, CustomSampleBank = customIndex }; + } foreach (var nested in collectSampleControlPoints(hitObject.NestedHitObjects)) yield return nested; From a6346171575e76ba0bf1b043040bbd0db8188b4e Mon Sep 17 00:00:00 2001 From: OliBomby Date: Tue, 25 Apr 2023 16:01:06 +0200 Subject: [PATCH 2677/2991] Fix file header notice --- osu.Game/Context/{IHasContext.cs => ContextContainer.cs} | 5 ++++- osu.Game/Context/IContext.cs | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) rename osu.Game/Context/{IHasContext.cs => ContextContainer.cs} (94%) diff --git a/osu.Game/Context/IHasContext.cs b/osu.Game/Context/ContextContainer.cs similarity index 94% rename from osu.Game/Context/IHasContext.cs rename to osu.Game/Context/ContextContainer.cs index bee81ea555..7ff0280bcf 100644 --- a/osu.Game/Context/IHasContext.cs +++ b/osu.Game/Context/ContextContainer.cs @@ -1,4 +1,7 @@ -using System; +// 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; namespace osu.Game.Context diff --git a/osu.Game/Context/IContext.cs b/osu.Game/Context/IContext.cs index f70cdea9f8..61b1b11f43 100644 --- a/osu.Game/Context/IContext.cs +++ b/osu.Game/Context/IContext.cs @@ -1,4 +1,7 @@ -namespace osu.Game.Context; +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Context; public interface IContext { From ebe1d852f53a80f3775f0ff602e95e8a74f3ca65 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Tue, 25 Apr 2023 16:01:43 +0200 Subject: [PATCH 2678/2991] remove other usages of hitobject SampleControlPoint --- osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs | 2 +- osu.Game/Rulesets/Edit/PlacementBlueprint.cs | 6 +++--- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 8 +------- osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs | 1 - osu.Game/Rulesets/UI/Playfield.cs | 4 ++-- 5 files changed, 7 insertions(+), 14 deletions(-) diff --git a/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs b/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs index 5b59a81f91..a2ae1764dd 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckMutedObjects.cs @@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Edit.Checks yield break; // Samples that allow themselves to be overridden by control points have a volume of 0. - int maxVolume = sampledHitObject.Samples.Max(sample => sample.Volume > 0 ? sample.Volume : sampledHitObject.SampleControlPoint.SampleVolume); + int maxVolume = sampledHitObject.Samples.Max(sample => sample.Volume); double samplePlayTime = sampledHitObject.GetEndTime(); EdgeType edgeType = getEdgeAtTime(hitObject, samplePlayTime); diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs index f810f51027..91dd7754d0 100644 --- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs +++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs @@ -74,9 +74,9 @@ namespace osu.Game.Rulesets.Edit /// Whether this call is committing a value for HitObject.StartTime and continuing with further adjustments. protected void BeginPlacement(bool commitStart = false) { - var nearestSampleControlPoint = beatmap.HitObjects.LastOrDefault(h => h.GetEndTime() < HitObject.StartTime)?.SampleControlPoint?.DeepClone() as SampleControlPoint; - - HitObject.SampleControlPoint = nearestSampleControlPoint ?? new SampleControlPoint(); + // Take the hitnormal sample of the last hit object + var lastHitNormal = beatmap.HitObjects.LastOrDefault(h => h.GetEndTime() < HitObject.StartTime)?.Samples?.FirstOrDefault(o => o.Name == HitSampleInfo.HIT_NORMAL); + HitObject.Samples.Add(lastHitNormal); placementHandler.BeginPlacement(HitObject); if (commitStart) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index f6c3452e48..79fc778287 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -357,13 +357,7 @@ namespace osu.Game.Rulesets.Objects.Drawables if (samples.Length <= 0) return; - if (HitObject.SampleControlPoint == null) - { - throw new InvalidOperationException($"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}." - + $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}."); - } - - Samples.Samples = samples.Select(s => HitObject.SampleControlPoint.ApplyTo(s)).Cast().ToArray(); + Samples.Samples = samples.Cast().ToArray(); } private void onSamplesChanged(object sender, NotifyCollectionChangedEventArgs e) => LoadSamples(); diff --git a/osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs b/osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs index e1c03e49e3..d4510a4519 100644 --- a/osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs +++ b/osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs @@ -52,7 +52,6 @@ namespace osu.Game.Rulesets.UI return; var samples = nextObject.Samples - .Select(s => nextObject.SampleControlPoint.ApplyTo(s)) .Cast() .ToArray(); diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index b1c3b78e67..6016a53918 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -293,10 +293,10 @@ namespace osu.Game.Rulesets.UI { // prepare sample pools ahead of time so we're not initialising at runtime. foreach (var sample in hitObject.Samples) - prepareSamplePool(hitObject.SampleControlPoint.ApplyTo(sample)); + prepareSamplePool(sample); foreach (var sample in hitObject.AuxiliarySamples) - prepareSamplePool(hitObject.SampleControlPoint.ApplyTo(sample)); + prepareSamplePool(sample); foreach (var nestedObject in hitObject.NestedHitObjects) preloadSamples(nestedObject); From 065464d90cae0c7ea887be51b7ca171011f70560 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Tue, 25 Apr 2023 18:12:53 +0200 Subject: [PATCH 2679/2991] Fixed DifficultyPointPiece --- osu.Game.Rulesets.Osu/Objects/Slider.cs | 9 ++- .../Rulesets/Objects/Legacy/ConvertSlider.cs | 9 ++- .../Objects/Types/IHasSliderVelocity.cs | 4 + .../Timeline/DifficultyPointPiece.cs | 23 ++++-- .../Timeline/HitObjectPointPiece.cs | 77 +++++++++---------- .../Components/Timeline/SamplePointPiece.cs | 5 +- .../Timeline/TimelineHitObjectBlueprint.cs | 45 ++++------- 7 files changed, 90 insertions(+), 82 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 73ac184c57..efb98ba888 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -11,6 +11,7 @@ using System.Linq; using System.Text.Json.Serialization; using System.Threading; using Newtonsoft.Json; +using osu.Framework.Bindables; using osu.Framework.Caching; using osu.Game.Audio; using osu.Game.Beatmaps; @@ -135,7 +136,13 @@ namespace osu.Game.Rulesets.Osu.Objects /// public bool OnlyJudgeNestedObjects = true; - public double SliderVelocity { get; set; } = 1; + public BindableDouble SliderVelocityBindable = new BindableDouble(1); + + public double SliderVelocity + { + get => SliderVelocityBindable.Value; + set => SliderVelocityBindable.Value = value; + } [JsonIgnore] public SliderHeadCircle HeadCircle { get; protected set; } diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index f602cbac09..94d21a06ed 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -6,6 +6,7 @@ using osu.Game.Rulesets.Objects.Types; using System.Collections.Generic; using Newtonsoft.Json; +using osu.Framework.Bindables; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; @@ -40,7 +41,13 @@ namespace osu.Game.Rulesets.Objects.Legacy public double Velocity = 1; - public double SliderVelocity { get; set; } = 1; + public BindableDouble SliderVelocityBindable = new BindableDouble(1); + + public double SliderVelocity + { + get => SliderVelocityBindable.Value; + set => SliderVelocityBindable.Value = value; + } protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, IBeatmapDifficultyInfo difficulty) { diff --git a/osu.Game/Rulesets/Objects/Types/IHasSliderVelocity.cs b/osu.Game/Rulesets/Objects/Types/IHasSliderVelocity.cs index a7195dab4b..c0ac5036ee 100644 --- a/osu.Game/Rulesets/Objects/Types/IHasSliderVelocity.cs +++ b/osu.Game/Rulesets/Objects/Types/IHasSliderVelocity.cs @@ -1,6 +1,8 @@ // 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.Bindables; + namespace osu.Game.Rulesets.Objects.Types; /// @@ -12,4 +14,6 @@ public interface IHasSliderVelocity /// The slider velocity multiplier. /// double SliderVelocity { get; set; } + + BindableNumber SliderVelocityBindable { get; } } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs index d3cdd461ea..4741b75641 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs @@ -13,12 +13,14 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; -using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; using osu.Game.Screens.Edit.Timing; using osuTK; +using osuTK.Graphics; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { @@ -29,13 +31,14 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private readonly BindableNumber speedMultiplier; public DifficultyPointPiece(HitObject hitObject) - : base(hitObject.DifficultyControlPoint) { HitObject = hitObject; - speedMultiplier = hitObject.DifficultyControlPoint.SliderVelocityBindable.GetBoundCopy(); + speedMultiplier = (hitObject as IHasSliderVelocity)?.SliderVelocityBindable.GetBoundCopy(); } + protected override Color4 GetRepresentingColour(OsuColour colours) => colours.Lime1; + protected override void LoadComplete() { base.LoadComplete(); @@ -78,7 +81,12 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline Spacing = new Vector2(0, 15), Children = new Drawable[] { - sliderVelocitySlider = new IndeterminateSliderWithTextBoxInput("Velocity", new DifficultyControlPoint().SliderVelocityBindable) + sliderVelocitySlider = new IndeterminateSliderWithTextBoxInput("Velocity", new BindableDouble(1) + { + Precision = 0.01, + MinValue = 0.1, + MaxValue = 10 + }) { KeyboardStep = 0.1f }, @@ -94,11 +102,10 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline // if the piece belongs to a currently selected object, assume that the user wants to change all selected objects. // if the piece belongs to an unselected object, operate on that object alone, independently of the selection. - var relevantObjects = (beatmap.SelectedHitObjects.Contains(hitObject) ? beatmap.SelectedHitObjects : hitObject.Yield()).ToArray(); - var relevantControlPoints = relevantObjects.Select(h => h.DifficultyControlPoint).ToArray(); + var relevantObjects = (beatmap.SelectedHitObjects.Contains(hitObject) ? beatmap.SelectedHitObjects : hitObject.Yield()).Where(o => o is IHasSliderVelocity).ToArray(); // even if there are multiple objects selected, we can still display a value if they all have the same value. - var selectedPointBindable = relevantControlPoints.Select(point => point.SliderVelocity).Distinct().Count() == 1 ? relevantControlPoints.First().SliderVelocityBindable : null; + var selectedPointBindable = relevantObjects.Select(point => ((IHasSliderVelocity)point).SliderVelocity).Distinct().Count() == 1 ? ((IHasSliderVelocity)relevantObjects.First()).SliderVelocityBindable : null; if (selectedPointBindable != null) { @@ -117,7 +124,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline foreach (var h in relevantObjects) { - h.DifficultyControlPoint.SliderVelocity = val.NewValue.Value; + ((IHasSliderVelocity)h).SliderVelocity = val.NewValue.Value; beatmap.Update(h); } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs index 5b0a5729c8..bd699c2e88 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs @@ -7,59 +7,54 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osuTK.Graphics; -namespace osu.Game.Screens.Edit.Compose.Components.Timeline +namespace osu.Game.Screens.Edit.Compose.Components.Timeline; + +public partial class HitObjectPointPiece : CircularContainer { - public partial class HitObjectPointPiece : CircularContainer + protected OsuSpriteText Label { get; private set; } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) { - private readonly ControlPoint point; + AutoSizeAxes = Axes.Both; - protected OsuSpriteText Label { get; private set; } + Color4 colour = GetRepresentingColour(colours); - protected HitObjectPointPiece(ControlPoint point) + InternalChildren = new Drawable[] { - this.point = point; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - AutoSizeAxes = Axes.Both; - - Color4 colour = point.GetRepresentingColour(colours); - - InternalChildren = new Drawable[] + new Container { - new Container + AutoSizeAxes = Axes.X, + Height = 16, + Masking = true, + CornerRadius = 8, + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Children = new Drawable[] { - AutoSizeAxes = Axes.X, - Height = 16, - Masking = true, - CornerRadius = 8, - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Children = new Drawable[] + new Box { - new Box - { - Colour = colour, - RelativeSizeAxes = Axes.Both, - }, - Label = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Padding = new MarginPadding(5), - Font = OsuFont.Default.With(size: 12, weight: FontWeight.SemiBold), - Colour = colours.B5, - } + Colour = colour, + RelativeSizeAxes = Axes.Both, + }, + Label = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Padding = new MarginPadding(5), + Font = OsuFont.Default.With(size: 12, weight: FontWeight.SemiBold), + Colour = colours.B5, } - }, - }; - } + } + }, + }; + + protected virtual Color4 GetRepresentingColour(OsuColour colours) + { + return colours.Yellow; } } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs index 314137a565..50278bffc0 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs @@ -13,10 +13,12 @@ using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Graphics; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Rulesets.Objects; using osu.Game.Screens.Edit.Timing; using osuTK; +using osuTK.Graphics; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { @@ -28,13 +30,14 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private readonly BindableNumber volume; public SamplePointPiece(HitObject hitObject) - : base(hitObject.SampleControlPoint) { HitObject = hitObject; volume = hitObject.SampleControlPoint.SampleVolumeBindable.GetBoundCopy(); bank = hitObject.SampleControlPoint.SampleBankBindable.GetBoundCopy(); } + protected override Color4 GetRepresentingColour(OsuColour colours) => colours.Pink; + [BackgroundDependencyLoader] private void load() { diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index 4e5087c004..de659cddb8 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -102,6 +102,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline }, } }, + sampleOverrideDisplay = new SamplePointPiece(Item) + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.TopCentre + }, }); if (item is IHasDuration) @@ -111,6 +116,16 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline OnDragHandled = e => OnDragHandled?.Invoke(e) }); } + + if (item is IHasSliderVelocity) + { + AddInternal(difficultyOverrideDisplay = new DifficultyPointPiece(Item) + { + Anchor = Anchor.TopLeft, + Origin = Anchor.BottomCentre + } + ); + } } protected override void LoadComplete() @@ -208,36 +223,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline if (Item is IHasRepeats repeats) updateRepeats(repeats); } - - if (!ReferenceEquals(difficultyControlPoint, Item.DifficultyControlPoint)) - { - difficultyControlPoint = Item.DifficultyControlPoint; - difficultyOverrideDisplay?.Expire(); - - if (Item.DifficultyControlPoint != null && Item is IHasDistance) - { - AddInternal(difficultyOverrideDisplay = new DifficultyPointPiece(Item) - { - Anchor = Anchor.TopLeft, - Origin = Anchor.BottomCentre - }); - } - } - - if (!ReferenceEquals(sampleControlPoint, Item.SampleControlPoint)) - { - sampleControlPoint = Item.SampleControlPoint; - sampleOverrideDisplay?.Expire(); - - if (Item.SampleControlPoint != null) - { - AddInternal(sampleOverrideDisplay = new SamplePointPiece(Item) - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.TopCentre - }); - } - } } private void updateRepeats(IHasRepeats repeats) From c23a7b014eb7a6a4b984bafc85459044cf29323e Mon Sep 17 00:00:00 2001 From: OliBomby Date: Tue, 25 Apr 2023 18:17:07 +0200 Subject: [PATCH 2680/2991] add missing } --- .../Edit/Compose/Components/Timeline/HitObjectPointPiece.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs index bd699c2e88..f7854705a4 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs @@ -52,6 +52,7 @@ public partial class HitObjectPointPiece : CircularContainer } }, }; + } protected virtual Color4 GetRepresentingColour(OsuColour colours) { From 66eda40cdf1911c2c4139c00fa9ebc8478058168 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Tue, 25 Apr 2023 18:22:22 +0200 Subject: [PATCH 2681/2991] fix implementations of IHasSliderVelocity --- osu.Game.Rulesets.Osu/Objects/Slider.cs | 2 +- osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index efb98ba888..e8eb197186 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -136,7 +136,7 @@ namespace osu.Game.Rulesets.Osu.Objects /// public bool OnlyJudgeNestedObjects = true; - public BindableDouble SliderVelocityBindable = new BindableDouble(1); + public BindableNumber SliderVelocityBindable { get; } = new BindableDouble(1); public double SliderVelocity { diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index 94d21a06ed..7ddd372dc9 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Objects.Legacy public double Velocity = 1; - public BindableDouble SliderVelocityBindable = new BindableDouble(1); + public BindableNumber SliderVelocityBindable { get; } = new BindableDouble(1); public double SliderVelocity { From 755ad25dbe22987fd1cd5e0c851adf1f99698640 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Tue, 25 Apr 2023 18:27:20 +0200 Subject: [PATCH 2682/2991] clean code --- .../Components/Timeline/TimelineHitObjectBlueprint.cs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index de659cddb8..1c36bec53e 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -102,7 +102,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline }, } }, - sampleOverrideDisplay = new SamplePointPiece(Item) + new SamplePointPiece(Item) { Anchor = Anchor.BottomLeft, Origin = Anchor.TopCentre @@ -119,7 +119,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline if (item is IHasSliderVelocity) { - AddInternal(difficultyOverrideDisplay = new DifficultyPointPiece(Item) + AddInternal(new DifficultyPointPiece(Item) { Anchor = Anchor.TopLeft, Origin = Anchor.BottomCentre @@ -202,12 +202,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline colouredComponents.Colour = OsuColour.ForegroundTextColourFor(averageColour); } - private SamplePointPiece? sampleOverrideDisplay; - private DifficultyPointPiece? difficultyOverrideDisplay; - - private DifficultyControlPoint difficultyControlPoint = null!; - private SampleControlPoint sampleControlPoint = null!; - protected override void Update() { base.Update(); From e4b64bdc3e0b3e3074c76a8286e986acfdeedb57 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Tue, 25 Apr 2023 19:06:29 +0200 Subject: [PATCH 2683/2991] clean up code stuff --- .../Patterns/Legacy/DistanceObjectPatternGenerator.cs | 1 - osu.Game.Rulesets.Osu/Objects/Slider.cs | 1 - .../Components/Timeline/TimelineHitObjectBlueprint.cs | 9 ++++----- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index b3a68269f7..2427812ecd 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -14,7 +14,6 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Legacy; using osu.Game.Utils; diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index e8eb197186..247cf94f59 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -8,7 +8,6 @@ using osu.Game.Rulesets.Objects.Types; using System.Collections.Generic; using osu.Game.Rulesets.Objects; using System.Linq; -using System.Text.Json.Serialization; using System.Threading; using Newtonsoft.Json; using osu.Framework.Bindables; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index 1c36bec53e..c2106e0598 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -120,11 +120,10 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline if (item is IHasSliderVelocity) { AddInternal(new DifficultyPointPiece(Item) - { - Anchor = Anchor.TopLeft, - Origin = Anchor.BottomCentre - } - ); + { + Anchor = Anchor.TopLeft, + Origin = Anchor.BottomCentre + }); } } From 753fa09356a2864060d0c8eb2dd95a29a7041785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 25 Apr 2023 20:10:11 +0200 Subject: [PATCH 2684/2991] Fix test failures due to type mismatch --- osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs | 2 +- osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index eecead5415..ae46dda750 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Gameplay // best way to check without exposing. private Drawable hideTarget => hudOverlay.KeyCounter; - private Drawable keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType>().Single(); + private Drawable keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType>().Single(); [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs index 7bbfc6a62b..0439656aae 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs @@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual.Gameplay // best way to check without exposing. private Drawable hideTarget => hudOverlay.KeyCounter; - private Drawable keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType>().Single(); + private Drawable keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType>().Single(); [Test] public void TestComboCounterIncrementing() From 196b5b41eb07f7e0377c84b0d8ca381386dbc541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 25 Apr 2023 20:17:52 +0200 Subject: [PATCH 2685/2991] Also disable counting on argon display in test Mostly for my own peace of mind. --- osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs index aabc25d660..22f7111f68 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs @@ -64,7 +64,11 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses.Value == 1); addPressKeyStep(); AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses.Value == 2); - AddStep("Disable counting", () => defaultDisplay.IsCounting.Value = false); + AddStep("Disable counting", () => + { + argonDisplay.IsCounting.Value = false; + defaultDisplay.IsCounting.Value = false; + }); addPressKeyStep(); AddAssert($"Check {testKey} count has not changed", () => testCounter.CountPresses.Value == 2); From 0841e73a39ba4c383a62e8897ed55b653f66be1a Mon Sep 17 00:00:00 2001 From: Terochi Date: Tue, 25 Apr 2023 21:05:40 +0200 Subject: [PATCH 2686/2991] Improved readability and sounds --- osu.Game.Tests/Mods/ModSettingsTest.cs | 29 +++----- osu.Game/OsuGameBase.cs | 35 ++++++---- osu.Game/Rulesets/Mods/Mod.cs | 95 +++++++++++--------------- 3 files changed, 69 insertions(+), 90 deletions(-) diff --git a/osu.Game.Tests/Mods/ModSettingsTest.cs b/osu.Game.Tests/Mods/ModSettingsTest.cs index d943f0ffb1..b3f6f8da7d 100644 --- a/osu.Game.Tests/Mods/ModSettingsTest.cs +++ b/osu.Game.Tests/Mods/ModSettingsTest.cs @@ -43,18 +43,18 @@ namespace osu.Game.Tests.Mods var modDouble = new TestNonMatchingSettingTypeModDouble { TestSetting = { Value = setting_change } }; var modBool = new TestNonMatchingSettingTypeModBool { TestSetting = { Default = false, Value = true } }; - var modInt = new TestNonMatchingSettingTypeModInt { TestSetting = { Value = (int)setting_change } }; + var modInt = new TestNonMatchingSettingTypeModInt { TestSetting = { Value = (int)setting_change / 2 } }; - modDouble.CopySharedSettings(modBool); - modDouble.CopySharedSettings(modInt); - modBool.CopySharedSettings(modDouble); - modBool.CopySharedSettings(modInt); - modInt.CopySharedSettings(modDouble); - modInt.CopySharedSettings(modBool); + modDouble.CopyCommonSettings(modBool); + modDouble.CopyCommonSettings(modInt); + modBool.CopyCommonSettings(modDouble); + modBool.CopyCommonSettings(modInt); + modInt.CopyCommonSettings(modDouble); + modInt.CopyCommonSettings(modBool); Assert.That(modDouble.TestSetting.Value, Is.EqualTo(setting_change)); Assert.That(modBool.TestSetting.Value, Is.EqualTo(!modBool.TestSetting.Default)); - Assert.That(modInt.TestSetting.Value, Is.EqualTo((int)setting_change)); + Assert.That(modInt.TestSetting.Value, Is.EqualTo((int)setting_change / 2)); } [Test] @@ -63,23 +63,12 @@ namespace osu.Game.Tests.Mods var modBoolTrue = new TestNonMatchingSettingTypeModBool { TestSetting = { Default = true, Value = false } }; var modBoolFalse = new TestNonMatchingSettingTypeModBool { TestSetting = { Default = false, Value = true } }; - modBoolFalse.CopySharedSettings(modBoolTrue); + modBoolFalse.CopyCommonSettings(modBoolTrue); Assert.That(modBoolFalse.TestSetting.Default, Is.EqualTo(false)); Assert.That(modBoolFalse.TestSetting.Value, Is.EqualTo(modBoolTrue.TestSetting.Value)); } - [Test] - public void TestValueResetsToDefaultWhenCopied() - { - var modDouble = new TestNonMatchingSettingTypeModDouble(); - var modBool = new TestNonMatchingSettingTypeModBool { TestSetting = { Default = false, Value = true } }; - - modBool.CopySharedSettings(modDouble); - - Assert.That(modBool.TestSetting.Value, Is.EqualTo(modBool.TestSetting.Default)); - } - private class TestNonMatchingSettingTypeModDouble : TestNonMatchingSettingTypeMod { public override string Acronym => "NMD"; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index de1f2e810c..f6cda62cc3 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -58,7 +58,6 @@ using osu.Game.Rulesets.Mods; using osu.Game.Scoring; using osu.Game.Skinning; using osu.Game.Utils; -using File = System.IO.File; using RuntimeInfo = osu.Framework.RuntimeInfo; namespace osu.Game @@ -71,7 +70,7 @@ namespace osu.Game [Cached(typeof(OsuGameBase))] public partial class OsuGameBase : Framework.Game, ICanAcceptFiles, IBeatSyncProvider { - public static readonly string[] VIDEO_EXTENSIONS = { ".mp4", ".mov", ".avi", ".flv" }; + public static readonly string[] VIDEO_EXTENSIONS = { ".mp4", ".mov", ".avi", ".flv", ".mpg", ".wmv", ".m4v" }; public const string OSU_PROTOCOL = "osu://"; @@ -626,20 +625,30 @@ namespace osu.Game return; } + var previouslySelectedCommonMods = new List(SelectedMods.Value.Count); + var convertedCommonMods = new List(SelectedMods.Value.Count); + + foreach (var mod in SelectedMods.Value) + { + var convertedMod = instance.CreateModFromAcronym(mod.Acronym); + + if (convertedMod == null) + continue; + + previouslySelectedCommonMods.Add(mod); + + convertedMod.CopyCommonSettings(mod); + convertedCommonMods.Add(convertedMod); + } + + if (!SelectedMods.Disabled) + // Select common mods to play the deselect samples for other mods + SelectedMods.Value = previouslySelectedCommonMods; + AvailableMods.Value = dict; if (!SelectedMods.Disabled) - { - //converting mods from one ruleset to the other, while also keeping their shared settings unchanged - SelectedMods.Value = SelectedMods.Value.Select(oldMod => - { - Mod newMod = instance.CreateModFromAcronym(oldMod.Acronym); - - newMod?.CopySharedSettings(oldMod); - - return newMod; - }).Where(m => m != null).ToArray(); - } + SelectedMods.Value = convertedCommonMods; void revertRulesetChange() => Ruleset.Value = r.OldValue?.Available == true ? r.OldValue : RulesetStore.AvailableRulesets.First(); } diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 623a734b82..97434ce493 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -115,21 +115,25 @@ namespace osu.Game.Rulesets.Mods [JsonIgnore] public virtual Type[] IncompatibleMods => Array.Empty(); - private IReadOnlyList? settingsBacking; + private IReadOnlyDictionary? settingsBacking; /// - /// A list of the all settings within this mod. + /// All settings within this mod. /// - internal IReadOnlyList Settings => + internal IEnumerable SettingsBindables => Settings.Values; + + /// + /// Provides mapping of names to s of all settings within this mod. + /// + internal IReadOnlyDictionary Settings => settingsBacking ??= this.GetSettingsSourceProperties() - .Select(p => p.Item2.GetValue(this)) - .Cast() - .ToList(); + .Select(p => p.Item2) + .ToDictionary(property => property.Name.ToSnakeCase(), property => (IBindable)property.GetValue(this)!); /// /// Whether all settings in this mod are set to their default state. /// - protected virtual bool UsesDefaultConfiguration => Settings.All(s => s.IsDefault); + protected virtual bool UsesDefaultConfiguration => SettingsBindables.All(s => s.IsDefault); /// /// Creates a copy of this initialised to a default state. @@ -160,60 +164,37 @@ namespace osu.Game.Rulesets.Mods } /// - /// Copies all mod setting values sharing same from into this instance. + /// When converting mods from one ruleset to the other, this method makes sure + /// to also copy the values of all settings sharing same between the two instances. /// - /// The mod to copy properties from. - internal void CopySharedSettings(Mod source) + /// Copied values are unchanged, even if they have different clamping ranges. + /// The mod to extract settings from. + public void CopyCommonSettings(Mod source) { - const string value = nameof(Bindable.Value); + if (source.UsesDefaultConfiguration) + return; - Dictionary sourceSettings = new Dictionary(); - - foreach (var (_, sourceProperty) in source.GetSettingsSourceProperties()) + foreach (var (name, targetSetting) in Settings) { - sourceSettings.Add(sourceProperty.Name.ToSnakeCase(), sourceProperty.GetValue(source)!); + if (!source.Settings.TryGetValue(name, out IBindable? sourceSetting)) + continue; + + if (sourceSetting.IsDefault) + continue; + + if (getBindableGenericType(targetSetting) != getBindableGenericType(sourceSetting)) + continue; + + // TODO: special case for handling number types + + PropertyInfo property = targetSetting.GetType().GetProperty(nameof(Bindable.Value))!; + property.SetValue(targetSetting, property.GetValue(sourceSetting)); } - foreach (var (_, targetProperty) in this.GetSettingsSourceProperties()) - { - object targetSetting = targetProperty.GetValue(this)!; - - if (!sourceSettings.TryGetValue(targetProperty.Name.ToSnakeCase(), out object? sourceSetting)) - continue; - - if (((IBindable)sourceSetting).IsDefault) - { - // reset to default value if the source is default - targetSetting.GetType().GetMethod(nameof(Bindable.SetDefault))!.Invoke(targetSetting, null); - continue; - } - - bool hasSameGenericArgument = getGenericBaseType(targetSetting, typeof(Bindable<>))!.GenericTypeArguments.Single() == - getGenericBaseType(sourceSetting, typeof(Bindable<>))!.GenericTypeArguments.Single(); - - if (!hasSameGenericArgument) - continue; - - Type? targetBindableNumberType = getGenericBaseType(targetSetting, typeof(BindableNumber<>)); - Type? sourceBindableNumberType = getGenericBaseType(sourceSetting, typeof(BindableNumber<>)); - - if (targetBindableNumberType == null || sourceBindableNumberType == null) - { - setValue(targetSetting, value, getValue(sourceSetting, value)); - continue; - } - - setValue(targetSetting, value, Convert.ChangeType(getValue(sourceSetting, value), targetBindableNumberType.GenericTypeArguments.Single())); - } - - object? getValue(object setting, string name) => - setting.GetType().GetProperty(name)!.GetValue(setting); - - void setValue(object setting, string name, object? newValue) => - setting.GetType().GetProperty(name)!.SetValue(setting, newValue); - - Type? getGenericBaseType(object setting, Type genericType) => - setting.GetType().GetTypeInheritance().FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == genericType); + Type getBindableGenericType(IBindable setting) => + setting.GetType().GetTypeInheritance() + .First(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Bindable<>)) + .GenericTypeArguments.Single(); } /// @@ -250,7 +231,7 @@ namespace osu.Game.Rulesets.Mods if (ReferenceEquals(this, other)) return true; return GetType() == other.GetType() && - Settings.SequenceEqual(other.Settings, ModSettingsEqualityComparer.Default); + SettingsBindables.SequenceEqual(other.SettingsBindables, ModSettingsEqualityComparer.Default); } public override int GetHashCode() @@ -259,7 +240,7 @@ namespace osu.Game.Rulesets.Mods hashCode.Add(GetType()); - foreach (var setting in Settings) + foreach (var setting in SettingsBindables) hashCode.Add(setting.GetUnderlyingSettingValue()); return hashCode.ToHashCode(); From 8e297dc60a18a9d7057d4b7525ec8cd6189bb504 Mon Sep 17 00:00:00 2001 From: Terochi Date: Tue, 25 Apr 2023 21:28:03 +0200 Subject: [PATCH 2687/2991] Added safety measures for invalid mod combinations --- osu.Game/OsuGameBase.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index f6cda62cc3..0473f2665b 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -641,6 +641,16 @@ namespace osu.Game convertedCommonMods.Add(convertedMod); } + if (!ModUtils.CheckValidForGameplay(convertedCommonMods, out var invalid)) + { + invalid.ForEach(mod => + { + int index = convertedCommonMods.IndexOf(mod); + convertedCommonMods.RemoveAt(index); + previouslySelectedCommonMods.RemoveAt(index); + }); + } + if (!SelectedMods.Disabled) // Select common mods to play the deselect samples for other mods SelectedMods.Value = previouslySelectedCommonMods; From 1efc78c0f8a7c3b17062c9a90318da3ef41a986c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Apr 2023 13:28:51 +0900 Subject: [PATCH 2688/2991] Actually use new end time property when setting lifetimes --- osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs | 2 +- osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs index e598c79b08..be77c9a98e 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs @@ -85,7 +85,7 @@ namespace osu.Game.Storyboards.Drawables Loop = animation.LoopType == AnimationLoopType.LoopForever; LifetimeStart = animation.StartTime; - LifetimeEnd = animation.EndTime; + LifetimeEnd = animation.EndTimeForDisplay; } [Resolved] diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs index f9b09ed57c..400d33481c 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs @@ -82,7 +82,7 @@ namespace osu.Game.Storyboards.Drawables Position = sprite.InitialPosition; LifetimeStart = sprite.StartTime; - LifetimeEnd = sprite.EndTime; + LifetimeEnd = sprite.EndTimeForDisplay; } [Resolved] From cb7b246e3352c08b73119b88fb0966e118720e2c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 26 Apr 2023 15:27:58 +0900 Subject: [PATCH 2689/2991] Fix naming and update in line with nullability --- osu.Game/Rulesets/Mods/ModFailCondition.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModFailCondition.cs b/osu.Game/Rulesets/Mods/ModFailCondition.cs index 63cebc9747..97789b7f5a 100644 --- a/osu.Game/Rulesets/Mods/ModFailCondition.cs +++ b/osu.Game/Rulesets/Mods/ModFailCondition.cs @@ -19,18 +19,19 @@ namespace osu.Game.Rulesets.Mods public virtual bool PerformFail() => true; public virtual bool RestartOnFail => Restart.Value; - private event Action failureTriggered; + + private Action? triggerFailureDelegate; public void ApplyToHealthProcessor(HealthProcessor healthProcessor) { - failureTriggered = healthProcessor.TriggerFailure; + triggerFailureDelegate = healthProcessor.TriggerFailure; healthProcessor.FailConditions += FailCondition; } /// /// Immediately triggers a failure on the loaded . /// - protected void TriggerFailure() => failureTriggered?.Invoke(); + protected void TriggerFailure() => triggerFailureDelegate?.Invoke(); /// /// Determines whether should trigger a failure. Called every time a From 332c199dc2b0cdabe76e56dc8696d6ee52f58fa9 Mon Sep 17 00:00:00 2001 From: Terochi Date: Wed, 26 Apr 2023 10:46:29 +0200 Subject: [PATCH 2690/2991] further simplification --- osu.Game/Rulesets/Mods/Mod.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 97434ce493..0af8717264 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; -using AutoMapper.Internal; using Newtonsoft.Json; using osu.Framework.Bindables; using osu.Framework.Extensions.TypeExtensions; @@ -182,7 +181,10 @@ namespace osu.Game.Rulesets.Mods if (sourceSetting.IsDefault) continue; - if (getBindableGenericType(targetSetting) != getBindableGenericType(sourceSetting)) + var targetType = targetSetting.GetType(); + var sourceType = sourceSetting.GetType(); + + if (!targetType.IsAssignableFrom(sourceType) && !sourceType.IsAssignableFrom(targetType)) continue; // TODO: special case for handling number types @@ -190,11 +192,6 @@ namespace osu.Game.Rulesets.Mods PropertyInfo property = targetSetting.GetType().GetProperty(nameof(Bindable.Value))!; property.SetValue(targetSetting, property.GetValue(sourceSetting)); } - - Type getBindableGenericType(IBindable setting) => - setting.GetType().GetTypeInheritance() - .First(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Bindable<>)) - .GenericTypeArguments.Single(); } /// From e27c4dfa101fe132f76614e32815c6a34ba455bc Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 26 Apr 2023 11:46:05 +0200 Subject: [PATCH 2691/2991] Invoke ApplyDefaultsToSelf --- osu.Game/Rulesets/Objects/HitObject.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 0502610eab..7702635057 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -105,6 +105,8 @@ namespace osu.Game.Rulesets.Objects /// The cancellation token. public void ApplyDefaults(ControlPointInfo controlPointInfo, IBeatmapDifficultyInfo difficulty, CancellationToken cancellationToken = default) { + ApplyDefaultsToSelf(controlPointInfo, difficulty); + nestedHitObjects.Clear(); CreateNestedHitObjects(cancellationToken); From 6c7094868163c7aeda18116d352739ba8309d57c Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 26 Apr 2023 13:10:57 +0200 Subject: [PATCH 2692/2991] Remove IContext & add IHasGenerateTicks --- .../Legacy/DistanceObjectPatternGenerator.cs | 4 +- osu.Game.Rulesets.Osu/Objects/Slider.cs | 8 +- .../Beatmaps/TaikoBeatmapConverter.cs | 4 +- .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 6 +- osu.Game/Beatmaps/Legacy/LegacyContext.cs | 32 ------- osu.Game/Context/ContextContainer.cs | 91 ------------------- osu.Game/Context/IContext.cs | 13 --- osu.Game/Rulesets/Objects/HitObject.cs | 9 +- .../Objects/Types/IHasGenerateTicks.cs | 17 ++++ 9 files changed, 37 insertions(+), 147 deletions(-) delete mode 100644 osu.Game/Beatmaps/Legacy/LegacyContext.cs delete mode 100644 osu.Game/Context/ContextContainer.cs delete mode 100644 osu.Game/Context/IContext.cs create mode 100644 osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 2427812ecd..20f39deed7 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -51,8 +51,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy TimingControlPoint timingPoint = beatmap.ControlPointInfo.TimingPointAt(hitObject.StartTime); double beatLength; - if (hitObject.HasContext()) - beatLength = timingPoint.BeatLength * hitObject.GetContext().BpmMultiplier; + if (hitObject.LegacyBpmMultiplier.HasValue) + beatLength = timingPoint.BeatLength * hitObject.LegacyBpmMultiplier.Value; else if (hitObject is IHasSliderVelocity hasSliderVelocity) beatLength = timingPoint.BeatLength / hasSliderVelocity.SliderVelocity; else diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 247cf94f59..dd75a86f96 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -15,14 +15,13 @@ using osu.Framework.Caching; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Beatmaps.Legacy; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Osu.Objects { - public class Slider : OsuHitObject, IHasPathWithRepeats, IHasSliderVelocity + public class Slider : OsuHitObject, IHasPathWithRepeats, IHasSliderVelocity, IHasGenerateTicks { public double EndTime => StartTime + this.SpanCount() * Path.Distance / Velocity; @@ -143,6 +142,8 @@ namespace osu.Game.Rulesets.Osu.Objects set => SliderVelocityBindable.Value = value; } + public bool GenerateTicks { get; set; } + [JsonIgnore] public SliderHeadCircle HeadCircle { get; protected set; } @@ -162,10 +163,9 @@ namespace osu.Game.Rulesets.Osu.Objects TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); double scoringDistance = BASE_SCORING_DISTANCE * difficulty.SliderMultiplier * SliderVelocity; - bool generateTicks = !HasContext() || GetContext().GenerateTicks; Velocity = scoringDistance / timingPoint.BeatLength; - TickDistance = generateTicks ? (scoringDistance / difficulty.SliderTickRate * TickDistanceMultiplier) : double.PositiveInfinity; + TickDistance = GenerateTicks ? (scoringDistance / difficulty.SliderTickRate * TickDistanceMultiplier) : double.PositiveInfinity; } protected override void CreateNestedHitObjects(CancellationToken cancellationToken) diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index ef73ffd517..2cf1d7a6ab 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -180,8 +180,8 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps TimingControlPoint timingPoint = beatmap.ControlPointInfo.TimingPointAt(obj.StartTime); double beatLength; - if (obj.HasContext()) - beatLength = timingPoint.BeatLength * obj.GetContext().BpmMultiplier; + if (obj.LegacyBpmMultiplier.HasValue) + beatLength = timingPoint.BeatLength * obj.LegacyBpmMultiplier.Value; else if (obj is IHasSliderVelocity hasSliderVelocity) beatLength = timingPoint.BeatLength / hasSliderVelocity.SliderVelocity; else diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index dad23df282..9a1935f929 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -105,7 +105,11 @@ namespace osu.Game.Beatmaps.Formats #pragma warning disable 618 if (difficultyControlPoint is LegacyDifficultyControlPoint legacyDifficultyControlPoint) #pragma warning restore 618 - hitObject.SetContext(new LegacyContext(legacyDifficultyControlPoint.BpmMultiplier, legacyDifficultyControlPoint.GenerateTicks)); + { + hitObject.LegacyBpmMultiplier = legacyDifficultyControlPoint.BpmMultiplier; + if (hitObject is IHasGenerateTicks hasGenerateTicks) + hasGenerateTicks.GenerateTicks = legacyDifficultyControlPoint.GenerateTicks; + } if (hitObject is IHasSliderVelocity hasSliderVelocity) hasSliderVelocity.SliderVelocity = difficultyControlPoint.SliderVelocity; diff --git a/osu.Game/Beatmaps/Legacy/LegacyContext.cs b/osu.Game/Beatmaps/Legacy/LegacyContext.cs deleted file mode 100644 index eeb02bdcb7..0000000000 --- a/osu.Game/Beatmaps/Legacy/LegacyContext.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Game.Context; - -namespace osu.Game.Beatmaps.Legacy; - -public class LegacyContext : IContext -{ - public LegacyContext(double bpmMultiplier, bool generateTicks) - { - BpmMultiplier = bpmMultiplier; - GenerateTicks = generateTicks; - } - - /// - /// Legacy BPM multiplier that introduces floating-point errors for rulesets that depend on it. - /// DO NOT USE THIS UNLESS 100% SURE. - /// - public double BpmMultiplier { get; } - - /// - /// Whether or not slider ticks should be generated at this control point. - /// This exists for backwards compatibility with maps that abuse NaN slider velocity behavior on osu!stable (e.g. /b/2628991). - /// - public bool GenerateTicks { get; } - - public IContext Copy() - { - return new LegacyContext(BpmMultiplier, GenerateTicks); - } -} diff --git a/osu.Game/Context/ContextContainer.cs b/osu.Game/Context/ContextContainer.cs deleted file mode 100644 index 7ff0280bcf..0000000000 --- a/osu.Game/Context/ContextContainer.cs +++ /dev/null @@ -1,91 +0,0 @@ -// 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; - -namespace osu.Game.Context -{ - public abstract class ContextContainer - { - /// - /// The contexts of this container. - /// The objects always have the type of their key. - /// - private readonly Dictionary contexts; - - protected ContextContainer() - { - contexts = new Dictionary(); - } - - /// - /// Checks whether this object has the context with type T. - /// - /// The type to check the context of. - /// Whether the context object with type T exists in this object. - public bool HasContext() where T : IContext - { - return contexts.ContainsKey(typeof(T)); - } - - /// - /// Gets the context with type T. - /// - /// The type to get the context of. - /// If the context does not exist in this hit object. - /// The context object with type T. - public T GetContext() where T : IContext - { - return (T)contexts[typeof(T)]; - } - - /// - /// Tries to get the context with type T. - /// - /// The found context with type T. - /// The type to get the context of. - /// Whether the context exists in this object. - public bool TryGetContext(out T context) where T : IContext - { - if (contexts.TryGetValue(typeof(T), out var context2)) - { - context = (T)context2; - return true; - } - - context = default!; - return false; - } - - /// - /// Sets the context object of type T. - /// - /// The context type to set. - /// The context object to store in this object. - public void SetContext(T context) where T : IContext - { - contexts[typeof(T)] = context; - } - - /// - /// Removes the context of type T from this object. - /// - /// The type to remove the context of. - /// Whether a context was removed. - public bool RemoveContext() where T : IContext - { - return RemoveContext(typeof(T)); - } - - /// - /// Removes the context of type T from this object. - /// - /// The type to remove the context of. - /// Whether a context was removed. - public bool RemoveContext(Type t) - { - return contexts.Remove(t); - } - } -} diff --git a/osu.Game/Context/IContext.cs b/osu.Game/Context/IContext.cs deleted file mode 100644 index 61b1b11f43..0000000000 --- a/osu.Game/Context/IContext.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -namespace osu.Game.Context; - -public interface IContext -{ - /// - /// Makes a deep copy of this context. - /// - /// The deep copy of this context. - public IContext Copy(); -} diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 7702635057..aaeffa49fc 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -16,7 +16,6 @@ using osu.Framework.Lists; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Context; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Scoring; @@ -29,7 +28,7 @@ namespace osu.Game.Rulesets.Objects /// HitObjects may contain more properties for which you should be checking through the IHas* types. /// /// - public class HitObject : ContextContainer + public class HitObject { /// /// A small adjustment to the start time of control points to account for rounding/precision errors. @@ -80,6 +79,12 @@ namespace osu.Game.Rulesets.Objects public SampleControlPoint SampleControlPoint = SampleControlPoint.DEFAULT; public DifficultyControlPoint DifficultyControlPoint = DifficultyControlPoint.DEFAULT; + /// + /// Legacy BPM multiplier that introduces floating-point errors for rulesets that depend on it. + /// DO NOT USE THIS UNLESS 100% SURE. + /// + public double? LegacyBpmMultiplier { get; set; } + /// /// Whether this is in Kiai time. /// diff --git a/osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs b/osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs new file mode 100644 index 0000000000..5de7d348c5 --- /dev/null +++ b/osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs @@ -0,0 +1,17 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Rulesets.Objects.Types +{ + /// + /// A type of which may or may not generate ticks. + /// + public interface IHasGenerateTicks + { + /// + /// Whether or not slider ticks should be generated at this control point. + /// This exists for backwards compatibility with maps that abuse NaN slider velocity behavior on osu!stable (e.g. /b/2628991). + /// + public bool GenerateTicks { get; set; } + } +} From 39d9f0c3f5d689506a0971d22d9e40fab01ecee4 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 26 Apr 2023 13:22:13 +0200 Subject: [PATCH 2693/2991] removing using --- .../Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 20f39deed7..91b7be6e8f 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -14,7 +14,6 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Beatmaps.Legacy; using osu.Game.Utils; namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy From 87ca0f5335ebd07abe29c3958bf2b5cd88f947ef Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 26 Apr 2023 13:45:58 +0200 Subject: [PATCH 2694/2991] Update SamplePointPiece.cs --- .../Components/Timeline/SamplePointPiece.cs | 57 ++++++++++++------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs index 50278bffc0..b02cfb505e 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs @@ -12,7 +12,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; -using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Audio; using osu.Game.Graphics; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Rulesets.Objects; @@ -26,14 +26,12 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { public readonly HitObject HitObject; - private readonly Bindable bank; - private readonly BindableNumber volume; + private readonly BindableList samplesBindable; public SamplePointPiece(HitObject hitObject) { HitObject = hitObject; - volume = hitObject.SampleControlPoint.SampleVolumeBindable.GetBoundCopy(); - bank = hitObject.SampleControlPoint.SampleBankBindable.GetBoundCopy(); + samplesBindable = hitObject.SamplesBindable.GetBoundCopy(); } protected override Color4 GetRepresentingColour(OsuColour colours) => colours.Pink; @@ -41,8 +39,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [BackgroundDependencyLoader] private void load() { - volume.BindValueChanged(_ => updateText()); - bank.BindValueChanged(_ => updateText(), true); + samplesBindable.BindCollectionChanged((_, _) => updateText(), true); } protected override bool OnClick(ClickEvent e) @@ -53,7 +50,17 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private void updateText() { - Label.Text = $"{bank.Value} {volume.Value}"; + Label.Text = $"{GetBankValue(samplesBindable)} {GetVolumeValue(samplesBindable)}"; + } + + public static string? GetBankValue(IEnumerable samples) + { + return samples.FirstOrDefault()?.Bank; + } + + public static int GetVolumeValue(ICollection samples) + { + return samples.Count == 0 ? 0 : samples.Max(o => o.Volume); } public Popover GetPopover() => new SampleEditPopover(HitObject); @@ -92,7 +99,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { Label = "Bank Name", }, - volume = new IndeterminateSliderWithTextBoxInput("Volume", new SampleControlPoint().SampleVolumeBindable) + volume = new IndeterminateSliderWithTextBoxInput("Volume", new BindableInt(100) + { + MinValue = 0, + MaxValue = 100, + }) } } }; @@ -103,14 +114,14 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline // if the piece belongs to a currently selected object, assume that the user wants to change all selected objects. // if the piece belongs to an unselected object, operate on that object alone, independently of the selection. var relevantObjects = (beatmap.SelectedHitObjects.Contains(hitObject) ? beatmap.SelectedHitObjects : hitObject.Yield()).ToArray(); - var relevantControlPoints = relevantObjects.Select(h => h.SampleControlPoint).ToArray(); + var relevantSamples = relevantObjects.Select(h => h.Samples).ToArray(); // even if there are multiple objects selected, we can still display sample volume or bank if they all have the same value. - string? commonBank = getCommonBank(relevantControlPoints); + string? commonBank = getCommonBank(relevantSamples); if (!string.IsNullOrEmpty(commonBank)) bank.Current.Value = commonBank; - int? commonVolume = getCommonVolume(relevantControlPoints); + int? commonVolume = getCommonVolume(relevantSamples); if (commonVolume != null) volume.Current.Value = commonVolume.Value; @@ -120,9 +131,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline updateBankFor(relevantObjects, val.NewValue); updateBankPlaceholderText(relevantObjects); }); - // on commit, ensure that the value is correct by sourcing it from the objects' control points again. + // on commit, ensure that the value is correct by sourcing it from the objects' samples again. // this ensures that committing empty text causes a revert to the previous value. - bank.OnCommit += (_, _) => bank.Current.Value = getCommonBank(relevantControlPoints); + bank.OnCommit += (_, _) => bank.Current.Value = getCommonBank(relevantSamples); volume.Current.BindValueChanged(val => updateVolumeFor(relevantObjects, val.NewValue)); } @@ -133,8 +144,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline ScheduleAfterChildren(() => GetContainingInputManager().ChangeFocus(volume)); } - private static string? getCommonBank(SampleControlPoint[] relevantControlPoints) => relevantControlPoints.Select(point => point.SampleBank).Distinct().Count() == 1 ? relevantControlPoints.First().SampleBank : null; - private static int? getCommonVolume(SampleControlPoint[] relevantControlPoints) => relevantControlPoints.Select(point => point.SampleVolume).Distinct().Count() == 1 ? relevantControlPoints.First().SampleVolume : null; + private static string? getCommonBank(IList[] relevantSamples) => relevantSamples.Select(GetBankValue).Distinct().Count() == 1 ? GetBankValue(relevantSamples.First()) : null; + private static int? getCommonVolume(IList[] relevantSamples) => relevantSamples.Select(GetVolumeValue).Distinct().Count() == 1 ? GetVolumeValue(relevantSamples.First()) : null; private void updateBankFor(IEnumerable objects, string? newBank) { @@ -145,7 +156,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline foreach (var h in objects) { - h.SampleControlPoint.SampleBank = newBank; + for (int i = 0; i < h.Samples.Count; i++) + { + h.Samples[i] = h.Samples[i].With(newBank: newBank); + } + beatmap.Update(h); } @@ -154,7 +169,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private void updateBankPlaceholderText(IEnumerable objects) { - string? commonBank = getCommonBank(objects.Select(h => h.SampleControlPoint).ToArray()); + string? commonBank = getCommonBank(objects.Select(h => h.Samples).ToArray()); bank.PlaceholderText = string.IsNullOrEmpty(commonBank) ? "(multiple)" : string.Empty; } @@ -167,7 +182,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline foreach (var h in objects) { - h.SampleControlPoint.SampleVolume = newVolume.Value; + for (int i = 0; i < h.Samples.Count; i++) + { + h.Samples[i] = h.Samples[i].With(newVolume: newVolume.Value); + } + beatmap.Update(h); } From d97daee96be2c10f90709cc30beceb1f369ae225 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 26 Apr 2023 13:55:39 +0200 Subject: [PATCH 2695/2991] remove all non-test usage of SampleControlPoint --- .../Objects/Drawables/DrawableHoldNote.cs | 8 +------- .../Blueprints/Sliders/SliderSelectionBlueprint.cs | 10 ---------- osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs | 1 - .../Objects/Drawables/DrawableSlider.cs | 10 ++-------- .../Objects/Drawables/DrawableSpinner.cs | 2 +- osu.Game.Rulesets.Osu/Objects/Spinner.cs | 2 +- osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs | 7 ++++--- 7 files changed, 9 insertions(+), 31 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 6e1c6cf80f..372ef1e164 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -350,13 +350,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { // Note: base.LoadSamples() isn't called since the slider plays the tail's hitsounds for the time being. - if (HitObject.SampleControlPoint == null) - { - throw new InvalidOperationException($"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}." - + $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}."); - } - - slidingSample.Samples = HitObject.CreateSlidingSamples().Select(s => HitObject.SampleControlPoint.ApplyTo(s)).Cast().ToArray(); + slidingSample.Samples = HitObject.CreateSlidingSamples().Cast().ToArray(); } public override void StopAllSamples() diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index e444287b73..8cf64a6a7e 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -311,17 +311,11 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders var splitControlPoints = controlPoints.Take(index + 1).ToList(); controlPoints.RemoveRange(0, index); - // Turn the control points which were split off into a new slider. - var samplePoint = (SampleControlPoint)HitObject.SampleControlPoint.DeepClone(); - var difficultyPoint = (DifficultyControlPoint)HitObject.DifficultyControlPoint.DeepClone(); - var newSlider = new Slider { StartTime = HitObject.StartTime, Position = HitObject.Position + splitControlPoints[0].Position, NewCombo = HitObject.NewCombo, - SampleControlPoint = samplePoint, - DifficultyControlPoint = difficultyPoint, LegacyLastTickOffset = HitObject.LegacyLastTickOffset, Samples = HitObject.Samples.Select(s => s.With()).ToList(), RepeatCount = HitObject.RepeatCount, @@ -378,15 +372,11 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders Vector2 position = HitObject.Position + HitObject.Path.PositionAt(pathPosition); - var samplePoint = (SampleControlPoint)HitObject.SampleControlPoint.DeepClone(); - samplePoint.Time = time; - editorBeatmap.Add(new HitCircle { StartTime = time, Position = position, NewCombo = i == 0 && HitObject.NewCombo, - SampleControlPoint = samplePoint, Samples = HitObject.HeadCircle.Samples.Select(s => s.With()).ToList() }); diff --git a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs index 6d5280e528..2a6d6ce4c3 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs @@ -362,7 +362,6 @@ namespace osu.Game.Rulesets.Osu.Edit StartTime = firstHitObject.StartTime, Position = firstHitObject.Position, NewCombo = firstHitObject.NewCombo, - SampleControlPoint = firstHitObject.SampleControlPoint, Samples = firstHitObject.Samples, }; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index a7b02596d5..664a8146e7 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -133,14 +133,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { // Note: base.LoadSamples() isn't called since the slider plays the tail's hitsounds for the time being. - if (HitObject.SampleControlPoint == null) - { - throw new InvalidOperationException($"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}." - + $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}."); - } - - Samples.Samples = HitObject.TailSamples.Select(s => HitObject.SampleControlPoint.ApplyTo(s)).Cast().ToArray(); - slidingSample.Samples = HitObject.CreateSlidingSamples().Select(s => HitObject.SampleControlPoint.ApplyTo(s)).Cast().ToArray(); + Samples.Samples = HitObject.TailSamples.Cast().ToArray(); + slidingSample.Samples = HitObject.CreateSlidingSamples().Cast().ToArray(); } public override void StopAllSamples() diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index a5193f1b6e..0ceda1d4b0 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -126,7 +126,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { base.LoadSamples(); - spinningSample.Samples = HitObject.CreateSpinningSamples().Select(s => HitObject.SampleControlPoint.ApplyTo(s)).Cast().ToArray(); + spinningSample.Samples = HitObject.CreateSpinningSamples().Cast().ToArray(); spinningSample.Frequency.Value = spinning_sample_initial_frequency; } diff --git a/osu.Game.Rulesets.Osu/Objects/Spinner.cs b/osu.Game.Rulesets.Osu/Objects/Spinner.cs index ed6f8a9a6a..55924c19c9 100644 --- a/osu.Game.Rulesets.Osu/Objects/Spinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Spinner.cs @@ -91,7 +91,7 @@ namespace osu.Game.Rulesets.Osu.Objects return new[] { - SampleControlPoint.ApplyTo(referenceSample).With("spinnerspin") + referenceSample.With("spinnerspin") }; } } diff --git a/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs b/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs index 4809791af8..92f2b74568 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using osu.Game.Audio; using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.UI; @@ -17,12 +18,12 @@ namespace osu.Game.Rulesets.Taiko.UI public void Play(HitType hitType) { - var hitObject = GetMostValidObject(); + var hitSample = GetMostValidObject()?.Samples?.FirstOrDefault(o => o.Name == HitSampleInfo.HIT_NORMAL); - if (hitObject == null) + if (hitSample == null) return; - PlaySamples(new ISampleInfo[] { hitObject.SampleControlPoint.GetSampleInfo(hitType == HitType.Rim ? HitSampleInfo.HIT_CLAP : HitSampleInfo.HIT_NORMAL) }); + PlaySamples(new ISampleInfo[] { new HitSampleInfo(hitType == HitType.Rim ? HitSampleInfo.HIT_CLAP : HitSampleInfo.HIT_NORMAL, hitSample.Bank, volume: hitSample.Volume) }); } public override void Play() => throw new InvalidOperationException(@"Use override with HitType parameter instead"); From c6fc1806595df9be3e3cb738fae20a0efaa8839d Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 26 Apr 2023 14:21:52 +0200 Subject: [PATCH 2696/2991] remove all test usages of SampleControlPoint --- .../Editor/TestSceneObjectMerging.cs | 3 +- .../Editor/TestSceneSliderSplitting.cs | 10 ++----- .../Editor/TestSceneSliderStreamConversion.cs | 3 +- .../Formats/LegacyBeatmapDecoderTest.cs | 6 ++-- .../Editing/TestSceneEditorClipboard.cs | 4 --- .../Visual/Editing/TestSceneEditorSaving.cs | 10 ------- ...estSceneHitObjectSamplePointAdjustments.cs | 29 ++++++++++++------- .../TestSceneGameplaySampleTriggerSource.cs | 6 ++-- osu.Game/Audio/HitSampleInfo.cs | 5 ++-- osu.Game/Rulesets/Objects/HitObject.cs | 1 - 10 files changed, 32 insertions(+), 45 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectMerging.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectMerging.cs index e7ac38c20e..b05c755bfd 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectMerging.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneObjectMerging.cs @@ -138,8 +138,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor var mergedSlider = (Slider)EditorBeatmap.SelectedHitObjects.First(); return slider1 is not null && mergedSlider.HeadCircle.Samples.SequenceEqual(slider1.HeadCircle.Samples) && mergedSlider.TailCircle.Samples.SequenceEqual(slider1.TailCircle.Samples) - && mergedSlider.Samples.SequenceEqual(slider1.Samples) - && mergedSlider.SampleControlPoint.IsRedundant(slider1.SampleControlPoint); + && mergedSlider.Samples.SequenceEqual(slider1.Samples); }); AddAssert("slider end is at same completion for last slider", () => diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSplitting.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSplitting.cs index 6cb77c7b92..a104433ea9 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSplitting.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSplitting.cs @@ -181,10 +181,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor { if (slider is null) return; - slider.SampleControlPoint.SampleBank = "soft"; - slider.SampleControlPoint.SampleVolume = 70; - sample = new HitSampleInfo("hitwhistle"); - slider.Samples.Add(sample); + sample = new HitSampleInfo("hitwhistle", "soft", volume: 70); + slider.Samples.Add(sample.With()); }); AddStep("select added slider", () => @@ -207,9 +205,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddAssert("sliders have hitsounds", hasHitsounds); bool hasHitsounds() => sample is not null && - EditorBeatmap.HitObjects.All(o => o.SampleControlPoint.SampleBank == "soft" && - o.SampleControlPoint.SampleVolume == 70 && - o.Samples.Contains(sample)); + EditorBeatmap.HitObjects.All(o => o.Samples.Contains(sample)); } private bool sliderCreatedFor(Slider s, double startTime, double endTime, params (Vector2 pos, PathType? pathType)[] expectedControlPoints) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderStreamConversion.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderStreamConversion.cs index 53465d43c9..a162d9a491 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderStreamConversion.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderStreamConversion.cs @@ -199,8 +199,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor Precision.AlmostEquals(circle.StartTime, time, 1) && Precision.AlmostEquals(circle.Position, position, 0.01f) && circle.NewCombo == startsNewCombo - && circle.Samples.SequenceEqual(slider.HeadCircle.Samples) - && circle.SampleControlPoint.IsRedundant(slider.SampleControlPoint); + && circle.Samples.SequenceEqual(slider.HeadCircle.Samples); } private bool sliderRestored(Slider slider) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 518981980b..622a1837eb 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -480,7 +480,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual("Gameplay/soft-hitnormal8", getTestableSampleInfo(hitObjects[4]).LookupNames.First()); } - static HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]); + static HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.Samples[0]; } [Test] @@ -498,7 +498,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual("Gameplay/normal-hitnormal3", getTestableSampleInfo(hitObjects[2]).LookupNames.First()); } - static HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]); + static HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.Samples[0]; } [Test] @@ -518,7 +518,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(70, getTestableSampleInfo(hitObjects[3]).Volume); } - static HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]); + static HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.Samples[0]; } [Test] diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs index d26bb6bb8a..3c98a83fa0 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs @@ -95,10 +95,6 @@ namespace osu.Game.Tests.Visual.Editing var path = slider.Path; return path.ControlPoints.Count == 2 && path.ControlPoints.SequenceEqual(addedObject.Path.ControlPoints); }); - - // see `HitObject.control_point_leniency`. - AddAssert("sample control point has correct time", () => Precision.AlmostEquals(slider.SampleControlPoint.Time, slider.GetEndTime(), 1)); - AddAssert("difficulty control point has correct time", () => slider.DifficultyControlPoint.Time == slider.StartTime); } [Test] diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs index b396b382ff..64c48e74cf 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs @@ -122,19 +122,9 @@ namespace osu.Game.Tests.Visual.Editing AddAssert("Beatmap has correct timing point", () => EditorBeatmap.ControlPointInfo.TimingPoints.Single().Time == 500); - // After placement these must be non-default as defaults are read-only. - AddAssert("Placed object has non-default control points", () => - !ReferenceEquals(EditorBeatmap.HitObjects[0].SampleControlPoint, SampleControlPoint.DEFAULT) && - !ReferenceEquals(EditorBeatmap.HitObjects[0].DifficultyControlPoint, DifficultyControlPoint.DEFAULT)); - ReloadEditorToSameBeatmap(); AddAssert("Beatmap still has correct timing point", () => EditorBeatmap.ControlPointInfo.TimingPoints.Single().Time == 500); - - // After placement these must be non-default as defaults are read-only. - AddAssert("Placed object still has non-default control points", () => - !ReferenceEquals(EditorBeatmap.HitObjects[0].SampleControlPoint, SampleControlPoint.DEFAULT) && - !ReferenceEquals(EditorBeatmap.HitObjects[0].DifficultyControlPoint, DifficultyControlPoint.DEFAULT)); } [Test] diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs index e8dcc6f19b..7403cad52f 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs @@ -7,6 +7,7 @@ using System.Linq; using Humanizer; using NUnit.Framework; using osu.Framework.Testing; +using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.UserInterface; @@ -39,10 +40,9 @@ namespace osu.Game.Tests.Visual.Editing { StartTime = 0, Position = (OsuPlayfield.BASE_SIZE - new Vector2(100, 0)) / 2, - SampleControlPoint = new SampleControlPoint + Samples = new List { - SampleBank = "normal", - SampleVolume = 80 + new HitSampleInfo(HitSampleInfo.HIT_NORMAL, "normal", volume: 80) } }); @@ -50,10 +50,9 @@ namespace osu.Game.Tests.Visual.Editing { StartTime = 500, Position = (OsuPlayfield.BASE_SIZE + new Vector2(100, 0)) / 2, - SampleControlPoint = new SampleControlPoint + Samples = new List { - SampleBank = "soft", - SampleVolume = 60 + new HitSampleInfo(HitSampleInfo.HIT_NORMAL, "soft", volume: 60) } }); }); @@ -96,7 +95,12 @@ namespace osu.Game.Tests.Visual.Editing AddStep("unify sample volume", () => { foreach (var h in EditorBeatmap.HitObjects) - h.SampleControlPoint.SampleVolume = 50; + { + for (int i = 0; i < h.Samples.Count; i++) + { + h.Samples[i] = h.Samples[i].With(newVolume: 50); + } + } }); AddStep("select both objects", () => EditorBeatmap.SelectedHitObjects.AddRange(EditorBeatmap.HitObjects)); @@ -136,7 +140,12 @@ namespace osu.Game.Tests.Visual.Editing AddStep("unify sample bank", () => { foreach (var h in EditorBeatmap.HitObjects) - h.SampleControlPoint.SampleBank = "soft"; + { + for (int i = 0; i < h.Samples.Count; i++) + { + h.Samples[i] = h.Samples[i].With(newBank: "soft"); + } + } }); AddStep("select both objects", () => EditorBeatmap.SelectedHitObjects.AddRange(EditorBeatmap.HitObjects)); @@ -248,7 +257,7 @@ namespace osu.Game.Tests.Visual.Editing private void hitObjectHasSampleVolume(int objectIndex, int volume) => AddAssert($"{objectIndex.ToOrdinalWords()} has volume {volume}", () => { var h = EditorBeatmap.HitObjects.ElementAt(objectIndex); - return h.SampleControlPoint.SampleVolume == volume; + return h.Samples.All(o => o.Volume == volume); }); private void setBankViaPopover(string bank) => AddStep($"set bank {bank} via popover", () => @@ -265,7 +274,7 @@ namespace osu.Game.Tests.Visual.Editing private void hitObjectHasSampleBank(int objectIndex, string bank) => AddAssert($"{objectIndex.ToOrdinalWords()} has bank {bank}", () => { var h = EditorBeatmap.HitObjects.ElementAt(objectIndex); - return h.SampleControlPoint.SampleBank == bank; + return h.Samples.All(o => o.Bank == bank); }); } } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs index 31133f00d9..114c554d28 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs @@ -73,8 +73,7 @@ namespace osu.Game.Tests.Visual.Gameplay new HitCircle { StartTime = t += spacing, - Samples = new[] { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) }, - SampleControlPoint = new SampleControlPoint { SampleBank = "soft" }, + Samples = new[] { new HitSampleInfo(HitSampleInfo.HIT_NORMAL, "soft") }, }, new HitCircle { @@ -84,8 +83,7 @@ namespace osu.Game.Tests.Visual.Gameplay { StartTime = t += spacing, Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, Vector2.UnitY * 200 }), - Samples = new[] { new HitSampleInfo(HitSampleInfo.HIT_WHISTLE) }, - SampleControlPoint = new SampleControlPoint { SampleBank = "soft" }, + Samples = new[] { new HitSampleInfo(HitSampleInfo.HIT_WHISTLE, "soft") }, }, }); diff --git a/osu.Game/Audio/HitSampleInfo.cs b/osu.Game/Audio/HitSampleInfo.cs index efa5562cb8..e9c06152cc 100644 --- a/osu.Game/Audio/HitSampleInfo.cs +++ b/osu.Game/Audio/HitSampleInfo.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using Newtonsoft.Json; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Utils; namespace osu.Game.Audio @@ -32,7 +33,7 @@ namespace osu.Game.Audio /// /// The bank to load the sample from. /// - public readonly string? Bank; + public readonly string Bank; /// /// An optional suffix to provide priority lookup. Falls back to non-suffixed . @@ -47,7 +48,7 @@ namespace osu.Game.Audio public HitSampleInfo(string name, string? bank = null, string? suffix = null, int volume = 0) { Name = name; - Bank = bank; + Bank = bank ?? SampleControlPoint.DEFAULT_BANK; Suffix = suffix; Volume = volume; } diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index aaeffa49fc..73ecc28404 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -76,7 +76,6 @@ namespace osu.Game.Rulesets.Objects /// public virtual IList AuxiliarySamples => ImmutableList.Empty; - public SampleControlPoint SampleControlPoint = SampleControlPoint.DEFAULT; public DifficultyControlPoint DifficultyControlPoint = DifficultyControlPoint.DEFAULT; /// From 5accb05f45d81d3e7fc385cdb53053d9aa9ee2c6 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 26 Apr 2023 14:28:48 +0200 Subject: [PATCH 2697/2991] fix invalidoperation exception --- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 04786cc9fb..a4783046c4 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -271,7 +271,9 @@ namespace osu.Game.Beatmaps.Formats if (hitObject.Samples.Count > 0) { int volume = hitObject.Samples.Max(o => o.Volume); - int customIndex = hitObject.Samples.OfType().Max(o => o.CustomSampleBank); + int customIndex = hitObject.Samples.Any(o => o is ConvertHitObjectParser.LegacyHitSampleInfo) + ? hitObject.Samples.OfType().Max(o => o.CustomSampleBank) + : 0; yield return new LegacyBeatmapDecoder.LegacySampleControlPoint { Time = hitObject.GetEndTime(), SampleVolume = volume, CustomSampleBank = customIndex }; } From 1b4f4372d5304553768c8b83bd6d460bad5acfc0 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 26 Apr 2023 14:32:12 +0200 Subject: [PATCH 2698/2991] fixed sample control point applying --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 9a1935f929..6b9e21f916 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -118,10 +118,7 @@ namespace osu.Game.Beatmaps.Formats SampleControlPoint sampleControlPoint = legacyInfo != null ? legacyInfo.SamplePointAt(hitObject.GetEndTime() + control_point_leniency) : SampleControlPoint.DEFAULT; - foreach (var hitSampleInfo in hitObject.Samples) - { - sampleControlPoint.ApplyTo(hitSampleInfo); - } + hitObject.Samples = hitObject.Samples.Select(o => sampleControlPoint.ApplyTo(o)).ToList(); if (hitObject is not IHasRepeats hasRepeats) return; @@ -130,10 +127,7 @@ namespace osu.Game.Beatmaps.Formats double time = hitObject.StartTime + i * hasRepeats.Duration / hasRepeats.SpanCount() + control_point_leniency; sampleControlPoint = legacyInfo != null ? legacyInfo.SamplePointAt(time) : SampleControlPoint.DEFAULT; - foreach (var hitSampleInfo in hasRepeats.NodeSamples[i]) - { - sampleControlPoint.ApplyTo(hitSampleInfo); - } + hasRepeats.NodeSamples[i] = hasRepeats.NodeSamples[i].Select(o => sampleControlPoint.ApplyTo(o)).ToList(); } } From 9f8d7bccbab8e011ca69288476fae517a62b1c38 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 26 Apr 2023 17:34:02 +0200 Subject: [PATCH 2699/2991] fix usings --- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 1 - osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs | 1 - .../Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index 8cf64a6a7e..6685507ee0 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -14,7 +14,6 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Framework.Utils; using osu.Game.Audio; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 2cf1d7a6ab..362ddccaf1 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -16,7 +16,6 @@ using JetBrains.Annotations; using osu.Game.Audio; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Formats; -using osu.Game.Beatmaps.Legacy; namespace osu.Game.Rulesets.Taiko.Beatmaps { diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs index 7403cad52f..7a0418cfec 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs @@ -4,12 +4,12 @@ #nullable disable using System.Linq; +using System.Collections.Generic; using Humanizer; using NUnit.Framework; using osu.Framework.Testing; using osu.Game.Audio; using osu.Game.Beatmaps; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Rulesets; From c44f71a7374f370831a72b3c13d0343368e6f86b Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 26 Apr 2023 17:55:38 +0200 Subject: [PATCH 2700/2991] remove all regular usage of DifficultyControlPoint --- .../Edit/Blueprints/Components/EditablePath.cs | 2 +- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 15 ++++++++++++--- .../Sliders/SliderPlacementBlueprint.cs | 8 +++----- .../Beatmaps/TaikoBeatmapConverter.cs | 4 +++- osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 13 +++++++++++-- ...estSceneHitObjectDifficultyPointAdjustments.cs | 5 +---- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 5 ++++- .../Rulesets/Edit/DistancedHitObjectComposer.cs | 3 ++- osu.Game/Rulesets/Objects/HitObject.cs | 2 +- .../Timeline/TimelineHitObjectBlueprint.cs | 12 ++++-------- 10 files changed, 42 insertions(+), 27 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs index 74d6565600..7a577f8a83 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs @@ -91,7 +91,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components public void UpdateHitObjectFromPath(JuiceStream hitObject) { // The SV setting may need to be changed for the current path. - var svBindable = hitObject.DifficultyControlPoint.SliderVelocityBindable; + var svBindable = hitObject.SliderVelocityBindable; double svToVelocityFactor = hitObject.Velocity / svBindable.Value; double requiredVelocity = path.ComputeRequiredVelocity(); diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 96e2d5c4e5..f8af161ad5 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using Newtonsoft.Json; +using osu.Framework.Bindables; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; @@ -16,7 +17,7 @@ using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Rulesets.Catch.Objects { - public class JuiceStream : CatchHitObject, IHasPathWithRepeats + public class JuiceStream : CatchHitObject, IHasPathWithRepeats, IHasSliderVelocity { /// /// Positional distance that results in a duration of one second, before any speed adjustments. @@ -27,6 +28,14 @@ namespace osu.Game.Rulesets.Catch.Objects public int RepeatCount { get; set; } + public BindableNumber SliderVelocityBindable { get; } = new BindableDouble(1); + + public double SliderVelocity + { + get => SliderVelocityBindable.Value; + set => SliderVelocityBindable.Value = value; + } + [JsonIgnore] private double velocityFactor; @@ -34,10 +43,10 @@ namespace osu.Game.Rulesets.Catch.Objects private double tickDistanceFactor; [JsonIgnore] - public double Velocity => velocityFactor * DifficultyControlPoint.SliderVelocity; + public double Velocity => velocityFactor * SliderVelocity; [JsonIgnore] - public double TickDistance => tickDistanceFactor * DifficultyControlPoint.SliderVelocity; + public double TickDistance => tickDistanceFactor * SliderVelocity; /// /// The length of one span of this . diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs index 77393efeb3..50514865e1 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs @@ -10,7 +10,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Input; using osu.Framework.Input.Events; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; @@ -83,11 +82,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders case SliderPlacementState.Initial: BeginPlacement(); - var nearestDifficultyPoint = editorBeatmap.HitObjects - .LastOrDefault(h => h is Slider && h.GetEndTime() < HitObject.StartTime)? - .DifficultyControlPoint?.DeepClone() as DifficultyControlPoint; + double? nearestSliderVelocity = (editorBeatmap.HitObjects + .LastOrDefault(h => h is Slider && h.GetEndTime() < HitObject.StartTime) as Slider)?.SliderVelocity; - HitObject.DifficultyControlPoint = nearestDifficultyPoint ?? new DifficultyControlPoint(); + HitObject.SliderVelocity = nearestSliderVelocity ?? 1; HitObject.Position = ToLocalSpace(result.ScreenSpacePosition); // Replacing the DifficultyControlPoint above doesn't trigger any kind of invalidation. diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 362ddccaf1..05fb314342 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -64,7 +64,9 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps foreach (HitObject hitObject in original.HitObjects) { - double nextScrollSpeed = hitObject.DifficultyControlPoint.SliderVelocity; + if (hitObject is not IHasSliderVelocity hasSliderVelocity) continue; + + double nextScrollSpeed = hasSliderVelocity.SliderVelocity; EffectControlPoint currentEffectPoint = converted.ControlPointInfo.EffectPointAt(hitObject.StartTime); if (!Precision.AlmostEquals(lastScrollSpeed, nextScrollSpeed, acceptableDifference: currentEffectPoint.ScrollSpeedBindable.Precision)) diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs index 3325eda7cf..5613bb190a 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs @@ -5,6 +5,7 @@ using osu.Game.Rulesets.Objects.Types; using System.Threading; +using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Formats; @@ -15,7 +16,7 @@ using osuTK; namespace osu.Game.Rulesets.Taiko.Objects { - public class DrumRoll : TaikoStrongableHitObject, IHasPath + public class DrumRoll : TaikoStrongableHitObject, IHasPath, IHasSliderVelocity { /// /// Drum roll distance that results in a duration of 1 speed-adjusted beat length. @@ -35,6 +36,14 @@ namespace osu.Game.Rulesets.Taiko.Objects /// public double Velocity { get; private set; } + public BindableNumber SliderVelocityBindable { get; } = new BindableDouble(1); + + public double SliderVelocity + { + get => SliderVelocityBindable.Value; + set => SliderVelocityBindable.Value = value; + } + /// /// Numer of ticks per beat length. /// @@ -52,7 +61,7 @@ namespace osu.Game.Rulesets.Taiko.Objects TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); - double scoringDistance = base_distance * difficulty.SliderMultiplier * DifficultyControlPoint.SliderVelocity; + double scoringDistance = base_distance * difficulty.SliderMultiplier * SliderVelocity; Velocity = scoringDistance / timingPoint.BeatLength; tickSpacing = timingPoint.BeatLength / TickRate; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectDifficultyPointAdjustments.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectDifficultyPointAdjustments.cs index ab82678eb9..f34e286f50 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectDifficultyPointAdjustments.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectDifficultyPointAdjustments.cs @@ -61,10 +61,7 @@ namespace osu.Game.Tests.Visual.Editing new PathControlPoint(new Vector2(100, 0)) } }, - DifficultyControlPoint = new DifficultyControlPoint - { - SliderVelocity = 2 - } + SliderVelocity = 2 }); }); } diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index a4783046c4..a681429d02 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -249,7 +249,10 @@ namespace osu.Game.Beatmaps.Formats yield break; foreach (var hitObject in hitObjects) - yield return hitObject.DifficultyControlPoint; + { + if (hitObject is IHasSliderVelocity hasSliderVelocity) + yield return new DifficultyControlPoint { Time = hitObject.StartTime, SliderVelocity = hasSliderVelocity.SliderVelocity }; + } } void extractDifficultyControlPoints(IEnumerable hitObjects) diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index aa47b4f424..5aa9e3c179 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -23,6 +23,7 @@ using osu.Game.Overlays; using osu.Game.Overlays.OSD; using osu.Game.Overlays.Settings.Sections; using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; using osu.Game.Screens.Edit.Components.TernaryButtons; namespace osu.Game.Rulesets.Edit @@ -239,7 +240,7 @@ namespace osu.Game.Rulesets.Edit public virtual float GetBeatSnapDistanceAt(HitObject referenceObject, bool useReferenceSliderVelocity = true) { - return (float)(100 * (useReferenceSliderVelocity ? referenceObject.DifficultyControlPoint.SliderVelocity : 1) * EditorBeatmap.Difficulty.SliderMultiplier * 1 + return (float)(100 * (useReferenceSliderVelocity && referenceObject is IHasSliderVelocity hasSliderVelocity ? hasSliderVelocity.SliderVelocity : 1) * EditorBeatmap.Difficulty.SliderMultiplier * 1 / BeatSnapProvider.BeatDivisor); } diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 73ecc28404..4822ec3919 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Objects /// public virtual IList AuxiliarySamples => ImmutableList.Empty; - public DifficultyControlPoint DifficultyControlPoint = DifficultyControlPoint.DEFAULT; + public DifficultyControlPoint DifficultyControlPoint { get; set; } = DifficultyControlPoint.DEFAULT; /// /// Legacy BPM multiplier that introduces floating-point errors for rulesets that depend on it. diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index c2106e0598..61a3931839 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -15,7 +15,6 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Framework.Threading; using osu.Framework.Utils; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; @@ -373,17 +372,14 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline case IHasRepeats repeatHitObject: double proposedDuration = time - hitObject.StartTime; - if (e.CurrentState.Keyboard.ShiftPressed) + if (e.CurrentState.Keyboard.ShiftPressed && hitObject is IHasSliderVelocity hasSliderVelocity) { - if (ReferenceEquals(hitObject.DifficultyControlPoint, DifficultyControlPoint.DEFAULT)) - hitObject.DifficultyControlPoint = new DifficultyControlPoint(); + double newVelocity = hasSliderVelocity.SliderVelocity * (repeatHitObject.Duration / proposedDuration); - double newVelocity = hitObject.DifficultyControlPoint.SliderVelocity * (repeatHitObject.Duration / proposedDuration); - - if (Precision.AlmostEquals(newVelocity, hitObject.DifficultyControlPoint.SliderVelocity)) + if (Precision.AlmostEquals(newVelocity, hasSliderVelocity.SliderVelocity)) return; - hitObject.DifficultyControlPoint.SliderVelocity = newVelocity; + hasSliderVelocity.SliderVelocity = newVelocity; beatmap.Update(hitObject); } else From 76df5fd3e27ddb2149182b5586ab1eff1634f7c4 Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Wed, 26 Apr 2023 18:05:47 +0200 Subject: [PATCH 2701/2991] Limit taiko playfield aspect ratio to 5:4 - 16:9 --- .../Mods/TaikoModClassic.cs | 2 +- .../UI/DrawableTaikoRuleset.cs | 8 ++++--- .../UI/TaikoPlayfieldAdjustmentContainer.cs | 22 ++++++++++++++----- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs index d0361b1c8d..cdeaafde10 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Taiko.Mods public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { var drawableTaikoRuleset = (DrawableTaikoRuleset)drawableRuleset; - drawableTaikoRuleset.LockPlayfieldMaxAspect.Value = false; + drawableTaikoRuleset.LockPlayfieldAspectRange.Value = false; var playfield = (TaikoPlayfield)drawableRuleset.Playfield; playfield.ClassicHitTargetPosition.Value = true; diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs index a08877e2dd..64d406a308 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Taiko.UI { public new BindableDouble TimeRange => base.TimeRange; - public readonly BindableBool LockPlayfieldMaxAspect = new BindableBool(true); + public readonly BindableBool LockPlayfieldAspectRange = new BindableBool(true); public new TaikoInputManager KeyBindingInputManager => (TaikoInputManager)base.KeyBindingInputManager; @@ -69,7 +69,9 @@ namespace osu.Game.Rulesets.Taiko.UI const float scroll_rate = 10; // Since the time range will depend on a positional value, it is referenced to the x480 pixel space. - float ratio = DrawHeight / 480; + // Width is used because it defines how many notes fit on the playfield. + // We clamp the ratio to the maximum aspect ratio to keep scroll speed consistent on widths lower than the default. + float ratio = Math.Max(DrawSize.X / 768f, TaikoPlayfieldAdjustmentContainer.MAXIMUM_ASPECT); TimeRange.Value = (Playfield.HitObjectContainer.DrawWidth / ratio) * scroll_rate; } @@ -92,7 +94,7 @@ namespace osu.Game.Rulesets.Taiko.UI public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new TaikoPlayfieldAdjustmentContainer { - LockPlayfieldMaxAspect = { BindTarget = LockPlayfieldMaxAspect } + LockPlayfieldAspectRange = { BindTarget = LockPlayfieldAspectRange } }; protected override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo); diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs index 42732d90e4..3587783104 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs @@ -11,9 +11,11 @@ namespace osu.Game.Rulesets.Taiko.UI public partial class TaikoPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer { private const float default_relative_height = TaikoPlayfield.DEFAULT_HEIGHT / 768; - private const float default_aspect = 16f / 9f; - public readonly IBindable LockPlayfieldMaxAspect = new BindableBool(true); + public const float MAXIMUM_ASPECT = 16f / 9f; + public const float MINIMUM_ASPECT = 5f / 4f; + + public readonly IBindable LockPlayfieldAspectRange = new BindableBool(true); protected override void Update() { @@ -26,12 +28,22 @@ namespace osu.Game.Rulesets.Taiko.UI // // As a middle-ground, the aspect ratio can still be adjusted in the downwards direction but has a maximum limit. // This is still a bit weird, because readability changes with window size, but it is what it is. - if (LockPlayfieldMaxAspect.Value && Parent.ChildSize.X / Parent.ChildSize.Y > default_aspect) - height *= Math.Clamp(Parent.ChildSize.X / Parent.ChildSize.Y, 0.4f, 4) / default_aspect; + if (LockPlayfieldAspectRange.Value) + { + float currentAspect = Parent.ChildSize.X / Parent.ChildSize.Y; + if (currentAspect > MAXIMUM_ASPECT) + height *= currentAspect / MAXIMUM_ASPECT; + else if (currentAspect < MINIMUM_ASPECT) + height *= currentAspect / MINIMUM_ASPECT; + } + + // Limit the maximum relative height of the playfield to one-third of available area to avoid it masking out on extreme resolutions. + height = Math.Min(height, 1f / 3f); Height = height; - // Position the taiko playfield exactly one playfield from the top of the screen. + // Position the taiko playfield exactly one playfield from the top of the screen, if there is enough space for it. + // Note that the relative height cannot exceed one-third - if that limit is hit, the playfield will be exactly centered. RelativePositionAxes = Axes.Y; Y = height; } From 354cd238742546522b78b74bd03238b49180551e Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 26 Apr 2023 18:17:02 +0200 Subject: [PATCH 2702/2991] removed all usage of hitobject's DifficultyControlPoint --- .../TestSceneJuiceStreamPlacementBlueprint.cs | 4 ++-- .../TestSceneJuiceStreamSelectionBlueprint.cs | 4 ++-- .../TestSceneObjectOrderedHitPolicy.cs | 2 +- .../TestSceneSliderFollowCircleInput.cs | 3 +-- .../TestSceneSliderInput.cs | 3 +-- .../TestSceneStartTimeOrderedHitPolicy.cs | 2 +- ...tSceneHitObjectComposerDistanceSnapping.cs | 22 ++++++------------- .../Editing/TestSceneEditorClipboard.cs | 1 - ...ceneHitObjectDifficultyPointAdjustments.cs | 8 +++---- osu.Game/Rulesets/Objects/HitObject.cs | 2 -- 10 files changed, 19 insertions(+), 32 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamPlacementBlueprint.cs b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamPlacementBlueprint.cs index 18d3d29bdc..2426f8c886 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamPlacementBlueprint.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor AddAssert("end time is correct", () => Precision.AlmostEquals(lastObject.EndTime, times[1])); AddAssert("start position is correct", () => Precision.AlmostEquals(lastObject.OriginalX, positions[0])); AddAssert("end position is correct", () => Precision.AlmostEquals(lastObject.EndX, positions[1])); - AddAssert("default slider velocity", () => lastObject.DifficultyControlPoint.SliderVelocityBindable.IsDefault); + AddAssert("default slider velocity", () => lastObject.SliderVelocityBindable.IsDefault); } [Test] @@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor addPlacementSteps(times, positions); addPathCheckStep(times, positions); - AddAssert("slider velocity changed", () => !lastObject.DifficultyControlPoint.SliderVelocityBindable.IsDefault); + AddAssert("slider velocity changed", () => !lastObject.SliderVelocityBindable.IsDefault); } [Test] diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs index f25b66c360..beba5811fe 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs @@ -108,11 +108,11 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor double[] times = { 100, 300 }; float[] positions = { 200, 300 }; addBlueprintStep(times, positions); - AddAssert("default slider velocity", () => hitObject.DifficultyControlPoint.SliderVelocityBindable.IsDefault); + AddAssert("default slider velocity", () => hitObject.SliderVelocityBindable.IsDefault); addDragStartStep(times[1], positions[1]); AddMouseMoveStep(times[1], 400); - AddAssert("slider velocity changed", () => !hitObject.DifficultyControlPoint.SliderVelocityBindable.IsDefault); + AddAssert("slider velocity changed", () => !hitObject.SliderVelocityBindable.IsDefault); } [Test] diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneObjectOrderedHitPolicy.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneObjectOrderedHitPolicy.cs index 5d9316a21b..ee70441688 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneObjectOrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneObjectOrderedHitPolicy.cs @@ -439,7 +439,7 @@ namespace osu.Game.Rulesets.Osu.Tests { public TestSlider() { - DifficultyControlPoint = new DifficultyControlPoint { SliderVelocity = 0.1f }; + SliderVelocity = 0.1f; DefaultsApplied += _ => { diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs index a32f0a13b8..fc2e6d1f72 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs @@ -7,7 +7,6 @@ using NUnit.Framework; using osu.Framework.Screens; using osu.Framework.Testing; using osu.Game.Beatmaps; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Replays; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; @@ -47,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = time_slider_start, Position = new Vector2(0, 0), - DifficultyControlPoint = new DifficultyControlPoint { SliderVelocity = velocity }, + SliderVelocity = velocity, Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index 5f27cdc191..d83926ab9b 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -8,7 +8,6 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Screens; using osu.Game.Beatmaps; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Replays; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; @@ -350,7 +349,7 @@ namespace osu.Game.Rulesets.Osu.Tests { StartTime = time_slider_start, Position = new Vector2(0, 0), - DifficultyControlPoint = new DifficultyControlPoint { SliderVelocity = 0.1f }, + SliderVelocity = 0.1f, Path = new SliderPath(PathType.PerfectCurve, new[] { Vector2.Zero, diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs index 29e6fc4301..f4257a9ee7 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs @@ -399,7 +399,7 @@ namespace osu.Game.Rulesets.Osu.Tests { public TestSlider() { - DifficultyControlPoint = new DifficultyControlPoint { SliderVelocity = 0.1f }; + SliderVelocity = 0.1f; DefaultsApplied += _ => { diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index f556f6e2fe..6399507aa0 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -14,6 +14,7 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Edit; +using osu.Game.Rulesets.Osu.Objects; using osu.Game.Screens.Edit; using osu.Game.Tests.Visual; @@ -74,12 +75,9 @@ namespace osu.Game.Tests.Editing [TestCase(2)] public void TestSpeedMultiplierDoesNotChangeDistanceSnap(float multiplier) { - assertSnapDistance(100, new HitObject + assertSnapDistance(100, new Slider { - DifficultyControlPoint = new DifficultyControlPoint - { - SliderVelocity = multiplier - } + SliderVelocity = multiplier }, false); } @@ -87,12 +85,9 @@ namespace osu.Game.Tests.Editing [TestCase(2)] public void TestSpeedMultiplierDoesChangeDistanceSnap(float multiplier) { - assertSnapDistance(100 * multiplier, new HitObject + assertSnapDistance(100 * multiplier, new Slider { - DifficultyControlPoint = new DifficultyControlPoint - { - SliderVelocity = multiplier - } + SliderVelocity = multiplier }, true); } @@ -114,12 +109,9 @@ namespace osu.Game.Tests.Editing const float base_distance = 100; const float slider_velocity = 1.2f; - var referenceObject = new HitObject + var referenceObject = new Slider { - DifficultyControlPoint = new DifficultyControlPoint - { - SliderVelocity = slider_velocity - } + SliderVelocity = slider_velocity }; assertSnapDistance(base_distance * slider_velocity, referenceObject, true); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs index 3c98a83fa0..c4c05278b5 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs @@ -6,7 +6,6 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Testing; -using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Edit; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectDifficultyPointAdjustments.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectDifficultyPointAdjustments.cs index f34e286f50..3b998b4219 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectDifficultyPointAdjustments.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectDifficultyPointAdjustments.cs @@ -8,10 +8,10 @@ using Humanizer; using NUnit.Framework; using osu.Framework.Testing; using osu.Game.Beatmaps; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets; using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.UI; @@ -97,8 +97,8 @@ namespace osu.Game.Tests.Visual.Editing { AddStep("unify slider velocity", () => { - foreach (var h in EditorBeatmap.HitObjects) - h.DifficultyControlPoint.SliderVelocity = 1.5; + foreach (var h in EditorBeatmap.HitObjects.OfType()) + h.SliderVelocity = 1.5; }); AddStep("select both objects", () => EditorBeatmap.SelectedHitObjects.AddRange(EditorBeatmap.HitObjects)); @@ -182,7 +182,7 @@ namespace osu.Game.Tests.Visual.Editing private void hitObjectHasVelocity(int objectIndex, double velocity) => AddAssert($"{objectIndex.ToOrdinalWords()} has velocity {velocity}", () => { var h = EditorBeatmap.HitObjects.ElementAt(objectIndex); - return h.DifficultyControlPoint.SliderVelocity == velocity; + return h is IHasSliderVelocity hasSliderVelocity && hasSliderVelocity.SliderVelocity == velocity; }); } } diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 4822ec3919..095ec1ff1b 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -76,8 +76,6 @@ namespace osu.Game.Rulesets.Objects /// public virtual IList AuxiliarySamples => ImmutableList.Empty; - public DifficultyControlPoint DifficultyControlPoint { get; set; } = DifficultyControlPoint.DEFAULT; - /// /// Legacy BPM multiplier that introduces floating-point errors for rulesets that depend on it. /// DO NOT USE THIS UNLESS 100% SURE. From f5c652325a55402d71dfb3182dea9769906f5d1b Mon Sep 17 00:00:00 2001 From: _ltn <46729135+rltn@users.noreply.github.com> Date: Thu, 27 Apr 2023 23:44:18 +0300 Subject: [PATCH 2703/2991] Create UpdateableCountryText.cs --- .../Users/Drawables/UpdateableCountryText.cs | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 osu.Game/Users/Drawables/UpdateableCountryText.cs diff --git a/osu.Game/Users/Drawables/UpdateableCountryText.cs b/osu.Game/Users/Drawables/UpdateableCountryText.cs new file mode 100644 index 0000000000..60174505a5 --- /dev/null +++ b/osu.Game/Users/Drawables/UpdateableCountryText.cs @@ -0,0 +1,67 @@ +// 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.Allocation; +using osu.Framework.Input.Events; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays; +using osu.Framework.Extensions; + +namespace osu.Game.Users.Drawables +{ + public partial class UpdateableCountryText : ModelBackedDrawable + { + public CountryCode CountryCode + { + get => Model; + set => Model = value; + } + + public bool ShowPlaceholderOnUnknown = true; + + public Action? Action; + + protected override Drawable? CreateDrawable(CountryCode countryCode) + { + if (countryCode == CountryCode.Unknown && !ShowPlaceholderOnUnknown) + return null; + + return new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new OsuSpriteText + { + Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular), + Margin = new MarginPadding { Left = 5 }, + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + Text = countryCode.GetDescription(), + }, + new HoverClickSounds() + } + }; + } + + [Resolved] + private RankingsOverlay? rankingsOverlay { get; set; } + + public UpdateableCountryText(CountryCode countryCode = CountryCode.Unknown) + { + CountryCode = countryCode; + } + protected override bool OnClick(ClickEvent e) + { + Action?.Invoke(); + rankingsOverlay?.ShowCountry(CountryCode); + return true; + } + } + +} \ No newline at end of file From b13201fb792801e87b5a9148abd2a9ec6a011976 Mon Sep 17 00:00:00 2001 From: _ltn <46729135+rltn@users.noreply.github.com> Date: Fri, 28 Apr 2023 01:14:42 +0300 Subject: [PATCH 2704/2991] UpdateableCountryText rewrite --- .../Users/Drawables/UpdateableCountryText.cs | 55 ++++++------------- 1 file changed, 17 insertions(+), 38 deletions(-) diff --git a/osu.Game/Users/Drawables/UpdateableCountryText.cs b/osu.Game/Users/Drawables/UpdateableCountryText.cs index 60174505a5..fd749da707 100644 --- a/osu.Game/Users/Drawables/UpdateableCountryText.cs +++ b/osu.Game/Users/Drawables/UpdateableCountryText.cs @@ -7,6 +7,7 @@ using osu.Framework.Input.Events; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays; @@ -14,53 +15,31 @@ using osu.Framework.Extensions; namespace osu.Game.Users.Drawables { - public partial class UpdateableCountryText : ModelBackedDrawable + public partial class UpdateableCountryText : OsuHoverContainer { - public CountryCode CountryCode - { - get => Model; - set => Model = value; - } public bool ShowPlaceholderOnUnknown = true; - public Action? Action; - - protected override Drawable? CreateDrawable(CountryCode countryCode) - { - if (countryCode == CountryCode.Unknown && !ShowPlaceholderOnUnknown) - return null; - - return new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - new OsuSpriteText - { - Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular), - Margin = new MarginPadding { Left = 5 }, - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - Text = countryCode.GetDescription(), - }, - new HoverClickSounds() - } - }; - } - [Resolved] private RankingsOverlay? rankingsOverlay { get; set; } - - public UpdateableCountryText(CountryCode countryCode = CountryCode.Unknown) + public UpdateableCountryText() { - CountryCode = countryCode; + AutoSizeAxes = Axes.Both; } - protected override bool OnClick(ClickEvent e) + + // [BackgroundDependencyLoader] + public void load(CountryCode countryCode) { - Action?.Invoke(); - rankingsOverlay?.ShowCountry(CountryCode); - return true; + Action = () => + { + rankingsOverlay?.ShowCountry(countryCode); + }; + + Child = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular), + Text = countryCode.GetDescription(), + }; } } From e9843f20665a00da524cc240a1ea307d00d548d2 Mon Sep 17 00:00:00 2001 From: _ltn <46729135+rltn@users.noreply.github.com> Date: Fri, 28 Apr 2023 01:16:50 +0300 Subject: [PATCH 2705/2991] replace country text object --- osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index d04329430b..811628c3c1 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -38,7 +38,7 @@ namespace osu.Game.Overlays.Profile.Header private ExternalLinkButton openUserExternally = null!; private OsuSpriteText titleText = null!; private UpdateableFlag userFlag = null!; - private OsuSpriteText userCountryText = null!; + private UpdateableCountryText userCountryText = null!; private GroupBadgeFlow groupBadgeFlow = null!; private ToggleCoverButton coverToggle = null!; @@ -156,9 +156,8 @@ namespace osu.Game.Overlays.Profile.Header Size = new Vector2(28, 20), ShowPlaceholderOnUnknown = false, }, - userCountryText = new OsuSpriteText + userCountryText = new UpdateableCountryText { - Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular), Margin = new MarginPadding { Left = 5 }, Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, @@ -201,7 +200,7 @@ namespace osu.Game.Overlays.Profile.Header usernameText.Text = user?.Username ?? string.Empty; openUserExternally.Link = $@"{api.WebsiteRootUrl}/users/{user?.Id ?? 0}"; userFlag.CountryCode = user?.CountryCode ?? default; - userCountryText.Text = (user?.CountryCode ?? default).GetDescription(); + userCountryText.load(user?.CountryCode ?? default); supporterTag.SupportLevel = user?.SupportLevel ?? 0; titleText.Text = user?.Title ?? string.Empty; titleText.Colour = Color4Extensions.FromHex(user?.Colour ?? "fff"); From 092377fdaa234738a79eeb409cea0e5722c154a4 Mon Sep 17 00:00:00 2001 From: _ltn <46729135+rltn@users.noreply.github.com> Date: Fri, 28 Apr 2023 01:47:14 +0300 Subject: [PATCH 2706/2991] moving UpdateableCountryText --- .../Profile/Header/TopHeaderContainer.cs | 41 +++++++++++++++++ .../Users/Drawables/UpdateableCountryText.cs | 46 ------------------- 2 files changed, 41 insertions(+), 46 deletions(-) delete mode 100644 osu.Game/Users/Drawables/UpdateableCountryText.cs diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 811628c3c1..54c84e08b8 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -19,6 +19,20 @@ using osu.Game.Users; using osu.Game.Users.Drawables; using osuTK; + +using System; +// using osu.Framework.Allocation; +using osu.Framework.Input.Events; +// using osu.Framework.Graphics; +// using osu.Framework.Graphics.Containers; +// using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +// using osu.Game.Graphics.Sprites; +// using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays; +using osu.Framework.Graphics.Sprites; +// using osu.Framework.Extensions; + namespace osu.Game.Overlays.Profile.Header { public partial class TopHeaderContainer : CompositeDrawable @@ -158,6 +172,7 @@ namespace osu.Game.Overlays.Profile.Header }, userCountryText = new UpdateableCountryText { + Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular), Margin = new MarginPadding { Left = 5 }, Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, @@ -228,5 +243,31 @@ namespace osu.Game.Overlays.Profile.Header Masking = true; } } + + private partial class UpdateableCountryText : OsuHoverContainer + { + public bool ShowPlaceholderOnUnknown = true; + public FontUsage Font = default; + [Resolved] + private RankingsOverlay? rankingsOverlay { get; set; } + public UpdateableCountryText() + { + AutoSizeAxes = Axes.Both; + } + + public void load(CountryCode countryCode) + { + Action = () => + { + rankingsOverlay?.ShowCountry(countryCode); + }; + + Child = new OsuSpriteText + { + Font = Font, + Text = countryCode.GetDescription(), + }; + } + } } } diff --git a/osu.Game/Users/Drawables/UpdateableCountryText.cs b/osu.Game/Users/Drawables/UpdateableCountryText.cs deleted file mode 100644 index fd749da707..0000000000 --- a/osu.Game/Users/Drawables/UpdateableCountryText.cs +++ /dev/null @@ -1,46 +0,0 @@ -// 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.Allocation; -using osu.Framework.Input.Events; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using osu.Game.Overlays; -using osu.Framework.Extensions; - -namespace osu.Game.Users.Drawables -{ - public partial class UpdateableCountryText : OsuHoverContainer - { - - public bool ShowPlaceholderOnUnknown = true; - - [Resolved] - private RankingsOverlay? rankingsOverlay { get; set; } - public UpdateableCountryText() - { - AutoSizeAxes = Axes.Both; - } - - // [BackgroundDependencyLoader] - public void load(CountryCode countryCode) - { - Action = () => - { - rankingsOverlay?.ShowCountry(countryCode); - }; - - Child = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular), - Text = countryCode.GetDescription(), - }; - } - } - -} \ No newline at end of file From 4d144cd5b5fb3e787fd51b75cef459bfab56fbf4 Mon Sep 17 00:00:00 2001 From: _ltn <46729135+rltn@users.noreply.github.com> Date: Fri, 28 Apr 2023 02:06:13 +0300 Subject: [PATCH 2707/2991] clearing the code --- .../Profile/Header/TopHeaderContainer.cs | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 54c84e08b8..3485037925 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -9,8 +9,10 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; using osu.Game.Configuration; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; @@ -20,19 +22,6 @@ using osu.Game.Users.Drawables; using osuTK; -using System; -// using osu.Framework.Allocation; -using osu.Framework.Input.Events; -// using osu.Framework.Graphics; -// using osu.Framework.Graphics.Containers; -// using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -// using osu.Game.Graphics.Sprites; -// using osu.Game.Graphics.UserInterface; -using osu.Game.Overlays; -using osu.Framework.Graphics.Sprites; -// using osu.Framework.Extensions; - namespace osu.Game.Overlays.Profile.Header { public partial class TopHeaderContainer : CompositeDrawable @@ -246,10 +235,12 @@ namespace osu.Game.Overlays.Profile.Header private partial class UpdateableCountryText : OsuHoverContainer { - public bool ShowPlaceholderOnUnknown = true; + public FontUsage Font = default; + [Resolved] private RankingsOverlay? rankingsOverlay { get; set; } + public UpdateableCountryText() { AutoSizeAxes = Axes.Both; From 17730f05bcf42c6af0c8876c46ae218adf71bb32 Mon Sep 17 00:00:00 2001 From: _ltn <46729135+rltn@users.noreply.github.com> Date: Fri, 28 Apr 2023 05:47:05 +0300 Subject: [PATCH 2708/2991] remove UpdateableCountryText --- .../Profile/Header/TopHeaderContainer.cs | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 3485037925..01fbf137d8 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -21,7 +21,6 @@ using osu.Game.Users; using osu.Game.Users.Drawables; using osuTK; - namespace osu.Game.Overlays.Profile.Header { public partial class TopHeaderContainer : CompositeDrawable @@ -41,7 +40,6 @@ namespace osu.Game.Overlays.Profile.Header private ExternalLinkButton openUserExternally = null!; private OsuSpriteText titleText = null!; private UpdateableFlag userFlag = null!; - private UpdateableCountryText userCountryText = null!; private GroupBadgeFlow groupBadgeFlow = null!; private ToggleCoverButton coverToggle = null!; @@ -204,7 +202,6 @@ namespace osu.Game.Overlays.Profile.Header usernameText.Text = user?.Username ?? string.Empty; openUserExternally.Link = $@"{api.WebsiteRootUrl}/users/{user?.Id ?? 0}"; userFlag.CountryCode = user?.CountryCode ?? default; - userCountryText.load(user?.CountryCode ?? default); supporterTag.SupportLevel = user?.SupportLevel ?? 0; titleText.Text = user?.Title ?? string.Empty; titleText.Colour = Color4Extensions.FromHex(user?.Colour ?? "fff"); @@ -232,33 +229,5 @@ namespace osu.Game.Overlays.Profile.Header Masking = true; } } - - private partial class UpdateableCountryText : OsuHoverContainer - { - - public FontUsage Font = default; - - [Resolved] - private RankingsOverlay? rankingsOverlay { get; set; } - - public UpdateableCountryText() - { - AutoSizeAxes = Axes.Both; - } - - public void load(CountryCode countryCode) - { - Action = () => - { - rankingsOverlay?.ShowCountry(countryCode); - }; - - Child = new OsuSpriteText - { - Font = Font, - Text = countryCode.GetDescription(), - }; - } - } } } From 4b0ee392f6d5bb6ec29a0c014fdc199543475e40 Mon Sep 17 00:00:00 2001 From: _ltn <46729135+rltn@users.noreply.github.com> Date: Fri, 28 Apr 2023 05:48:54 +0300 Subject: [PATCH 2709/2991] add OsuHoverContainer --- .../Profile/Header/TopHeaderContainer.cs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 01fbf137d8..618e487dc3 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -33,6 +33,9 @@ namespace osu.Game.Overlays.Profile.Header [Resolved] private IAPIProvider api { get; set; } = null!; + [Resolved] + private RankingsOverlay? rankingsOverlay { get; set; } + private UserCoverBackground cover = null!; private SupporterIcon supporterTag = null!; private UpdateableAvatar avatar = null!; @@ -40,6 +43,8 @@ namespace osu.Game.Overlays.Profile.Header private ExternalLinkButton openUserExternally = null!; private OsuSpriteText titleText = null!; private UpdateableFlag userFlag = null!; + private OsuHoverContainer userCountryContainer = null!; + private OsuSpriteText userCountryText = null!; private GroupBadgeFlow groupBadgeFlow = null!; private ToggleCoverButton coverToggle = null!; @@ -157,13 +162,20 @@ namespace osu.Game.Overlays.Profile.Header Size = new Vector2(28, 20), ShowPlaceholderOnUnknown = false, }, - userCountryText = new UpdateableCountryText + userCountryContainer = new OsuHoverContainer { - Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular), Margin = new MarginPadding { Left = 5 }, Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, - } + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + userCountryText = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular), + }, + }, + }, } }, } @@ -202,6 +214,8 @@ namespace osu.Game.Overlays.Profile.Header usernameText.Text = user?.Username ?? string.Empty; openUserExternally.Link = $@"{api.WebsiteRootUrl}/users/{user?.Id ?? 0}"; userFlag.CountryCode = user?.CountryCode ?? default; + userCountryText.Text = (user?.CountryCode ?? default).GetDescription(); + userCountryContainer.Action = () => rankingsOverlay?.ShowCountry(user?.CountryCode ?? default); supporterTag.SupportLevel = user?.SupportLevel ?? 0; titleText.Text = user?.Title ?? string.Empty; titleText.Colour = Color4Extensions.FromHex(user?.Colour ?? "fff"); From 6929be49b707568074899d822c4df0d3e053cc2d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Apr 2023 22:35:55 +0900 Subject: [PATCH 2710/2991] Change condition for exclusive fullscreen notice to only show when using the correct renderer This avoids the notice showing when running on windows, but using the newer renderers (where the underlying logic hasn't been tested properly and can result in false-positives). Supersedes https://github.com/ppy/osu-framework/pull/5759 as a more correct implementation. --- osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 2765d2b437..a46205d40d 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -256,7 +256,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics return; } - if (host.Window is WindowsWindow) + if (host.Renderer is IWindowsRenderer) { switch (fullscreenCapability.Value) { From f7c84030ac3c6cd1156f496540169840ed73421d Mon Sep 17 00:00:00 2001 From: OliBomby Date: Fri, 28 Apr 2023 17:22:34 +0200 Subject: [PATCH 2711/2991] remove bank default value --- osu.Game/Audio/HitSampleInfo.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Audio/HitSampleInfo.cs b/osu.Game/Audio/HitSampleInfo.cs index e9c06152cc..efa5562cb8 100644 --- a/osu.Game/Audio/HitSampleInfo.cs +++ b/osu.Game/Audio/HitSampleInfo.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using Newtonsoft.Json; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Utils; namespace osu.Game.Audio @@ -33,7 +32,7 @@ namespace osu.Game.Audio /// /// The bank to load the sample from. /// - public readonly string Bank; + public readonly string? Bank; /// /// An optional suffix to provide priority lookup. Falls back to non-suffixed . @@ -48,7 +47,7 @@ namespace osu.Game.Audio public HitSampleInfo(string name, string? bank = null, string? suffix = null, int volume = 0) { Name = name; - Bank = bank ?? SampleControlPoint.DEFAULT_BANK; + Bank = bank; Suffix = suffix; Volume = volume; } From 2d6c0d2900be5779bc1ceea643458372c403daeb Mon Sep 17 00:00:00 2001 From: _ltn <46729135+rltn@users.noreply.github.com> Date: Fri, 28 Apr 2023 19:24:07 +0300 Subject: [PATCH 2712/2991] use of Child instead of Children --- .../Overlays/Profile/Header/TopHeaderContainer.cs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 618e487dc3..de678cb5d1 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Containers; @@ -164,16 +163,13 @@ namespace osu.Game.Overlays.Profile.Header }, userCountryContainer = new OsuHoverContainer { - Margin = new MarginPadding { Left = 5 }, - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, - Children = new Drawable[] + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Left = 5 }, + Child = userCountryText = new OsuSpriteText { - userCountryText = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular), - }, + Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular), }, }, } From 607a04ae7319b823da095c948be9897767ff84bd Mon Sep 17 00:00:00 2001 From: Cootz Date: Fri, 28 Apr 2023 17:45:00 +0300 Subject: [PATCH 2713/2991] Fix the issue --- osu.Game/Screens/Edit/Editor.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index d89392f757..b5d304a031 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -210,7 +210,10 @@ namespace osu.Game.Screens.Edit // this is a bit haphazard, but guards against setting the lease Beatmap bindable if // the editor has already been exited. if (!ValidForPush) + { + beatmapManager.Delete(loadableBeatmap.BeatmapSetInfo); return; + } } try From c5357d30ab0c545a7eb4dd652eeefcb828c1f433 Mon Sep 17 00:00:00 2001 From: Cootz Date: Fri, 28 Apr 2023 20:36:31 +0300 Subject: [PATCH 2714/2991] Add test --- .../Navigation/TestSceneBeatmapEditor.cs | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs new file mode 100644 index 0000000000..67835ed0f5 --- /dev/null +++ b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs @@ -0,0 +1,57 @@ +// 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 System.Threading.Tasks; +using DeepEqual.Syntax; +using NUnit.Framework; +using osu.Framework.Screens; +using osu.Game.Beatmaps; +using osu.Game.Screens.Edit; +using osu.Game.Screens.Menu; + +namespace osu.Game.Tests.Visual.Navigation +{ + public partial class TestSceneBeatmapEditor : OsuGameTestScene + { + [Test] + public void TestCancelNavigationToEditor() + { + BeatmapSetInfo[] beatmapSets = Array.Empty(); + + AddStep("Timestamp current beatmapsets", () => + { + Game.Realm.Run(realm => + { + beatmapSets = realm.All().Where(x => !x.DeletePending).ToArray(); + }); + }); + + AddStep("Open editor and close it while loading", () => + { + var task = Task.Run(async () => + { + await Task.Delay(100); + Game.ScreenStack.CurrentScreen.Exit(); + }); + + Game.ScreenStack.Push(new EditorLoader()); + }); + + AddUntilStep("wait for editor", () => Game.ScreenStack.CurrentScreen is MainMenu); + + BeatmapSetInfo[] currentSetInfos = Array.Empty(); + + AddStep("Get current beatmaps", () => + { + Game.Realm.Run(realm => + { + currentSetInfos = realm.All().Where(x => !x.DeletePending).ToArray(); + }); + }); + + AddAssert("dummy beatmap didn't appear", () => currentSetInfos.IsDeepEqual(beatmapSets)); + } + } +} From d9b3c97179d2f9fd5114909fcb323208ff630f22 Mon Sep 17 00:00:00 2001 From: Cootz Date: Fri, 28 Apr 2023 21:23:00 +0300 Subject: [PATCH 2715/2991] Fix testing --- .../Navigation/TestSceneBeatmapEditor.cs | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs index 67835ed0f5..9760fc2c97 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs @@ -1,9 +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 System.Linq; -using System.Threading.Tasks; using DeepEqual.Syntax; using NUnit.Framework; using osu.Framework.Screens; @@ -18,7 +16,7 @@ namespace osu.Game.Tests.Visual.Navigation [Test] public void TestCancelNavigationToEditor() { - BeatmapSetInfo[] beatmapSets = Array.Empty(); + BeatmapSetInfo[]? beatmapSets = null; AddStep("Timestamp current beatmapsets", () => { @@ -28,20 +26,26 @@ namespace osu.Game.Tests.Visual.Navigation }); }); - AddStep("Open editor and close it while loading", () => + AddStep("Set current beatmap to default", () => { - var task = Task.Run(async () => - { - await Task.Delay(100); - Game.ScreenStack.CurrentScreen.Exit(); - }); + Game.Beatmap.SetDefault(); + }); + AddStep("Open editor loader", () => + { Game.ScreenStack.Push(new EditorLoader()); }); + AddUntilStep("wait for editor", () => Game.ScreenStack.CurrentScreen is EditorLoader); + + AddStep("close editor while loading", () => + { + Game.ScreenStack.CurrentScreen.Exit(); + }); + AddUntilStep("wait for editor", () => Game.ScreenStack.CurrentScreen is MainMenu); - BeatmapSetInfo[] currentSetInfos = Array.Empty(); + BeatmapSetInfo[]? currentSetInfos = null; AddStep("Get current beatmaps", () => { @@ -51,7 +55,7 @@ namespace osu.Game.Tests.Visual.Navigation }); }); - AddAssert("dummy beatmap didn't appear", () => currentSetInfos.IsDeepEqual(beatmapSets)); + AddAssert("dummy beatmap didn't appear", () => currentSetInfos.IsDeepEqual(beatmapSets) && currentSetInfos is not null); } } } From 428b5fad3c45a545820d3fec8e06e9ce05803020 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 29 Apr 2023 10:34:50 +0900 Subject: [PATCH 2716/2991] Rename test scene to explicitly mention navigation testing --- ...ceneBeatmapEditor.cs => TestSceneBeatmapEditorNavigation.cs} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename osu.Game.Tests/Visual/Navigation/{TestSceneBeatmapEditor.cs => TestSceneBeatmapEditorNavigation.cs} (96%) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs similarity index 96% rename from osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs rename to osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs index 9760fc2c97..e1fba1d630 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs @@ -11,7 +11,7 @@ using osu.Game.Screens.Menu; namespace osu.Game.Tests.Visual.Navigation { - public partial class TestSceneBeatmapEditor : OsuGameTestScene + public partial class TestSceneBeatmapEditorNavigation : OsuGameTestScene { [Test] public void TestCancelNavigationToEditor() From a6f01861124b3ba119c830c43178af95945864ad Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 29 Apr 2023 10:49:25 +0900 Subject: [PATCH 2717/2991] Improve legibility and code quality of new test --- .../TestSceneBeatmapEditorNavigation.cs | 48 ++++++------------- 1 file changed, 14 insertions(+), 34 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs index e1fba1d630..c76758e6c6 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs @@ -16,46 +16,26 @@ namespace osu.Game.Tests.Visual.Navigation [Test] public void TestCancelNavigationToEditor() { - BeatmapSetInfo[]? beatmapSets = null; + BeatmapSetInfo[] beatmapSets = null!; - AddStep("Timestamp current beatmapsets", () => + AddStep("Fetch initial beatmaps", () => { - Game.Realm.Run(realm => - { - beatmapSets = realm.All().Where(x => !x.DeletePending).ToArray(); - }); + beatmapSets = Game.Realm.Run(realm => realm.All().Where(x => !x.DeletePending).ToArray()); }); - AddStep("Set current beatmap to default", () => + AddStep("Set current beatmap to default", () => Game.Beatmap.SetDefault()); + + AddStep("Push editor loader", () => Game.ScreenStack.Push(new EditorLoader())); + AddUntilStep("Wait for loader current", () => Game.ScreenStack.CurrentScreen is EditorLoader); + AddStep("Close editor while loading", () => Game.ScreenStack.CurrentScreen.Exit()); + + AddUntilStep("Wait for menu", () => Game.ScreenStack.CurrentScreen is MainMenu); + + AddAssert("Check no new beatmaps were made", () => { - Game.Beatmap.SetDefault(); + var beatmapSetsAfter = Game.Realm.Run(realm => realm.All().Where(x => !x.DeletePending).ToArray()); + return beatmapSetsAfter.SequenceEqual(beatmapSets); }); - - AddStep("Open editor loader", () => - { - Game.ScreenStack.Push(new EditorLoader()); - }); - - AddUntilStep("wait for editor", () => Game.ScreenStack.CurrentScreen is EditorLoader); - - AddStep("close editor while loading", () => - { - Game.ScreenStack.CurrentScreen.Exit(); - }); - - AddUntilStep("wait for editor", () => Game.ScreenStack.CurrentScreen is MainMenu); - - BeatmapSetInfo[]? currentSetInfos = null; - - AddStep("Get current beatmaps", () => - { - Game.Realm.Run(realm => - { - currentSetInfos = realm.All().Where(x => !x.DeletePending).ToArray(); - }); - }); - - AddAssert("dummy beatmap didn't appear", () => currentSetInfos.IsDeepEqual(beatmapSets) && currentSetInfos is not null); } } } From 32f8c674f4d751937db57082cc872bc38a1c7bed Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 29 Apr 2023 11:01:29 +0900 Subject: [PATCH 2718/2991] Extract beatmap retrieval method for more legibility --- .../Navigation/TestSceneBeatmapEditorNavigation.cs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs index c76758e6c6..554da36cc4 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; -using DeepEqual.Syntax; using NUnit.Framework; using osu.Framework.Screens; using osu.Game.Beatmaps; @@ -18,10 +17,7 @@ namespace osu.Game.Tests.Visual.Navigation { BeatmapSetInfo[] beatmapSets = null!; - AddStep("Fetch initial beatmaps", () => - { - beatmapSets = Game.Realm.Run(realm => realm.All().Where(x => !x.DeletePending).ToArray()); - }); + AddStep("Fetch initial beatmaps", () => beatmapSets = allBeatmapSets()); AddStep("Set current beatmap to default", () => Game.Beatmap.SetDefault()); @@ -30,12 +26,9 @@ namespace osu.Game.Tests.Visual.Navigation AddStep("Close editor while loading", () => Game.ScreenStack.CurrentScreen.Exit()); AddUntilStep("Wait for menu", () => Game.ScreenStack.CurrentScreen is MainMenu); + AddAssert("Check no new beatmaps were made", () => allBeatmapSets().SequenceEqual(beatmapSets)); - AddAssert("Check no new beatmaps were made", () => - { - var beatmapSetsAfter = Game.Realm.Run(realm => realm.All().Where(x => !x.DeletePending).ToArray()); - return beatmapSetsAfter.SequenceEqual(beatmapSets); - }); + BeatmapSetInfo[] allBeatmapSets() => Game.Realm.Run(realm => realm.All().Where(x => !x.DeletePending).ToArray()); } } } From 26431006448c9d192ac5931fc1fc3cf10f76c2a9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 29 Apr 2023 11:05:10 +0900 Subject: [PATCH 2719/2991] Add xmldoc to new test mentioning failure rate and general purpose --- .../Visual/Navigation/TestSceneBeatmapEditorNavigation.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs index 554da36cc4..603573058e 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs @@ -12,6 +12,14 @@ namespace osu.Game.Tests.Visual.Navigation { public partial class TestSceneBeatmapEditorNavigation : OsuGameTestScene { + /// + /// When entering the editor, a new beatmap is created as part of the asynchronous load process. + /// This test ensures that in the case of an early exit from the editor (ie. while it's still loading) + /// doesn't leave a dangling beatmap behind. + /// + /// This may not fail 100% due to timing, but has a pretty high chance of hitting a failure so works well enough + /// as a test. + /// [Test] public void TestCancelNavigationToEditor() { From 3b0ba4b38bc886538d62e56fbbfdf7b081cf5d84 Mon Sep 17 00:00:00 2001 From: Terochi Date: Sat, 29 Apr 2023 19:52:22 +0200 Subject: [PATCH 2720/2991] Improved logic for `ApplyStateChange` for skin editor --- .../SkinEditor/SkinEditorChangeHandler.cs | 65 ++++++++++++++++--- 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs index d1a1850796..151557c9e1 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.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 System.Collections.Generic; using System.IO; using System.Linq; @@ -56,20 +57,64 @@ namespace osu.Game.Overlays.SkinEditor if (deserializedContent == null) return; - SerialisedDrawableInfo[] skinnableInfo = deserializedContent.ToArray(); - Drawable[] targetComponents = firstTarget.Components.OfType().ToArray(); + SerialisedDrawableInfo[] skinnableInfos = deserializedContent.ToArray(); + ISerialisableDrawable[] targetComponents = firstTarget.Components.ToArray(); - if (!skinnableInfo.Select(s => s.Type).SequenceEqual(targetComponents.Select(d => d.GetType()))) + // Store indexes based on type for later lookup + + var skinnableInfoIndexes = new Dictionary>(); + var targetComponentsIndexes = new Dictionary>(); + + for (int i = 0; i < skinnableInfos.Length; i++) { - // Perform a naive full reload for now. - firstTarget.Reload(skinnableInfo); + Type lookup = skinnableInfos[i].Type; + + if (!skinnableInfoIndexes.TryGetValue(lookup, out List? infoIndexes)) + skinnableInfoIndexes.Add(lookup, infoIndexes = new List()); + + infoIndexes.Add(i); } - else - { - int i = 0; - foreach (var drawable in targetComponents) - drawable.ApplySerialisedInfo(skinnableInfo[i++]); + for (int i = 0; i < targetComponents.Length; i++) + { + Type lookup = targetComponents[i].GetType(); + + if (!targetComponentsIndexes.TryGetValue(lookup, out List? componentIndexes)) + targetComponentsIndexes.Add(lookup, componentIndexes = new List()); + + componentIndexes.Add(i); + } + + foreach ((Type lookup, List infoIndexes) in skinnableInfoIndexes) + { + if (!targetComponentsIndexes.TryGetValue(lookup, out List? componentIndexes)) + componentIndexes = new List(0); + + int j = 0; + + for (int i = 0; i < infoIndexes.Count; i++) + { + if (i >= componentIndexes.Count) + // Add new component + firstTarget.Add((ISerialisableDrawable)skinnableInfos[infoIndexes[i]].CreateInstance()); + else + // Modify existing component + ((Drawable)targetComponents[componentIndexes[j++]]).ApplySerialisedInfo(skinnableInfos[infoIndexes[i]]); + } + + // Remove extra components + for (; j < componentIndexes.Count; j++) + firstTarget.Remove(targetComponents[componentIndexes[j]], false); + } + + foreach ((Type lookup, List componentIndexes) in targetComponentsIndexes) + { + if (skinnableInfoIndexes.ContainsKey(lookup)) + continue; + + // Remove extra components that weren't removed above + for (int i = 0; i < componentIndexes.Count; i++) + firstTarget.Remove(targetComponents[componentIndexes[i]], false); } } } From 17e4b75dfd5f55756e7d67316566bbb1f195a9dc Mon Sep 17 00:00:00 2001 From: Terochi Date: Sat, 29 Apr 2023 20:54:19 +0200 Subject: [PATCH 2721/2991] Save first state when editing --- osu.Game/Overlays/SkinEditor/SkinEditor.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/SkinEditor/SkinEditor.cs b/osu.Game/Overlays/SkinEditor/SkinEditor.cs index 2b23ce290f..f0ad92d4da 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditor.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditor.cs @@ -235,10 +235,7 @@ namespace osu.Game.Overlays.SkinEditor }, true); canPaste.Current.BindValueChanged(paste => pasteMenuItem.Action.Disabled = !paste.NewValue, true); - SelectedComponents.BindCollectionChanged((_, _) => - { - canCopy.Value = canCut.Value = SelectedComponents.Any(); - }, true); + SelectedComponents.BindCollectionChanged((_, _) => canCopy.Value = canCut.Value = SelectedComponents.Any(), true); clipboard.Content.BindValueChanged(content => canPaste.Value = !string.IsNullOrEmpty(content.NewValue), true); @@ -345,6 +342,7 @@ namespace osu.Game.Overlays.SkinEditor changeHandler = new SkinEditorChangeHandler(skinComponentsContainer); changeHandler.CanUndo.BindValueChanged(v => undoMenuItem.Action.Disabled = !v.NewValue, true); changeHandler.CanRedo.BindValueChanged(v => redoMenuItem.Action.Disabled = !v.NewValue, true); + changeHandler.SaveState(); content.Child = new SkinBlueprintContainer(skinComponentsContainer); @@ -479,12 +477,18 @@ namespace osu.Game.Overlays.SkinEditor protected void Cut() { + if (!canCut.Value) + return; + Copy(); DeleteItems(SelectedComponents.ToArray()); } protected void Copy() { + if (!canCopy.Value) + return; + clipboard.Content.Value = JsonConvert.SerializeObject(SelectedComponents.Cast().Select(s => s.CreateSerialisedInfo()).ToArray()); } @@ -500,6 +504,9 @@ namespace osu.Game.Overlays.SkinEditor protected void Paste() { + if (!canPaste.Value) + return; + changeHandler?.BeginChange(); var drawableInfo = JsonConvert.DeserializeObject(clipboard.Content.Value); From ffcc8e91b242a22a17701566ac284a62d8f057c1 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Sat, 29 Apr 2023 23:51:49 +0200 Subject: [PATCH 2722/2991] fix legacy parser incorrectly assigning sample info for sliders --- osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index 68ca6bc506..ba5de6c14b 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Objects.Legacy } if (split.Length > 10) - readCustomSampleBanks(split[10], bankInfo); + readCustomSampleBanks(split[10], bankInfo, true); // One node for each repeat + the start and end nodes int nodes = repeatCount + 2; @@ -182,7 +182,7 @@ namespace osu.Game.Rulesets.Objects.Legacy return result; } - private void readCustomSampleBanks(string str, SampleBankInfo bankInfo) + private void readCustomSampleBanks(string str, SampleBankInfo bankInfo, bool banksOnly = false) { if (string.IsNullOrEmpty(str)) return; @@ -202,6 +202,8 @@ namespace osu.Game.Rulesets.Objects.Legacy bankInfo.BankForNormal = stringBank; bankInfo.BankForAdditions = string.IsNullOrEmpty(stringAddBank) ? stringBank : stringAddBank; + if (banksOnly) return; + if (split.Length > 2) bankInfo.CustomSampleBank = Parsing.ParseInt(split[2]); From 92efd04f3138b62d49458fb296021e7101fb3105 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Sat, 29 Apr 2023 23:52:24 +0200 Subject: [PATCH 2723/2991] fix sample of drumroll ticks being bankless --- osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 5 ++++- .../Objects/TaikoStrongableHitObject.cs | 2 +- osu.Game/Rulesets/Objects/HitObject.cs | 11 +++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs index 5613bb190a..c1a78f46b2 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs @@ -3,9 +3,11 @@ #nullable disable +using System.Linq; using osu.Game.Rulesets.Objects.Types; using System.Threading; using osu.Framework.Bindables; +using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Formats; @@ -90,7 +92,8 @@ namespace osu.Game.Rulesets.Taiko.Objects FirstTick = first, TickSpacing = tickSpacing, StartTime = t, - IsStrong = IsStrong + IsStrong = IsStrong, + Samples = Samples.Where(s => s.Name == HitSampleInfo.HIT_FINISH).ToList() }); first = false; diff --git a/osu.Game.Rulesets.Taiko/Objects/TaikoStrongableHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/TaikoStrongableHitObject.cs index d4d59d5d44..0043f231d2 100644 --- a/osu.Game.Rulesets.Taiko/Objects/TaikoStrongableHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/TaikoStrongableHitObject.cs @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Taiko.Objects if (IsStrongBindable.Value != strongSamples.Any()) { if (IsStrongBindable.Value) - Samples.Add(new HitSampleInfo(HitSampleInfo.HIT_FINISH)); + Samples.Add(GetSampleInfo(HitSampleInfo.HIT_FINISH)); else { foreach (var sample in strongSamples) diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 095ec1ff1b..774ff9dc1d 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -204,6 +204,17 @@ namespace osu.Game.Rulesets.Objects return slidingSamples; } + + /// + /// Create a SampleInfo based on the sample settings of the hit normal sample in . + /// + /// The name of the sample. + /// A populated . + protected HitSampleInfo GetSampleInfo(string sampleName) + { + var hitnormalSample = Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL); + return hitnormalSample == null ? new HitSampleInfo(sampleName) : hitnormalSample.With(newName: sampleName); + } } public static class HitObjectExtensions From a6e780a1b9c5740e74c17d9c9f098a9e30e4871f Mon Sep 17 00:00:00 2001 From: OliBomby Date: Sat, 29 Apr 2023 23:52:30 +0200 Subject: [PATCH 2724/2991] Update CheckMutedObjectsTest.cs --- .../Editing/Checks/CheckMutedObjectsTest.cs | 104 +----------------- 1 file changed, 6 insertions(+), 98 deletions(-) diff --git a/osu.Game.Tests/Editing/Checks/CheckMutedObjectsTest.cs b/osu.Game.Tests/Editing/Checks/CheckMutedObjectsTest.cs index 1e1c214c30..5a3ef619d1 100644 --- a/osu.Game.Tests/Editing/Checks/CheckMutedObjectsTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckMutedObjectsTest.cs @@ -37,45 +37,6 @@ namespace osu.Game.Tests.Editing.Checks cpi.Add(2000, new SampleControlPoint { SampleVolume = volume_muted }); } - [Test] - public void TestNormalControlPointVolume() - { - var hitCircle = new HitCircle - { - StartTime = 0, - Samples = new List { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) } - }; - hitCircle.ApplyDefaults(cpi, new BeatmapDifficulty()); - - assertOk(new List { hitCircle }); - } - - [Test] - public void TestLowControlPointVolume() - { - var hitCircle = new HitCircle - { - StartTime = 1000, - Samples = new List { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) } - }; - hitCircle.ApplyDefaults(cpi, new BeatmapDifficulty()); - - assertLowVolume(new List { hitCircle }); - } - - [Test] - public void TestMutedControlPointVolume() - { - var hitCircle = new HitCircle - { - StartTime = 2000, - Samples = new List { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) } - }; - hitCircle.ApplyDefaults(cpi, new BeatmapDifficulty()); - - assertMuted(new List { hitCircle }); - } - [Test] public void TestNormalSampleVolume() { @@ -122,7 +83,7 @@ namespace osu.Game.Tests.Editing.Checks var sliderHead = new SliderHeadCircle { StartTime = 0, - Samples = new List { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) } + Samples = new List { new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: volume_regular) } }; sliderHead.ApplyDefaults(cpi, new BeatmapDifficulty()); @@ -135,7 +96,7 @@ namespace osu.Game.Tests.Editing.Checks var slider = new MockNestableHitObject(new List { sliderHead, sliderTick, }, startTime: 0, endTime: 500) { - Samples = new List { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) } + Samples = new List { new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: volume_regular) } }; slider.ApplyDefaults(cpi, new BeatmapDifficulty()); @@ -155,13 +116,13 @@ namespace osu.Game.Tests.Editing.Checks var sliderTick = new SliderTick { StartTime = 250, - Samples = new List { new HitSampleInfo("slidertick") } + Samples = new List { new HitSampleInfo("slidertick", volume: volume_regular) } }; sliderTick.ApplyDefaults(cpi, new BeatmapDifficulty()); var slider = new MockNestableHitObject(new List { sliderHead, sliderTick, }, startTime: 0, endTime: 500) { - Samples = new List { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) } // Applies to the tail. + Samples = new List { new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: volume_regular) } // Applies to the tail. }; slider.ApplyDefaults(cpi, new BeatmapDifficulty()); @@ -174,14 +135,14 @@ namespace osu.Game.Tests.Editing.Checks var sliderHead = new SliderHeadCircle { StartTime = 0, - Samples = new List { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) } + Samples = new List { new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: volume_regular) } }; sliderHead.ApplyDefaults(cpi, new BeatmapDifficulty()); var sliderTick = new SliderTick { StartTime = 250, - Samples = new List { new HitSampleInfo("slidertick") } + Samples = new List { new HitSampleInfo("slidertick", volume: volume_regular) } }; sliderTick.ApplyDefaults(cpi, new BeatmapDifficulty()); @@ -194,59 +155,6 @@ namespace osu.Game.Tests.Editing.Checks assertMutedPassive(new List { slider }); } - [Test] - public void TestMutedControlPointVolumeSliderHead() - { - var sliderHead = new SliderHeadCircle - { - StartTime = 2000, - Samples = new List { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) } - }; - sliderHead.ApplyDefaults(cpi, new BeatmapDifficulty()); - - var sliderTick = new SliderTick - { - StartTime = 2250, - Samples = new List { new HitSampleInfo("slidertick") } - }; - sliderTick.ApplyDefaults(cpi, new BeatmapDifficulty()); - - var slider = new MockNestableHitObject(new List { sliderHead, sliderTick, }, startTime: 2000, endTime: 2500) - { - Samples = new List { new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: volume_regular) } - }; - slider.ApplyDefaults(cpi, new BeatmapDifficulty()); - - assertMuted(new List { slider }); - } - - [Test] - public void TestMutedControlPointVolumeSliderTail() - { - var sliderHead = new SliderHeadCircle - { - StartTime = 0, - Samples = new List { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) } - }; - sliderHead.ApplyDefaults(cpi, new BeatmapDifficulty()); - - var sliderTick = new SliderTick - { - StartTime = 250, - Samples = new List { new HitSampleInfo("slidertick") } - }; - sliderTick.ApplyDefaults(cpi, new BeatmapDifficulty()); - - // Ends after the 5% control point. - var slider = new MockNestableHitObject(new List { sliderHead, sliderTick, }, startTime: 0, endTime: 2500) - { - Samples = new List { new HitSampleInfo(HitSampleInfo.HIT_NORMAL) } - }; - slider.ApplyDefaults(cpi, new BeatmapDifficulty()); - - assertMutedPassive(new List { slider }); - } - private void assertOk(List hitObjects) { Assert.That(check.Run(getContext(hitObjects)), Is.Empty); From 83111223e0d9ef4ea85c16746a6d79c0e31b6bd2 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Sun, 30 Apr 2023 01:08:52 +0200 Subject: [PATCH 2725/2991] fix null sample --- osu.Game/Rulesets/Edit/PlacementBlueprint.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs index 91dd7754d0..96128c6981 100644 --- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs +++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs @@ -76,7 +76,8 @@ namespace osu.Game.Rulesets.Edit { // Take the hitnormal sample of the last hit object var lastHitNormal = beatmap.HitObjects.LastOrDefault(h => h.GetEndTime() < HitObject.StartTime)?.Samples?.FirstOrDefault(o => o.Name == HitSampleInfo.HIT_NORMAL); - HitObject.Samples.Add(lastHitNormal); + if (lastHitNormal != null) + HitObject.Samples[0] = lastHitNormal; placementHandler.BeginPlacement(HitObject); if (commitStart) From 9a9e02b110431b32bcf9281db2349ef1418c8abe Mon Sep 17 00:00:00 2001 From: Terochi Date: Sun, 30 Apr 2023 02:00:35 +0200 Subject: [PATCH 2726/2991] Added tests --- .../Visual/Gameplay/TestSceneSkinEditor.cs | 89 ++++++++++++++----- 1 file changed, 69 insertions(+), 20 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs index 119b753d70..71eabd776a 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs @@ -2,12 +2,15 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.IO; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input; using osu.Framework.Testing; using osu.Game.Overlays; using osu.Game.Overlays.Settings; @@ -97,15 +100,10 @@ namespace osu.Game.Tests.Visual.Gameplay InputManager.PressButton(MouseButton.Left); }); - AddStep("Drag to bottom right", () => - { - InputManager.MoveMouseTo(box3.ScreenSpaceDrawQuad.TopRight + new Vector2(-box3.ScreenSpaceDrawQuad.Width / 8, box3.ScreenSpaceDrawQuad.Height / 4)); - }); + AddStep("Drag to bottom right", + () => { InputManager.MoveMouseTo(box3.ScreenSpaceDrawQuad.TopRight + new Vector2(-box3.ScreenSpaceDrawQuad.Width / 8, box3.ScreenSpaceDrawQuad.Height / 4)); }); - AddStep("Release button", () => - { - InputManager.ReleaseButton(MouseButton.Left); - }); + AddStep("Release button", () => { InputManager.ReleaseButton(MouseButton.Left); }); AddAssert("First two boxes selected", () => skinEditor.SelectedComponents, () => Is.EqualTo(new[] { box1, box2 })); @@ -115,15 +113,9 @@ namespace osu.Game.Tests.Visual.Gameplay InputManager.PressButton(MouseButton.Left); }); - AddStep("Drag to top left", () => - { - InputManager.MoveMouseTo(box2.ScreenSpaceDrawQuad.Centre - new Vector2(box2.ScreenSpaceDrawQuad.Width / 4)); - }); + AddStep("Drag to top left", () => { InputManager.MoveMouseTo(box2.ScreenSpaceDrawQuad.Centre - new Vector2(box2.ScreenSpaceDrawQuad.Width / 4)); }); - AddStep("Release button", () => - { - InputManager.ReleaseButton(MouseButton.Left); - }); + AddStep("Release button", () => { InputManager.ReleaseButton(MouseButton.Left); }); AddAssert("Last two boxes selected", () => skinEditor.SelectedComponents, () => Is.EqualTo(new[] { box2, box3 })); @@ -147,10 +139,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("Three black boxes added", () => targetContainer.Components.OfType().Count(), () => Is.EqualTo(3)); - AddStep("Store black box blueprints", () => - { - blueprints = skinEditor.ChildrenOfType().Where(b => b.Item is BigBlackBox).ToArray(); - }); + AddStep("Store black box blueprints", () => { blueprints = skinEditor.ChildrenOfType().Where(b => b.Item is BigBlackBox).ToArray(); }); AddAssert("Selection is black box 1", () => skinEditor.SelectedComponents.Single(), () => Is.EqualTo(blueprints[0].Item)); @@ -182,6 +171,48 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("all boxes still selected", () => skinEditor.SelectedComponents, () => Has.Count.EqualTo(2)); } + [Test] + public void TestUndo() + { + SkinComponentsContainer firstTarget = null!; + TestSkinEditorChangeHandler changeHandler = null!; + byte[] defaultState = null!; + IEnumerable testComponents = null!; + + AddStep("Load necessary things", () => + { + firstTarget = Player.ChildrenOfType().First(); + changeHandler = new TestSkinEditorChangeHandler(firstTarget); + changeHandler.SaveState(); + defaultState = changeHandler.GetCurrentState(); + testComponents = new[] { targetContainer.Components.First(), targetContainer.Components[targetContainer.Components.Count / 2], targetContainer.Components.Last() }; + }); + + AddStep("Press undo", () => InputManager.Keys(PlatformAction.Undo)); + AddAssert("Nothing changed", () => defaultState.SequenceEqual(changeHandler.GetCurrentState())); + + AddStep("Add big black boxes", () => + { + InputManager.MoveMouseTo(skinEditor.ChildrenOfType().First()); + InputManager.Click(MouseButton.Left); + InputManager.Click(MouseButton.Left); + InputManager.Click(MouseButton.Left); + }); + AddStep("Revert changes", () => changeHandler.RestoreState(int.MinValue)); + AddAssert("Nothing changed", () => defaultState.SequenceEqual(changeHandler.GetCurrentState())); + + AddStep("Select components", () => skinEditor.SelectedComponents.AddRange(testComponents)); + AddStep("Bring to front", () => skinEditor.BringSelectionToFront()); + + AddStep("Revert changes", () => changeHandler.RestoreState(int.MinValue)); + AddAssert("Nothing changed", () => defaultState.SequenceEqual(changeHandler.GetCurrentState())); + + AddStep("Remove components", () => testComponents.ForEach(c => firstTarget.Remove(c, false))); + + AddStep("Revert changes", () => changeHandler.RestoreState(int.MinValue)); + AddAssert("Nothing changed", () => defaultState.SequenceEqual(changeHandler.GetCurrentState())); + } + [TestCase(false)] [TestCase(true)] public void TestBringToFront(bool alterSelectionOrder) @@ -269,5 +300,23 @@ namespace osu.Game.Tests.Visual.Gameplay } protected override Ruleset CreatePlayerRuleset() => new OsuRuleset(); + + private partial class TestSkinEditorChangeHandler : SkinEditorChangeHandler + { + public TestSkinEditorChangeHandler(Drawable targetScreen) + : base(targetScreen) + { + } + + public byte[] GetCurrentState() + { + using var stream = new MemoryStream(); + + WriteCurrentStateToStream(stream); + byte[] newState = stream.ToArray(); + + return newState; + } + } } } From 8ec2154965cd79939daa44adb7d0c678606bfae8 Mon Sep 17 00:00:00 2001 From: Terochi Date: Sun, 30 Apr 2023 02:01:18 +0200 Subject: [PATCH 2727/2991] Fixed `ApplyStateChange` to happen in correct order --- .../SkinEditor/SkinEditorChangeHandler.cs | 48 +++++++------------ 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs index 151557c9e1..f38f6b0911 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs @@ -62,19 +62,8 @@ namespace osu.Game.Overlays.SkinEditor // Store indexes based on type for later lookup - var skinnableInfoIndexes = new Dictionary>(); var targetComponentsIndexes = new Dictionary>(); - for (int i = 0; i < skinnableInfos.Length; i++) - { - Type lookup = skinnableInfos[i].Type; - - if (!skinnableInfoIndexes.TryGetValue(lookup, out List? infoIndexes)) - skinnableInfoIndexes.Add(lookup, infoIndexes = new List()); - - infoIndexes.Add(i); - } - for (int i = 0; i < targetComponents.Length; i++) { Type lookup = targetComponents[i].GetType(); @@ -85,35 +74,34 @@ namespace osu.Game.Overlays.SkinEditor componentIndexes.Add(i); } - foreach ((Type lookup, List infoIndexes) in skinnableInfoIndexes) + var indexCounting = new Dictionary(); + + var empty = new List(0); + + for (int i = 0; i < skinnableInfos.Length; i++) { + Type lookup = skinnableInfos[i].Type; + if (!targetComponentsIndexes.TryGetValue(lookup, out List? componentIndexes)) - componentIndexes = new List(0); + componentIndexes = empty; - int j = 0; + if (!indexCounting.ContainsKey(lookup)) + indexCounting.Add(lookup, 0); - for (int i = 0; i < infoIndexes.Count; i++) - { - if (i >= componentIndexes.Count) - // Add new component - firstTarget.Add((ISerialisableDrawable)skinnableInfos[infoIndexes[i]].CreateInstance()); - else - // Modify existing component - ((Drawable)targetComponents[componentIndexes[j++]]).ApplySerialisedInfo(skinnableInfos[infoIndexes[i]]); - } - - // Remove extra components - for (; j < componentIndexes.Count; j++) - firstTarget.Remove(targetComponents[componentIndexes[j]], false); + if (i >= componentIndexes.Count) + // Add new component + firstTarget.Add((ISerialisableDrawable)skinnableInfos[i].CreateInstance()); + else + // Modify existing component + ((Drawable)targetComponents[componentIndexes[indexCounting[lookup]++]]).ApplySerialisedInfo(skinnableInfos[i]); } foreach ((Type lookup, List componentIndexes) in targetComponentsIndexes) { - if (skinnableInfoIndexes.ContainsKey(lookup)) - continue; + indexCounting.TryGetValue(lookup, out int i); // Remove extra components that weren't removed above - for (int i = 0; i < componentIndexes.Count; i++) + for (; i < componentIndexes.Count; i++) firstTarget.Remove(targetComponents[componentIndexes[i]], false); } } From 585318400cacf70533aefef88d2880f30d4f909b Mon Sep 17 00:00:00 2001 From: Terochi Date: Sun, 30 Apr 2023 02:32:20 +0200 Subject: [PATCH 2728/2991] Refactor tests --- .../Visual/Gameplay/TestSceneSkinEditor.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs index 71eabd776a..45cc329f53 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs @@ -183,15 +183,22 @@ namespace osu.Game.Tests.Visual.Gameplay { firstTarget = Player.ChildrenOfType().First(); changeHandler = new TestSkinEditorChangeHandler(firstTarget); + changeHandler.SaveState(); defaultState = changeHandler.GetCurrentState(); - testComponents = new[] { targetContainer.Components.First(), targetContainer.Components[targetContainer.Components.Count / 2], targetContainer.Components.Last() }; + + testComponents = new[] + { + targetContainer.Components.First(), + targetContainer.Components[targetContainer.Components.Count / 2], + targetContainer.Components.Last() + }; }); AddStep("Press undo", () => InputManager.Keys(PlatformAction.Undo)); AddAssert("Nothing changed", () => defaultState.SequenceEqual(changeHandler.GetCurrentState())); - AddStep("Add big black boxes", () => + AddStep("Add components", () => { InputManager.MoveMouseTo(skinEditor.ChildrenOfType().First()); InputManager.Click(MouseButton.Left); @@ -203,12 +210,10 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("Select components", () => skinEditor.SelectedComponents.AddRange(testComponents)); AddStep("Bring to front", () => skinEditor.BringSelectionToFront()); - AddStep("Revert changes", () => changeHandler.RestoreState(int.MinValue)); AddAssert("Nothing changed", () => defaultState.SequenceEqual(changeHandler.GetCurrentState())); AddStep("Remove components", () => testComponents.ForEach(c => firstTarget.Remove(c, false))); - AddStep("Revert changes", () => changeHandler.RestoreState(int.MinValue)); AddAssert("Nothing changed", () => defaultState.SequenceEqual(changeHandler.GetCurrentState())); } From b39a9d816e1881bd40e471aa738fe8d455828871 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 29 Apr 2023 16:05:45 +0900 Subject: [PATCH 2729/2991] Add basic structural requirements for cursor ripples --- .../Configuration/OsuRulesetConfigManager.cs | 2 ++ .../Legacy/OsuLegacySkinTransformer.cs | 5 +++++ .../UI/Cursor/CursorRippleVisualiser.cs | 21 +++++++++++++++++++ .../UI/Cursor/OsuCursorContainer.cs | 1 + .../UI/OsuSettingsSubsection.cs | 5 +++++ .../Localisation/RulesetSettingsStrings.cs | 5 +++++ 6 files changed, 39 insertions(+) create mode 100644 osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs diff --git a/osu.Game.Rulesets.Osu/Configuration/OsuRulesetConfigManager.cs b/osu.Game.Rulesets.Osu/Configuration/OsuRulesetConfigManager.cs index b8ad61e6dd..2056a50eda 100644 --- a/osu.Game.Rulesets.Osu/Configuration/OsuRulesetConfigManager.cs +++ b/osu.Game.Rulesets.Osu/Configuration/OsuRulesetConfigManager.cs @@ -22,6 +22,7 @@ namespace osu.Game.Rulesets.Osu.Configuration SetDefault(OsuRulesetSetting.SnakingInSliders, true); SetDefault(OsuRulesetSetting.SnakingOutSliders, true); SetDefault(OsuRulesetSetting.ShowCursorTrail, true); + SetDefault(OsuRulesetSetting.ShowCursorRipples, false); SetDefault(OsuRulesetSetting.PlayfieldBorderStyle, PlayfieldBorderStyle.None); } } @@ -31,6 +32,7 @@ namespace osu.Game.Rulesets.Osu.Configuration SnakingInSliders, SnakingOutSliders, ShowCursorTrail, + ShowCursorRipples, PlayfieldBorderStyle, } } diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs index 620540b8ef..279835747f 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs @@ -100,6 +100,11 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy return null; + case OsuSkinComponents.CursorRipple: + // TODO: resize texture to 0.5?? but that might break skins.. + if (GetTexture("cursor-ripple") != null) + return this.GetAnimation("cursor-ripple", false, false); + case OsuSkinComponents.CursorParticles: if (GetTexture("star2") != null) return new LegacyCursorParticles(); diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs b/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs new file mode 100644 index 0000000000..ef0cae7de8 --- /dev/null +++ b/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs @@ -0,0 +1,21 @@ +// 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.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Osu.Configuration; + +namespace osu.Game.Rulesets.Osu.UI.Cursor +{ + public partial class CursorRippleVisualiser : CompositeDrawable + { + private readonly Bindable showRipples = new Bindable(true); + + [BackgroundDependencyLoader(true)] + private void load(OsuRulesetConfigManager rulesetConfig) + { + rulesetConfig?.BindWith(OsuRulesetSetting.ShowCursorTrail, showRipples); + } + } +} diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs index 5d7648b073..2b541bd345 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs @@ -48,6 +48,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor Children = new[] { cursorTrail = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorTrail), _ => new DefaultCursorTrail(), confineMode: ConfineMode.NoScaling), + new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorRipples), confineMode: ConfineMode.NoScaling), new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorParticles), confineMode: ConfineMode.NoScaling), } }; diff --git a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs index 64c4e7eef6..0e410dbf57 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs @@ -43,6 +43,11 @@ namespace osu.Game.Rulesets.Osu.UI LabelText = RulesetSettingsStrings.CursorTrail, Current = config.GetBindable(OsuRulesetSetting.ShowCursorTrail) }, + new SettingsCheckbox + { + LabelText = RulesetSettingsStrings.CursorRipples, + Current = config.GetBindable(OsuRulesetSetting.ShowCursorRipples) + }, new SettingsEnumDropdown { LabelText = RulesetSettingsStrings.PlayfieldBorderStyle, diff --git a/osu.Game/Localisation/RulesetSettingsStrings.cs b/osu.Game/Localisation/RulesetSettingsStrings.cs index 1b0df6ecf6..52e6a5eaac 100644 --- a/osu.Game/Localisation/RulesetSettingsStrings.cs +++ b/osu.Game/Localisation/RulesetSettingsStrings.cs @@ -29,6 +29,11 @@ namespace osu.Game.Localisation /// public static LocalisableString CursorTrail => new TranslatableString(getKey(@"cursor_trail"), @"Cursor trail"); + /// + /// "Cursor ripples" + /// + public static LocalisableString CursorRipples => new TranslatableString(getKey(@"cursor_ripples"), @"Cursor ripples"); + /// /// "Playfield border style" /// From a4ae9e409bf1cb5e9c2f614e2967dc3bf82210b7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 29 Apr 2023 16:06:08 +0900 Subject: [PATCH 2730/2991] Implement ripples (legacy and default) --- .../TestSceneGameplayCursor.cs | 13 +++++ osu.Game.Rulesets.Osu/OsuSkinComponents.cs | 1 + .../Legacy/OsuLegacySkinTransformer.cs | 2 + .../UI/Cursor/CursorRippleVisualiser.cs | 53 +++++++++++++++++-- .../UI/Cursor/OsuCursorContainer.cs | 2 +- 5 files changed, 67 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs index 907422858e..c84a6ab70f 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs @@ -8,6 +8,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -18,6 +19,7 @@ using osu.Framework.Testing.Input; using osu.Framework.Utils; using osu.Game.Audio; using osu.Game.Configuration; +using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Rulesets.Osu.Skinning; using osu.Game.Rulesets.Osu.UI.Cursor; using osu.Game.Screens.Play; @@ -40,6 +42,8 @@ namespace osu.Game.Rulesets.Osu.Tests private Drawable background; + private readonly Bindable ripples = new Bindable(); + public TestSceneGameplayCursor() { var ruleset = new OsuRuleset(); @@ -57,6 +61,8 @@ namespace osu.Game.Rulesets.Osu.Tests }); }); + AddToggleStep("ripples", v => ripples.Value = v); + AddSliderStep("circle size", 0f, 10f, 0f, val => { config.SetValue(OsuSetting.AutoCursorSize, true); @@ -67,6 +73,13 @@ namespace osu.Game.Rulesets.Osu.Tests AddStep("test cursor container", () => loadContent(false)); } + [BackgroundDependencyLoader] + private void load() + { + var rulesetConfig = (OsuRulesetConfigManager)RulesetConfigs.GetConfigFor(Ruleset.Value.CreateInstance()).AsNonNull(); + rulesetConfig.BindWith(OsuRulesetSetting.ShowCursorRipples, ripples); + } + [TestCase(1, 1)] [TestCase(5, 1)] [TestCase(10, 1)] diff --git a/osu.Game.Rulesets.Osu/OsuSkinComponents.cs b/osu.Game.Rulesets.Osu/OsuSkinComponents.cs index 8fdf3821fa..52fdfea95f 100644 --- a/osu.Game.Rulesets.Osu/OsuSkinComponents.cs +++ b/osu.Game.Rulesets.Osu/OsuSkinComponents.cs @@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Osu Cursor, CursorTrail, CursorParticles, + CursorRipple, SliderScorePoint, ReverseArrow, HitCircleText, diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs index 279835747f..bf817eda29 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs @@ -105,6 +105,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy if (GetTexture("cursor-ripple") != null) return this.GetAnimation("cursor-ripple", false, false); + return null; + case OsuSkinComponents.CursorParticles: if (GetTexture("star2") != null) return new LegacyCursorParticles(); diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs b/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs index ef0cae7de8..401525efcd 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs @@ -3,19 +3,66 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Input.Bindings; +using osu.Framework.Input.Events; using osu.Game.Rulesets.Osu.Configuration; +using osu.Game.Rulesets.Osu.Skinning.Default; +using osu.Game.Skinning; +using osuTK; namespace osu.Game.Rulesets.Osu.UI.Cursor { - public partial class CursorRippleVisualiser : CompositeDrawable + public partial class CursorRippleVisualiser : CompositeDrawable, IKeyBindingHandler { private readonly Bindable showRipples = new Bindable(true); [BackgroundDependencyLoader(true)] - private void load(OsuRulesetConfigManager rulesetConfig) + private void load(OsuRulesetConfigManager? rulesetConfig) { - rulesetConfig?.BindWith(OsuRulesetSetting.ShowCursorTrail, showRipples); + rulesetConfig?.BindWith(OsuRulesetSetting.ShowCursorRipples, showRipples); + } + + public bool OnPressed(KeyBindingPressEvent e) + { + if (showRipples.Value) + { + var ripple = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorRipple), _ => new DefaultCursorRipple()) + { + Blending = BlendingParameters.Additive, + Position = e.MousePosition + }; + + AddInternal(ripple); + + ripple.ScaleTo(0.05f) + .ScaleTo(0.5f, 700, Easing.Out) + .FadeTo(0.2f) + .FadeOut(700) + .Expire(); + } + + return false; + } + + public void OnReleased(KeyBindingReleaseEvent e) + { + } + + public partial class DefaultCursorRipple : CompositeDrawable + { + [BackgroundDependencyLoader] + private void load() + { + InternalChildren = new Drawable[] + { + new RingPiece(3) + { + Size = new Vector2(512), + } + }; + } } } } diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs index 2b541bd345..35fb8e67d8 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor Children = new[] { cursorTrail = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorTrail), _ => new DefaultCursorTrail(), confineMode: ConfineMode.NoScaling), - new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorRipples), confineMode: ConfineMode.NoScaling), + new CursorRippleVisualiser(), new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorParticles), confineMode: ConfineMode.NoScaling), } }; From c994adfc22a3c7a25985988bd2b9f48ac47c3b58 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 29 Apr 2023 22:00:17 +0900 Subject: [PATCH 2731/2991] Add pooling support for ripples --- .../UI/Cursor/CursorRippleVisualiser.cs | 50 +++++++++++++------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs b/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs index 401525efcd..e13e0d5dfb 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs @@ -5,6 +5,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Pooling; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Game.Rulesets.Osu.Configuration; @@ -18,6 +19,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor { private readonly Bindable showRipples = new Bindable(true); + private readonly DrawablePool ripplePool = new DrawablePool(20); + [BackgroundDependencyLoader(true)] private void load(OsuRulesetConfigManager? rulesetConfig) { @@ -27,21 +30,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor public bool OnPressed(KeyBindingPressEvent e) { if (showRipples.Value) - { - var ripple = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorRipple), _ => new DefaultCursorRipple()) - { - Blending = BlendingParameters.Additive, - Position = e.MousePosition - }; - - AddInternal(ripple); - - ripple.ScaleTo(0.05f) - .ScaleTo(0.5f, 700, Easing.Out) - .FadeTo(0.2f) - .FadeOut(700) - .Expire(); - } + AddInternal(ripplePool.Get()); return false; } @@ -50,6 +39,37 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor { } + private partial class CursorRipple : PoolableDrawable + { + [BackgroundDependencyLoader] + private void load() + { + AutoSizeAxes = Axes.Both; + Origin = Anchor.Centre; + + InternalChildren = new Drawable[] + { + new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorRipple), _ => new DefaultCursorRipple()) + { + Blending = BlendingParameters.Additive, + } + }; + } + + protected override void PrepareForUse() + { + base.PrepareForUse(); + + ClearTransforms(true); + + this.ScaleTo(0.05f) + .ScaleTo(0.5f, 700, Easing.Out) + .FadeTo(0.2f) + .FadeOut(700) + .Expire(); + } + } + public partial class DefaultCursorRipple : CompositeDrawable { [BackgroundDependencyLoader] From 6a62949fcd36e4ee62fdfb8de528901784733cf6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 30 Apr 2023 10:38:21 +0900 Subject: [PATCH 2732/2991] Fix positioning and rewinding support for ripples --- .../UI/Cursor/CursorRippleVisualiser.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs b/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs index e13e0d5dfb..27e9d1d347 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs @@ -21,6 +21,11 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor private readonly DrawablePool ripplePool = new DrawablePool(20); + public CursorRippleVisualiser() + { + RelativeSizeAxes = Axes.Both; + } + [BackgroundDependencyLoader(true)] private void load(OsuRulesetConfigManager? rulesetConfig) { @@ -30,7 +35,12 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor public bool OnPressed(KeyBindingPressEvent e) { if (showRipples.Value) - AddInternal(ripplePool.Get()); + { + AddInternal(ripplePool.Get(r => + { + r.Position = e.MousePosition; + })); + } return false; } @@ -66,7 +76,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor .ScaleTo(0.5f, 700, Easing.Out) .FadeTo(0.2f) .FadeOut(700) - .Expire(); + .Expire(true); } } @@ -75,6 +85,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor [BackgroundDependencyLoader] private void load() { + AutoSizeAxes = Axes.Both; + InternalChildren = new Drawable[] { new RingPiece(3) From 72b472a75604a97d1f15ee211550bf28e2b4204c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 30 Apr 2023 11:19:03 +0900 Subject: [PATCH 2733/2991] Change default scaling and add note about legacy `cursor-ripple` scale --- .../Legacy/OsuLegacySkinTransformer.cs | 19 +++++++++++++++++-- .../UI/Cursor/CursorRippleVisualiser.cs | 8 ++++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs index bf817eda29..f049aa088f 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs @@ -101,9 +101,24 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy return null; case OsuSkinComponents.CursorRipple: - // TODO: resize texture to 0.5?? but that might break skins.. if (GetTexture("cursor-ripple") != null) - return this.GetAnimation("cursor-ripple", false, false); + { + var ripple = this.GetAnimation("cursor-ripple", false, false); + + // In stable this element was scaled down to 50% and opacity 20%, but this makes the elements WAY too big and inflexible. + // If anyone complains about these not being applied, this can be uncommented. + // + // But if no one complains I'd rather fix this in lazer. Wiki documentation doesn't mention size, + // so we might be okay. + // + // if (ripple != null) + // { + // ripple.Scale = new Vector2(0.5f); + // ripple.Alpha = 0.2f; + // } + + return ripple; + } return null; diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs b/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs index 27e9d1d347..465b708b5a 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs @@ -73,9 +73,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor ClearTransforms(true); this.ScaleTo(0.05f) - .ScaleTo(0.5f, 700, Easing.Out) - .FadeTo(0.2f) - .FadeOut(700) + .ScaleTo(1, 700, Easing.Out) + .FadeOutFromOne(700) .Expire(true); } } @@ -91,7 +90,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor { new RingPiece(3) { - Size = new Vector2(512), + Size = new Vector2(256), + Alpha = 0.2f, } }; } From 949dc1c0f96e31d0a20323d83f3fa8a98ab95592 Mon Sep 17 00:00:00 2001 From: Terochi Date: Sun, 30 Apr 2023 12:05:55 +0200 Subject: [PATCH 2734/2991] Improved logic --- .../Visual/Gameplay/TestSceneSkinEditor.cs | 25 +++++--- .../SkinEditor/SkinEditorChangeHandler.cs | 57 +++++++++---------- 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs index 45cc329f53..4a0be3bb68 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs @@ -172,7 +172,7 @@ namespace osu.Game.Tests.Visual.Gameplay } [Test] - public void TestUndo() + public void TestUndoEditHistory() { SkinComponentsContainer firstTarget = null!; TestSkinEditorChangeHandler changeHandler = null!; @@ -205,17 +205,28 @@ namespace osu.Game.Tests.Visual.Gameplay InputManager.Click(MouseButton.Left); InputManager.Click(MouseButton.Left); }); - AddStep("Revert changes", () => changeHandler.RestoreState(int.MinValue)); - AddAssert("Nothing changed", () => defaultState.SequenceEqual(changeHandler.GetCurrentState())); + revertAndCheckUnchanged(); + + AddStep("Move components", () => + { + changeHandler.BeginChange(); + testComponents.ForEach(c => ((Drawable)c).Position += Vector2.One); + changeHandler.EndChange(); + }); + revertAndCheckUnchanged(); AddStep("Select components", () => skinEditor.SelectedComponents.AddRange(testComponents)); AddStep("Bring to front", () => skinEditor.BringSelectionToFront()); - AddStep("Revert changes", () => changeHandler.RestoreState(int.MinValue)); - AddAssert("Nothing changed", () => defaultState.SequenceEqual(changeHandler.GetCurrentState())); + revertAndCheckUnchanged(); AddStep("Remove components", () => testComponents.ForEach(c => firstTarget.Remove(c, false))); - AddStep("Revert changes", () => changeHandler.RestoreState(int.MinValue)); - AddAssert("Nothing changed", () => defaultState.SequenceEqual(changeHandler.GetCurrentState())); + revertAndCheckUnchanged(); + + void revertAndCheckUnchanged() + { + AddStep("Revert changes", () => changeHandler.RestoreState(int.MinValue)); + AddAssert("Nothing changed", () => defaultState.SequenceEqual(changeHandler.GetCurrentState())); + } } [TestCase(false)] diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs index f38f6b0911..6285080d36 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs @@ -60,49 +60,48 @@ namespace osu.Game.Overlays.SkinEditor SerialisedDrawableInfo[] skinnableInfos = deserializedContent.ToArray(); ISerialisableDrawable[] targetComponents = firstTarget.Components.ToArray(); - // Store indexes based on type for later lookup + // Store components based on type for later lookup + var typedComponents = new Dictionary>(); - var targetComponentsIndexes = new Dictionary>(); - - for (int i = 0; i < targetComponents.Length; i++) + foreach (var component in targetComponents) { - Type lookup = targetComponents[i].GetType(); + Type lookup = component.GetType(); - if (!targetComponentsIndexes.TryGetValue(lookup, out List? componentIndexes)) - targetComponentsIndexes.Add(lookup, componentIndexes = new List()); + if (!typedComponents.TryGetValue(lookup, out List? typeComponents)) + typedComponents.Add(lookup, typeComponents = new List()); - componentIndexes.Add(i); + typeComponents.Add(component); } - var indexCounting = new Dictionary(); + // Remove all components + for (int i = targetComponents.Length - 1; i >= 0; i--) + firstTarget.Remove(targetComponents[i], false); - var empty = new List(0); + // Keeps count of how many components for each type were already revived + Dictionary typedComponentCounter = typedComponents.Keys.ToDictionary(t => t, _ => 0); - for (int i = 0; i < skinnableInfos.Length; i++) + foreach (var skinnableInfo in skinnableInfos) { - Type lookup = skinnableInfos[i].Type; + Type lookup = skinnableInfo.Type; - if (!targetComponentsIndexes.TryGetValue(lookup, out List? componentIndexes)) - componentIndexes = empty; + if (!typedComponents.TryGetValue(lookup, out List? typeComponents)) + { + firstTarget.Add((ISerialisableDrawable)skinnableInfo.CreateInstance()); + continue; + } - if (!indexCounting.ContainsKey(lookup)) - indexCounting.Add(lookup, 0); + int typeComponentsUsed = typedComponentCounter[lookup]++; - if (i >= componentIndexes.Count) - // Add new component - firstTarget.Add((ISerialisableDrawable)skinnableInfos[i].CreateInstance()); + ISerialisableDrawable component; + + if (typeComponentsUsed < typeComponents.Count) + // Re-use unused component + ((Drawable)(component = typeComponents[typeComponentsUsed])).ApplySerialisedInfo(skinnableInfo); else - // Modify existing component - ((Drawable)targetComponents[componentIndexes[indexCounting[lookup]++]]).ApplySerialisedInfo(skinnableInfos[i]); - } + // Create new one + component = (ISerialisableDrawable)skinnableInfo.CreateInstance(); - foreach ((Type lookup, List componentIndexes) in targetComponentsIndexes) - { - indexCounting.TryGetValue(lookup, out int i); - - // Remove extra components that weren't removed above - for (; i < componentIndexes.Count; i++) - firstTarget.Remove(targetComponents[componentIndexes[i]], false); + firstTarget.Add(component); } } } From 1eb2e35dffb3215b3c58987fa6b244710babc49a Mon Sep 17 00:00:00 2001 From: OliBomby Date: Sun, 30 Apr 2023 16:03:58 +0200 Subject: [PATCH 2735/2991] fix ticks not being generated by default --- osu.Game.Rulesets.Osu/Objects/Slider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index dd75a86f96..98e536de38 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -142,7 +142,7 @@ namespace osu.Game.Rulesets.Osu.Objects set => SliderVelocityBindable.Value = value; } - public bool GenerateTicks { get; set; } + public bool GenerateTicks { get; set; } = true; [JsonIgnore] public SliderHeadCircle HeadCircle { get; protected set; } From e7a478ce9c7e8dc20be47173233f0700fd6d88e9 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Sun, 30 Apr 2023 16:04:03 +0200 Subject: [PATCH 2736/2991] Update convert-samples-expected-conversion.json --- .../Testing/Beatmaps/convert-samples-expected-conversion.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/convert-samples-expected-conversion.json b/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/convert-samples-expected-conversion.json index 6f1d45ad8c..4d298bb671 100644 --- a/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/convert-samples-expected-conversion.json +++ b/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/convert-samples-expected-conversion.json @@ -10,7 +10,7 @@ ["Gameplay/soft-hitnormal"], ["Gameplay/drum-hitnormal"] ], - "Samples": ["Gameplay/-hitnormal"] + "Samples": ["Gameplay/normal-hitnormal"] }, { "StartTime": 1875.0, "EndTime": 2750.0, @@ -19,7 +19,7 @@ ["Gameplay/soft-hitnormal"], ["Gameplay/drum-hitnormal"] ], - "Samples": ["Gameplay/-hitnormal"] + "Samples": ["Gameplay/normal-hitnormal"] }] }, { "StartTime": 3750.0, From 8f02bd80f967db674c7d1655c3f5f72645b77c76 Mon Sep 17 00:00:00 2001 From: Terochi Date: Sun, 30 Apr 2023 16:10:59 +0200 Subject: [PATCH 2737/2991] Addressed changes --- .../Visual/Gameplay/TestSceneSkinEditor.cs | 29 +++++++++---- osu.Game/Overlays/SkinEditor/SkinEditor.cs | 15 ++----- .../SkinEditor/SkinEditorChangeHandler.cs | 41 +++++++++++-------- 3 files changed, 48 insertions(+), 37 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs index 4a0be3bb68..f7eb42872d 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs @@ -100,10 +100,15 @@ namespace osu.Game.Tests.Visual.Gameplay InputManager.PressButton(MouseButton.Left); }); - AddStep("Drag to bottom right", - () => { InputManager.MoveMouseTo(box3.ScreenSpaceDrawQuad.TopRight + new Vector2(-box3.ScreenSpaceDrawQuad.Width / 8, box3.ScreenSpaceDrawQuad.Height / 4)); }); + AddStep("Drag to bottom right", () => + { + InputManager.MoveMouseTo(box3.ScreenSpaceDrawQuad.TopRight + new Vector2(-box3.ScreenSpaceDrawQuad.Width / 8, box3.ScreenSpaceDrawQuad.Height / 4)); + }); - AddStep("Release button", () => { InputManager.ReleaseButton(MouseButton.Left); }); + AddStep("Release button", () => + { + InputManager.ReleaseButton(MouseButton.Left); + }); AddAssert("First two boxes selected", () => skinEditor.SelectedComponents, () => Is.EqualTo(new[] { box1, box2 })); @@ -113,9 +118,15 @@ namespace osu.Game.Tests.Visual.Gameplay InputManager.PressButton(MouseButton.Left); }); - AddStep("Drag to top left", () => { InputManager.MoveMouseTo(box2.ScreenSpaceDrawQuad.Centre - new Vector2(box2.ScreenSpaceDrawQuad.Width / 4)); }); + AddStep("Drag to top left", () => + { + InputManager.MoveMouseTo(box2.ScreenSpaceDrawQuad.Centre - new Vector2(box2.ScreenSpaceDrawQuad.Width / 4)); + }); - AddStep("Release button", () => { InputManager.ReleaseButton(MouseButton.Left); }); + AddStep("Release button", () => + { + InputManager.ReleaseButton(MouseButton.Left); + }); AddAssert("Last two boxes selected", () => skinEditor.SelectedComponents, () => Is.EqualTo(new[] { box2, box3 })); @@ -139,7 +150,10 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("Three black boxes added", () => targetContainer.Components.OfType().Count(), () => Is.EqualTo(3)); - AddStep("Store black box blueprints", () => { blueprints = skinEditor.ChildrenOfType().Where(b => b.Item is BigBlackBox).ToArray(); }); + AddStep("Store black box blueprints", () => + { + blueprints = skinEditor.ChildrenOfType().Where(b => b.Item is BigBlackBox).ToArray(); + }); AddAssert("Selection is black box 1", () => skinEditor.SelectedComponents.Single(), () => Is.EqualTo(blueprints[0].Item)); @@ -184,7 +198,6 @@ namespace osu.Game.Tests.Visual.Gameplay firstTarget = Player.ChildrenOfType().First(); changeHandler = new TestSkinEditorChangeHandler(firstTarget); - changeHandler.SaveState(); defaultState = changeHandler.GetCurrentState(); testComponents = new[] @@ -225,7 +238,7 @@ namespace osu.Game.Tests.Visual.Gameplay void revertAndCheckUnchanged() { AddStep("Revert changes", () => changeHandler.RestoreState(int.MinValue)); - AddAssert("Nothing changed", () => defaultState.SequenceEqual(changeHandler.GetCurrentState())); + AddAssert("Current state is same as default", () => defaultState.SequenceEqual(changeHandler.GetCurrentState())); } } diff --git a/osu.Game/Overlays/SkinEditor/SkinEditor.cs b/osu.Game/Overlays/SkinEditor/SkinEditor.cs index f0ad92d4da..2b23ce290f 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditor.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditor.cs @@ -235,7 +235,10 @@ namespace osu.Game.Overlays.SkinEditor }, true); canPaste.Current.BindValueChanged(paste => pasteMenuItem.Action.Disabled = !paste.NewValue, true); - SelectedComponents.BindCollectionChanged((_, _) => canCopy.Value = canCut.Value = SelectedComponents.Any(), true); + SelectedComponents.BindCollectionChanged((_, _) => + { + canCopy.Value = canCut.Value = SelectedComponents.Any(); + }, true); clipboard.Content.BindValueChanged(content => canPaste.Value = !string.IsNullOrEmpty(content.NewValue), true); @@ -342,7 +345,6 @@ namespace osu.Game.Overlays.SkinEditor changeHandler = new SkinEditorChangeHandler(skinComponentsContainer); changeHandler.CanUndo.BindValueChanged(v => undoMenuItem.Action.Disabled = !v.NewValue, true); changeHandler.CanRedo.BindValueChanged(v => redoMenuItem.Action.Disabled = !v.NewValue, true); - changeHandler.SaveState(); content.Child = new SkinBlueprintContainer(skinComponentsContainer); @@ -477,18 +479,12 @@ namespace osu.Game.Overlays.SkinEditor protected void Cut() { - if (!canCut.Value) - return; - Copy(); DeleteItems(SelectedComponents.ToArray()); } protected void Copy() { - if (!canCopy.Value) - return; - clipboard.Content.Value = JsonConvert.SerializeObject(SelectedComponents.Cast().Select(s => s.CreateSerialisedInfo()).ToArray()); } @@ -504,9 +500,6 @@ namespace osu.Game.Overlays.SkinEditor protected void Paste() { - if (!canPaste.Value) - return; - changeHandler?.BeginChange(); var drawableInfo = JsonConvert.DeserializeObject(clipboard.Content.Value); diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs index 6285080d36..8c7f7bbab7 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.SkinEditor return; components = new BindableList { BindTarget = firstTarget.Components }; - components.BindCollectionChanged((_, _) => SaveState()); + components.BindCollectionChanged((_, _) => SaveState(), true); } protected override void WriteCurrentStateToStream(MemoryStream stream) @@ -61,47 +61,52 @@ namespace osu.Game.Overlays.SkinEditor ISerialisableDrawable[] targetComponents = firstTarget.Components.ToArray(); // Store components based on type for later lookup - var typedComponents = new Dictionary>(); + var typedComponents = new Dictionary>(); - foreach (var component in targetComponents) + for (int i = targetComponents.Length - 1; i >= 0; i--) { + Drawable component = (Drawable)targetComponents[i]; Type lookup = component.GetType(); - if (!typedComponents.TryGetValue(lookup, out List? typeComponents)) - typedComponents.Add(lookup, typeComponents = new List()); + if (!typedComponents.TryGetValue(lookup, out Stack? typeComponents)) + typedComponents.Add(lookup, typeComponents = new Stack()); - typeComponents.Add(component); + typeComponents.Push(component); } // Remove all components for (int i = targetComponents.Length - 1; i >= 0; i--) firstTarget.Remove(targetComponents[i], false); - // Keeps count of how many components for each type were already revived - Dictionary typedComponentCounter = typedComponents.Keys.ToDictionary(t => t, _ => 0); - foreach (var skinnableInfo in skinnableInfos) { Type lookup = skinnableInfo.Type; - if (!typedComponents.TryGetValue(lookup, out List? typeComponents)) + if (!typedComponents.TryGetValue(lookup, out Stack? typeComponents)) { firstTarget.Add((ISerialisableDrawable)skinnableInfo.CreateInstance()); continue; } - int typeComponentsUsed = typedComponentCounter[lookup]++; - - ISerialisableDrawable component; - - if (typeComponentsUsed < typeComponents.Count) + if (typeComponents.TryPop(out Drawable? component)) + { // Re-use unused component - ((Drawable)(component = typeComponents[typeComponentsUsed])).ApplySerialisedInfo(skinnableInfo); + component.ApplySerialisedInfo(skinnableInfo); + } else + { // Create new one - component = (ISerialisableDrawable)skinnableInfo.CreateInstance(); + component = skinnableInfo.CreateInstance(); + } - firstTarget.Add(component); + firstTarget.Add((ISerialisableDrawable)component); + } + + foreach ((Type _, Stack typeComponents) in typedComponents) + { + // Dispose extra components + foreach (var component in typeComponents) + component.Dispose(); } } } From fb4b681cc527c1b9430d2537e474d77f9035286c Mon Sep 17 00:00:00 2001 From: Terochi Date: Sun, 30 Apr 2023 16:36:01 +0200 Subject: [PATCH 2738/2991] Use `Queue` instead of `Stack` --- .../SkinEditor/SkinEditorChangeHandler.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs index 8c7f7bbab7..18ffdb0edc 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs @@ -61,17 +61,16 @@ namespace osu.Game.Overlays.SkinEditor ISerialisableDrawable[] targetComponents = firstTarget.Components.ToArray(); // Store components based on type for later lookup - var typedComponents = new Dictionary>(); + var typedComponents = new Dictionary>(); - for (int i = targetComponents.Length - 1; i >= 0; i--) + foreach (ISerialisableDrawable component in targetComponents) { - Drawable component = (Drawable)targetComponents[i]; Type lookup = component.GetType(); - if (!typedComponents.TryGetValue(lookup, out Stack? typeComponents)) - typedComponents.Add(lookup, typeComponents = new Stack()); + if (!typedComponents.TryGetValue(lookup, out Queue? typeComponents)) + typedComponents.Add(lookup, typeComponents = new Queue()); - typeComponents.Push(component); + typeComponents.Enqueue((Drawable)component); } // Remove all components @@ -82,13 +81,13 @@ namespace osu.Game.Overlays.SkinEditor { Type lookup = skinnableInfo.Type; - if (!typedComponents.TryGetValue(lookup, out Stack? typeComponents)) + if (!typedComponents.TryGetValue(lookup, out Queue? typeComponents)) { firstTarget.Add((ISerialisableDrawable)skinnableInfo.CreateInstance()); continue; } - if (typeComponents.TryPop(out Drawable? component)) + if (typeComponents.TryDequeue(out Drawable? component)) { // Re-use unused component component.ApplySerialisedInfo(skinnableInfo); @@ -102,7 +101,7 @@ namespace osu.Game.Overlays.SkinEditor firstTarget.Add((ISerialisableDrawable)component); } - foreach ((Type _, Stack typeComponents) in typedComponents) + foreach ((Type _, Queue typeComponents) in typedComponents) { // Dispose extra components foreach (var component in typeComponents) From 79f3cfec91e58bc67cb3a1df1d099fc08e991938 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Sun, 30 Apr 2023 16:43:26 +0200 Subject: [PATCH 2739/2991] fix 0 velocity juicestream --- .../Edit/Blueprints/Components/EditablePath.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs index 7a577f8a83..75ee0546dd 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs @@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components // // The value is clamped here by the bindable min and max values. // In case the required velocity is too large, the path is not preserved. - svBindable.Value = Math.Ceiling(requiredVelocity / svToVelocityFactor); + svBindable.Value = requiredVelocity == 0 ? 1 : Math.Ceiling(requiredVelocity / svToVelocityFactor); path.ConvertToSliderPath(hitObject.Path, hitObject.LegacyConvertedY, hitObject.Velocity); From d35355970f2aa40dbddb54dee6eacac225ad5f84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 30 Apr 2023 17:23:45 +0200 Subject: [PATCH 2740/2991] Add test case covering failure scenario --- .../TestSceneModSelectOverlay.cs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs index 5ccaebd721..f99fe1d8d4 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs @@ -14,6 +14,7 @@ using osu.Framework.Localisation; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays; using osu.Game.Overlays.Mods; using osu.Game.Overlays.Settings; using osu.Game.Rulesets; @@ -67,6 +68,19 @@ namespace osu.Game.Tests.Visual.UserInterface } } }); + r.Add(new ModPreset + { + Name = "Half Time 0.5x", + Description = "Very slow", + Ruleset = r.Find(OsuRuleset.SHORT_NAME), + Mods = new[] + { + new OsuModHalfTime + { + SpeedChange = { Value = 0.5 } + } + } + }); }); }); } @@ -566,6 +580,28 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("5 columns visible", () => this.ChildrenOfType().Count(col => col.IsPresent) == 5); } + [Test] + public void TestModMultiplierUpdates() + { + createScreen(); + + AddStep("select mod preset with half time", () => + { + InputManager.MoveMouseTo(this.ChildrenOfType().Single(preset => preset.Preset.Value.Name == "Half Time 0.5x")); + InputManager.Click(MouseButton.Left); + }); + AddAssert("difficulty multiplier display shows correct value", () => modSelectOverlay.ChildrenOfType().Single().Current.Value, () => Is.EqualTo(0.5)); + + // this is highly unorthodox in a test, but because the `ModSettingChangeTracker` machinery heavily leans on events and object disposal and re-creation, + // it is instrumental in the reproduction of the failure scenario that this test is supposed to cover. + AddStep("force collection", GC.Collect); + + AddStep("open customisation area", () => modSelectOverlay.CustomisationButton!.TriggerClick()); + AddStep("reset half time speed to default", () => modSelectOverlay.ChildrenOfType().Single() + .ChildrenOfType>().Single().TriggerClick()); + AddUntilStep("difficulty multiplier display shows correct value", () => modSelectOverlay.ChildrenOfType().Single().Current.Value, () => Is.EqualTo(0.7)); + } + private void waitForColumnLoad() => AddUntilStep("all column content loaded", () => modSelectOverlay.ChildrenOfType().Any() && modSelectOverlay.ChildrenOfType().All(column => column.IsLoaded && column.ItemsLoaded)); From 2e3daf0a541e14fb518292fabcc2ae8dde319e12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 30 Apr 2023 17:24:07 +0200 Subject: [PATCH 2741/2991] Fix leak of `ModSettingChangeTracker` instances The `SelectedMods.BindValueChanged()` callback in `ModSelectOverlay` can in some instances run recursively. This is most heavily leaned on in scenarios where `SelectedMods` is updated by an external component. In such cases, the mod select overlay needs to replace the mod instances received externally with mod instances which it owns, so that the changes made on the overlay can propagate outwards. This in particular means that prior to this commit, it was possible to encounter the following scenario: modSettingChangeTracker?.Dispose(); updateFromExternalSelection(); // mutates SelectedMods to perform the replacement // therefore causing a recursive call modSettingChangeTracker?.Dispose(); // inner call continues modSettingChangeTracker = new ModSettingChangeTracker(SelectedMods.Value); // outer call continues modSettingChangeTracker = new ModSettingChangeTracker(SelectedMods.Value); This leaks one `modSettingChangeTracker` instance from the inner call, which is never disposed. To avoid this, move the disposal to the same side of the recursion that the creation happens on, changing the call pattern to: updateFromExternalSelection(); // mutates SelectedMods to perform the replacement // therefore causing a recursive call modSettingChangeTracker?.Dispose(); // inner call continues modSettingChangeTracker = new ModSettingChangeTracker(SelectedMods.Value); modSettingChangeTracker?.Dispose(); // outer call continues modSettingChangeTracker = new ModSettingChangeTracker(SelectedMods.Value); which, while slightly wasteful, does not cause any leaks. The solution is definitely suboptimal, but addressing this properly would entail a major rewrite of the mod instance management in the mods overlay, which is probably not the wisest move to make right now. --- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index d611fd3c0b..46d3620c9c 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -244,12 +244,12 @@ namespace osu.Game.Overlays.Mods SelectedMods.BindValueChanged(val => { - modSettingChangeTracker?.Dispose(); - updateMultiplier(); updateFromExternalSelection(); updateCustomisation(); + modSettingChangeTracker?.Dispose(); + if (AllowCustomisation) { modSettingChangeTracker = new ModSettingChangeTracker(SelectedMods.Value); From 139a1d7e6d6ec8f5d5c13de881f4ddfdd2542bc4 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Sun, 30 Apr 2023 17:46:47 +0200 Subject: [PATCH 2742/2991] fix legacy encoder writing sample info while not writing node samples --- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index a681429d02..c5a8cc89be 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -476,16 +476,16 @@ namespace osu.Game.Beatmaps.Formats if (curveData != null) { - for (int i = 0; i < curveData.NodeSamples.Count; i++) + for (int i = 0; i < curveData.SpanCount() + 1; i++) { - writer.Write(FormattableString.Invariant($"{(int)toLegacyHitSoundType(curveData.NodeSamples[i])}")); - writer.Write(i != curveData.NodeSamples.Count - 1 ? "|" : ","); + writer.Write(FormattableString.Invariant($"{(i < curveData.NodeSamples.Count ? (int)toLegacyHitSoundType(curveData.NodeSamples[i]) : 0)}")); + writer.Write(i != curveData.SpanCount() ? "|" : ","); } - for (int i = 0; i < curveData.NodeSamples.Count; i++) + for (int i = 0; i < curveData.SpanCount() + 1; i++) { - writer.Write(getSampleBank(curveData.NodeSamples[i], true)); - writer.Write(i != curveData.NodeSamples.Count - 1 ? "|" : ","); + writer.Write(i < curveData.NodeSamples.Count ? getSampleBank(curveData.NodeSamples[i], true) : "0:0"); + writer.Write(i != curveData.SpanCount() ? "|" : ","); } } } From 4a0ff046ae302ceb2b2eb379055ec119eb240b4a Mon Sep 17 00:00:00 2001 From: OliBomby Date: Sun, 30 Apr 2023 19:20:42 +0200 Subject: [PATCH 2743/2991] pass new hitobject properties through beatmap converters --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs | 4 +++- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs | 6 +++++- osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs | 3 ++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index 7774a7da09..2c8ef9eae0 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -26,6 +26,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps var xPositionData = obj as IHasXPosition; var yPositionData = obj as IHasYPosition; var comboData = obj as IHasCombo; + var sliderVelocityData = obj as IHasSliderVelocity; switch (obj) { @@ -41,7 +42,8 @@ namespace osu.Game.Rulesets.Catch.Beatmaps NewCombo = comboData?.NewCombo ?? false, ComboOffset = comboData?.ComboOffset ?? 0, LegacyLastTickOffset = (obj as IHasLegacyLastTickOffset)?.LegacyLastTickOffset ?? 0, - LegacyConvertedY = yPositionData?.Y ?? CatchHitObject.DEFAULT_LEGACY_CONVERT_Y + LegacyConvertedY = yPositionData?.Y ?? CatchHitObject.DEFAULT_LEGACY_CONVERT_Y, + SliderVelocity = sliderVelocityData?.SliderVelocity ?? 1 }.Yield(); case IHasDuration endTime: diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs index e9518895be..d03ee81f0d 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs @@ -30,6 +30,8 @@ namespace osu.Game.Rulesets.Osu.Beatmaps { var positionData = original as IHasPosition; var comboData = original as IHasCombo; + var sliderVelocityData = original as IHasSliderVelocity; + var generateTicksData = original as IHasGenerateTicks; switch (original) { @@ -47,7 +49,9 @@ namespace osu.Game.Rulesets.Osu.Beatmaps LegacyLastTickOffset = (original as IHasLegacyLastTickOffset)?.LegacyLastTickOffset, // prior to v8, speed multipliers don't adjust for how many ticks are generated over the same distance. // this results in more (or less) ticks being generated in Date: Sun, 30 Apr 2023 19:32:24 +0200 Subject: [PATCH 2744/2991] add min and max value to SliderVelocity --- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 7 ++++++- osu.Game.Rulesets.Osu/Objects/Slider.cs | 7 ++++++- osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 7 ++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index f8af161ad5..169e99c90c 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -28,7 +28,12 @@ namespace osu.Game.Rulesets.Catch.Objects public int RepeatCount { get; set; } - public BindableNumber SliderVelocityBindable { get; } = new BindableDouble(1); + public BindableNumber SliderVelocityBindable { get; } = new BindableDouble(1) + { + Precision = 0.01, + MinValue = 0.1, + MaxValue = 10 + }; public double SliderVelocity { diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 98e536de38..4189f8ba1e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -134,7 +134,12 @@ namespace osu.Game.Rulesets.Osu.Objects /// public bool OnlyJudgeNestedObjects = true; - public BindableNumber SliderVelocityBindable { get; } = new BindableDouble(1); + public BindableNumber SliderVelocityBindable { get; } = new BindableDouble(1) + { + Precision = 0.01, + MinValue = 0.1, + MaxValue = 10 + }; public double SliderVelocity { diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs index c1a78f46b2..b4a12fd314 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs @@ -38,7 +38,12 @@ namespace osu.Game.Rulesets.Taiko.Objects /// public double Velocity { get; private set; } - public BindableNumber SliderVelocityBindable { get; } = new BindableDouble(1); + public BindableNumber SliderVelocityBindable { get; } = new BindableDouble(1) + { + Precision = 0.01, + MinValue = 0.1, + MaxValue = 10 + }; public double SliderVelocity { From 2a947571546bd883716e7a182a52100a68210548 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Mon, 1 May 2023 00:49:01 +0200 Subject: [PATCH 2745/2991] Make sure the first object you place has bank and volume --- osu.Game/Rulesets/Edit/PlacementBlueprint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs index 96128c6981..bdcb334738 100644 --- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs +++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs @@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Edit HitObject = hitObject; // adding the default hit sample should be the case regardless of the ruleset. - HitObject.Samples.Add(new HitSampleInfo(HitSampleInfo.HIT_NORMAL)); + HitObject.Samples.Add(new HitSampleInfo(HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK, volume: 100)); RelativeSizeAxes = Axes.Both; From b8ae508639421a89dbfe0fadb1b433bdaa46d05f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 1 May 2023 13:09:00 +0900 Subject: [PATCH 2746/2991] Fix incorrect starting scale for ripples --- osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs b/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs index 465b708b5a..663c1f54fc 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs @@ -72,7 +72,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor ClearTransforms(true); - this.ScaleTo(0.05f) + this.ScaleTo(0.1f) .ScaleTo(1, 700, Easing.Out) .FadeOutFromOne(700) .Expire(true); From 5cbfefbcb4d6177a4012527d28d53d56c13ffab0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 1 May 2023 13:18:04 +0900 Subject: [PATCH 2747/2991] Adjust metrics of default ripple to match stable default better --- osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs b/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs index 663c1f54fc..cee5574f06 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Pooling; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Game.Rulesets.Osu.Configuration; +using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Skinning.Default; using osu.Game.Skinning; using osuTK; @@ -90,8 +91,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor { new RingPiece(3) { - Size = new Vector2(256), - Alpha = 0.2f, + Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2), + Alpha = 0.1f, } }; } From 0a70734331f2ba319c74c9b909ddcca3f338a6a6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 1 May 2023 14:40:48 +0900 Subject: [PATCH 2748/2991] Adjust ripple size with cursor scale (including CS) --- .../UI/Cursor/CursorRippleVisualiser.cs | 18 +++++++++++------- .../UI/Cursor/OsuCursorContainer.cs | 5 ++++- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs b/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs index cee5574f06..076d97d06a 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/CursorRippleVisualiser.cs @@ -27,6 +27,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor RelativeSizeAxes = Axes.Both; } + public Vector2 CursorScale { get; set; } = Vector2.One; + [BackgroundDependencyLoader(true)] private void load(OsuRulesetConfigManager? rulesetConfig) { @@ -40,6 +42,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor AddInternal(ripplePool.Get(r => { r.Position = e.MousePosition; + r.Scale = CursorScale; })); } @@ -52,18 +55,17 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor private partial class CursorRipple : PoolableDrawable { + private Drawable ripple = null!; + [BackgroundDependencyLoader] private void load() { AutoSizeAxes = Axes.Both; Origin = Anchor.Centre; - InternalChildren = new Drawable[] + InternalChild = ripple = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorRipple), _ => new DefaultCursorRipple()) { - new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorRipple), _ => new DefaultCursorRipple()) - { - Blending = BlendingParameters.Additive, - } + Blending = BlendingParameters.Additive, }; } @@ -73,8 +75,10 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor ClearTransforms(true); - this.ScaleTo(0.1f) - .ScaleTo(1, 700, Easing.Out) + ripple.ScaleTo(0.1f) + .ScaleTo(1, 700, Easing.Out); + + this .FadeOutFromOne(700) .Expire(true); } diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs index 35fb8e67d8..bf1ff872dd 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs @@ -40,6 +40,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor private Bindable userCursorScale; private Bindable autoCursorScale; + private readonly CursorRippleVisualiser rippleVisualiser; + public OsuCursorContainer() { InternalChild = fadeContainer = new Container @@ -48,7 +50,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor Children = new[] { cursorTrail = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorTrail), _ => new DefaultCursorTrail(), confineMode: ConfineMode.NoScaling), - new CursorRippleVisualiser(), + rippleVisualiser = new CursorRippleVisualiser(), new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorParticles), confineMode: ConfineMode.NoScaling), } }; @@ -83,6 +85,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor var newScale = new Vector2(e.NewValue); ActiveCursor.Scale = newScale; + rippleVisualiser.CursorScale = newScale; cursorTrail.Scale = newScale; }, true); From ff29189e8951945c6ef701159cc7636a75032d51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 1 May 2023 09:33:37 +0200 Subject: [PATCH 2749/2991] Add custom `cursor-ripple` to cover skinnability in test --- .../Resources/special-skin/cursor-ripple@2x.png | Bin 0 -> 2149 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 osu.Game.Rulesets.Osu.Tests/Resources/special-skin/cursor-ripple@2x.png diff --git a/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/cursor-ripple@2x.png b/osu.Game.Rulesets.Osu.Tests/Resources/special-skin/cursor-ripple@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..258162c4864ddc469ba21697770b2fc8e1297eb5 GIT binary patch literal 2149 zcmcgsX;4#V6us|}kS8dFF-#Ic5|_5rT2^f>iv$Bgv@GHZ1A?;2AVv@s6p|2B6e7xW zlxhVxtS~NA5Em3f6%wnCsC65ug_3cob&Xbu8uEHSrtPn`e>!7ka^Ac5o_o&u^4?@q zY;?p3hfxjyFhUU-76(A#Ed`7{UJ~=_Gq6~fC6~u4$>GtPQ{e0-z%ys3EC>aJhf-of7Z^qsf-otCubWW*_atCL+XG%{l}KK3qE zJJPQx;zpf&wKAq{&gx;c4|)bNUo~(mD5|PpyZGCvv!Ow4S#G-qHl-e(c&MYlBlW|i zt(K}s227|wKV7@3M&Kw8hQ>S7shd&{f=X2*z(Bu6#$MS$(MqiyF}RJ(ZDDev_IHcKYigqyWfn0mafQXJTG&9a-P zZ+ju;oVC05gOMGuHLv2Fd!j!x5Dnm|}@n!fi!HEkh|KDMDWe-yn9#<6jxP$&`zJdSWLeZrcAtD)9n?HxowT38fCiXBKhX zNTaMwKn(T~D?S%ZOFaLT+P>07WU6jubmo~!9E0V67oBR26PEa@8YfHiobTSJam)=<3+kH)j3YO6AWl_5pq4je%{>Id;MBdWWTQYP3+T7>3@7Dgwi+~={G(>p5BOWJ`rCSF zl>EZLb|b5G(9F7Ed)Zp6ny|Y^vuE%x`{8Fsb{QGBnf0HLakllD6B&zHd_iz*U>6Y& znOo~tC6A+%fRn=z4j)1%f_#m}YzH*oM+GvV4bH&G+AS1N zj3@-8K$&>Jai21TK?KvR_@KzzR0V#bM(d$o4wcb}jV@rKJ(;Bb} O@S_Ni4m&z6Mf(Thel05i literal 0 HcmV?d00001 From cef9f73d346cdafb9e4d5c7aa3f4a5a25f82ef1a Mon Sep 17 00:00:00 2001 From: OliBomby Date: Mon, 1 May 2023 12:31:27 +0200 Subject: [PATCH 2750/2991] dont assign custom sample bank and volume to hitobjects in non-mania gamemodes this makes it easier to edit hitsounds in the stable editor after export because the sample control point effects wont get overwritten by the properties of the hitobject --- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index c5a8cc89be..28f3a8d951 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -520,6 +520,14 @@ namespace osu.Game.Beatmaps.Formats string sampleFilename = samples.FirstOrDefault(s => string.IsNullOrEmpty(s.Name))?.LookupNames.First() ?? string.Empty; int volume = samples.FirstOrDefault()?.Volume ?? 100; + // We want to ignore custom sample banks and volume when not encoding to the mania game mode, + // because they cause unexpected results in the editor and are already satisfied by the control points. + if (onlineRulesetID != 3) + { + customSampleBank = "0"; + volume = 0; + } + sb.Append(':'); sb.Append(FormattableString.Invariant($"{customSampleBank}:")); sb.Append(FormattableString.Invariant($"{volume}:")); From 4d52ce769bcea52ee6e10cbc3826a4d570f48707 Mon Sep 17 00:00:00 2001 From: Terochi Date: Mon, 1 May 2023 12:53:58 +0200 Subject: [PATCH 2751/2991] Revert `SaveState()` calling on initialization --- osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs | 1 + osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs index f7eb42872d..7b37b6624d 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinEditor.cs @@ -198,6 +198,7 @@ namespace osu.Game.Tests.Visual.Gameplay firstTarget = Player.ChildrenOfType().First(); changeHandler = new TestSkinEditorChangeHandler(firstTarget); + changeHandler.SaveState(); defaultState = changeHandler.GetCurrentState(); testComponents = new[] diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs index 18ffdb0edc..3dddf639cc 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.SkinEditor return; components = new BindableList { BindTarget = firstTarget.Components }; - components.BindCollectionChanged((_, _) => SaveState(), true); + components.BindCollectionChanged((_, _) => SaveState()); } protected override void WriteCurrentStateToStream(MemoryStream stream) From 27cfadca16476bc9cbe069294bbc3b141c9cdcc7 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Mon, 1 May 2023 14:14:57 +0200 Subject: [PATCH 2752/2991] add sample info to Banana and SpinnerBonusTick --- osu.Game.Rulesets.Catch/Objects/Banana.cs | 8 +++----- osu.Game.Rulesets.Catch/Objects/BananaShower.cs | 2 +- osu.Game.Rulesets.Osu/Objects/Spinner.cs | 2 +- osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs | 6 ------ osu.Game/Rulesets/Objects/HitObject.cs | 2 +- 5 files changed, 6 insertions(+), 14 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Banana.cs b/osu.Game.Rulesets.Catch/Objects/Banana.cs index af03c9acab..e137204c32 100644 --- a/osu.Game.Rulesets.Catch/Objects/Banana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Banana.cs @@ -22,11 +22,9 @@ namespace osu.Game.Rulesets.Catch.Objects public override Judgement CreateJudgement() => new CatchBananaJudgement(); - private static readonly List samples = new List { new BananaHitSampleInfo() }; - - public Banana() + public Banana(int volume = 100) { - Samples = samples; + Samples = new List { new BananaHitSampleInfo(volume) }; } // override any external colour changes with banananana @@ -53,7 +51,7 @@ namespace osu.Game.Rulesets.Catch.Objects public override IEnumerable LookupNames => lookup_names; - public BananaHitSampleInfo(int volume = 0) + public BananaHitSampleInfo(int volume = 100) : base(string.Empty, volume: volume) { } diff --git a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs index b45f95a8e6..08febeabbf 100644 --- a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Catch.Objects { cancellationToken.ThrowIfCancellationRequested(); - AddNested(new Banana + AddNested(new Banana(GetSampleInfo().Volume) { StartTime = time, BananaIndex = i, diff --git a/osu.Game.Rulesets.Osu/Objects/Spinner.cs b/osu.Game.Rulesets.Osu/Objects/Spinner.cs index 55924c19c9..df5898fd67 100644 --- a/osu.Game.Rulesets.Osu/Objects/Spinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Spinner.cs @@ -72,7 +72,7 @@ namespace osu.Game.Rulesets.Osu.Objects AddNested(i < SpinsRequired ? new SpinnerTick { StartTime = startTime, SpinnerDuration = Duration } - : new SpinnerBonusTick { StartTime = startTime, SpinnerDuration = Duration }); + : new SpinnerBonusTick { StartTime = startTime, SpinnerDuration = Duration, Samples = new[] { GetSampleInfo("spinnerbonus") } }); } } diff --git a/osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs b/osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs index 81cdf5755b..00ceccaf7b 100644 --- a/osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs @@ -3,7 +3,6 @@ #nullable disable -using osu.Game.Audio; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; @@ -11,11 +10,6 @@ namespace osu.Game.Rulesets.Osu.Objects { public class SpinnerBonusTick : SpinnerTick { - public SpinnerBonusTick() - { - Samples.Add(new HitSampleInfo("spinnerbonus")); - } - public override Judgement CreateJudgement() => new OsuSpinnerBonusTickJudgement(); public class OsuSpinnerBonusTickJudgement : OsuSpinnerTickJudgement diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 774ff9dc1d..a4cb976d50 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -210,7 +210,7 @@ namespace osu.Game.Rulesets.Objects /// /// The name of the sample. /// A populated . - protected HitSampleInfo GetSampleInfo(string sampleName) + protected HitSampleInfo GetSampleInfo(string sampleName = HitSampleInfo.HIT_NORMAL) { var hitnormalSample = Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL); return hitnormalSample == null ? new HitSampleInfo(sampleName) : hitnormalSample.With(newName: sampleName); From 8302bb1f37b5c5c18d85134fc0a5834b7c4caaa9 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Mon, 1 May 2023 14:56:29 +0200 Subject: [PATCH 2753/2991] dont encode custom sample bank for objects without legacy samples --- .../Beatmaps/Formats/LegacyBeatmapEncoder.cs | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 28f3a8d951..343dd7b082 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.IO; using System.Linq; using System.Text; @@ -173,9 +172,6 @@ namespace osu.Game.Beatmaps.Formats private void handleControlPoints(TextWriter writer) { - if (beatmap.ControlPointInfo.Groups.Count == 0) - return; - var legacyControlPoints = new LegacyControlPointInfo(); foreach (var point in beatmap.ControlPointInfo.AllControlPoints) legacyControlPoints.Add(point.Time, point.DeepClone()); @@ -199,6 +195,8 @@ namespace osu.Game.Beatmaps.Formats legacyControlPoints.Add(point.Time, new DifficultyControlPoint { SliderVelocity = point.ScrollSpeed }); } + int lastCustomSampleIndex = 0; + foreach (var group in legacyControlPoints.Groups) { var groupTimingPoint = group.ControlPoints.OfType().FirstOrDefault(); @@ -227,6 +225,12 @@ namespace osu.Game.Beatmaps.Formats // Apply the control point to a hit sample to uncover legacy properties (e.g. suffix) HitSampleInfo tempHitSample = samplePoint.ApplyTo(new ConvertHitObjectParser.LegacyHitSampleInfo(string.Empty)); + // Inherit the previous sample bank if the current sample bank is not set + int customSampleBank = toLegacyCustomSampleBank(tempHitSample); + if (customSampleBank < 0) + customSampleBank = lastCustomSampleIndex; + lastCustomSampleIndex = customSampleBank; + // Convert effect flags to the legacy format LegacyEffectFlags effectFlags = LegacyEffectFlags.None; if (effectPoint.KiaiMode) @@ -236,7 +240,7 @@ namespace osu.Game.Beatmaps.Formats writer.Write(FormattableString.Invariant($"{timingPoint.TimeSignature.Numerator},")); writer.Write(FormattableString.Invariant($"{(int)toLegacySampleBank(tempHitSample.Bank)},")); - writer.Write(FormattableString.Invariant($"{toLegacyCustomSampleBank(tempHitSample)},")); + writer.Write(FormattableString.Invariant($"{customSampleBank},")); writer.Write(FormattableString.Invariant($"{tempHitSample.Volume},")); writer.Write(FormattableString.Invariant($"{(isTimingPoint ? '1' : '0')},")); writer.Write(FormattableString.Invariant($"{(int)effectFlags}")); @@ -276,7 +280,8 @@ namespace osu.Game.Beatmaps.Formats int volume = hitObject.Samples.Max(o => o.Volume); int customIndex = hitObject.Samples.Any(o => o is ConvertHitObjectParser.LegacyHitSampleInfo) ? hitObject.Samples.OfType().Max(o => o.CustomSampleBank) - : 0; + : -1; + yield return new LegacyBeatmapDecoder.LegacySampleControlPoint { Time = hitObject.GetEndTime(), SampleVolume = volume, CustomSampleBank = customIndex }; } @@ -516,7 +521,7 @@ namespace osu.Game.Beatmaps.Formats if (!banksOnly) { - string customSampleBank = toLegacyCustomSampleBank(samples.FirstOrDefault(s => !string.IsNullOrEmpty(s.Name))); + int customSampleBank = toLegacyCustomSampleBank(samples.FirstOrDefault(s => !string.IsNullOrEmpty(s.Name))); string sampleFilename = samples.FirstOrDefault(s => string.IsNullOrEmpty(s.Name))?.LookupNames.First() ?? string.Empty; int volume = samples.FirstOrDefault()?.Volume ?? 100; @@ -524,7 +529,7 @@ namespace osu.Game.Beatmaps.Formats // because they cause unexpected results in the editor and are already satisfied by the control points. if (onlineRulesetID != 3) { - customSampleBank = "0"; + customSampleBank = 0; volume = 0; } @@ -580,12 +585,12 @@ namespace osu.Game.Beatmaps.Formats } } - private string toLegacyCustomSampleBank(HitSampleInfo hitSampleInfo) + private int toLegacyCustomSampleBank(HitSampleInfo hitSampleInfo) { if (hitSampleInfo is ConvertHitObjectParser.LegacyHitSampleInfo legacy) - return legacy.CustomSampleBank.ToString(CultureInfo.InvariantCulture); + return legacy.CustomSampleBank; - return "0"; + return 0; } } } From 1dc34ee25de83fd4c2bc73151bfd3fde607519d0 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Mon, 1 May 2023 15:48:54 +0200 Subject: [PATCH 2754/2991] fix infinite repeat count when adjusting length of 0 length slider --- .../Compose/Components/Timeline/TimelineHitObjectBlueprint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index 4e5087c004..50f941a1e5 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -414,7 +414,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline double lengthOfOneRepeat = repeatHitObject.Duration / (repeatHitObject.RepeatCount + 1); int proposedCount = Math.Max(0, (int)Math.Round(proposedDuration / lengthOfOneRepeat) - 1); - if (proposedCount == repeatHitObject.RepeatCount) + if (proposedCount == repeatHitObject.RepeatCount || lengthOfOneRepeat == 0) return; repeatHitObject.RepeatCount = proposedCount; From dbb2a8980b001c3ca97f31d3b7b9431ea1d30f7c Mon Sep 17 00:00:00 2001 From: OliBomby Date: Mon, 1 May 2023 15:56:23 +0200 Subject: [PATCH 2755/2991] add test --- .../TestSceneTimelineHitObjectBlueprint.cs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTimelineHitObjectBlueprint.cs b/osu.Game.Tests/Visual/Editing/TestSceneTimelineHitObjectBlueprint.cs index 709d796e97..932e45b1a6 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneTimelineHitObjectBlueprint.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneTimelineHitObjectBlueprint.cs @@ -77,5 +77,38 @@ namespace osu.Game.Tests.Visual.Editing AddAssert("object has non-zero duration", () => EditorBeatmap.HitObjects.OfType().Single().Duration > 0); } + + [Test] + public void TestDisallowRepeatsOnZeroDurationObjects() + { + DragArea dragArea; + + AddStep("add zero length slider", () => + { + EditorBeatmap.Clear(); + EditorBeatmap.Add(new Slider + { + Position = new Vector2(256, 256), + StartTime = 2700 + }); + }); + + AddStep("hold down drag bar", () => + { + // distinguishes between the actual drag bar and its "underlay shadow". + dragArea = this.ChildrenOfType().Single(bar => bar.HandlePositionalInput); + InputManager.MoveMouseTo(dragArea); + InputManager.PressButton(MouseButton.Left); + }); + + AddStep("try to extend drag bar", () => + { + var blueprint = this.ChildrenOfType().Single(); + InputManager.MoveMouseTo(blueprint.SelectionQuad.TopLeft + new Vector2(100, 0)); + InputManager.ReleaseButton(MouseButton.Left); + }); + + AddAssert("object has zero repeats", () => EditorBeatmap.HitObjects.OfType().Single().RepeatCount == 0); + } } } From 8c21fddb5e1d98a0158e664b44b0c7331c2338f7 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Mon, 1 May 2023 16:53:38 +0200 Subject: [PATCH 2756/2991] remove all redundancies from encoded control points --- .../Beatmaps/Formats/LegacyBeatmapEncoder.cs | 72 ++++++++++++++----- 1 file changed, 54 insertions(+), 18 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 343dd7b082..6b228a56a1 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Text; @@ -170,6 +171,24 @@ namespace osu.Game.Beatmaps.Formats writer.WriteLine(FormattableString.Invariant($"{(int)LegacyEventType.Break},{b.StartTime},{b.EndTime}")); } + private struct LegacyControlPointProperties + { + internal double SliderVelocity { get; set; } + internal int TimingSignature { get; init; } + internal int SampleBank { get; init; } + internal int CustomSampleBank { get; init; } + internal int SampleVolume { get; init; } + internal LegacyEffectFlags EffectFlags { get; init; } + + internal bool IsRedundant(LegacyControlPointProperties other) => + SliderVelocity == other.SliderVelocity && + TimingSignature == other.TimingSignature && + SampleBank == other.SampleBank && + CustomSampleBank == other.CustomSampleBank && + SampleVolume == other.SampleVolume && + EffectFlags == other.EffectFlags; + } + private void handleControlPoints(TextWriter writer) { var legacyControlPoints = new LegacyControlPointInfo(); @@ -195,41 +214,44 @@ namespace osu.Game.Beatmaps.Formats legacyControlPoints.Add(point.Time, new DifficultyControlPoint { SliderVelocity = point.ScrollSpeed }); } - int lastCustomSampleIndex = 0; + LegacyControlPointProperties lastControlPointProperties = new LegacyControlPointProperties(); foreach (var group in legacyControlPoints.Groups) { var groupTimingPoint = group.ControlPoints.OfType().FirstOrDefault(); + var controlPointProperties = getLegacyControlPointProperties(group, groupTimingPoint != null); // If the group contains a timing control point, it needs to be output separately. if (groupTimingPoint != null) { writer.Write(FormattableString.Invariant($"{groupTimingPoint.Time},")); writer.Write(FormattableString.Invariant($"{groupTimingPoint.BeatLength},")); - outputControlPointAt(groupTimingPoint.Time, true); + outputControlPointAt(controlPointProperties, true); + lastControlPointProperties = controlPointProperties; + lastControlPointProperties.SliderVelocity = 1; } + if (controlPointProperties.IsRedundant(lastControlPointProperties)) + continue; + // Output any remaining effects as secondary non-timing control point. - var difficultyPoint = legacyControlPoints.DifficultyPointAt(group.Time); writer.Write(FormattableString.Invariant($"{group.Time},")); - writer.Write(FormattableString.Invariant($"{-100 / difficultyPoint.SliderVelocity},")); - outputControlPointAt(group.Time, false); + writer.Write(FormattableString.Invariant($"{-100 / controlPointProperties.SliderVelocity},")); + outputControlPointAt(controlPointProperties, false); + lastControlPointProperties = controlPointProperties; } - void outputControlPointAt(double time, bool isTimingPoint) + LegacyControlPointProperties getLegacyControlPointProperties(ControlPointGroup group, bool updateSampleBank) { + double time = group.Time; + var timingPoint = legacyControlPoints.TimingPointAt(time); + var difficultyPoint = legacyControlPoints.DifficultyPointAt(time); var samplePoint = legacyControlPoints.SamplePointAt(time); var effectPoint = legacyControlPoints.EffectPointAt(time); - var timingPoint = legacyControlPoints.TimingPointAt(time); // Apply the control point to a hit sample to uncover legacy properties (e.g. suffix) HitSampleInfo tempHitSample = samplePoint.ApplyTo(new ConvertHitObjectParser.LegacyHitSampleInfo(string.Empty)); - - // Inherit the previous sample bank if the current sample bank is not set int customSampleBank = toLegacyCustomSampleBank(tempHitSample); - if (customSampleBank < 0) - customSampleBank = lastCustomSampleIndex; - lastCustomSampleIndex = customSampleBank; // Convert effect flags to the legacy format LegacyEffectFlags effectFlags = LegacyEffectFlags.None; @@ -238,12 +260,26 @@ namespace osu.Game.Beatmaps.Formats if (timingPoint.OmitFirstBarLine) effectFlags |= LegacyEffectFlags.OmitFirstBarLine; - writer.Write(FormattableString.Invariant($"{timingPoint.TimeSignature.Numerator},")); - writer.Write(FormattableString.Invariant($"{(int)toLegacySampleBank(tempHitSample.Bank)},")); - writer.Write(FormattableString.Invariant($"{customSampleBank},")); - writer.Write(FormattableString.Invariant($"{tempHitSample.Volume},")); - writer.Write(FormattableString.Invariant($"{(isTimingPoint ? '1' : '0')},")); - writer.Write(FormattableString.Invariant($"{(int)effectFlags}")); + return new LegacyControlPointProperties + { + SliderVelocity = difficultyPoint.SliderVelocity, + TimingSignature = timingPoint.TimeSignature.Numerator, + SampleBank = updateSampleBank ? (int)toLegacySampleBank(tempHitSample.Bank) : lastControlPointProperties.SampleBank, + // Inherit the previous custom sample bank if the current custom sample bank is not set + CustomSampleBank = customSampleBank >= 0 ? customSampleBank : lastControlPointProperties.CustomSampleBank, + SampleVolume = tempHitSample.Volume, + EffectFlags = effectFlags + }; + } + + void outputControlPointAt(LegacyControlPointProperties controlPoint, bool isTimingPoint) + { + writer.Write(FormattableString.Invariant($"{controlPoint.TimingSignature.ToString(CultureInfo.InvariantCulture)},")); + writer.Write(FormattableString.Invariant($"{controlPoint.SampleBank.ToString(CultureInfo.InvariantCulture)},")); + writer.Write(FormattableString.Invariant($"{controlPoint.CustomSampleBank.ToString(CultureInfo.InvariantCulture)},")); + writer.Write(FormattableString.Invariant($"{controlPoint.SampleVolume.ToString(CultureInfo.InvariantCulture)},")); + writer.Write(FormattableString.Invariant($"{(isTimingPoint ? "1" : "0")},")); + writer.Write(FormattableString.Invariant($"{((int)controlPoint.EffectFlags).ToString(CultureInfo.InvariantCulture)}")); writer.WriteLine(); } From 8ab3a87b13b7a7d0efce52d8db67b2e8af9f6a81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 1 May 2023 17:13:09 +0200 Subject: [PATCH 2757/2991] Add failing test case covering online ID reset on save This test scene passes at e58e1151f3c610d8019e1f1e408a1cb55d204c24 and fails at current master, due to an inadvertent regression caused by e72f103c1759e61c3afa7080f962c639265996c3. As it turns out, the online lookup flow that was causing UI thread freezes when saving beatmaps in the editor, was also responsible for resetting the online ID of locally-modified beatmaps if online lookup failed. --- ...TestSceneLocallyModifyingOnlineBeatmaps.cs | 56 +++++++++++++++++++ .../Tests/Visual/EditorSavingTestScene.cs | 27 ++++++++- 2 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 osu.Game.Tests/Visual/Editing/TestSceneLocallyModifyingOnlineBeatmaps.cs diff --git a/osu.Game.Tests/Visual/Editing/TestSceneLocallyModifyingOnlineBeatmaps.cs b/osu.Game.Tests/Visual/Editing/TestSceneLocallyModifyingOnlineBeatmaps.cs new file mode 100644 index 0000000000..be9bbcfdd8 --- /dev/null +++ b/osu.Game.Tests/Visual/Editing/TestSceneLocallyModifyingOnlineBeatmaps.cs @@ -0,0 +1,56 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using System.Net; +using NUnit.Framework; +using osu.Framework.Extensions; +using osu.Game.Database; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Tests.Resources; + +namespace osu.Game.Tests.Visual.Editing +{ + public partial class TestSceneLocallyModifyingOnlineBeatmaps : EditorSavingTestScene + { + private DummyAPIAccess dummyAPI => (DummyAPIAccess)API; + + public override void SetUpSteps() + { + CreateInitialBeatmap = () => + { + var importedSet = Game.BeatmapManager.Import(new ImportTask(TestResources.GetTestBeatmapForImport())).GetResultSafely(); + return Game.BeatmapManager.GetWorkingBeatmap(importedSet!.Value.Beatmaps.First()); + }; + + base.SetUpSteps(); + } + + [Test] + public void TestLocallyModifyingOnlineBeatmap() + { + AddAssert("editor beatmap has online ID", () => EditorBeatmap.BeatmapInfo.OnlineID, () => Is.GreaterThan(0)); + + AddStep("delete first hitobject", () => EditorBeatmap.RemoveAt(0)); + + AddStep("mock online lookup failure", () => + { + dummyAPI.HandleRequest = req => + { + if (req is GetBeatmapRequest) + { + req.TriggerFailure(new APIException("Beatmap not found", new WebException("NotFound"))); + return true; + } + + return false; + }; + }); + SaveEditor(); + + ReloadEditorToSameBeatmap(); + AddAssert("editor beatmap online ID reset", () => EditorBeatmap.BeatmapInfo.OnlineID, () => Is.EqualTo(-1)); + } + } +} diff --git a/osu.Game/Tests/Visual/EditorSavingTestScene.cs b/osu.Game/Tests/Visual/EditorSavingTestScene.cs index cd9e9e1d52..78188d7cf7 100644 --- a/osu.Game/Tests/Visual/EditorSavingTestScene.cs +++ b/osu.Game/Tests/Visual/EditorSavingTestScene.cs @@ -3,9 +3,12 @@ #nullable disable +using System; using System.Linq; +using JetBrains.Annotations; using osu.Framework.Input; using osu.Framework.Testing; +using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Setup; @@ -24,18 +27,27 @@ namespace osu.Game.Tests.Visual protected EditorBeatmap EditorBeatmap => (EditorBeatmap)Editor.Dependencies.Get(typeof(EditorBeatmap)); + [CanBeNull] + protected Func CreateInitialBeatmap { get; set; } + [SetUpSteps] public override void SetUpSteps() { base.SetUpSteps(); - AddStep("set default beatmap", () => Game.Beatmap.SetDefault()); + if (CreateInitialBeatmap == null) + AddStep("set default beatmap", () => Game.Beatmap.SetDefault()); + else + { + AddStep("set test beatmap", () => Game.Beatmap.Value = CreateInitialBeatmap?.Invoke()); + } PushAndConfirm(() => new EditorLoader()); AddUntilStep("wait for editor load", () => Editor?.IsLoaded == true); - AddUntilStep("wait for metadata screen load", () => Editor.ChildrenOfType().FirstOrDefault()?.IsLoaded == true); + if (CreateInitialBeatmap == null) + AddUntilStep("wait for metadata screen load", () => Editor.ChildrenOfType().FirstOrDefault()?.IsLoaded == true); // We intentionally switch away from the metadata screen, else there is a feedback loop with the textbox handling which causes metadata changes below to get overwritten. @@ -50,6 +62,14 @@ namespace osu.Game.Tests.Visual protected void ReloadEditorToSameBeatmap() { + Guid beatmapSetGuid = Guid.Empty; + Guid beatmapGuid = Guid.Empty; + + AddStep("Store beatmap GUIDs", () => + { + beatmapSetGuid = EditorBeatmap.BeatmapInfo.BeatmapSet!.ID; + beatmapGuid = EditorBeatmap.BeatmapInfo.ID; + }); AddStep("Exit", () => InputManager.Key(Key.Escape)); AddUntilStep("Wait for main menu", () => Game.ScreenStack.CurrentScreen is MainMenu); @@ -59,7 +79,8 @@ namespace osu.Game.Tests.Visual PushAndConfirm(() => songSelect = new PlaySongSelect()); AddUntilStep("wait for carousel load", () => songSelect.BeatmapSetsLoaded); - AddUntilStep("Wait for beatmap selected", () => !Game.Beatmap.IsDefault); + AddStep("Present same beatmap", () => Game.PresentBeatmap(Game.BeatmapManager.QueryBeatmapSet(set => set.ID == beatmapSetGuid)!.Value, beatmap => beatmap.ID == beatmapGuid)); + AddUntilStep("Wait for beatmap selected", () => Game.Beatmap.Value.BeatmapInfo.ID == beatmapGuid); AddStep("Open options", () => InputManager.Key(Key.F3)); AddStep("Enter editor", () => InputManager.Key(Key.Number5)); From f470b2c9cc379b24be498b4865f0f82f6fa41a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 1 May 2023 17:24:58 +0200 Subject: [PATCH 2758/2991] Always reset online info when saving local beatmap --- osu.Game/Beatmaps/BeatmapManager.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 6af6a25579..3f2ab9b391 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -440,6 +440,7 @@ namespace osu.Game.Beatmaps beatmapInfo.LastLocalUpdate = DateTimeOffset.Now; beatmapInfo.Status = BeatmapOnlineStatus.LocallyModified; + beatmapInfo.ResetOnlineInfo(); AddFile(setInfo, stream, createBeatmapFilenameFromMetadata(beatmapInfo)); From 1fb4c814f4446eefa768e9f2f0f73af0334c64f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 1 May 2023 17:31:55 +0200 Subject: [PATCH 2759/2991] Remove no longer needed API call mocking The online ID will be reset unconditionally after any local change is made to any beatmap. That behaviour no longer depends on online lookups succeeding or failing. This may change at a later date when beatmap submission is integrated into lazer - the idea is that online IDs would get re-populated on local beatmaps once they are submitted to web. --- ...TestSceneLocallyModifyingOnlineBeatmaps.cs | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneLocallyModifyingOnlineBeatmaps.cs b/osu.Game.Tests/Visual/Editing/TestSceneLocallyModifyingOnlineBeatmaps.cs index be9bbcfdd8..7f9a69833c 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneLocallyModifyingOnlineBeatmaps.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneLocallyModifyingOnlineBeatmaps.cs @@ -2,20 +2,15 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; -using System.Net; using NUnit.Framework; using osu.Framework.Extensions; using osu.Game.Database; -using osu.Game.Online.API; -using osu.Game.Online.API.Requests; using osu.Game.Tests.Resources; namespace osu.Game.Tests.Visual.Editing { public partial class TestSceneLocallyModifyingOnlineBeatmaps : EditorSavingTestScene { - private DummyAPIAccess dummyAPI => (DummyAPIAccess)API; - public override void SetUpSteps() { CreateInitialBeatmap = () => @@ -33,20 +28,6 @@ namespace osu.Game.Tests.Visual.Editing AddAssert("editor beatmap has online ID", () => EditorBeatmap.BeatmapInfo.OnlineID, () => Is.GreaterThan(0)); AddStep("delete first hitobject", () => EditorBeatmap.RemoveAt(0)); - - AddStep("mock online lookup failure", () => - { - dummyAPI.HandleRequest = req => - { - if (req is GetBeatmapRequest) - { - req.TriggerFailure(new APIException("Beatmap not found", new WebException("NotFound"))); - return true; - } - - return false; - }; - }); SaveEditor(); ReloadEditorToSameBeatmap(); From cf5211aec922852673c77dcedae081c89ca005e1 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Mon, 1 May 2023 19:22:52 +0200 Subject: [PATCH 2760/2991] Enable current distance snap when exactly on a hit object --- osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index aa47b4f424..09c6af3820 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.Edit private (HitObject before, HitObject after)? getObjectsOnEitherSideOfCurrentTime() { - HitObject lastBefore = Playfield.HitObjectContainer.AliveObjects.LastOrDefault(h => h.HitObject.StartTime <= EditorClock.CurrentTime)?.HitObject; + HitObject lastBefore = Playfield.HitObjectContainer.AliveObjects.LastOrDefault(h => h.HitObject.StartTime < EditorClock.CurrentTime)?.HitObject; if (lastBefore == null) return null; From 436ebdcfcb1d556c6bad05dea472aa9f4f41959a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 1 May 2023 19:06:25 +0200 Subject: [PATCH 2761/2991] Fix beatmap leaderboard test failure Because the online info reset (which includes online ID reset) was happening after encoding, `TestSceneBeatmapLeaderboard.TestLocalScoresDisplayOnBeatmapEdit()` started failing, as the hash no longer matched expectations after the first save of the map. --- osu.Game/Beatmaps/BeatmapManager.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 3f2ab9b391..ae62564b0d 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -415,6 +415,13 @@ namespace osu.Game.Beatmaps // All changes to metadata are made in the provided beatmapInfo, so this should be copied to the `IBeatmap` before encoding. beatmapContent.BeatmapInfo = beatmapInfo; + // Since now this is a locally-modified beatmap, we also set all relevant flags to indicate this. + // Importantly, the `ResetOnlineInfo()` call must happen before encoding, as online ID is encoded into the `.osu` file, + // which influences the beatmap checksums. + beatmapInfo.LastLocalUpdate = DateTimeOffset.Now; + beatmapInfo.Status = BeatmapOnlineStatus.LocallyModified; + beatmapInfo.ResetOnlineInfo(); + using (var stream = new MemoryStream()) { using (var sw = new StreamWriter(stream, Encoding.UTF8, 1024, true)) @@ -438,10 +445,6 @@ namespace osu.Game.Beatmaps beatmapInfo.MD5Hash = stream.ComputeMD5Hash(); beatmapInfo.Hash = stream.ComputeSHA2Hash(); - beatmapInfo.LastLocalUpdate = DateTimeOffset.Now; - beatmapInfo.Status = BeatmapOnlineStatus.LocallyModified; - beatmapInfo.ResetOnlineInfo(); - AddFile(setInfo, stream, createBeatmapFilenameFromMetadata(beatmapInfo)); updateHashAndMarkDirty(setInfo); From 87db89114368d55a4029ff45109a0a9b9002c268 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 13:12:08 +0900 Subject: [PATCH 2762/2991] Adjust test to reliabily fail --- .../Visual/Editing/TestSceneTimelineHitObjectBlueprint.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneTimelineHitObjectBlueprint.cs b/osu.Game.Tests/Visual/Editing/TestSceneTimelineHitObjectBlueprint.cs index 932e45b1a6..08e036248b 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneTimelineHitObjectBlueprint.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneTimelineHitObjectBlueprint.cs @@ -105,9 +105,10 @@ namespace osu.Game.Tests.Visual.Editing { var blueprint = this.ChildrenOfType().Single(); InputManager.MoveMouseTo(blueprint.SelectionQuad.TopLeft + new Vector2(100, 0)); - InputManager.ReleaseButton(MouseButton.Left); }); + AddStep("release button", () => InputManager.PressButton(MouseButton.Left)); + AddAssert("object has zero repeats", () => EditorBeatmap.HitObjects.OfType().Single().RepeatCount == 0); } } From 63890ef6feb9b8fffd28152545aaf88d0aefe9ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 13:24:19 +0900 Subject: [PATCH 2763/2991] Fix audio offset tooltip potentially showing "-0 ms" Closes https://github.com/ppy/osu/issues/23339. --- osu.Game/Graphics/UserInterface/TimeSlider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/TimeSlider.cs b/osu.Game/Graphics/UserInterface/TimeSlider.cs index e4058827f3..e6e7ae9305 100644 --- a/osu.Game/Graphics/UserInterface/TimeSlider.cs +++ b/osu.Game/Graphics/UserInterface/TimeSlider.cs @@ -12,6 +12,6 @@ namespace osu.Game.Graphics.UserInterface /// public partial class TimeSlider : RoundedSliderBar { - public override LocalisableString TooltipText => $"{Current.Value:N0} ms"; + public override LocalisableString TooltipText => $"{base.TooltipText} ms"; } } From e808e7316b320c3b9f4105ed2f79081bf8203283 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 13:29:30 +0900 Subject: [PATCH 2764/2991] Mark delegate value unused and add comment to avoid future regression --- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 46d3620c9c..38ae8c68cb 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -242,7 +242,7 @@ namespace osu.Game.Overlays.Mods if (AllowCustomisation) ((IBindable>)modSettingsArea.SelectedMods).BindTo(SelectedMods); - SelectedMods.BindValueChanged(val => + SelectedMods.BindValueChanged(_ => { updateMultiplier(); updateFromExternalSelection(); @@ -252,6 +252,10 @@ namespace osu.Game.Overlays.Mods if (AllowCustomisation) { + // Importantly, use SelectedMods.Value here (and not the ValueChanged NewValue) as the latter can + // potentially be stale, due to complexities in the way change trackers work. + // + // See https://github.com/ppy/osu/pull/23284#issuecomment-1529056988 modSettingChangeTracker = new ModSettingChangeTracker(SelectedMods.Value); modSettingChangeTracker.SettingChanged += _ => updateMultiplier(); } From 37a5dde8592c48edebdc3ffaa36da96da75d226c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 13:47:49 +0900 Subject: [PATCH 2765/2991] Fix `BeatmapAttributeText` not supporting unicode artist/title --- osu.Game/Skinning/Components/BeatmapAttributeText.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/Components/BeatmapAttributeText.cs b/osu.Game/Skinning/Components/BeatmapAttributeText.cs index 2c16a67cac..6523039a3f 100644 --- a/osu.Game/Skinning/Components/BeatmapAttributeText.cs +++ b/osu.Game/Skinning/Components/BeatmapAttributeText.cs @@ -84,8 +84,8 @@ namespace osu.Game.Skinning.Components private void updateBeatmapContent(WorkingBeatmap workingBeatmap) { - valueDictionary[BeatmapAttribute.Title] = workingBeatmap.BeatmapInfo.Metadata.Title; - valueDictionary[BeatmapAttribute.Artist] = workingBeatmap.BeatmapInfo.Metadata.Artist; + valueDictionary[BeatmapAttribute.Title] = new RomanisableString(workingBeatmap.BeatmapInfo.Metadata.TitleUnicode, workingBeatmap.BeatmapInfo.Metadata.Title); + valueDictionary[BeatmapAttribute.Artist] = new RomanisableString(workingBeatmap.BeatmapInfo.Metadata.ArtistUnicode, workingBeatmap.BeatmapInfo.Metadata.Artist); valueDictionary[BeatmapAttribute.DifficultyName] = workingBeatmap.BeatmapInfo.DifficultyName; valueDictionary[BeatmapAttribute.Creator] = workingBeatmap.BeatmapInfo.Metadata.Author.Username; valueDictionary[BeatmapAttribute.Length] = TimeSpan.FromMilliseconds(workingBeatmap.BeatmapInfo.Length).ToFormattedDuration(); From ad40099e3280d0929ce13b2adca488354bef9f81 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 14:00:52 +0900 Subject: [PATCH 2766/2991] Ensure negative sign is only applied when the post-rounded result is negative --- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index 0c36d73085..0e26029ffa 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -97,7 +97,9 @@ namespace osu.Game.Graphics.UserInterface // Find the number of significant digits (we could have less than 5 after normalize()) int significantDigits = FormatUtils.FindPrecision(decimalPrecision); - return floatValue.ToString($"N{significantDigits}"); + string negativeSign = Math.Round(floatValue, significantDigits) < 0 ? "-" : string.Empty; + + return $"{negativeSign}{Math.Abs(floatValue).ToString($"N{significantDigits}")}"; } /// From 736be6a73ba2c9ff5332b39f828f0310a8d76851 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 14:11:16 +0900 Subject: [PATCH 2767/2991] Refactor slightly for readability --- osu.Game/Overlays/Music/PlaylistItem.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 4a39cc06c8..90fdfd0491 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -56,7 +56,7 @@ namespace osu.Game.Overlays.Music var artist = new RomanisableString(metadata.ArtistUnicode, metadata.Artist); titlePart = text.AddText(title, sprite => sprite.Font = OsuFont.GetFont(weight: FontWeight.Regular)); - titlePart.DrawablePartsRecreated += _ => updateSelectionState(SelectedSet.Value, instant: true); + titlePart.DrawablePartsRecreated += _ => updateSelectionState(SelectedSet.Value, applyImmediately: true); text.AddText(@" "); // to separate the title from the artist. text.AddText(artist, sprite => @@ -66,24 +66,25 @@ namespace osu.Game.Overlays.Music sprite.Padding = new MarginPadding { Top = 1 }; }); - SelectedSet.BindValueChanged(set => updateSelectionState(set.NewValue, instant: false)); - updateSelectionState(SelectedSet.Value, instant: true); + SelectedSet.BindValueChanged(set => updateSelectionState(set.NewValue)); + updateSelectionState(SelectedSet.Value, applyImmediately: true); }); } private bool selected; - private void updateSelectionState(Live selectedSet, bool instant) + private void updateSelectionState(Live selectedSet, bool applyImmediately = false) { - bool newSelected = selectedSet?.Equals(Model) == true; + bool wasSelected = selected; + selected = selectedSet?.Equals(Model) == true; - if (newSelected == selected && !instant) // instant updates should forcibly set correct state regardless of previous state. + // Immediate updates should forcibly set correct state regardless of previous state. + // This ensures that the initial state is correctly applied. + if (wasSelected == selected && !applyImmediately) return; - selected = newSelected; - foreach (Drawable s in titlePart.Drawables) - s.FadeColour(selected ? colours.Yellow : Color4.White, instant ? 0 : FADE_DURATION); + s.FadeColour(selected ? colours.Yellow : Color4.White, applyImmediately ? 0 : FADE_DURATION); } protected override Drawable CreateContent() => new DelayedLoadWrapper(text = new OsuTextFlowContainer From 7a840e1d8227a3e2dd5073afd27305c47dc7f494 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 14:29:26 +0900 Subject: [PATCH 2768/2991] Remove unnecessary `TransferValue` spec --- osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 0515e8dc97..ad47039579 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -171,7 +171,6 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics Current = scalingBackgroundDim, KeyboardStep = 0.01f, DisplayAsPercentage = true, - TransferValueOnCommit = false }, } }, From ab4f66fad331aa7d048f8f1365ec12f25071098b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 14:31:39 +0900 Subject: [PATCH 2769/2991] Minor readability refactors --- osu.Game/Graphics/Containers/ScalingContainer.cs | 2 +- .../Settings/Sections/Graphics/LayoutSettings.cs | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/Containers/ScalingContainer.cs b/osu.Game/Graphics/Containers/ScalingContainer.cs index bd52c8bb32..84eb382d34 100644 --- a/osu.Game/Graphics/Containers/ScalingContainer.cs +++ b/osu.Game/Graphics/Containers/ScalingContainer.cs @@ -155,7 +155,7 @@ namespace osu.Game.Graphics.Containers private bool requiresBackgroundVisible => (scalingMode.Value == ScalingMode.Everything || scalingMode.Value == ScalingMode.ExcludeOverlays) && (sizeX.Value != 1 || sizeY.Value != 1) - && scalingMenuBackgroundDim.Value != 1f; + && scalingMenuBackgroundDim.Value < 1; private void updateSize() { diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index ad47039579..2e26d15105 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -230,11 +230,12 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics if (s == dimSlider) { s.CanBeShown.Value = scalingMode.Value == ScalingMode.Everything || scalingMode.Value == ScalingMode.ExcludeOverlays; - return; } - - s.TransferValueOnCommit = scalingMode.Value == ScalingMode.Everything; - s.CanBeShown.Value = scalingMode.Value != ScalingMode.Off; + else + { + s.TransferValueOnCommit = scalingMode.Value == ScalingMode.Everything; + s.CanBeShown.Value = scalingMode.Value != ScalingMode.Off; + } }); } } From 57f48e070359f65100e33838091ee72f28d6cc68 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 14:33:57 +0900 Subject: [PATCH 2770/2991] Start colour black to ensure initial appear transition doesn't look silly --- osu.Game/Graphics/Containers/ScalingContainer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Graphics/Containers/ScalingContainer.cs b/osu.Game/Graphics/Containers/ScalingContainer.cs index 84eb382d34..c47aba2f0c 100644 --- a/osu.Game/Graphics/Containers/ScalingContainer.cs +++ b/osu.Game/Graphics/Containers/ScalingContainer.cs @@ -15,6 +15,7 @@ using osu.Game.Configuration; using osu.Game.Screens; using osu.Game.Screens.Backgrounds; using osuTK; +using osuTK.Graphics; namespace osu.Game.Graphics.Containers { @@ -169,6 +170,7 @@ namespace osu.Game.Graphics.Containers AddInternal(backgroundStack = new BackgroundScreenStack { Alpha = 0, + Colour = Color4.Black, Depth = float.MaxValue }); From 8a536c1cdb75496ad56b056baa83fc2d14376deb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 15:09:24 +0900 Subject: [PATCH 2771/2991] Fix non-block namespace usage --- .../Timeline/HitObjectPointPiece.cs | 83 ++++++++++--------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs index f7854705a4..4b357d3a62 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/HitObjectPointPiece.cs @@ -11,51 +11,52 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osuTK.Graphics; -namespace osu.Game.Screens.Edit.Compose.Components.Timeline; - -public partial class HitObjectPointPiece : CircularContainer +namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - protected OsuSpriteText Label { get; private set; } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) + public partial class HitObjectPointPiece : CircularContainer { - AutoSizeAxes = Axes.Both; + protected OsuSpriteText Label { get; private set; } - Color4 colour = GetRepresentingColour(colours); - - InternalChildren = new Drawable[] + [BackgroundDependencyLoader] + private void load(OsuColour colours) { - new Container - { - AutoSizeAxes = Axes.X, - Height = 16, - Masking = true, - CornerRadius = 8, - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Children = new Drawable[] - { - new Box - { - Colour = colour, - RelativeSizeAxes = Axes.Both, - }, - Label = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Padding = new MarginPadding(5), - Font = OsuFont.Default.With(size: 12, weight: FontWeight.SemiBold), - Colour = colours.B5, - } - } - }, - }; - } + AutoSizeAxes = Axes.Both; - protected virtual Color4 GetRepresentingColour(OsuColour colours) - { - return colours.Yellow; + Color4 colour = GetRepresentingColour(colours); + + InternalChildren = new Drawable[] + { + new Container + { + AutoSizeAxes = Axes.X, + Height = 16, + Masking = true, + CornerRadius = 8, + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Children = new Drawable[] + { + new Box + { + Colour = colour, + RelativeSizeAxes = Axes.Both, + }, + Label = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Padding = new MarginPadding(5), + Font = OsuFont.Default.With(size: 12, weight: FontWeight.SemiBold), + Colour = colours.B5, + } + } + }, + }; + } + + protected virtual Color4 GetRepresentingColour(OsuColour colours) + { + return colours.Yellow; + } } } From 67f83f246b1c65c62416a24375ef580139d046dc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 15:36:01 +0900 Subject: [PATCH 2772/2991] Add more padding around playfield in editor to avoid overlap with tool areas Closes #23130. --- osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs | 9 +++++++-- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 12 ++++++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 7a70257f3a..ff1e208186 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -13,8 +13,8 @@ using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; -using osu.Framework.Utils; using osu.Framework.Input.Events; +using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; using osu.Game.Input.Bindings; @@ -62,7 +62,12 @@ namespace osu.Game.Rulesets.Osu.Edit private void load() { // Give a bit of breathing room around the playfield content. - PlayfieldContentContainer.Padding = new MarginPadding(10); + PlayfieldContentContainer.Padding = new MarginPadding + { + Vertical = 10, + Left = TOOLBOX_CONTRACTED_SIZE_LEFT + 10, + Right = TOOLBOX_CONTRACTED_SIZE_RIGHT + 10, + }; LayerBelowRuleset.AddRange(new Drawable[] { diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 653861c11c..e2dbd2acdc 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -116,6 +116,11 @@ namespace osu.Game.Rulesets.Edit PlayfieldContentContainer = new Container { Name = "Content", + Padding = new MarginPadding + { + Left = TOOLBOX_CONTRACTED_SIZE_LEFT, + Right = TOOLBOX_CONTRACTED_SIZE_RIGHT, + }, RelativeSizeAxes = Axes.Both, Children = new Drawable[] { @@ -138,7 +143,7 @@ namespace osu.Game.Rulesets.Edit Colour = colourProvider.Background5, RelativeSizeAxes = Axes.Both, }, - LeftToolbox = new ExpandingToolboxContainer(60, 200) + LeftToolbox = new ExpandingToolboxContainer(TOOLBOX_CONTRACTED_SIZE_LEFT, 200) { Children = new Drawable[] { @@ -173,7 +178,7 @@ namespace osu.Game.Rulesets.Edit Colour = colourProvider.Background5, RelativeSizeAxes = Axes.Both, }, - RightToolbox = new ExpandingToolboxContainer(130, 250) + RightToolbox = new ExpandingToolboxContainer(TOOLBOX_CONTRACTED_SIZE_RIGHT, 250) { Child = new EditorToolboxGroup("inspector") { @@ -450,6 +455,9 @@ namespace osu.Game.Rulesets.Edit [Cached] public abstract partial class HitObjectComposer : CompositeDrawable, IPositionSnapProvider { + public const float TOOLBOX_CONTRACTED_SIZE_LEFT = 60; + public const float TOOLBOX_CONTRACTED_SIZE_RIGHT = 130; + public readonly Ruleset Ruleset; protected HitObjectComposer(Ruleset ruleset) From c2ad8c23201814a3ce3103584e2bacc51c30b020 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Tue, 2 May 2023 08:41:30 +0200 Subject: [PATCH 2773/2991] Fix comment 1 osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs Co-authored-by: Dean Herbert --- osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs b/osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs index 5de7d348c5..c587654cda 100644 --- a/osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs +++ b/osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Objects.Types public interface IHasGenerateTicks { /// - /// Whether or not slider ticks should be generated at this control point. + /// Whether or not slider ticks should be generated by this object. /// This exists for backwards compatibility with maps that abuse NaN slider velocity behavior on osu!stable (e.g. /b/2628991). /// public bool GenerateTicks { get; set; } From 2e018c8b0696b2394465ef31d1f49aad7c514627 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Tue, 2 May 2023 08:41:47 +0200 Subject: [PATCH 2774/2991] Fix comment 2 osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs Co-authored-by: Dean Herbert --- osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs b/osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs index c587654cda..3ac8b8a086 100644 --- a/osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs +++ b/osu.Game/Rulesets/Objects/Types/IHasGenerateTicks.cs @@ -4,7 +4,7 @@ namespace osu.Game.Rulesets.Objects.Types { /// - /// A type of which may or may not generate ticks. + /// A type of which explicitly specifies whether it should generate ticks. /// public interface IHasGenerateTicks { From bd72c67d68aa3bc4bc18f70cd0fd6a4c8c9eb9d2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 15:47:35 +0900 Subject: [PATCH 2775/2991] Increase the rate of slider ball fade on argon skins to match other implementations --- osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderBall.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderBall.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderBall.cs index d6ce793c7e..461b4a3b45 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderBall.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderBall.cs @@ -98,7 +98,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime)) { - this.FadeOut(duration, Easing.OutQuint); + // intentionally pile on an extra FadeOut to make it happen much faster + this.FadeOut(duration / 4, Easing.OutQuint); icon.ScaleTo(defaultIconScale * icon_scale, duration, Easing.OutQuint); } } From e3c51b96526223674cada703130544646b768f97 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 16:26:56 +0900 Subject: [PATCH 2776/2991] Add ability to toggle snaking in slider test scene --- .../TestSceneSlider.cs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs index 1e9f931b74..4ad78a3190 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs @@ -15,6 +15,10 @@ using osuTK.Graphics; using osu.Game.Rulesets.Mods; using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Extensions.ObjectExtensions; +using osu.Framework.Testing; using osu.Game.Beatmaps.Legacy; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; @@ -22,6 +26,7 @@ using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Osu.Configuration; namespace osu.Game.Rulesets.Osu.Tests { @@ -30,6 +35,27 @@ namespace osu.Game.Rulesets.Osu.Tests { private int depthIndex; + private readonly BindableBool snakingIn = new BindableBool(); + private readonly BindableBool snakingOut = new BindableBool(); + + [SetUpSteps] + public void SetUpSteps() + { + AddToggleStep("toggle snaking", v => + { + snakingIn.Value = v; + snakingOut.Value = v; + }); + } + + [BackgroundDependencyLoader] + private void load() + { + var config = (OsuRulesetConfigManager)RulesetConfigs.GetConfigFor(Ruleset.Value.CreateInstance()).AsNonNull(); + config.BindWith(OsuRulesetSetting.SnakingInSliders, snakingIn); + config.BindWith(OsuRulesetSetting.SnakingOutSliders, snakingOut); + } + [Test] public void TestVariousSliders() { From 1a04be15c74b009bb9e329bf0d35b0031abe5328 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 16:27:17 +0900 Subject: [PATCH 2777/2991] Fix fade in delay for first slider end circle being incorrect when snaking disabled --- .../Objects/Drawables/DrawableSliderRepeat.cs | 11 +++++++---- .../Objects/Drawables/DrawableSliderTail.cs | 8 +++++++- osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs | 5 +---- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs index 3446d41fb4..d474db0526 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs @@ -87,12 +87,15 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void UpdateInitialTransforms() { + // When snaking in is enabled, the first end circle needs to be delayed until the snaking completes. + bool delayFadeIn = DrawableSlider.SliderBody!.SnakingIn.Value && HitObject.RepeatIndex == 0; + animDuration = Math.Min(300, HitObject.SpanDuration); - this.Animate( - d => d.FadeIn(animDuration), - d => d.ScaleTo(0.5f).ScaleTo(1f, animDuration * 2, Easing.OutElasticHalf) - ); + this + .FadeOut() + .Delay(delayFadeIn ? Slider!.TimePreempt / 3f : 0) + .FadeIn(HitObject.RepeatIndex == 0 ? HitObject.TimeFadeIn : animDuration); } protected override void UpdateHitStateTransforms(ArmedState state) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs index 2c1b68e05a..da4feae242 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs @@ -91,7 +91,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { base.UpdateInitialTransforms(); - CirclePiece.FadeInFromZero(HitObject.TimeFadeIn); + // When snaking in is enabled, the first end circle needs to be delayed until the snaking completes. + bool delayFadeIn = DrawableSlider.SliderBody!.SnakingIn.Value && HitObject.RepeatIndex == 0; + + CirclePiece + .FadeOut() + .Delay(delayFadeIn ? Slider!.TimePreempt / 3f : 0) + .FadeIn(HitObject.TimeFadeIn); } protected override void UpdateHitStateTransforms(ArmedState state) diff --git a/osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs b/osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs index 35bec92354..b5374333c9 100644 --- a/osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs @@ -39,11 +39,8 @@ namespace osu.Game.Rulesets.Osu.Objects } else { - // taken from osu-stable - const float first_end_circle_preempt_adjust = 2 / 3f; - // The first end circle should fade in with the slider. - TimePreempt = (StartTime - slider.StartTime) + slider.TimePreempt * first_end_circle_preempt_adjust; + TimePreempt = (StartTime - slider.StartTime) + slider.TimePreempt; } } From a619812cab7f881c2968db977e2bb5322299b03e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 16:36:43 +0900 Subject: [PATCH 2778/2991] Fix nullability and remove extra preempt from `SliderEndCircle` calculation --- .../Objects/Drawables/DrawableSliderRepeat.cs | 4 ++-- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs | 4 ++-- osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs index d474db0526..fc4863f164 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs @@ -88,13 +88,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void UpdateInitialTransforms() { // When snaking in is enabled, the first end circle needs to be delayed until the snaking completes. - bool delayFadeIn = DrawableSlider.SliderBody!.SnakingIn.Value && HitObject.RepeatIndex == 0; + bool delayFadeIn = DrawableSlider.SliderBody?.SnakingIn.Value == true && HitObject.RepeatIndex == 0; animDuration = Math.Min(300, HitObject.SpanDuration); this .FadeOut() - .Delay(delayFadeIn ? Slider!.TimePreempt / 3f : 0) + .Delay(delayFadeIn ? (Slider?.TimePreempt ?? 0) / 3 : 0) .FadeIn(HitObject.RepeatIndex == 0 ? HitObject.TimeFadeIn : animDuration); } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs index da4feae242..d9501f7d58 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs @@ -92,11 +92,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables base.UpdateInitialTransforms(); // When snaking in is enabled, the first end circle needs to be delayed until the snaking completes. - bool delayFadeIn = DrawableSlider.SliderBody!.SnakingIn.Value && HitObject.RepeatIndex == 0; + bool delayFadeIn = DrawableSlider.SliderBody?.SnakingIn.Value == true && HitObject.RepeatIndex == 0; CirclePiece .FadeOut() - .Delay(delayFadeIn ? Slider!.TimePreempt / 3f : 0) + .Delay(delayFadeIn ? (Slider?.TimePreempt ?? 0) / 3 : 0) .FadeIn(HitObject.TimeFadeIn); } diff --git a/osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs b/osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs index b5374333c9..f52c3ab382 100644 --- a/osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Osu.Objects else { // The first end circle should fade in with the slider. - TimePreempt = (StartTime - slider.StartTime) + slider.TimePreempt; + TimePreempt += StartTime - slider.StartTime; } } From 414b80d44e78ee5495aa18ae3afd7661b9fe32a7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 17:00:54 +0900 Subject: [PATCH 2779/2991] Change flashlight depth in a more standard way --- osu.Game/Rulesets/Mods/ModFlashlight.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index 9527e8ab5d..215fc877dc 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -82,12 +82,12 @@ namespace osu.Game.Rulesets.Mods flashlight.RelativeSizeAxes = Axes.Both; flashlight.Colour = Color4.Black; + // Flashlight mods should always draw above any other mod adding overlays. + flashlight.Depth = float.MinValue; flashlight.Combo.BindTo(Combo); drawableRuleset.Overlays.Add(flashlight); - // Stop flashlight from being drawn underneath other mods that generate HitObjects. - drawableRuleset.Overlays.ChangeChildDepth(flashlight, float.MinValue); } protected abstract Flashlight CreateFlashlight(); From fb0e90913db89e8ffc80fc17056d8ed1f4cbfecc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 17:07:12 +0900 Subject: [PATCH 2780/2991] Ensure lifetime start is also updated when reverting judgements --- osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs index 0fc27c8f1d..bfc6c24fa5 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs @@ -111,7 +111,7 @@ namespace osu.Game.Rulesets.Osu.Mods BubbleDrawable? lastBubble = bubbleContainer.OfType().LastOrDefault(); lastBubble?.ClearTransforms(); - lastBubble?.Expire(); + lastBubble?.Expire(true); }; } From 7830711c8e97b83852f705dbad25d50cc71a1604 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 17:07:22 +0900 Subject: [PATCH 2781/2991] Tidy up various code quality issues in `OsuModBubbles` --- osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs | 22 ++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs index bfc6c24fa5..9ae38de7c9 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs @@ -165,15 +165,15 @@ namespace osu.Game.Rulesets.Osu.Mods ColourInfo colourDarker = DrawableOsuHitObject.AccentColour.Value.Darken(0.1f); // The absolute length of the bubble's animation, can be used in fractions for animations of partial length - double getAnimationDuration = 1700 + Math.Pow(FadeTime, 1.07f); + double duration = 1700 + Math.Pow(FadeTime, 1.07f); // Main bubble scaling based on combo this.FadeTo(1) - .ScaleTo(MaxSize, getAnimationDuration * 0.8f) + .ScaleTo(MaxSize, duration * 0.8f) .Then() // Pop at the end of the bubbles life time - .ScaleTo(MaxSize * 1.5f, getAnimationDuration * 0.2f, Easing.OutQuint) - .FadeOut(getAnimationDuration * 0.2f, Easing.OutCirc).Expire(); + .ScaleTo(MaxSize * 1.5f, duration * 0.2f, Easing.OutQuint) + .FadeOut(duration * 0.2f, Easing.OutCirc).Expire(); if (!DrawableOsuHitObject.IsHit) return; @@ -182,28 +182,28 @@ namespace osu.Game.Rulesets.Osu.Mods colourBox.FadeColour(colourDarker); - content.TransformTo(nameof(BorderColour), colourDarker, getAnimationDuration * 0.3f, Easing.OutQuint); + content.TransformTo(nameof(BorderColour), colourDarker, duration * 0.3f, Easing.OutQuint); // Ripple effect utilises the border to reduce drawable count - content.TransformTo(nameof(BorderThickness), 2f, getAnimationDuration * 0.3f, Easing.OutQuint) + content.TransformTo(nameof(BorderThickness), 2f, duration * 0.3f, Easing.OutQuint) // Avoids transparency overlap issues during the bubble "pop" .Then().Schedule(() => content.BorderThickness = 0); } - private Vector2 getPosition(DrawableOsuHitObject drawableOsuHitObject) + private Vector2 getPosition(DrawableOsuHitObject drawableObject) { - switch (drawableOsuHitObject) + switch (drawableObject) { // SliderHeads are derived from HitCircles, // so we must handle them before to avoid them using the wrong positioning logic case DrawableSliderHead: - return drawableOsuHitObject.HitObject.Position; + return drawableObject.HitObject.Position; // Using hitobject position will cause issues with HitCircle placement due to stack leniency. case DrawableHitCircle: - return drawableOsuHitObject.Position; + return drawableObject.Position; default: - return drawableOsuHitObject.HitObject.Position; + return drawableObject.HitObject.Position; } } } From e44672bdd5f4f11ae0d309c20df29271d4203f05 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 2 May 2023 17:08:49 +0900 Subject: [PATCH 2782/2991] Avoid using `Schedule` in transforms (doesn't handle rewind well) --- osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs index 9ae38de7c9..12e2090f89 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBubbles.cs @@ -185,8 +185,9 @@ namespace osu.Game.Rulesets.Osu.Mods content.TransformTo(nameof(BorderColour), colourDarker, duration * 0.3f, Easing.OutQuint); // Ripple effect utilises the border to reduce drawable count content.TransformTo(nameof(BorderThickness), 2f, duration * 0.3f, Easing.OutQuint) + .Then() // Avoids transparency overlap issues during the bubble "pop" - .Then().Schedule(() => content.BorderThickness = 0); + .TransformTo(nameof(BorderThickness), 0f); } private Vector2 getPosition(DrawableOsuHitObject drawableObject) From 8160d562640f4c3f40d8d4b01a68306f8177e31c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 2 May 2023 11:51:05 +0300 Subject: [PATCH 2783/2991] Update test shaders --- .../Resources/Shaders/sh_TestFragment.fs | 15 ++++--- .../Resources/Shaders/sh_TestVertex.vs | 42 ++++++++----------- 2 files changed, 27 insertions(+), 30 deletions(-) diff --git a/osu.Game.Tests/Resources/Shaders/sh_TestFragment.fs b/osu.Game.Tests/Resources/Shaders/sh_TestFragment.fs index c70ad751be..99b85d0502 100644 --- a/osu.Game.Tests/Resources/Shaders/sh_TestFragment.fs +++ b/osu.Game.Tests/Resources/Shaders/sh_TestFragment.fs @@ -1,11 +1,14 @@ -#include "sh_Utils.h" +#define HIGH_PRECISION_VERTEX -varying mediump vec2 v_TexCoord; -varying mediump vec4 v_TexRect; +#include "sh_Utils.h" +#include "sh_Masking.h" + +layout(location = 2) in highp vec2 v_TexCoord; + +layout(location = 0) out vec4 o_Colour; void main(void) { - float hueValue = v_TexCoord.x / (v_TexRect[2] - v_TexRect[0]); - gl_FragColor = hsv2rgb(vec4(hueValue, 1, 1, 1)); + highp float hueValue = v_TexCoord.x / (v_TexRect[2] - v_TexRect[0]); + o_Colour = getRoundedColor(hsv2rgb(vec4(hueValue, 1, 1, 1)), v_TexCoord); } - diff --git a/osu.Game.Tests/Resources/Shaders/sh_TestVertex.vs b/osu.Game.Tests/Resources/Shaders/sh_TestVertex.vs index 4485356fa4..505554bb33 100644 --- a/osu.Game.Tests/Resources/Shaders/sh_TestVertex.vs +++ b/osu.Game.Tests/Resources/Shaders/sh_TestVertex.vs @@ -1,31 +1,25 @@ -#include "sh_Utils.h" +layout(location = 0) in highp vec2 m_Position; +layout(location = 1) in lowp vec4 m_Colour; +layout(location = 2) in highp vec2 m_TexCoord; +layout(location = 3) in highp vec4 m_TexRect; +layout(location = 4) in mediump vec2 m_BlendRange; -attribute highp vec2 m_Position; -attribute lowp vec4 m_Colour; -attribute mediump vec2 m_TexCoord; -attribute mediump vec4 m_TexRect; -attribute mediump vec2 m_BlendRange; - -varying highp vec2 v_MaskingPosition; -varying lowp vec4 v_Colour; -varying mediump vec2 v_TexCoord; -varying mediump vec4 v_TexRect; -varying mediump vec2 v_BlendRange; - -uniform highp mat4 g_ProjMatrix; -uniform highp mat3 g_ToMaskingSpace; +layout(location = 0) out highp vec2 v_MaskingPosition; +layout(location = 1) out lowp vec4 v_Colour; +layout(location = 2) out highp vec2 v_TexCoord; +layout(location = 3) out highp vec4 v_TexRect; +layout(location = 4) out mediump vec2 v_BlendRange; void main(void) { - // Transform from screen space to masking space. - highp vec3 maskingPos = g_ToMaskingSpace * vec3(m_Position, 1.0); - v_MaskingPosition = maskingPos.xy / maskingPos.z; + // Transform from screen space to masking space. + highp vec3 maskingPos = g_ToMaskingSpace * vec3(m_Position, 1.0); + v_MaskingPosition = maskingPos.xy / maskingPos.z; - v_Colour = m_Colour; - v_TexCoord = m_TexCoord; - v_TexRect = m_TexRect; - v_BlendRange = m_BlendRange; + v_Colour = m_Colour; + v_TexCoord = m_TexCoord; + v_TexRect = m_TexRect; + v_BlendRange = m_BlendRange; - gl_Position = gProjMatrix * vec4(m_Position, 1.0, 1.0); + gl_Position = g_ProjMatrix * vec4(m_Position, 1.0, 1.0); } - From ba5088f71a57bf7d26eac4f6d319b9c0eb08d438 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 2 May 2023 11:55:05 +0300 Subject: [PATCH 2784/2991] Add missing ruleset shader tests --- osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs b/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs index 585a3f95e7..f0a9ce7beb 100644 --- a/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs +++ b/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs @@ -53,6 +53,8 @@ namespace osu.Game.Tests.Testing { Dependencies.Get().GetRawData(@"sh_TestVertex.vs"); Dependencies.Get().GetRawData(@"sh_TestFragment.fs"); + Dependencies.Get().Load(@"TestVertex", @"TestFragment"); + Dependencies.Get().Load(VertexShaderDescriptor.TEXTURE_2, @"TestFragment"); }); } From d2d81bb82c6fe9fcca7e7c8f4ac3879994aa8aa4 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Tue, 2 May 2023 12:29:11 +0200 Subject: [PATCH 2785/2991] remove redundant zero check in sv calculation --- .../Edit/Blueprints/Components/EditablePath.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs index 75ee0546dd..7a577f8a83 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs @@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components // // The value is clamped here by the bindable min and max values. // In case the required velocity is too large, the path is not preserved. - svBindable.Value = requiredVelocity == 0 ? 1 : Math.Ceiling(requiredVelocity / svToVelocityFactor); + svBindable.Value = Math.Ceiling(requiredVelocity / svToVelocityFactor); path.ConvertToSliderPath(hitObject.Path, hitObject.LegacyConvertedY, hitObject.Velocity); From 90d98cd3294ec30533017d83382d60525305f98c Mon Sep 17 00:00:00 2001 From: OliBomby Date: Tue, 2 May 2023 12:41:39 +0200 Subject: [PATCH 2786/2991] remove constructor argument from Banana --- osu.Game.Rulesets.Catch/Objects/Banana.cs | 8 +++++--- osu.Game.Rulesets.Catch/Objects/BananaShower.cs | 5 ++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Banana.cs b/osu.Game.Rulesets.Catch/Objects/Banana.cs index e137204c32..e4aa778902 100644 --- a/osu.Game.Rulesets.Catch/Objects/Banana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Banana.cs @@ -22,9 +22,11 @@ namespace osu.Game.Rulesets.Catch.Objects public override Judgement CreateJudgement() => new CatchBananaJudgement(); - public Banana(int volume = 100) + private static readonly List samples = new List { new BananaHitSampleInfo() }; + + public Banana() { - Samples = new List { new BananaHitSampleInfo(volume) }; + Samples = samples; } // override any external colour changes with banananana @@ -45,7 +47,7 @@ namespace osu.Game.Rulesets.Catch.Objects } } - private class BananaHitSampleInfo : HitSampleInfo, IEquatable + public class BananaHitSampleInfo : HitSampleInfo, IEquatable { private static readonly string[] lookup_names = { "Gameplay/metronomelow", "Gameplay/catch-banana" }; diff --git a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs index 08febeabbf..5bd4ac86f5 100644 --- a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs @@ -1,7 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using System.Threading; +using osu.Game.Audio; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Types; @@ -35,10 +37,11 @@ namespace osu.Game.Rulesets.Catch.Objects { cancellationToken.ThrowIfCancellationRequested(); - AddNested(new Banana(GetSampleInfo().Volume) + AddNested(new Banana { StartTime = time, BananaIndex = i, + Samples = new List { new Banana.BananaHitSampleInfo(GetSampleInfo().Volume) } }); time += spacing; From 95badb9455218c2c2d1d755eb9bf1668c7624984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 2 May 2023 18:35:06 +0200 Subject: [PATCH 2787/2991] Adjust composer tests to new screen layout `TestSceneHitObjectComposer.TestPlacementFailsWhenClickingButton()` was attempting to cover the case of the user clicking a toolbox button which was in front of the playfield, and ensure that the click did not result in a placement. However, since the paddings in 67f83f246b1c65c62416a24375ef580139d046dc were added, it is impossible for a toolbox button to be in front of the playfield in the collapsed state, which the test was relying on. The test scenario is still however relevant in the case of the toolbox being expanded, as in that state the toolbux buttons may very well end up being in front of the playfield, and they still should not result in a hitobject being placed. To ensure that this is the case, add a few extra test steps ensuring that the toolbox is expanded first before trying to retrieve an overlapping button. --- .../Visual/Editing/TestSceneHitObjectComposer.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs index 7ab0188114..9bdb9a513c 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs @@ -108,12 +108,16 @@ namespace osu.Game.Tests.Visual.Editing AddStep("Change to hitcircle", () => hitObjectComposer.ChildrenOfType().First(d => d.Button.Label == "HitCircle").TriggerClick()); + ExpandingToolboxContainer toolboxContainer = null!; + + AddStep("move mouse to toolbox", () => InputManager.MoveMouseTo(toolboxContainer = hitObjectComposer.ChildrenOfType().First())); + AddUntilStep("toolbox is expanded", () => toolboxContainer.Expanded.Value); + AddUntilStep("wait for toolbox to expand", () => toolboxContainer.LatestTransformEndTime, () => Is.EqualTo(Time.Current)); + AddStep("move mouse to overlapping toggle button", () => { var playfield = hitObjectComposer.Playfield.ScreenSpaceDrawQuad; - var button = hitObjectComposer - .ChildrenOfType().First() - .ChildrenOfType().First(b => playfield.Contains(b.ScreenSpaceDrawQuad.Centre)); + var button = toolboxContainer.ChildrenOfType().First(b => playfield.Contains(b.ScreenSpaceDrawQuad.Centre)); InputManager.MoveMouseTo(button); }); From 9c4312b407bb208917a8abf42283018bdf47bd56 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 May 2023 12:37:07 +0900 Subject: [PATCH 2788/2991] Add support for flipping colour of reverse arrow on legacy default skin when combo colour is too bright --- .../Skinning/Legacy/LegacyReverseArrow.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs index fbe094ef81..e6166e9441 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs @@ -3,11 +3,13 @@ using System.Diagnostics; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Skinning; +using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Skinning.Legacy { @@ -18,6 +20,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy private Drawable proxy = null!; + private Bindable accentColour = null!; + + private bool textureIsDefaultSkin; + + private Drawable arrow = null!; + [BackgroundDependencyLoader] private void load(ISkinSource skinSource) { @@ -26,7 +34,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy string lookupName = new OsuSkinComponentLookup(OsuSkinComponents.ReverseArrow).LookupName; var skin = skinSource.FindProvider(s => s.GetTexture(lookupName) != null); - InternalChild = skin?.GetAnimation(lookupName, true, true) ?? Empty(); + + InternalChild = arrow = (skin?.GetAnimation(lookupName, true, true) ?? Empty()); + textureIsDefaultSkin = skin is ISkinTransformer transformer && transformer.Skin is DefaultLegacySkin; } protected override void LoadComplete() @@ -39,6 +49,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { drawableHitObject.HitObjectApplied += onHitObjectApplied; onHitObjectApplied(drawableHitObject); + + accentColour = drawableHitObject.AccentColour.GetBoundCopy(); + accentColour.BindValueChanged(c => + { + arrow.Colour = textureIsDefaultSkin && c.NewValue.R + c.NewValue.G + c.NewValue.B > (600 / 255f) ? Color4.Black : Color4.White; + }, true); } } From 16c624fb61a7dd02460e799dd48570162f3eb2a7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 May 2023 13:02:05 +0900 Subject: [PATCH 2789/2991] Ensure `static` banana samples are not mutated --- osu.Game.Rulesets.Catch/Objects/Banana.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Banana.cs b/osu.Game.Rulesets.Catch/Objects/Banana.cs index e4aa778902..4c66c054e1 100644 --- a/osu.Game.Rulesets.Catch/Objects/Banana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Banana.cs @@ -22,11 +22,11 @@ namespace osu.Game.Rulesets.Catch.Objects public override Judgement CreateJudgement() => new CatchBananaJudgement(); - private static readonly List samples = new List { new BananaHitSampleInfo() }; + private static readonly IList default_banana_samples = new List { new BananaHitSampleInfo() }.AsReadOnly(); public Banana() { - Samples = samples; + Samples = default_banana_samples; } // override any external colour changes with banananana From 588a4e6196cc038928fa0d68481b72cae0cba4e9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 May 2023 13:19:13 +0900 Subject: [PATCH 2790/2991] Move pragma disable to top of `LegacyBeatmapDecoder` Makes more sense as it's used multiple times in the class. --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index d20f7e198b..9dcd97459f 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -3,6 +3,8 @@ #nullable disable +#pragma warning disable 618 + using System; using System.Collections.Generic; using System.IO; @@ -102,9 +104,8 @@ namespace osu.Game.Beatmaps.Formats var legacyInfo = beatmap.ControlPointInfo as LegacyControlPointInfo; DifficultyControlPoint difficultyControlPoint = legacyInfo != null ? legacyInfo.DifficultyPointAt(hitObject.StartTime) : DifficultyControlPoint.DEFAULT; -#pragma warning disable 618 + if (difficultyControlPoint is LegacyDifficultyControlPoint legacyDifficultyControlPoint) -#pragma warning restore 618 { hitObject.LegacyBpmMultiplier = legacyDifficultyControlPoint.BpmMultiplier; if (hitObject is IHasGenerateTicks hasGenerateTicks) @@ -494,9 +495,7 @@ namespace osu.Game.Beatmaps.Formats int onlineRulesetID = beatmap.BeatmapInfo.Ruleset.OnlineID; -#pragma warning disable 618 addControlPoint(time, new LegacyDifficultyControlPoint(onlineRulesetID, beatLength) -#pragma warning restore 618 { SliderVelocity = speedMultiplier, }, timingChange); From cca15f930c5ab8a4ef7a3558613bf4bf12f84d33 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 May 2023 13:26:50 +0900 Subject: [PATCH 2791/2991] Refactor `applyLegacyInfoAndDefaults` for legibility --- .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 9dcd97459f..90be90fcaf 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -101,9 +101,14 @@ namespace osu.Game.Beatmaps.Formats private void applyLegacyInfoAndDefaults(HitObject hitObject) { - var legacyInfo = beatmap.ControlPointInfo as LegacyControlPointInfo; + DifficultyControlPoint difficultyControlPoint = DifficultyControlPoint.DEFAULT; + SampleControlPoint sampleControlPoint = SampleControlPoint.DEFAULT; - DifficultyControlPoint difficultyControlPoint = legacyInfo != null ? legacyInfo.DifficultyPointAt(hitObject.StartTime) : DifficultyControlPoint.DEFAULT; + if (beatmap.ControlPointInfo is LegacyControlPointInfo legacyInfo) + { + difficultyControlPoint = legacyInfo.DifficultyPointAt(hitObject.StartTime); + sampleControlPoint = legacyInfo.SamplePointAt(hitObject.GetEndTime() + control_point_leniency); + } if (difficultyControlPoint is LegacyDifficultyControlPoint legacyDifficultyControlPoint) { @@ -117,18 +122,17 @@ namespace osu.Game.Beatmaps.Formats hitObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.Difficulty); - SampleControlPoint sampleControlPoint = legacyInfo != null ? legacyInfo.SamplePointAt(hitObject.GetEndTime() + control_point_leniency) : SampleControlPoint.DEFAULT; - hitObject.Samples = hitObject.Samples.Select(o => sampleControlPoint.ApplyTo(o)).ToList(); - if (hitObject is not IHasRepeats hasRepeats) return; - - for (int i = 0; i < hasRepeats.NodeSamples.Count; i++) + if (hitObject is IHasRepeats hasRepeats) { - double time = hitObject.StartTime + i * hasRepeats.Duration / hasRepeats.SpanCount() + control_point_leniency; - sampleControlPoint = legacyInfo != null ? legacyInfo.SamplePointAt(time) : SampleControlPoint.DEFAULT; + for (int i = 0; i < hasRepeats.NodeSamples.Count; i++) + { + double time = hitObject.StartTime + i * hasRepeats.Duration / hasRepeats.SpanCount() + control_point_leniency; + sampleControlPoint = (beatmap.ControlPointInfo as LegacyControlPointInfo)?.SamplePointAt(time) ?? SampleControlPoint.DEFAULT; - hasRepeats.NodeSamples[i] = hasRepeats.NodeSamples[i].Select(o => sampleControlPoint.ApplyTo(o)).ToList(); + hasRepeats.NodeSamples[i] = hasRepeats.NodeSamples[i].Select(o => sampleControlPoint.ApplyTo(o)).ToList(); + } } } From 48fd99818ea448a6f21fa2ecb9e67bd8ef260e0e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 May 2023 13:30:45 +0900 Subject: [PATCH 2792/2991] Split out default and sample application --- .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 90be90fcaf..5e98025c9a 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -95,20 +95,14 @@ namespace osu.Game.Beatmaps.Formats foreach (var hitObject in this.beatmap.HitObjects) { - applyLegacyInfoAndDefaults(hitObject); + applyDefaults(hitObject); + applySamples(hitObject); } } - private void applyLegacyInfoAndDefaults(HitObject hitObject) + private void applyDefaults(HitObject hitObject) { - DifficultyControlPoint difficultyControlPoint = DifficultyControlPoint.DEFAULT; - SampleControlPoint sampleControlPoint = SampleControlPoint.DEFAULT; - - if (beatmap.ControlPointInfo is LegacyControlPointInfo legacyInfo) - { - difficultyControlPoint = legacyInfo.DifficultyPointAt(hitObject.StartTime); - sampleControlPoint = legacyInfo.SamplePointAt(hitObject.GetEndTime() + control_point_leniency); - } + DifficultyControlPoint difficultyControlPoint = (beatmap.ControlPointInfo as LegacyControlPointInfo)?.DifficultyPointAt(hitObject.StartTime) ?? DifficultyControlPoint.DEFAULT; if (difficultyControlPoint is LegacyDifficultyControlPoint legacyDifficultyControlPoint) { @@ -121,6 +115,11 @@ namespace osu.Game.Beatmaps.Formats hasSliderVelocity.SliderVelocity = difficultyControlPoint.SliderVelocity; hitObject.ApplyDefaults(beatmap.ControlPointInfo, beatmap.Difficulty); + } + + private void applySamples(HitObject hitObject) + { + SampleControlPoint sampleControlPoint = (beatmap.ControlPointInfo as LegacyControlPointInfo)?.SamplePointAt(hitObject.GetEndTime() + control_point_leniency) ?? SampleControlPoint.DEFAULT; hitObject.Samples = hitObject.Samples.Select(o => sampleControlPoint.ApplyTo(o)).ToList(); @@ -129,9 +128,9 @@ namespace osu.Game.Beatmaps.Formats for (int i = 0; i < hasRepeats.NodeSamples.Count; i++) { double time = hitObject.StartTime + i * hasRepeats.Duration / hasRepeats.SpanCount() + control_point_leniency; - sampleControlPoint = (beatmap.ControlPointInfo as LegacyControlPointInfo)?.SamplePointAt(time) ?? SampleControlPoint.DEFAULT; + var nodeSamplePoint = (beatmap.ControlPointInfo as LegacyControlPointInfo)?.SamplePointAt(time) ?? SampleControlPoint.DEFAULT; - hasRepeats.NodeSamples[i] = hasRepeats.NodeSamples[i].Select(o => sampleControlPoint.ApplyTo(o)).ToList(); + hasRepeats.NodeSamples[i] = hasRepeats.NodeSamples[i].Select(o => nodeSamplePoint.ApplyTo(o)).ToList(); } } } From f930c4bd0aaa4137ce2c2fbcbe5870a7d919fefb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 May 2023 13:33:31 +0900 Subject: [PATCH 2793/2991] Move `struct` to bottom of file --- .../Beatmaps/Formats/LegacyBeatmapEncoder.cs | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 6b228a56a1..7fbcca9adb 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -92,7 +92,8 @@ namespace osu.Game.Beatmaps.Formats writer.WriteLine(FormattableString.Invariant($"AudioLeadIn: {beatmap.BeatmapInfo.AudioLeadIn}")); writer.WriteLine(FormattableString.Invariant($"PreviewTime: {beatmap.Metadata.PreviewTime}")); writer.WriteLine(FormattableString.Invariant($"Countdown: {(int)beatmap.BeatmapInfo.Countdown}")); - writer.WriteLine(FormattableString.Invariant($"SampleSet: {toLegacySampleBank(((beatmap.ControlPointInfo as LegacyControlPointInfo)?.SamplePoints?.FirstOrDefault() ?? SampleControlPoint.DEFAULT).SampleBank)}")); + writer.WriteLine(FormattableString.Invariant( + $"SampleSet: {toLegacySampleBank(((beatmap.ControlPointInfo as LegacyControlPointInfo)?.SamplePoints?.FirstOrDefault() ?? SampleControlPoint.DEFAULT).SampleBank)}")); writer.WriteLine(FormattableString.Invariant($"StackLeniency: {beatmap.BeatmapInfo.StackLeniency}")); writer.WriteLine(FormattableString.Invariant($"Mode: {onlineRulesetID}")); writer.WriteLine(FormattableString.Invariant($"LetterboxInBreaks: {(beatmap.BeatmapInfo.LetterboxInBreaks ? '1' : '0')}")); @@ -171,24 +172,6 @@ namespace osu.Game.Beatmaps.Formats writer.WriteLine(FormattableString.Invariant($"{(int)LegacyEventType.Break},{b.StartTime},{b.EndTime}")); } - private struct LegacyControlPointProperties - { - internal double SliderVelocity { get; set; } - internal int TimingSignature { get; init; } - internal int SampleBank { get; init; } - internal int CustomSampleBank { get; init; } - internal int SampleVolume { get; init; } - internal LegacyEffectFlags EffectFlags { get; init; } - - internal bool IsRedundant(LegacyControlPointProperties other) => - SliderVelocity == other.SliderVelocity && - TimingSignature == other.TimingSignature && - SampleBank == other.SampleBank && - CustomSampleBank == other.CustomSampleBank && - SampleVolume == other.SampleVolume && - EffectFlags == other.EffectFlags; - } - private void handleControlPoints(TextWriter writer) { var legacyControlPoints = new LegacyControlPointInfo(); @@ -243,11 +226,10 @@ namespace osu.Game.Beatmaps.Formats LegacyControlPointProperties getLegacyControlPointProperties(ControlPointGroup group, bool updateSampleBank) { - double time = group.Time; - var timingPoint = legacyControlPoints.TimingPointAt(time); - var difficultyPoint = legacyControlPoints.DifficultyPointAt(time); - var samplePoint = legacyControlPoints.SamplePointAt(time); - var effectPoint = legacyControlPoints.EffectPointAt(time); + var timingPoint = legacyControlPoints.TimingPointAt(group.Time); + var difficultyPoint = legacyControlPoints.DifficultyPointAt(group.Time); + var samplePoint = legacyControlPoints.SamplePointAt(group.Time); + var effectPoint = legacyControlPoints.EffectPointAt(group.Time); // Apply the control point to a hit sample to uncover legacy properties (e.g. suffix) HitSampleInfo tempHitSample = samplePoint.ApplyTo(new ConvertHitObjectParser.LegacyHitSampleInfo(string.Empty)); @@ -628,5 +610,23 @@ namespace osu.Game.Beatmaps.Formats return 0; } + + private struct LegacyControlPointProperties + { + internal double SliderVelocity { get; set; } + internal int TimingSignature { get; init; } + internal int SampleBank { get; init; } + internal int CustomSampleBank { get; init; } + internal int SampleVolume { get; init; } + internal LegacyEffectFlags EffectFlags { get; init; } + + internal bool IsRedundant(LegacyControlPointProperties other) => + SliderVelocity == other.SliderVelocity && + TimingSignature == other.TimingSignature && + SampleBank == other.SampleBank && + CustomSampleBank == other.CustomSampleBank && + SampleVolume == other.SampleVolume && + EffectFlags == other.EffectFlags; + } } } From 384693a431757767d27594ef8906cd3d1ace0861 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 May 2023 14:30:57 +0900 Subject: [PATCH 2794/2991] Fix test failure in `MultiplayerMatchSongSelect` due to multiple overlays present https://github.com/ppy/osu/actions/runs/4868337922/jobs/8681736995?pr=23308. --- .../Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs index c0b6a0beab..9b130071cc 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSongSelect.cs @@ -98,6 +98,10 @@ namespace osu.Game.Tests.Visual.Multiplayer AddStep($"select {requiredMod.ReadableName()} as required", () => songSelect.Mods.Value = new[] { (Mod)Activator.CreateInstance(requiredMod) }); AddAssert("freemods empty", () => songSelect.FreeMods.Value.Count == 0); + + // A previous test's mod overlay could still be fading out. + AddUntilStep("wait for only one freemod overlay", () => this.ChildrenOfType().Count() == 1); + assertHasFreeModButton(allowedMod, false); assertHasFreeModButton(requiredMod, false); } From a3efae36907fc596061ffadf7e552d6c078c360a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 May 2023 14:33:30 +0900 Subject: [PATCH 2795/2991] Fix potentially incorrect thread access in `OsuTabControlCheckbox` https://github.com/ppy/osu/actions/runs/4868337922/jobs/8681736829. --- .../UserInterface/OsuTabControlCheckbox.cs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs index fa58ae27f2..71bc18737f 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs @@ -49,11 +49,10 @@ namespace osu.Game.Graphics.UserInterface private const float transition_length = 500; private Sample sampleChecked; private Sample sampleUnchecked; + private readonly SpriteIcon icon; public OsuTabControlCheckbox() { - SpriteIcon icon; - AutoSizeAxes = Axes.Both; Children = new Drawable[] @@ -85,14 +84,6 @@ namespace osu.Game.Graphics.UserInterface Anchor = Anchor.BottomLeft, } }; - - Current.ValueChanged += selected => - { - icon.Icon = selected.NewValue ? FontAwesome.Regular.CheckCircle : FontAwesome.Regular.Circle; - text.Font = text.Font.With(weight: selected.NewValue ? FontWeight.Bold : FontWeight.Medium); - - updateFade(); - }; } [BackgroundDependencyLoader] @@ -103,6 +94,14 @@ namespace osu.Game.Graphics.UserInterface sampleChecked = audio.Samples.Get(@"UI/check-on"); sampleUnchecked = audio.Samples.Get(@"UI/check-off"); + + Current.ValueChanged += selected => + { + icon.Icon = selected.NewValue ? FontAwesome.Regular.CheckCircle : FontAwesome.Regular.Circle; + text.Font = text.Font.With(weight: selected.NewValue ? FontWeight.Bold : FontWeight.Medium); + + updateFade(); + }; } protected override bool OnHover(HoverEvent e) From bede1292de37f4be3270c2e86c215783e3ef52d8 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 2 May 2023 22:24:07 -0700 Subject: [PATCH 2796/2991] Fix overlay scroll back button not absorbing hover from behind --- osu.Game/Overlays/OverlayScrollContainer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/OverlayScrollContainer.cs b/osu.Game/Overlays/OverlayScrollContainer.cs index 9752e04f44..ba7486a57f 100644 --- a/osu.Game/Overlays/OverlayScrollContainer.cs +++ b/osu.Game/Overlays/OverlayScrollContainer.cs @@ -185,6 +185,8 @@ namespace osu.Game.Overlays content.ScaleTo(1, 1000, Easing.OutElastic); base.OnMouseUp(e); } + + protected override bool OnHover(HoverEvent e) => true; } } } From 1c74f6e8ea60fe91335c95883bc8d434e51b07ac Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 2 May 2023 22:54:42 -0700 Subject: [PATCH 2797/2991] Fix regressed button hover fade in --- osu.Game/Overlays/OverlayScrollContainer.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/OverlayScrollContainer.cs b/osu.Game/Overlays/OverlayScrollContainer.cs index ba7486a57f..2a615f0e12 100644 --- a/osu.Game/Overlays/OverlayScrollContainer.cs +++ b/osu.Game/Overlays/OverlayScrollContainer.cs @@ -186,7 +186,11 @@ namespace osu.Game.Overlays base.OnMouseUp(e); } - protected override bool OnHover(HoverEvent e) => true; + protected override bool OnHover(HoverEvent e) + { + base.OnHover(e); + return true; + } } } } From 453143813fafc7a62736ab473a883a194d7e643d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 May 2023 14:57:31 +0900 Subject: [PATCH 2798/2991] Extend input handling of osu! logo to full border area This is the easiest way to make this happen. It does mean the pink area is being drawn behind the white border, but I haven't found a scenario where this is noticeable. Closes #4217. --- osu.Game/Screens/Menu/OsuLogo.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 9430a1cda8..33dc23d88d 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -35,6 +35,12 @@ namespace osu.Game.Screens.Menu private const double transition_length = 300; + /// + /// The osu! logo sprite has a shadow included in its texture. + /// This adjustment vector is used to match the precise edge of the border of the logo. + /// + private static readonly Vector2 scale_adjust = new Vector2(0.96f); + private readonly Sprite logo; private readonly CircularContainer logoContainer; private readonly Container logoBounceContainer; @@ -150,7 +156,7 @@ namespace osu.Game.Screens.Menu Origin = Anchor.Centre, Anchor = Anchor.Centre, Alpha = visualizer_default_alpha, - Size = new Vector2(0.96f) + Size = scale_adjust }, new Container { @@ -162,7 +168,7 @@ namespace osu.Game.Screens.Menu Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - Scale = new Vector2(0.88f), + Scale = scale_adjust, Masking = true, Children = new Drawable[] { From 6a59ded1bad631e2b3ce508b4050b0a937126037 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 May 2023 15:18:37 +0900 Subject: [PATCH 2799/2991] Move logic to `Update` instead --- .../Objects/Drawables/DrawableHoldNote.cs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index b2c84b140b..20daab2447 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -219,6 +219,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (Time.Current < releaseTime) releaseTime = null; + if (Time.Current < HoldStartTime) + endHold(); + // Pad the full size container so its contents (i.e. the masking container) reach under the tail. // This is required for the tail to not be masked away, since it lies outside the bounds of the hold note. sizingContainer.Padding = new MarginPadding @@ -322,15 +325,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (e.Action != Action.Value) return; - // do not run any of this logic when rewinding, as it inverts order of presses/releases. - if (Time.Elapsed < 0) - { - // Except for the IsHitting state, as this handles animations that need to be reapplied - // after rewind. - isHitting.Value = false; - return; - } - // Make sure a hold was started if (HoldStartTime == null) return; From 5f781bd6de1ef4c2e067eec5e985722500b7b192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 3 May 2023 09:26:54 +0200 Subject: [PATCH 2800/2991] Move callback to `LoadComplete()` Is the more correct place for `BindValueChanged()` callbacks. --- osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs index 71bc18737f..8eb6b792c6 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs @@ -94,14 +94,19 @@ namespace osu.Game.Graphics.UserInterface sampleChecked = audio.Samples.Get(@"UI/check-on"); sampleUnchecked = audio.Samples.Get(@"UI/check-off"); + } - Current.ValueChanged += selected => + protected override void LoadComplete() + { + base.LoadComplete(); + + Current.BindValueChanged(selected => { icon.Icon = selected.NewValue ? FontAwesome.Regular.CheckCircle : FontAwesome.Regular.Circle; text.Font = text.Font.With(weight: selected.NewValue ? FontWeight.Bold : FontWeight.Medium); updateFade(); - }; + }); } protected override bool OnHover(HoverEvent e) From de1b28bcb284e9e07b4b36eb9a3513a5f7228732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 3 May 2023 09:27:23 +0200 Subject: [PATCH 2801/2991] Fix incorrect initial state of checkbox This only ever barely used to work without the `(..., true)` in `master` because of haphazard operation ordering. --- osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs index 8eb6b792c6..c9e1f74917 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControlCheckbox.cs @@ -106,7 +106,7 @@ namespace osu.Game.Graphics.UserInterface text.Font = text.Font.With(weight: selected.NewValue ? FontWeight.Bold : FontWeight.Medium); updateFade(); - }); + }, true); } protected override bool OnHover(HoverEvent e) From 5757eb75299234da77876e70de818ae53d4e8728 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 May 2023 18:20:12 +0900 Subject: [PATCH 2802/2991] Update a few more instances of `0.96f` scale constants --- osu.Game/Screens/Menu/IntroWelcome.cs | 2 +- osu.Game/Screens/Menu/OsuLogo.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Menu/IntroWelcome.cs b/osu.Game/Screens/Menu/IntroWelcome.cs index da44161507..2a6ebecb92 100644 --- a/osu.Game/Screens/Menu/IntroWelcome.cs +++ b/osu.Game/Screens/Menu/IntroWelcome.cs @@ -131,7 +131,7 @@ namespace osu.Game.Screens.Menu Anchor = Anchor.Centre, Origin = Anchor.Centre, Colour = Color4.DarkBlue, - Size = new Vector2(0.96f) + Size = OsuLogo.SCALE_ADJUST, }, new Circle { diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 33dc23d88d..277b8bf888 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -39,7 +39,7 @@ namespace osu.Game.Screens.Menu /// The osu! logo sprite has a shadow included in its texture. /// This adjustment vector is used to match the precise edge of the border of the logo. /// - private static readonly Vector2 scale_adjust = new Vector2(0.96f); + public static readonly Vector2 SCALE_ADJUST = new Vector2(0.96f); private readonly Sprite logo; private readonly CircularContainer logoContainer; @@ -156,7 +156,7 @@ namespace osu.Game.Screens.Menu Origin = Anchor.Centre, Anchor = Anchor.Centre, Alpha = visualizer_default_alpha, - Size = scale_adjust + Size = SCALE_ADJUST }, new Container { @@ -168,7 +168,7 @@ namespace osu.Game.Screens.Menu Anchor = Anchor.Centre, Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - Scale = scale_adjust, + Scale = SCALE_ADJUST, Masking = true, Children = new Drawable[] { @@ -412,7 +412,7 @@ namespace osu.Game.Screens.Menu public void Impact() { impactContainer.FadeOutFromOne(250, Easing.In); - impactContainer.ScaleTo(0.96f); + impactContainer.ScaleTo(SCALE_ADJUST); impactContainer.ScaleTo(1.12f, 250); } From cd31cff8cdd4c26c64183f640178b604e638682e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 May 2023 18:41:29 +0900 Subject: [PATCH 2803/2991] Fix event subscriptions not being cleaned up in `DrawableCarouselBeatmap` The handling of cleanup is performed only the `Item_Set` method. This was already correctly called for `DrawableCarouselBeatmapSet`, but not for the class in question here. This would cause runaway memory usage at song select when opening many beatmaps to show their difficulties. For simplicity, we don't yet pool these (and generate the drawables each time a set is opened) which isn't great but likely will be improved upon when we update the visual / filtering of the carousel. But this simplicity caused the memory usage to blow out until exiting back to the main menu when cleanup would finally occur. --- osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index f08d14720b..55d442215b 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -250,6 +250,9 @@ namespace osu.Game.Screens.Select.Carousel { base.Dispose(isDisposing); starDifficultyCancellationSource?.Cancel(); + + // This is important to clean up event subscriptions. + Item = null; } } } From 444f66b0eefdce3c4defaf46fffa927a886f6f51 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 May 2023 18:45:09 +0900 Subject: [PATCH 2804/2991] Move to base class for added safety --- .../Screens/Select/Carousel/DrawableCarouselBeatmap.cs | 3 --- .../Screens/Select/Carousel/DrawableCarouselItem.cs | 10 +++++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index 55d442215b..f08d14720b 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -250,9 +250,6 @@ namespace osu.Game.Screens.Select.Carousel { base.Dispose(isDisposing); starDifficultyCancellationSource?.Cancel(); - - // This is important to clean up event subscriptions. - Item = null; } } } diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs index f065926eb7..0c3de5848b 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs @@ -58,7 +58,7 @@ namespace osu.Game.Screens.Select.Carousel item = value; - if (IsLoaded) + if (IsLoaded && !IsDisposed) UpdateItem(); } } @@ -165,5 +165,13 @@ namespace osu.Game.Screens.Select.Carousel Item.State.Value = CarouselItemState.Selected; return true; } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + // This is important to clean up event subscriptions. + Item = null; + } } } From b28d7b1a928cbda8ee6da8a682683ea9dbd7376f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 May 2023 18:51:02 +0900 Subject: [PATCH 2805/2991] Fix non-block namespace --- .../Online/API/Requests/ChatReportRequest.cs | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/osu.Game/Online/API/Requests/ChatReportRequest.cs b/osu.Game/Online/API/Requests/ChatReportRequest.cs index 01cb455183..85e5559e01 100644 --- a/osu.Game/Online/API/Requests/ChatReportRequest.cs +++ b/osu.Game/Online/API/Requests/ChatReportRequest.cs @@ -5,33 +5,34 @@ using System.Net.Http; using osu.Framework.IO.Network; using osu.Game.Overlays.Chat; -namespace osu.Game.Online.API.Requests; - -public class ChatReportRequest : APIRequest +namespace osu.Game.Online.API.Requests { - public readonly long? MessageId; - public readonly ChatReportReason Reason; - public readonly string Comment; - - public ChatReportRequest(long? id, ChatReportReason reason, string comment) + public class ChatReportRequest : APIRequest { - MessageId = id; - Reason = reason; - Comment = comment; + public readonly long? MessageId; + public readonly ChatReportReason Reason; + public readonly string Comment; + + public ChatReportRequest(long? id, ChatReportReason reason, string comment) + { + MessageId = id; + Reason = reason; + Comment = comment; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + req.Method = HttpMethod.Post; + + req.AddParameter(@"reportable_type", @"message"); + req.AddParameter(@"reportable_id", $"{MessageId}"); + req.AddParameter(@"reason", Reason.ToString()); + req.AddParameter(@"comments", Comment); + + return req; + } + + protected override string Target => @"reports"; } - - protected override WebRequest CreateWebRequest() - { - var req = base.CreateWebRequest(); - req.Method = HttpMethod.Post; - - req.AddParameter(@"reportable_type", @"message"); - req.AddParameter(@"reportable_id", $"{MessageId}"); - req.AddParameter(@"reason", Reason.ToString()); - req.AddParameter(@"comments", Comment); - - return req; - } - - protected override string Target => @"reports"; } From b932e4d98690f9935aa1d50df4dd8757f9380928 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 May 2023 18:53:22 +0900 Subject: [PATCH 2806/2991] Rename `DrawableUsername` to `DrawableChatUsername` and only pass message ID --- osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs | 2 +- osu.Game/Overlays/Chat/ChatLine.cs | 4 ++-- .../{DrawableUsername.cs => DrawableChatUsername.cs} | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) rename osu.Game/Overlays/Chat/{DrawableUsername.cs => DrawableChatUsername.cs} (96%) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index faf48ef854..e9e2cc63c2 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -616,7 +616,7 @@ namespace osu.Game.Tests.Visual.Online }; }); - AddStep("Show report popover", () => this.ChildrenOfType().First().ShowPopover()); + AddStep("Show report popover", () => this.ChildrenOfType().First().ShowPopover()); AddStep("Set report reason to other", () => { diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index 0e69501ae9..dca34128d1 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -55,7 +55,7 @@ namespace osu.Game.Overlays.Chat private readonly OsuSpriteText drawableTimestamp; - private readonly DrawableUsername drawableUsername; + private readonly DrawableChatUsername drawableUsername; private readonly LinkFlowContainer drawableContentFlow; @@ -92,7 +92,7 @@ namespace osu.Game.Overlays.Chat Font = OsuFont.GetFont(size: FontSize * 0.75f, weight: FontWeight.SemiBold, fixedWidth: true), AlwaysPresent = true, }, - drawableUsername = new DrawableUsername(message) + drawableUsername = new DrawableChatUsername(message.Sender, message.Id) { Width = UsernameWidth, FontSize = FontSize, diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableChatUsername.cs similarity index 96% rename from osu.Game/Overlays/Chat/DrawableUsername.cs rename to osu.Game/Overlays/Chat/DrawableChatUsername.cs index 25967003e9..4ba5c9769a 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableChatUsername.cs @@ -31,7 +31,7 @@ using ChatStrings = osu.Game.Localisation.ChatStrings; namespace osu.Game.Overlays.Chat { - public partial class DrawableUsername : OsuClickableContainer, IHasContextMenu, IHasPopover + public partial class DrawableChatUsername : OsuClickableContainer, IHasContextMenu, IHasPopover { public Color4 AccentColour { get; } @@ -73,15 +73,15 @@ namespace osu.Game.Overlays.Chat private Bindable? currentChannel { get; set; } private readonly APIUser user; - private readonly Message message; + private readonly long? messageId; private readonly OsuSpriteText drawableText; private readonly Drawable colouredDrawable; - public DrawableUsername(Message message) + public DrawableChatUsername(APIUser user, long? messageId) { - this.message = message; - user = message.Sender; + this.user = user; + this.messageId = messageId; Action = openUserProfile; @@ -182,7 +182,7 @@ namespace osu.Game.Overlays.Chat private void report(ChatReportReason reason, string comments) { - var request = new ChatReportRequest(message.Id, reason, comments); + var request = new ChatReportRequest(messageId, reason, comments); request.Failure += _ => Schedule(() => { From be15d07b1734b853d1424c996b3e0de10a94c213 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 May 2023 18:59:39 +0900 Subject: [PATCH 2807/2991] Tidy up various implementation details --- osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs | 7 ++++--- osu.Game/Overlays/Chat/DrawableChatUsername.cs | 10 +++++----- osu.Game/Overlays/Comments/CommentReportButton.cs | 10 +++++----- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs b/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs index 46006402ad..a5c60bb9e6 100644 --- a/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs +++ b/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs @@ -24,11 +24,12 @@ namespace osu.Game.Graphics.UserInterfaceV2 private OsuEnumDropdown reasonDropdown = null!; private OsuTextBox commentsTextBox = null!; private RoundedButton submitButton = null!; - public LocalisableString Header; + + private readonly LocalisableString header; protected ReportPopover(LocalisableString headerString) { - Header = headerString; + header = headerString; } [BackgroundDependencyLoader] @@ -53,7 +54,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 { Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, - Text = Header, + Text = header, Font = OsuFont.Torus.With(size: 25), Margin = new MarginPadding { Bottom = 10 } }, diff --git a/osu.Game/Overlays/Chat/DrawableChatUsername.cs b/osu.Game/Overlays/Chat/DrawableChatUsername.cs index 4ba5c9769a..b3bbc74be7 100644 --- a/osu.Game/Overlays/Chat/DrawableChatUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableChatUsername.cs @@ -180,6 +180,11 @@ namespace osu.Game.Overlays.Chat } } + public Popover GetPopover() => new ReportChatPopover(user) + { + Action = report + }; + private void report(ChatReportReason reason, string comments) { var request = new ChatReportRequest(messageId, reason, comments); @@ -260,10 +265,5 @@ namespace osu.Game.Overlays.Chat Color4Extensions.FromHex("812a96"), Color4Extensions.FromHex("992861"), }; - - public Popover GetPopover() => new ReportChatPopover(user) - { - Action = report - }; } } diff --git a/osu.Game/Overlays/Comments/CommentReportButton.cs b/osu.Game/Overlays/Comments/CommentReportButton.cs index ba5319094b..e4d4d671da 100644 --- a/osu.Game/Overlays/Comments/CommentReportButton.cs +++ b/osu.Game/Overlays/Comments/CommentReportButton.cs @@ -57,6 +57,11 @@ namespace osu.Game.Overlays.Comments link.AddLink(ReportStrings.CommentButton.ToLower(), this.ShowPopover); } + public Popover GetPopover() => new ReportCommentPopover(comment) + { + Action = report + }; + private void report(CommentReportReason reason, string comments) { var request = new CommentReportRequest(comment.Id, reason, comments); @@ -83,10 +88,5 @@ namespace osu.Game.Overlays.Comments api.Queue(request); } - - public Popover GetPopover() => new ReportCommentPopover(comment) - { - Action = report - }; } } From 25bf4e68ec32b5fa68f40280aed8246cefcd42e8 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 3 May 2023 22:53:13 +0900 Subject: [PATCH 2808/2991] remove useless wait --- osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index e9e2cc63c2..041556a5a6 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -631,7 +631,6 @@ namespace osu.Game.Tests.Visual.Online InputManager.Click(MouseButton.Left); }); - AddWaitStep("Wait", 3); AddAssert("Nothing happened", () => this.ChildrenOfType().Any()); AddStep("Set report data", () => { From 3a15783a3c53e610b86ff71c891df125d3651bb1 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 3 May 2023 22:56:47 +0900 Subject: [PATCH 2809/2991] remove wait, use AddUntilStep --- .../Visual/UserInterface/TestSceneModPresetColumn.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs index c4c5584c5e..55fe142d9f 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs @@ -301,7 +301,6 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.Click(MouseButton.Left); }); - AddWaitStep("wait some", 3); AddAssert("present is not changed", () => panel.Preset.Value.Name == presetName); AddUntilStep("popover is unchanged", () => this.ChildrenOfType().FirstOrDefault() == popover); AddStep("edit preset name", () => popover.ChildrenOfType().First().Current.Value = "something new"); @@ -357,8 +356,8 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.MoveMouseTo(popover.ChildrenOfType().ElementAt(1)); InputManager.Click(MouseButton.Left); }); - AddWaitStep("wait some", 3); - AddAssert("present mod not changed", () => + + AddUntilStep("present mod not changed", () => new HashSet(this.ChildrenOfType().First().Preset.Value.Mods).SetEquals(previousMod)); AddStep("select mods", () => SelectedMods.Value = mods); @@ -388,8 +387,8 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.MoveMouseTo(popover.ChildrenOfType().ElementAt(1)); InputManager.Click(MouseButton.Left); }); - AddWaitStep("wait some", 3); - AddAssert("present mod is changed", () => + + AddUntilStep("present mod is changed", () => new HashSet(this.ChildrenOfType().First().Preset.Value.Mods).SetEquals(mods)); } From c609e6345cf6c3b41b57917fe1dac841b1be9a4c Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 3 May 2023 23:01:31 +0900 Subject: [PATCH 2810/2991] remove `Use Current Mods` menu item --- .../UserInterface/TestSceneModPresetColumn.cs | 44 ------------------- osu.Game/Overlays/Mods/ModPresetPanel.cs | 21 ++------- 2 files changed, 4 insertions(+), 61 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs index 55fe142d9f..0cbbe00311 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs @@ -392,50 +392,6 @@ namespace osu.Game.Tests.Visual.UserInterface new HashSet(this.ChildrenOfType().First().Preset.Value.Mods).SetEquals(mods)); } - [Test] - public void TestEditPresetModInContextMenu() - { - ModPresetColumn modPresetColumn = null!; - var mods = new Mod[] { new OsuModHidden() }; - - AddStep("clear mods", () => SelectedMods.Value = Array.Empty()); - AddStep("create content", () => Child = modPresetColumn = new ModPresetColumn - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }); - - AddUntilStep("items loaded", () => modPresetColumn.IsLoaded && modPresetColumn.ItemsLoaded); - - AddStep("right click first panel", () => - { - var panel = this.ChildrenOfType().First(); - InputManager.MoveMouseTo(panel); - InputManager.Click(MouseButton.Right); - }); - AddUntilStep("wait for context menu", () => this.ChildrenOfType().Any()); - AddAssert("No Use Current Mods", () => this.ChildrenOfType().Count() == 2); - - AddStep("select mods", () => SelectedMods.Value = mods); - AddStep("right click second panel", () => - { - var panel = this.ChildrenOfType().ElementAt(1); - InputManager.MoveMouseTo(panel); - InputManager.Click(MouseButton.Right); - }); - - AddUntilStep("wait for context menu", () => this.ChildrenOfType().Any()); - AddAssert("Have Use Current Mods", () => this.ChildrenOfType().Count() == 3); - AddStep("Click Use Current Mods", () => - { - var editItem = this.ChildrenOfType().ElementAt(1); - InputManager.MoveMouseTo(editItem); - InputManager.Click(MouseButton.Left); - }); - AddAssert("present mod is changed", () => - new HashSet(this.ChildrenOfType().ElementAt(1).Preset.Value.Mods).SetEquals(mods)); - } - private ICollection createTestPresets() => new[] { new ModPreset diff --git a/osu.Game/Overlays/Mods/ModPresetPanel.cs b/osu.Game/Overlays/Mods/ModPresetPanel.cs index d01981d18c..6999f2cede 100644 --- a/osu.Game/Overlays/Mods/ModPresetPanel.cs +++ b/osu.Game/Overlays/Mods/ModPresetPanel.cs @@ -90,24 +90,11 @@ namespace osu.Game.Overlays.Mods #region IHasContextMenu - public MenuItem[] ContextMenuItems + public MenuItem[] ContextMenuItems => new MenuItem[] { - get - { - var menu = new List - { - new OsuMenuItem(CommonStrings.ButtonsEdit, MenuItemType.Highlighted, this.ShowPopover), - new OsuMenuItem(CommonStrings.ButtonsDelete, MenuItemType.Destructive, () => dialogOverlay?.Push(new DeleteModPresetDialog(Preset))), - }; - - if (CheckCurrentModCanBeSave()) - { - menu.Insert(1, new OsuMenuItem("Use Current Mods", MenuItemType.Destructive, () => SaveCurrentMod())); - } - - return menu.ToArray(); - } - } + new OsuMenuItem(CommonStrings.ButtonsEdit, MenuItemType.Highlighted, this.ShowPopover), + new OsuMenuItem(CommonStrings.ButtonsDelete, MenuItemType.Destructive, () => dialogOverlay?.Push(new DeleteModPresetDialog(Preset))), + }; #endregion From aa5a026c676c0503f6110c0d4fa610b3669bc9fd Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 3 May 2023 23:14:24 +0900 Subject: [PATCH 2811/2991] remove local button handle --- osu.Game/Overlays/Mods/EditPresetPopover.cs | 27 ++++++--------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs index 0e21260493..77980ea629 100644 --- a/osu.Game/Overlays/Mods/EditPresetPopover.cs +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -95,7 +95,7 @@ namespace osu.Game.Overlays.Mods Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Text = "Use Current Mods", - Action = trySaveCurrentMod + Action = saveCurrentMod }, createButton = new ShearedButton { @@ -123,19 +123,17 @@ namespace osu.Game.Overlays.Mods createButton.LighterColour = colours.Orange0; createButton.TextColour = colourProvider.Background6; + useCurrentModButton.DarkerColour = colours.Blue1; + useCurrentModButton.LighterColour = colours.Blue0; + useCurrentModButton.TextColour = colourProvider.Background6; + selectedMods.BindValueChanged(_ => updateActiveState(), true); scrollContent.ChildrenEnumerable = preset.Mods.Select(mod => new ModPresetRow(mod)); } - private void trySaveCurrentMod() + private void saveCurrentMod() { - if (!checkCanBeSave()) - { - Body.Shake(); - return; - } - saveModAfterClosed = selectedMods.Value.ToList(); scrollContent.Clear(); scrollContent.ChildrenEnumerable = saveModAfterClosed.Select(mod => new ModPresetRow(mod)); @@ -144,18 +142,7 @@ namespace osu.Game.Overlays.Mods private void updateActiveState() { - if (checkCanBeSave()) - { - useCurrentModButton.DarkerColour = colours.Blue1; - useCurrentModButton.LighterColour = colours.Blue0; - useCurrentModButton.TextColour = colourProvider.Background6; - } - else - { - useCurrentModButton.DarkerColour = colours.Blue3; - useCurrentModButton.LighterColour = colours.Blue4; - useCurrentModButton.TextColour = colourProvider.Background2; - } + useCurrentModButton.Enabled.Value = checkCanBeSave(); } private bool checkCanBeSave() From f4b1264cc9859acd275e0f99bf68c2b6cd59306b Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 3 May 2023 23:22:46 +0900 Subject: [PATCH 2812/2991] use button `Enable` status to ensure preset name is not null --- osu.Game/Overlays/Mods/AddPresetPopover.cs | 15 ++++++------- osu.Game/Overlays/Mods/EditPresetPopover.cs | 25 ++++++++++----------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/osu.Game/Overlays/Mods/AddPresetPopover.cs b/osu.Game/Overlays/Mods/AddPresetPopover.cs index 33d72ff383..6fd4231f2c 100644 --- a/osu.Game/Overlays/Mods/AddPresetPopover.cs +++ b/osu.Game/Overlays/Mods/AddPresetPopover.cs @@ -67,7 +67,7 @@ namespace osu.Game.Overlays.Mods Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Text = ModSelectOverlayStrings.AddPreset, - Action = tryCreatePreset + Action = createPreset } } }; @@ -89,16 +89,15 @@ namespace osu.Game.Overlays.Mods base.LoadComplete(); ScheduleAfterChildren(() => GetContainingInputManager().ChangeFocus(nameTextBox)); + + nameTextBox.Current.BindValueChanged(s => + { + createButton.Enabled.Value = !string.IsNullOrWhiteSpace(s.NewValue); + }, true); } - private void tryCreatePreset() + private void createPreset() { - if (string.IsNullOrWhiteSpace(nameTextBox.Current.Value)) - { - Body.Shake(); - return; - } - realm.Write(r => r.Add(new ModPreset { Name = nameTextBox.Current.Value, diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs index 77980ea629..451c1ec712 100644 --- a/osu.Game/Overlays/Mods/EditPresetPopover.cs +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Mods private readonly LabelledTextBox nameTextBox; private readonly LabelledTextBox descriptionTextBox; private readonly ShearedButton useCurrentModButton; - private readonly ShearedButton createButton; + private readonly ShearedButton editButton; private readonly FillFlowContainer scrollContent; private readonly ModPreset preset; @@ -97,12 +97,12 @@ namespace osu.Game.Overlays.Mods Text = "Use Current Mods", Action = saveCurrentMod }, - createButton = new ShearedButton + editButton = new ShearedButton { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Text = Resources.Localisation.Web.CommonStrings.ButtonsSave, - Action = tryEditPreset + Action = editPreset }, } } @@ -119,9 +119,9 @@ namespace osu.Game.Overlays.Mods nameTextBox.Current.Value = preset.Name; descriptionTextBox.Current.Value = preset.Description; - createButton.DarkerColour = colours.Orange1; - createButton.LighterColour = colours.Orange0; - createButton.TextColour = colourProvider.Background6; + editButton.DarkerColour = colours.Orange1; + editButton.LighterColour = colours.Orange0; + editButton.TextColour = colourProvider.Background6; useCurrentModButton.DarkerColour = colours.Blue1; useCurrentModButton.LighterColour = colours.Blue0; @@ -130,6 +130,11 @@ namespace osu.Game.Overlays.Mods selectedMods.BindValueChanged(_ => updateActiveState(), true); scrollContent.ChildrenEnumerable = preset.Mods.Select(mod => new ModPresetRow(mod)); + + nameTextBox.Current.BindValueChanged(s => + { + editButton.Enabled.Value = !string.IsNullOrWhiteSpace(s.NewValue); + }, true); } private void saveCurrentMod() @@ -165,14 +170,8 @@ namespace osu.Game.Overlays.Mods ScheduleAfterChildren(() => GetContainingInputManager().ChangeFocus(nameTextBox)); } - private void tryEditPreset() + private void editPreset() { - if (string.IsNullOrWhiteSpace(nameTextBox.Current.Value)) - { - Body.Shake(); - return; - } - button.Preset.PerformWrite(s => { s.Name = nameTextBox.Current.Value; From debbd376bd6e8155612ea8a2b6e2fe1db2a9c884 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 3 May 2023 23:24:14 +0900 Subject: [PATCH 2813/2991] move `scrollContent` update logic to `updateActiveState()` --- osu.Game/Overlays/Mods/EditPresetPopover.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs index 451c1ec712..e96168d8ff 100644 --- a/osu.Game/Overlays/Mods/EditPresetPopover.cs +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -129,8 +129,6 @@ namespace osu.Game.Overlays.Mods selectedMods.BindValueChanged(_ => updateActiveState(), true); - scrollContent.ChildrenEnumerable = preset.Mods.Select(mod => new ModPresetRow(mod)); - nameTextBox.Current.BindValueChanged(s => { editButton.Enabled.Value = !string.IsNullOrWhiteSpace(s.NewValue); @@ -141,12 +139,12 @@ namespace osu.Game.Overlays.Mods { saveModAfterClosed = selectedMods.Value.ToList(); scrollContent.Clear(); - scrollContent.ChildrenEnumerable = saveModAfterClosed.Select(mod => new ModPresetRow(mod)); updateActiveState(); } private void updateActiveState() { + scrollContent.ChildrenEnumerable = preset.Mods.Select(mod => new ModPresetRow(mod)); useCurrentModButton.Enabled.Value = checkCanBeSave(); } From 967e801f9c77cc4b745fd32625c674fd708d25e9 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Wed, 3 May 2023 23:26:58 +0900 Subject: [PATCH 2814/2991] code inspect --- osu.Game/Overlays/Mods/AddPresetPopover.cs | 1 - osu.Game/Overlays/Mods/EditPresetPopover.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/osu.Game/Overlays/Mods/AddPresetPopover.cs b/osu.Game/Overlays/Mods/AddPresetPopover.cs index 6fd4231f2c..d9e350e560 100644 --- a/osu.Game/Overlays/Mods/AddPresetPopover.cs +++ b/osu.Game/Overlays/Mods/AddPresetPopover.cs @@ -9,7 +9,6 @@ using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Database; -using osu.Game.Extensions; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs index e96168d8ff..7f7b9472a7 100644 --- a/osu.Game/Overlays/Mods/EditPresetPopover.cs +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -8,7 +8,6 @@ using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Extensions; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; From d1d4b54c640df278987ff8ba8ccad28519e59e44 Mon Sep 17 00:00:00 2001 From: Terochi Date: Wed, 3 May 2023 18:31:35 +0200 Subject: [PATCH 2815/2991] Simplified --- osu.Game/OsuGameBase.cs | 46 +++++++++++++---------------------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index e6d6deabe9..076c1213ad 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -625,40 +625,22 @@ namespace osu.Game return; } - var previouslySelectedCommonMods = new List(SelectedMods.Value.Count); - var convertedCommonMods = new List(SelectedMods.Value.Count); - - foreach (var mod in SelectedMods.Value) - { - var convertedMod = instance.CreateModFromAcronym(mod.Acronym); - - if (convertedMod == null) - continue; - - previouslySelectedCommonMods.Add(mod); - - convertedMod.CopyCommonSettings(mod); - convertedCommonMods.Add(convertedMod); - } - - if (!ModUtils.CheckValidForGameplay(convertedCommonMods, out var invalid)) - { - invalid.ForEach(mod => - { - int index = convertedCommonMods.IndexOf(mod); - convertedCommonMods.RemoveAt(index); - previouslySelectedCommonMods.RemoveAt(index); - }); - } - - if (!SelectedMods.Disabled) - // Select common mods to play the deselect samples for other mods - SelectedMods.Value = previouslySelectedCommonMods; - AvailableMods.Value = dict; - if (!SelectedMods.Disabled) - SelectedMods.Value = convertedCommonMods; + if (SelectedMods.Disabled) + return; + + var convertedMods = SelectedMods.Value.Select(mod => + { + var newMod = instance.CreateModFromAcronym(mod.Acronym); + newMod?.CopyCommonSettings(mod); + return newMod; + }).Where(newMod => newMod != null).ToList(); + + if (!ModUtils.CheckValidForGameplay(convertedMods, out var invalid)) + invalid.ForEach(newMod => convertedMods.Remove(newMod)); + + SelectedMods.Value = convertedMods; void revertRulesetChange() => Ruleset.Value = r.OldValue?.Available == true ? r.OldValue : RulesetStore.AvailableRulesets.First(); } From 27fabd99fbc996705e5f700ebdc96f028c035872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 3 May 2023 19:21:16 +0200 Subject: [PATCH 2816/2991] Rename variables for legibility Having `typedComponents` and `typeComponents` next to each other is asking for trouble. --- .../Overlays/SkinEditor/SkinEditorChangeHandler.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs index 3dddf639cc..f3c5bc9ce2 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs @@ -61,16 +61,16 @@ namespace osu.Game.Overlays.SkinEditor ISerialisableDrawable[] targetComponents = firstTarget.Components.ToArray(); // Store components based on type for later lookup - var typedComponents = new Dictionary>(); + var componentsPerTypeLookup = new Dictionary>(); foreach (ISerialisableDrawable component in targetComponents) { Type lookup = component.GetType(); - if (!typedComponents.TryGetValue(lookup, out Queue? typeComponents)) - typedComponents.Add(lookup, typeComponents = new Queue()); + if (!componentsPerTypeLookup.TryGetValue(lookup, out Queue? componentsOfSameType)) + componentsPerTypeLookup.Add(lookup, componentsOfSameType = new Queue()); - typeComponents.Enqueue((Drawable)component); + componentsOfSameType.Enqueue((Drawable)component); } // Remove all components @@ -81,13 +81,13 @@ namespace osu.Game.Overlays.SkinEditor { Type lookup = skinnableInfo.Type; - if (!typedComponents.TryGetValue(lookup, out Queue? typeComponents)) + if (!componentsPerTypeLookup.TryGetValue(lookup, out Queue? componentsOfSameType)) { firstTarget.Add((ISerialisableDrawable)skinnableInfo.CreateInstance()); continue; } - if (typeComponents.TryDequeue(out Drawable? component)) + if (componentsOfSameType.TryDequeue(out Drawable? component)) { // Re-use unused component component.ApplySerialisedInfo(skinnableInfo); @@ -101,7 +101,7 @@ namespace osu.Game.Overlays.SkinEditor firstTarget.Add((ISerialisableDrawable)component); } - foreach ((Type _, Queue typeComponents) in typedComponents) + foreach ((Type _, Queue typeComponents) in componentsPerTypeLookup) { // Dispose extra components foreach (var component in typeComponents) From 1d4d31e35c8b85eb5104734a25b971ec8c827ad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 3 May 2023 19:22:52 +0200 Subject: [PATCH 2817/2991] Trim comments Leaving only the ones that add anything useful and do not restate the code verbatim. --- osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs index f3c5bc9ce2..673ba873c4 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditorChangeHandler.cs @@ -60,7 +60,7 @@ namespace osu.Game.Overlays.SkinEditor SerialisedDrawableInfo[] skinnableInfos = deserializedContent.ToArray(); ISerialisableDrawable[] targetComponents = firstTarget.Components.ToArray(); - // Store components based on type for later lookup + // Store components based on type for later reuse var componentsPerTypeLookup = new Dictionary>(); foreach (ISerialisableDrawable component in targetComponents) @@ -73,7 +73,6 @@ namespace osu.Game.Overlays.SkinEditor componentsOfSameType.Enqueue((Drawable)component); } - // Remove all components for (int i = targetComponents.Length - 1; i >= 0; i--) firstTarget.Remove(targetComponents[i], false); @@ -87,23 +86,22 @@ namespace osu.Game.Overlays.SkinEditor continue; } + // Wherever possible, attempt to reuse existing component instances. if (componentsOfSameType.TryDequeue(out Drawable? component)) { - // Re-use unused component component.ApplySerialisedInfo(skinnableInfo); } else { - // Create new one component = skinnableInfo.CreateInstance(); } firstTarget.Add((ISerialisableDrawable)component); } + // Dispose components which were not reused. foreach ((Type _, Queue typeComponents) in componentsPerTypeLookup) { - // Dispose extra components foreach (var component in typeComponents) component.Dispose(); } From 0a584f065235d3317067b9ed2860a686fe419122 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 May 2023 11:07:09 +0900 Subject: [PATCH 2818/2991] Simplify check logic and improve variable naming --- osu.Game/Overlays/Mods/EditPresetPopover.cs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs index 7f7b9472a7..9015218910 100644 --- a/osu.Game/Overlays/Mods/EditPresetPopover.cs +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -29,7 +29,8 @@ namespace osu.Game.Overlays.Mods private readonly FillFlowContainer scrollContent; private readonly ModPreset preset; - private List saveModAfterClosed = new List(); + + private HashSet? newMods; [Resolved] private Bindable> selectedMods { get; set; } = null!; @@ -136,7 +137,7 @@ namespace osu.Game.Overlays.Mods private void saveCurrentMod() { - saveModAfterClosed = selectedMods.Value.ToList(); + newMods = selectedMods.Value.ToHashSet(); scrollContent.Clear(); updateActiveState(); } @@ -144,18 +145,16 @@ namespace osu.Game.Overlays.Mods private void updateActiveState() { scrollContent.ChildrenEnumerable = preset.Mods.Select(mod => new ModPresetRow(mod)); - useCurrentModButton.Enabled.Value = checkCanBeSave(); + useCurrentModButton.Enabled.Value = checkSelectedModsDiffersFromSaved(); } - private bool checkCanBeSave() + private bool checkSelectedModsDiffersFromSaved() { if (!selectedMods.Value.Any()) return false; - if (saveModAfterClosed.Any()) - { - return !new HashSet(saveModAfterClosed).SetEquals(selectedMods.Value); - } + if (newMods?.SetEquals(selectedMods.Value) == false) + return true; return button.CheckCurrentModCanBeSave(); } @@ -174,10 +173,8 @@ namespace osu.Game.Overlays.Mods s.Name = nameTextBox.Current.Value; s.Description = descriptionTextBox.Current.Value; - if (saveModAfterClosed.Any()) - { - s.Mods = saveModAfterClosed; - } + if (newMods != null) + s.Mods = newMods; }); this.HidePopover(); From b7abab6d8aff61e2e79c17f7fd367999f72857de Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 May 2023 11:10:05 +0900 Subject: [PATCH 2819/2991] More variable improvements --- osu.Game/Overlays/Mods/EditPresetPopover.cs | 32 ++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs index 9015218910..91beea8e38 100644 --- a/osu.Game/Overlays/Mods/EditPresetPopover.cs +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -24,8 +24,8 @@ namespace osu.Game.Overlays.Mods private readonly LabelledTextBox nameTextBox; private readonly LabelledTextBox descriptionTextBox; - private readonly ShearedButton useCurrentModButton; - private readonly ShearedButton editButton; + private readonly ShearedButton useCurrentModsButton; + private readonly ShearedButton saveButton; private readonly FillFlowContainer scrollContent; private readonly ModPreset preset; @@ -90,19 +90,19 @@ namespace osu.Game.Overlays.Mods Spacing = new Vector2(7), Children = new Drawable[] { - useCurrentModButton = new ShearedButton + useCurrentModsButton = new ShearedButton { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Text = "Use Current Mods", - Action = saveCurrentMod + Action = useCurrentMods }, - editButton = new ShearedButton + saveButton = new ShearedButton { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Text = Resources.Localisation.Web.CommonStrings.ButtonsSave, - Action = editPreset + Action = save }, } } @@ -119,23 +119,23 @@ namespace osu.Game.Overlays.Mods nameTextBox.Current.Value = preset.Name; descriptionTextBox.Current.Value = preset.Description; - editButton.DarkerColour = colours.Orange1; - editButton.LighterColour = colours.Orange0; - editButton.TextColour = colourProvider.Background6; + saveButton.DarkerColour = colours.Orange1; + saveButton.LighterColour = colours.Orange0; + saveButton.TextColour = colourProvider.Background6; - useCurrentModButton.DarkerColour = colours.Blue1; - useCurrentModButton.LighterColour = colours.Blue0; - useCurrentModButton.TextColour = colourProvider.Background6; + useCurrentModsButton.DarkerColour = colours.Blue1; + useCurrentModsButton.LighterColour = colours.Blue0; + useCurrentModsButton.TextColour = colourProvider.Background6; selectedMods.BindValueChanged(_ => updateActiveState(), true); nameTextBox.Current.BindValueChanged(s => { - editButton.Enabled.Value = !string.IsNullOrWhiteSpace(s.NewValue); + saveButton.Enabled.Value = !string.IsNullOrWhiteSpace(s.NewValue); }, true); } - private void saveCurrentMod() + private void useCurrentMods() { newMods = selectedMods.Value.ToHashSet(); scrollContent.Clear(); @@ -145,7 +145,7 @@ namespace osu.Game.Overlays.Mods private void updateActiveState() { scrollContent.ChildrenEnumerable = preset.Mods.Select(mod => new ModPresetRow(mod)); - useCurrentModButton.Enabled.Value = checkSelectedModsDiffersFromSaved(); + useCurrentModsButton.Enabled.Value = checkSelectedModsDiffersFromSaved(); } private bool checkSelectedModsDiffersFromSaved() @@ -166,7 +166,7 @@ namespace osu.Game.Overlays.Mods ScheduleAfterChildren(() => GetContainingInputManager().ChangeFocus(nameTextBox)); } - private void editPreset() + private void save() { button.Preset.PerformWrite(s => { From be995f1359e19de4d9573fe1ad76645400c0949b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 May 2023 11:11:19 +0900 Subject: [PATCH 2820/2991] Add localisation support for new button string --- osu.Game/Localisation/ModSelectOverlayStrings.cs | 5 +++++ osu.Game/Overlays/Mods/EditPresetPopover.cs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Localisation/ModSelectOverlayStrings.cs b/osu.Game/Localisation/ModSelectOverlayStrings.cs index d6a01c4794..f11c52ee20 100644 --- a/osu.Game/Localisation/ModSelectOverlayStrings.cs +++ b/osu.Game/Localisation/ModSelectOverlayStrings.cs @@ -34,6 +34,11 @@ namespace osu.Game.Localisation /// public static LocalisableString AddPreset => new TranslatableString(getKey(@"add_preset"), @"Add preset"); + /// + /// "Use current mods" + /// + public static LocalisableString UseCurrentMods => new TranslatableString(getKey(@"use_current_mods"), @"Use current mods"); + private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs index 91beea8e38..b826bdf944 100644 --- a/osu.Game/Overlays/Mods/EditPresetPopover.cs +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -94,7 +94,7 @@ namespace osu.Game.Overlays.Mods { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - Text = "Use Current Mods", + Text = ModSelectOverlayStrings.UseCurrentMods, Action = useCurrentMods }, saveButton = new ShearedButton From 99d2616c34d51b8e4027543f01b73a8efe499475 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 May 2023 11:14:51 +0900 Subject: [PATCH 2821/2991] Move drawable construction to `load` for simplicity --- osu.Game/Overlays/Mods/EditPresetPopover.cs | 58 ++++++++++----------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs index b826bdf944..f02c200654 100644 --- a/osu.Game/Overlays/Mods/EditPresetPopover.cs +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -20,13 +20,13 @@ namespace osu.Game.Overlays.Mods { internal partial class EditPresetPopover : OsuPopover { - private readonly ModPresetPanel button; + private readonly ModPresetPanel presetPanel; - private readonly LabelledTextBox nameTextBox; - private readonly LabelledTextBox descriptionTextBox; - private readonly ShearedButton useCurrentModsButton; - private readonly ShearedButton saveButton; - private readonly FillFlowContainer scrollContent; + private LabelledTextBox nameTextBox = null!; + private LabelledTextBox descriptionTextBox = null!; + private ShearedButton useCurrentModsButton = null!; + private ShearedButton saveButton = null!; + private FillFlowContainer scrollContent = null!; private readonly ModPreset preset; @@ -41,11 +41,15 @@ namespace osu.Game.Overlays.Mods [Resolved] private OverlayColourProvider colourProvider { get; set; } = null!; - public EditPresetPopover(ModPresetPanel modPresetPanel) + public EditPresetPopover(ModPresetPanel presetPanel) { - button = modPresetPanel; - preset = button.Preset.Value; + this.presetPanel = presetPanel; + preset = presetPanel.Preset.Value; + } + [BackgroundDependencyLoader] + private void load() + { Child = new FillFlowContainer { Width = 300, @@ -59,14 +63,16 @@ namespace osu.Game.Overlays.Mods Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Label = CommonStrings.Name, - TabbableContentContainer = this + TabbableContentContainer = this, + Current = { Value = preset.Name }, }, descriptionTextBox = new LabelledTextBox { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Label = CommonStrings.Description, - TabbableContentContainer = this + TabbableContentContainer = this, + Current = { Value = preset.Description }, }, new OsuScrollContainer { @@ -95,40 +101,30 @@ namespace osu.Game.Overlays.Mods Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Text = ModSelectOverlayStrings.UseCurrentMods, - Action = useCurrentMods + DarkerColour = colours.Blue1, + LighterColour = colours.Blue0, + TextColour = colourProvider.Background6, + Action = useCurrentMods, }, saveButton = new ShearedButton { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Text = Resources.Localisation.Web.CommonStrings.ButtonsSave, - Action = save + DarkerColour = colours.Orange1, + LighterColour = colours.Orange0, + TextColour = colourProvider.Background6, + Action = save, }, } } } }; - } - [BackgroundDependencyLoader] - private void load() - { Body.BorderThickness = 3; Body.BorderColour = colours.Orange1; - nameTextBox.Current.Value = preset.Name; - descriptionTextBox.Current.Value = preset.Description; - - saveButton.DarkerColour = colours.Orange1; - saveButton.LighterColour = colours.Orange0; - saveButton.TextColour = colourProvider.Background6; - - useCurrentModsButton.DarkerColour = colours.Blue1; - useCurrentModsButton.LighterColour = colours.Blue0; - useCurrentModsButton.TextColour = colourProvider.Background6; - selectedMods.BindValueChanged(_ => updateActiveState(), true); - nameTextBox.Current.BindValueChanged(s => { saveButton.Enabled.Value = !string.IsNullOrWhiteSpace(s.NewValue); @@ -156,7 +152,7 @@ namespace osu.Game.Overlays.Mods if (newMods?.SetEquals(selectedMods.Value) == false) return true; - return button.CheckCurrentModCanBeSave(); + return presetPanel.CheckCurrentModCanBeSave(); } protected override void LoadComplete() @@ -168,7 +164,7 @@ namespace osu.Game.Overlays.Mods private void save() { - button.Preset.PerformWrite(s => + presetPanel.Preset.PerformWrite(s => { s.Name = nameTextBox.Current.Value; s.Description = descriptionTextBox.Current.Value; From b12d139317b55d47046eb0eaaf50756aaf07fb67 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 May 2023 11:16:52 +0900 Subject: [PATCH 2822/2991] Remove dead code --- osu.Game/Overlays/Mods/ModPresetPanel.cs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModPresetPanel.cs b/osu.Game/Overlays/Mods/ModPresetPanel.cs index 6999f2cede..3f5a764ab1 100644 --- a/osu.Game/Overlays/Mods/ModPresetPanel.cs +++ b/osu.Game/Overlays/Mods/ModPresetPanel.cs @@ -98,18 +98,6 @@ namespace osu.Game.Overlays.Mods #endregion - public bool SaveCurrentMod() - { - if (!CheckCurrentModCanBeSave()) - return false; - - Preset.PerformWrite(s => - { - s.Mods = selectedMods.Value.ToArray(); - }); - return true; - } - public bool CheckCurrentModCanBeSave() => (!Active.Value && selectedMods.Value.Any()); protected override void Dispose(bool isDisposing) From 49fb5da1a237c30768f753d98d793733750bea5a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 May 2023 11:19:09 +0900 Subject: [PATCH 2823/2991] Stop passing preset panel to popover --- osu.Game/Overlays/Mods/EditPresetPopover.cs | 23 ++++++++------------- osu.Game/Overlays/Mods/ModPresetPanel.cs | 4 +--- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs index f02c200654..3f5eca8ad0 100644 --- a/osu.Game/Overlays/Mods/EditPresetPopover.cs +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -8,6 +8,7 @@ using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; @@ -20,15 +21,13 @@ namespace osu.Game.Overlays.Mods { internal partial class EditPresetPopover : OsuPopover { - private readonly ModPresetPanel presetPanel; - private LabelledTextBox nameTextBox = null!; private LabelledTextBox descriptionTextBox = null!; private ShearedButton useCurrentModsButton = null!; private ShearedButton saveButton = null!; private FillFlowContainer scrollContent = null!; - private readonly ModPreset preset; + private readonly Live preset; private HashSet? newMods; @@ -41,10 +40,9 @@ namespace osu.Game.Overlays.Mods [Resolved] private OverlayColourProvider colourProvider { get; set; } = null!; - public EditPresetPopover(ModPresetPanel presetPanel) + public EditPresetPopover(Live preset) { - this.presetPanel = presetPanel; - preset = presetPanel.Preset.Value; + this.preset = preset; } [BackgroundDependencyLoader] @@ -64,7 +62,7 @@ namespace osu.Game.Overlays.Mods Origin = Anchor.TopCentre, Label = CommonStrings.Name, TabbableContentContainer = this, - Current = { Value = preset.Name }, + Current = { Value = preset.PerformRead(p => p.Name) }, }, descriptionTextBox = new LabelledTextBox { @@ -72,7 +70,7 @@ namespace osu.Game.Overlays.Mods Origin = Anchor.TopCentre, Label = CommonStrings.Description, TabbableContentContainer = this, - Current = { Value = preset.Description }, + Current = { Value = preset.PerformRead(p => p.Description) }, }, new OsuScrollContainer { @@ -140,7 +138,7 @@ namespace osu.Game.Overlays.Mods private void updateActiveState() { - scrollContent.ChildrenEnumerable = preset.Mods.Select(mod => new ModPresetRow(mod)); + scrollContent.ChildrenEnumerable = preset.PerformRead(p => p.Mods.Select(mod => new ModPresetRow(mod))); useCurrentModsButton.Enabled.Value = checkSelectedModsDiffersFromSaved(); } @@ -149,10 +147,7 @@ namespace osu.Game.Overlays.Mods if (!selectedMods.Value.Any()) return false; - if (newMods?.SetEquals(selectedMods.Value) == false) - return true; - - return presetPanel.CheckCurrentModCanBeSave(); + return newMods?.SetEquals(selectedMods.Value) == false; } protected override void LoadComplete() @@ -164,7 +159,7 @@ namespace osu.Game.Overlays.Mods private void save() { - presetPanel.Preset.PerformWrite(s => + preset.PerformWrite(s => { s.Name = nameTextBox.Current.Value; s.Description = descriptionTextBox.Current.Value; diff --git a/osu.Game/Overlays/Mods/ModPresetPanel.cs b/osu.Game/Overlays/Mods/ModPresetPanel.cs index 3f5a764ab1..8bcb5e4e4e 100644 --- a/osu.Game/Overlays/Mods/ModPresetPanel.cs +++ b/osu.Game/Overlays/Mods/ModPresetPanel.cs @@ -98,8 +98,6 @@ namespace osu.Game.Overlays.Mods #endregion - public bool CheckCurrentModCanBeSave() => (!Active.Value && selectedMods.Value.Any()); - protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); @@ -107,6 +105,6 @@ namespace osu.Game.Overlays.Mods settingChangeTracker?.Dispose(); } - public Popover GetPopover() => new EditPresetPopover(this); + public Popover GetPopover() => new EditPresetPopover(Preset); } } From 26b8c5b852d31b1e0d340d0926821dfcd0910fa5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 May 2023 11:23:51 +0900 Subject: [PATCH 2824/2991] Fix mod list display not updating after clicking "use current" This is not a regression from my changes. It was broken before them. --- osu.Game/Overlays/Mods/EditPresetPopover.cs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs index 3f5eca8ad0..82d0bdb51e 100644 --- a/osu.Game/Overlays/Mods/EditPresetPopover.cs +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Mods private readonly Live preset; - private HashSet? newMods; + private HashSet saveableMods; [Resolved] private Bindable> selectedMods { get; set; } = null!; @@ -43,6 +43,7 @@ namespace osu.Game.Overlays.Mods public EditPresetPopover(Live preset) { this.preset = preset; + saveableMods = preset.PerformRead(p => p.Mods).ToHashSet(); } [BackgroundDependencyLoader] @@ -122,7 +123,7 @@ namespace osu.Game.Overlays.Mods Body.BorderThickness = 3; Body.BorderColour = colours.Orange1; - selectedMods.BindValueChanged(_ => updateActiveState(), true); + selectedMods.BindValueChanged(_ => updateState(), true); nameTextBox.Current.BindValueChanged(s => { saveButton.Enabled.Value = !string.IsNullOrWhiteSpace(s.NewValue); @@ -131,14 +132,14 @@ namespace osu.Game.Overlays.Mods private void useCurrentMods() { - newMods = selectedMods.Value.ToHashSet(); + saveableMods = selectedMods.Value.ToHashSet(); scrollContent.Clear(); - updateActiveState(); + updateState(); } - private void updateActiveState() + private void updateState() { - scrollContent.ChildrenEnumerable = preset.PerformRead(p => p.Mods.Select(mod => new ModPresetRow(mod))); + scrollContent.ChildrenEnumerable = saveableMods.Select(mod => new ModPresetRow(mod)); useCurrentModsButton.Enabled.Value = checkSelectedModsDiffersFromSaved(); } @@ -147,7 +148,7 @@ namespace osu.Game.Overlays.Mods if (!selectedMods.Value.Any()) return false; - return newMods?.SetEquals(selectedMods.Value) == false; + return !saveableMods.SetEquals(selectedMods.Value); } protected override void LoadComplete() @@ -163,9 +164,7 @@ namespace osu.Game.Overlays.Mods { s.Name = nameTextBox.Current.Value; s.Description = descriptionTextBox.Current.Value; - - if (newMods != null) - s.Mods = newMods; + s.Mods = saveableMods; }); this.HidePopover(); From 0034124d79ee949f00dc5ec7fcd98fe8780d250e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 May 2023 11:25:10 +0900 Subject: [PATCH 2825/2991] Remove unnecessary content clear --- osu.Game/Overlays/Mods/EditPresetPopover.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs index 82d0bdb51e..5220f6a391 100644 --- a/osu.Game/Overlays/Mods/EditPresetPopover.cs +++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs @@ -133,7 +133,6 @@ namespace osu.Game.Overlays.Mods private void useCurrentMods() { saveableMods = selectedMods.Value.ToHashSet(); - scrollContent.Clear(); updateState(); } From 95b541ab39169f3f46e534c7652b0246e416bbf2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 May 2023 11:27:18 +0900 Subject: [PATCH 2826/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 3ede0b85da..59bef84bd2 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -11,7 +11,7 @@ manifestmerger.jar - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 085f78b27b..404fbada95 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 127994c670..c4df0a2347 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -16,6 +16,6 @@ iossimulator-x64 - + From 2cb6642b0d8f805317f1458078e545c685c0a148 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Thu, 4 May 2023 13:18:25 +0900 Subject: [PATCH 2827/2991] use AddUntilStep or not wait --- osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 041556a5a6..339d861d3b 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -645,8 +645,7 @@ namespace osu.Game.Tests.Visual.Online InputManager.Click(MouseButton.Left); }); - AddWaitStep("Wait", 3); - AddAssert("Overlay closed", () => !this.ChildrenOfType().Any()); + AddUntilStep("Overlay closed", () => !this.ChildrenOfType().Any()); AddStep("Complete request", () => requestLock.Set()); AddUntilStep("Request sent", () => request != null); } From 0d2396c5575cd34864e42974b7c99218e4074c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 4 May 2023 18:15:12 +0200 Subject: [PATCH 2828/2991] Rename method to better indicate directionality --- osu.Game.Tests/Mods/ModSettingsTest.cs | 14 +++++++------- osu.Game/OsuGameBase.cs | 2 +- osu.Game/Rulesets/Mods/Mod.cs | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Mods/ModSettingsTest.cs b/osu.Game.Tests/Mods/ModSettingsTest.cs index b3f6f8da7d..4dcc4511db 100644 --- a/osu.Game.Tests/Mods/ModSettingsTest.cs +++ b/osu.Game.Tests/Mods/ModSettingsTest.cs @@ -45,12 +45,12 @@ namespace osu.Game.Tests.Mods var modBool = new TestNonMatchingSettingTypeModBool { TestSetting = { Default = false, Value = true } }; var modInt = new TestNonMatchingSettingTypeModInt { TestSetting = { Value = (int)setting_change / 2 } }; - modDouble.CopyCommonSettings(modBool); - modDouble.CopyCommonSettings(modInt); - modBool.CopyCommonSettings(modDouble); - modBool.CopyCommonSettings(modInt); - modInt.CopyCommonSettings(modDouble); - modInt.CopyCommonSettings(modBool); + modDouble.CopyCommonSettingsFrom(modBool); + modDouble.CopyCommonSettingsFrom(modInt); + modBool.CopyCommonSettingsFrom(modDouble); + modBool.CopyCommonSettingsFrom(modInt); + modInt.CopyCommonSettingsFrom(modDouble); + modInt.CopyCommonSettingsFrom(modBool); Assert.That(modDouble.TestSetting.Value, Is.EqualTo(setting_change)); Assert.That(modBool.TestSetting.Value, Is.EqualTo(!modBool.TestSetting.Default)); @@ -63,7 +63,7 @@ namespace osu.Game.Tests.Mods var modBoolTrue = new TestNonMatchingSettingTypeModBool { TestSetting = { Default = true, Value = false } }; var modBoolFalse = new TestNonMatchingSettingTypeModBool { TestSetting = { Default = false, Value = true } }; - modBoolFalse.CopyCommonSettings(modBoolTrue); + modBoolFalse.CopyCommonSettingsFrom(modBoolTrue); Assert.That(modBoolFalse.TestSetting.Default, Is.EqualTo(false)); Assert.That(modBoolFalse.TestSetting.Value, Is.EqualTo(modBoolTrue.TestSetting.Value)); diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 076c1213ad..c55b6c249f 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -633,7 +633,7 @@ namespace osu.Game var convertedMods = SelectedMods.Value.Select(mod => { var newMod = instance.CreateModFromAcronym(mod.Acronym); - newMod?.CopyCommonSettings(mod); + newMod?.CopyCommonSettingsFrom(mod); return newMod; }).Where(newMod => newMod != null).ToList(); diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 0af8717264..cf5a1c6fcc 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -168,7 +168,7 @@ namespace osu.Game.Rulesets.Mods /// /// Copied values are unchanged, even if they have different clamping ranges. /// The mod to extract settings from. - public void CopyCommonSettings(Mod source) + public void CopyCommonSettingsFrom(Mod source) { if (source.UsesDefaultConfiguration) return; From 26337dbcd8c7ca314cf0a8034ee2a6cdad9058b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 4 May 2023 18:26:45 +0200 Subject: [PATCH 2829/2991] Do not rely on unspecified `Dictionary.Values` ordering --- osu.Game/Rulesets/Mods/Mod.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index cf5a1c6fcc..db7e7ce8e3 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -119,7 +119,11 @@ namespace osu.Game.Rulesets.Mods /// /// All settings within this mod. /// - internal IEnumerable SettingsBindables => Settings.Values; + /// + /// The settings are returned in ascending key order as per . + /// The ordering is intentionally enforced manually, as ordering of is unspecified. + /// + internal IEnumerable SettingsBindables => Settings.OrderBy(pair => pair.Key).Select(pair => pair.Value); /// /// Provides mapping of names to s of all settings within this mod. From 88e77ad390fad33752395905260f97ed95f86def Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 4 May 2023 18:30:41 +0200 Subject: [PATCH 2830/2991] Rename `Settings{-> Map}` --- osu.Game/Rulesets/Mods/Mod.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index db7e7ce8e3..cd89b45a5e 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -120,15 +120,15 @@ namespace osu.Game.Rulesets.Mods /// All settings within this mod. /// /// - /// The settings are returned in ascending key order as per . + /// The settings are returned in ascending key order as per . /// The ordering is intentionally enforced manually, as ordering of is unspecified. /// - internal IEnumerable SettingsBindables => Settings.OrderBy(pair => pair.Key).Select(pair => pair.Value); + internal IEnumerable SettingsBindables => SettingsMap.OrderBy(pair => pair.Key).Select(pair => pair.Value); /// /// Provides mapping of names to s of all settings within this mod. /// - internal IReadOnlyDictionary Settings => + internal IReadOnlyDictionary SettingsMap => settingsBacking ??= this.GetSettingsSourceProperties() .Select(p => p.Item2) .ToDictionary(property => property.Name.ToSnakeCase(), property => (IBindable)property.GetValue(this)!); @@ -177,9 +177,9 @@ namespace osu.Game.Rulesets.Mods if (source.UsesDefaultConfiguration) return; - foreach (var (name, targetSetting) in Settings) + foreach (var (name, targetSetting) in SettingsMap) { - if (!source.Settings.TryGetValue(name, out IBindable? sourceSetting)) + if (!source.SettingsMap.TryGetValue(name, out IBindable? sourceSetting)) continue; if (sourceSetting.IsDefault) From 1f1342b099752b99de109a2fc6a6fcbaa9b37bbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 4 May 2023 18:33:49 +0200 Subject: [PATCH 2831/2991] Reword xmldoc --- osu.Game/Rulesets/Mods/Mod.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index cd89b45a5e..f5ccde01cf 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -167,10 +167,13 @@ namespace osu.Game.Rulesets.Mods } /// - /// When converting mods from one ruleset to the other, this method makes sure - /// to also copy the values of all settings sharing same between the two instances. + /// This method copies the values of all settings from that share the same names with this mod instance. + /// The most frequent use of this is when switching rulesets, in order to preserve values of common settings during the switch. /// - /// Copied values are unchanged, even if they have different clamping ranges. + /// + /// The values are copied directly, without adjusting for possibly different allowed ranges of values. + /// If the value of a setting is not valid for this instance due to not falling inside of the allowed range, it will be clamped accordingly. + /// /// The mod to extract settings from. public void CopyCommonSettingsFrom(Mod source) { From e43fc23606e4b579fdf46ee54aa3fb144bb85d5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 4 May 2023 18:46:36 +0200 Subject: [PATCH 2832/2991] Fix typos in test --- .../Visual/UserInterface/TestSceneModPresetColumn.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs index 0cbbe00311..3efdba8754 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModPresetColumn.cs @@ -262,7 +262,7 @@ namespace osu.Game.Tests.Visual.UserInterface } [Test] - public void TestEditPresentName() + public void TestEditPresetName() { ModPresetColumn modPresetColumn = null!; string presetName = null!; @@ -301,7 +301,7 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.Click(MouseButton.Left); }); - AddAssert("present is not changed", () => panel.Preset.Value.Name == presetName); + AddAssert("preset is not changed", () => panel.Preset.Value.Name == presetName); AddUntilStep("popover is unchanged", () => this.ChildrenOfType().FirstOrDefault() == popover); AddStep("edit preset name", () => popover.ChildrenOfType().First().Current.Value = "something new"); AddStep("attempt preset edit", () => @@ -310,7 +310,7 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.Click(MouseButton.Left); }); AddUntilStep("popover closed", () => !this.ChildrenOfType().Any()); - AddAssert("present is changed", () => panel.Preset.Value.Name != presetName); + AddAssert("preset is changed", () => panel.Preset.Value.Name != presetName); } [Test] @@ -357,7 +357,7 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.Click(MouseButton.Left); }); - AddUntilStep("present mod not changed", () => + AddUntilStep("preset mod not changed", () => new HashSet(this.ChildrenOfType().First().Preset.Value.Mods).SetEquals(previousMod)); AddStep("select mods", () => SelectedMods.Value = mods); @@ -388,7 +388,7 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.Click(MouseButton.Left); }); - AddUntilStep("present mod is changed", () => + AddUntilStep("preset mod is changed", () => new HashSet(this.ChildrenOfType().First().Preset.Value.Mods).SetEquals(mods)); } From 485b7282dce5a7c220fa534e2f5f9655935270e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 4 May 2023 19:06:07 +0200 Subject: [PATCH 2833/2991] Clarify type check --- osu.Game/Rulesets/Mods/Mod.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index f5ccde01cf..787da926ea 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -188,10 +188,13 @@ namespace osu.Game.Rulesets.Mods if (sourceSetting.IsDefault) continue; - var targetType = targetSetting.GetType(); - var sourceType = sourceSetting.GetType(); + var targetBindableType = targetSetting.GetType(); + var sourceBindableType = sourceSetting.GetType(); - if (!targetType.IsAssignableFrom(sourceType) && !sourceType.IsAssignableFrom(targetType)) + // if either the target is assignable to the source or the source is assignable to the target, + // then we presume that the data types contained in both bindables are compatible and we can proceed with the copy. + // this handles cases like `Bindable` and `BindableInt`. + if (!targetBindableType.IsAssignableFrom(sourceBindableType) && !sourceBindableType.IsAssignableFrom(targetBindableType)) continue; // TODO: special case for handling number types From aa7885ab973a258c350ad26c19bc51d89befdf51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 4 May 2023 19:11:51 +0200 Subject: [PATCH 2834/2991] Use better test step names --- .../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 b4b5052f23..f079b65e23 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs @@ -399,7 +399,7 @@ namespace osu.Game.Tests.Visual.UserInterface changeRuleset(1); AddAssert("taiko variant selected", () => SelectedMods.Value.SingleOrDefault() is TaikoModDifficultyAdjust); - AddAssert("shared settings didn't change", () => + AddAssert("shared settings preserved", () => { var taikoMod = getMod(); @@ -408,7 +408,7 @@ namespace osu.Game.Tests.Visual.UserInterface taikoMod.OverallDifficulty.Value == setting_change; }); - AddAssert("non-shared settings unchanged", () => + AddAssert("non-shared settings remain default", () => { var taikoMod = getMod(); From 99e8b2ce70276a34d648960556373917b50d0e46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 4 May 2023 19:12:22 +0200 Subject: [PATCH 2835/2991] Make `getMod()` method generally better --- .../Visual/UserInterface/TestSceneModSelectOverlay.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs index f079b65e23..9993893a99 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs @@ -387,7 +387,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("change mod settings", () => { - var osuMod = getMod(); + var osuMod = getSelectedMod(); osuMod.ExtendedLimits.Value = true; osuMod.CircleSize.Value = setting_change; @@ -401,7 +401,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("shared settings preserved", () => { - var taikoMod = getMod(); + var taikoMod = getSelectedMod(); return taikoMod.ExtendedLimits.Value && taikoMod.DrainRate.Value == setting_change && @@ -410,7 +410,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("non-shared settings remain default", () => { - var taikoMod = getMod(); + var taikoMod = getSelectedMod(); return taikoMod.ScrollSpeed.IsDefault; }); @@ -626,7 +626,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert($"customisation toggle is {(active ? "" : "not ")}active", () => modSelectOverlay.CustomisationButton.AsNonNull().Active.Value == active); } - private T getMod() where T : Mod => (T)SelectedMods.Value.Single(); + private T getSelectedMod() where T : Mod => SelectedMods.Value.OfType().Single(); private ModPanel getPanelForMod(Type modType) => modSelectOverlay.ChildrenOfType().Single(panel => panel.Mod.GetType() == modType); From a1106d0a4e0a2522122f945d283f92368714f4f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 4 May 2023 19:14:20 +0200 Subject: [PATCH 2836/2991] Be explicit in test --- osu.Game.Tests/Mods/ModSettingsTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Mods/ModSettingsTest.cs b/osu.Game.Tests/Mods/ModSettingsTest.cs index 4dcc4511db..5ec9629dc2 100644 --- a/osu.Game.Tests/Mods/ModSettingsTest.cs +++ b/osu.Game.Tests/Mods/ModSettingsTest.cs @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Mods modInt.CopyCommonSettingsFrom(modBool); Assert.That(modDouble.TestSetting.Value, Is.EqualTo(setting_change)); - Assert.That(modBool.TestSetting.Value, Is.EqualTo(!modBool.TestSetting.Default)); + Assert.That(modBool.TestSetting.Value, Is.EqualTo(true)); Assert.That(modInt.TestSetting.Value, Is.EqualTo((int)setting_change / 2)); } From dcd2abae6d5f7a196fae601854f08a794999c470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 4 May 2023 20:46:27 +0200 Subject: [PATCH 2837/2991] Add test coverage for mod equality with multiple settings --- .../Mods/ModSettingsEqualityComparison.cs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/osu.Game.Tests/Mods/ModSettingsEqualityComparison.cs b/osu.Game.Tests/Mods/ModSettingsEqualityComparison.cs index cd6879cf01..a03b29f7bc 100644 --- a/osu.Game.Tests/Mods/ModSettingsEqualityComparison.cs +++ b/osu.Game.Tests/Mods/ModSettingsEqualityComparison.cs @@ -49,5 +49,31 @@ namespace osu.Game.Tests.Mods Assert.That(mod3, Is.EqualTo(mod2)); Assert.That(doubleConvertedMod3, Is.EqualTo(doubleConvertedMod2)); } + + [Test] + public void TestModWithMultipleSettings() + { + var ruleset = new OsuRuleset(); + + var mod1 = new OsuModDifficultyAdjust { OverallDifficulty = { Value = 10 }, CircleSize = { Value = 0 } }; + var mod2 = new OsuModDifficultyAdjust { OverallDifficulty = { Value = 10 }, CircleSize = { Value = 6 } }; + var mod3 = new OsuModDifficultyAdjust { OverallDifficulty = { Value = 10 }, CircleSize = { Value = 6 } }; + + var doubleConvertedMod1 = new APIMod(mod1).ToMod(ruleset); + var doubleConvertedMod2 = new APIMod(mod2).ToMod(ruleset); + var doubleConvertedMod3 = new APIMod(mod3).ToMod(ruleset); + + Assert.That(mod1, Is.Not.EqualTo(mod2)); + Assert.That(doubleConvertedMod1, Is.Not.EqualTo(doubleConvertedMod2)); + + Assert.That(mod2, Is.EqualTo(mod2)); + Assert.That(doubleConvertedMod2, Is.EqualTo(doubleConvertedMod2)); + + Assert.That(mod2, Is.EqualTo(mod3)); + Assert.That(doubleConvertedMod2, Is.EqualTo(doubleConvertedMod3)); + + Assert.That(mod3, Is.EqualTo(mod2)); + Assert.That(doubleConvertedMod3, Is.EqualTo(doubleConvertedMod2)); + } } } From 8391e2a538c7ca7777e2c04a9cdf90a9f191abf7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 13:58:13 +0900 Subject: [PATCH 2838/2991] Move reporting code out of `DrawableChatUsername` into more correct locations --- .../Visual/Online/TestSceneChatOverlay.cs | 2 +- osu.Game/Overlays/Chat/ChatLine.cs | 14 +++++--- .../Overlays/Chat/DrawableChatUsername.cs | 34 +++---------------- osu.Game/Overlays/Chat/ReportChatPopover.cs | 31 +++++++++++++++-- 4 files changed, 44 insertions(+), 37 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 339d861d3b..99ce837665 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -616,7 +616,7 @@ namespace osu.Game.Tests.Visual.Online }; }); - AddStep("Show report popover", () => this.ChildrenOfType().First().ShowPopover()); + AddStep("Show report popover", () => this.ChildrenOfType().First().ShowPopover()); AddStep("Set report reason to other", () => { diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index dca34128d1..2f4c175ac4 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -1,25 +1,28 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Online.Chat; -using osu.Framework.Graphics.Sprites; namespace osu.Game.Overlays.Chat { - public partial class ChatLine : CompositeDrawable + public partial class ChatLine : CompositeDrawable, IHasPopover { private Message message = null!; @@ -92,7 +95,7 @@ namespace osu.Game.Overlays.Chat Font = OsuFont.GetFont(size: FontSize * 0.75f, weight: FontWeight.SemiBold, fixedWidth: true), AlwaysPresent = true, }, - drawableUsername = new DrawableChatUsername(message.Sender, message.Id) + drawableUsername = new DrawableChatUsername(message.Sender) { Width = UsernameWidth, FontSize = FontSize, @@ -100,6 +103,7 @@ namespace osu.Game.Overlays.Chat Origin = Anchor.TopRight, Anchor = Anchor.TopRight, Margin = new MarginPadding { Horizontal = Spacing }, + ReportRequested = this.ShowPopover, }, drawableContentFlow = new LinkFlowContainer(styleMessageContent) { @@ -128,6 +132,8 @@ namespace osu.Game.Overlays.Chat FinishTransforms(true); } + public Popover GetPopover() => new ReportChatPopover(message); + /// /// Performs a highlight animation on this . /// diff --git a/osu.Game/Overlays/Chat/DrawableChatUsername.cs b/osu.Game/Overlays/Chat/DrawableChatUsername.cs index b3bbc74be7..4b4afc204c 100644 --- a/osu.Game/Overlays/Chat/DrawableChatUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableChatUsername.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -21,7 +20,6 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Localisation; using osu.Game.Online.API; -using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; using osu.Game.Resources.Localisation.Web; @@ -31,8 +29,10 @@ using ChatStrings = osu.Game.Localisation.ChatStrings; namespace osu.Game.Overlays.Chat { - public partial class DrawableChatUsername : OsuClickableContainer, IHasContextMenu, IHasPopover + public partial class DrawableChatUsername : OsuClickableContainer, IHasContextMenu { + public Action? ReportRequested; + public Color4 AccentColour { get; } public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => @@ -73,15 +73,13 @@ namespace osu.Game.Overlays.Chat private Bindable? currentChannel { get; set; } private readonly APIUser user; - private readonly long? messageId; private readonly OsuSpriteText drawableText; private readonly Drawable colouredDrawable; - public DrawableChatUsername(APIUser user, long? messageId) + public DrawableChatUsername(APIUser user) { this.user = user; - this.messageId = messageId; Action = openUserProfile; @@ -174,34 +172,12 @@ namespace osu.Game.Overlays.Chat } if (!user.Equals(api.LocalUser.Value)) - items.Add(new OsuMenuItem("Report", MenuItemType.Destructive, this.ShowPopover)); + items.Add(new OsuMenuItem("Report", MenuItemType.Destructive, ReportRequested)); return items.ToArray(); } } - public Popover GetPopover() => new ReportChatPopover(user) - { - Action = report - }; - - private void report(ChatReportReason reason, string comments) - { - var request = new ChatReportRequest(messageId, reason, comments); - - request.Failure += _ => Schedule(() => - { - currentChannel?.Value?.AddNewMessages(new ErrorMessage("Report failed to send, please retry")); - }); - - request.Success += () => Schedule(() => - { - currentChannel?.Value?.AddNewMessages(new InfoMessage("Report has been sent")); - }); - - api.Queue(request); - } - private void openUserChannel() { chatManager?.OpenPrivateChannel(user); diff --git a/osu.Game/Overlays/Chat/ReportChatPopover.cs b/osu.Game/Overlays/Chat/ReportChatPopover.cs index de5f3268b8..f02e52eb2e 100644 --- a/osu.Game/Overlays/Chat/ReportChatPopover.cs +++ b/osu.Game/Overlays/Chat/ReportChatPopover.cs @@ -1,22 +1,47 @@ // 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.Allocation; using osu.Game.Graphics.UserInterfaceV2; -using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.Chat; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Chat { public partial class ReportChatPopover : ReportPopover { - public ReportChatPopover(APIUser? user) - : base(ReportStrings.UserTitle(user?.Username ?? @"Someone")) + [Resolved] + private IAPIProvider api { get; set; } = null!; + + [Resolved] + private ChannelManager channelManager { get; set; } = null!; + + private readonly Message message; + + public ReportChatPopover(Message message) + : base(ReportStrings.UserTitle(message.Sender?.Username ?? @"Someone")) { + this.message = message; + Action = report; } protected override bool CheckCanSubmitEmptyComment(ChatReportReason reason) { return reason != ChatReportReason.Other; } + + private void report(ChatReportReason reason, string comments) + { + var request = new ChatReportRequest(message.Id, reason, comments); + + request.Success += () => Schedule(() => + { + channelManager.CurrentChannel.Value.AddNewMessages(new InfoMessage(UsersStrings.ReportThanks.ToString())); + }); + + api.Queue(request); + } } } From 560f71ef5366a673cd0f7e79ba55ef16c4c73610 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 14:29:03 +0900 Subject: [PATCH 2839/2991] Adjust `BlurredIcon` expansion ratio to fix glow getting cut off at lower resolutions Closes https://github.com/ppy/osu/issues/23210. Ballparked the fix to work down to the lowest resolution we support. The previous number (`2.5f`) was also likely ballparked so the fix seems in line with expectations. I don't want to put too much thought into this because the design of this screen is likely going to change in the mean time anyway. --- osu.Game/Screens/Play/Break/BlurredIcon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Break/BlurredIcon.cs b/osu.Game/Screens/Play/Break/BlurredIcon.cs index cd38390324..6ce1c2e686 100644 --- a/osu.Game/Screens/Play/Break/BlurredIcon.cs +++ b/osu.Game/Screens/Play/Break/BlurredIcon.cs @@ -27,7 +27,7 @@ namespace osu.Game.Screens.Play.Break set { icon.Size = value; - base.Size = value + BlurSigma * 2.5f; + base.Size = value + BlurSigma * 5; ForceRedraw(); } get => base.Size; From 76b2f0e6dd57f50c956cc38ede5565aa6bda522e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 15:15:18 +0900 Subject: [PATCH 2840/2991] Show slider velocity in hit object inspector --- osu.Game/Rulesets/Edit/HitObjectInspector.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Rulesets/Edit/HitObjectInspector.cs b/osu.Game/Rulesets/Edit/HitObjectInspector.cs index 977d00ede2..7eeee7a6e9 100644 --- a/osu.Game/Rulesets/Edit/HitObjectInspector.cs +++ b/osu.Game/Rulesets/Edit/HitObjectInspector.cs @@ -98,6 +98,12 @@ namespace osu.Game.Rulesets.Edit addValue($"{distance.Distance:#,0.##}px"); } + if (selected is IHasSliderVelocity sliderVelocity) + { + addHeader("Slider Velocity"); + addValue($"{sliderVelocity.SliderVelocity:#,0.00}x"); + } + if (selected is IHasRepeats repeats) { addHeader("Repeats"); From 4663057060ee71e79aba79bfd99594ba24ebad73 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 15:40:34 +0900 Subject: [PATCH 2841/2991] Split out `EditorInspector` implementation for reuse --- osu.Game/Rulesets/Edit/EditorInspector.cs | 50 ++++++++++ osu.Game/Rulesets/Edit/HitObjectInspector.cs | 99 ++++++-------------- 2 files changed, 79 insertions(+), 70 deletions(-) create mode 100644 osu.Game/Rulesets/Edit/EditorInspector.cs diff --git a/osu.Game/Rulesets/Edit/EditorInspector.cs b/osu.Game/Rulesets/Edit/EditorInspector.cs new file mode 100644 index 0000000000..ed7f305a28 --- /dev/null +++ b/osu.Game/Rulesets/Edit/EditorInspector.cs @@ -0,0 +1,50 @@ +// 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.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Overlays; +using osu.Game.Screens.Edit; + +namespace osu.Game.Rulesets.Edit +{ + internal partial class EditorInspector : CompositeDrawable + { + protected OsuTextFlowContainer InspectorText = null!; + + [Resolved] + protected EditorBeatmap EditorBeatmap { get; private set; } = null!; + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } = null!; + + [BackgroundDependencyLoader] + private void load() + { + AutoSizeAxes = Axes.Y; + RelativeSizeAxes = Axes.X; + + InternalChild = InspectorText = new OsuTextFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + }; + } + + protected void AddHeader(string header) => InspectorText.AddParagraph($"{header}: ", s => + { + s.Padding = new MarginPadding { Top = 2 }; + s.Font = s.Font.With(size: 12); + s.Colour = colourProvider.Content2; + }); + + protected void AddValue(string value) => InspectorText.AddParagraph(value, s => + { + s.Font = s.Font.With(weight: FontWeight.SemiBold); + s.Colour = colourProvider.Content1; + }); + } +} diff --git a/osu.Game/Rulesets/Edit/HitObjectInspector.cs b/osu.Game/Rulesets/Edit/HitObjectInspector.cs index 7eeee7a6e9..d13190e484 100644 --- a/osu.Game/Rulesets/Edit/HitObjectInspector.cs +++ b/osu.Game/Rulesets/Edit/HitObjectInspector.cs @@ -2,43 +2,15 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; -using osu.Framework.Allocation; using osu.Framework.Extensions.TypeExtensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Threading; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osu.Game.Overlays; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; -using osu.Game.Screens.Edit; namespace osu.Game.Rulesets.Edit { - internal partial class HitObjectInspector : CompositeDrawable + internal partial class HitObjectInspector : EditorInspector { - private OsuTextFlowContainer inspectorText = null!; - - [Resolved] - protected EditorBeatmap EditorBeatmap { get; private set; } = null!; - - [Resolved] - private OverlayColourProvider colourProvider { get; set; } = null!; - - [BackgroundDependencyLoader] - private void load() - { - AutoSizeAxes = Axes.Y; - RelativeSizeAxes = Axes.X; - - InternalChild = inspectorText = new OsuTextFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - }; - } - protected override void LoadComplete() { base.LoadComplete(); @@ -53,69 +25,69 @@ namespace osu.Game.Rulesets.Edit private void updateInspectorText() { - inspectorText.Clear(); + InspectorText.Clear(); rollingTextUpdate?.Cancel(); rollingTextUpdate = null; switch (EditorBeatmap.SelectedHitObjects.Count) { case 0: - addValue("No selection"); + AddValue("No selection"); break; case 1: var selected = EditorBeatmap.SelectedHitObjects.Single(); - addHeader("Type"); - addValue($"{selected.GetType().ReadableName()}"); + AddHeader("Type"); + AddValue($"{selected.GetType().ReadableName()}"); - addHeader("Time"); - addValue($"{selected.StartTime:#,0.##}ms"); + AddHeader("Time"); + AddValue($"{selected.StartTime:#,0.##}ms"); switch (selected) { case IHasPosition pos: - addHeader("Position"); - addValue($"x:{pos.X:#,0.##} y:{pos.Y:#,0.##}"); + AddHeader("Position"); + AddValue($"x:{pos.X:#,0.##} y:{pos.Y:#,0.##}"); break; case IHasXPosition x: - addHeader("Position"); + AddHeader("Position"); - addValue($"x:{x.X:#,0.##} "); + AddValue($"x:{x.X:#,0.##} "); break; case IHasYPosition y: - addHeader("Position"); + AddHeader("Position"); - addValue($"y:{y.Y:#,0.##}"); + AddValue($"y:{y.Y:#,0.##}"); break; } if (selected is IHasDistance distance) { - addHeader("Distance"); - addValue($"{distance.Distance:#,0.##}px"); + AddHeader("Distance"); + AddValue($"{distance.Distance:#,0.##}px"); } if (selected is IHasSliderVelocity sliderVelocity) { - addHeader("Slider Velocity"); - addValue($"{sliderVelocity.SliderVelocity:#,0.00}x"); + AddHeader("Slider Velocity"); + AddValue($"{sliderVelocity.SliderVelocity:#,0.00}x"); } if (selected is IHasRepeats repeats) { - addHeader("Repeats"); - addValue($"{repeats.RepeatCount:#,0.##}"); + AddHeader("Repeats"); + AddValue($"{repeats.RepeatCount:#,0.##}"); } if (selected is IHasDuration duration) { - addHeader("End Time"); - addValue($"{duration.EndTime:#,0.##}ms"); - addHeader("Duration"); - addValue($"{duration.Duration:#,0.##}ms"); + AddHeader("End Time"); + AddValue($"{duration.EndTime:#,0.##}ms"); + AddHeader("Duration"); + AddValue($"{duration.Duration:#,0.##}ms"); } // I'd hope there's a better way to do this, but I don't want to bind to each and every property above to watch for changes. @@ -124,29 +96,16 @@ namespace osu.Game.Rulesets.Edit break; default: - addHeader("Selected Objects"); - addValue($"{EditorBeatmap.SelectedHitObjects.Count:#,0.##}"); + AddHeader("Selected Objects"); + AddValue($"{EditorBeatmap.SelectedHitObjects.Count:#,0.##}"); - addHeader("Start Time"); - addValue($"{EditorBeatmap.SelectedHitObjects.Min(o => o.StartTime):#,0.##}ms"); + AddHeader("Start Time"); + AddValue($"{EditorBeatmap.SelectedHitObjects.Min(o => o.StartTime):#,0.##}ms"); - addHeader("End Time"); - addValue($"{EditorBeatmap.SelectedHitObjects.Max(o => o.GetEndTime()):#,0.##}ms"); + AddHeader("End Time"); + AddValue($"{EditorBeatmap.SelectedHitObjects.Max(o => o.GetEndTime()):#,0.##}ms"); break; } - - void addHeader(string header) => inspectorText.AddParagraph($"{header}: ", s => - { - s.Padding = new MarginPadding { Top = 2 }; - s.Font = s.Font.With(size: 12); - s.Colour = colourProvider.Content2; - }); - - void addValue(string value) => inspectorText.AddParagraph(value, s => - { - s.Font = s.Font.With(weight: FontWeight.SemiBold); - s.Colour = colourProvider.Content1; - }); } } } From cc70d89bf94269d34b3e32cfc24a66884d26f6dc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 15:42:34 +0900 Subject: [PATCH 2842/2991] Move editor inspector classes out of ruleset namespace --- .../Edit/Compose/Components}/EditorInspector.cs | 3 +-- .../Edit/Compose/Components}/HitObjectInspector.cs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) rename osu.Game/{Rulesets/Edit => Screens/Edit/Compose/Components}/EditorInspector.cs (96%) rename osu.Game/{Rulesets/Edit => Screens/Edit/Compose/Components}/HitObjectInspector.cs (98%) diff --git a/osu.Game/Rulesets/Edit/EditorInspector.cs b/osu.Game/Screens/Edit/Compose/Components/EditorInspector.cs similarity index 96% rename from osu.Game/Rulesets/Edit/EditorInspector.cs rename to osu.Game/Screens/Edit/Compose/Components/EditorInspector.cs index ed7f305a28..442454f97a 100644 --- a/osu.Game/Rulesets/Edit/EditorInspector.cs +++ b/osu.Game/Screens/Edit/Compose/Components/EditorInspector.cs @@ -7,9 +7,8 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Overlays; -using osu.Game.Screens.Edit; -namespace osu.Game.Rulesets.Edit +namespace osu.Game.Screens.Edit.Compose.Components { internal partial class EditorInspector : CompositeDrawable { diff --git a/osu.Game/Rulesets/Edit/HitObjectInspector.cs b/osu.Game/Screens/Edit/Compose/Components/HitObjectInspector.cs similarity index 98% rename from osu.Game/Rulesets/Edit/HitObjectInspector.cs rename to osu.Game/Screens/Edit/Compose/Components/HitObjectInspector.cs index d13190e484..597925e3e2 100644 --- a/osu.Game/Rulesets/Edit/HitObjectInspector.cs +++ b/osu.Game/Screens/Edit/Compose/Components/HitObjectInspector.cs @@ -7,7 +7,7 @@ using osu.Framework.Threading; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; -namespace osu.Game.Rulesets.Edit +namespace osu.Game.Screens.Edit.Compose.Components { internal partial class HitObjectInspector : EditorInspector { From b7a287869a5867c6ed5c2388e29ddff36ea94084 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 15:54:27 +0900 Subject: [PATCH 2843/2991] Add display of beatmap slider velocity when adjusting --- .../Timeline/DifficultyPointPiece.cs | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs index 4741b75641..9192913fa0 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs @@ -95,7 +95,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, Text = "Hold shift while dragging the end of an object to adjust velocity while snapping." - } + }, + new SliderVelocityInspector(), } } }; @@ -105,7 +106,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline var relevantObjects = (beatmap.SelectedHitObjects.Contains(hitObject) ? beatmap.SelectedHitObjects : hitObject.Yield()).Where(o => o is IHasSliderVelocity).ToArray(); // even if there are multiple objects selected, we can still display a value if they all have the same value. - var selectedPointBindable = relevantObjects.Select(point => ((IHasSliderVelocity)point).SliderVelocity).Distinct().Count() == 1 ? ((IHasSliderVelocity)relevantObjects.First()).SliderVelocityBindable : null; + var selectedPointBindable = relevantObjects.Select(point => ((IHasSliderVelocity)point).SliderVelocity).Distinct().Count() == 1 + ? ((IHasSliderVelocity)relevantObjects.First()).SliderVelocityBindable + : null; if (selectedPointBindable != null) { @@ -139,4 +142,37 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline } } } + + internal partial class SliderVelocityInspector : EditorInspector + { + [BackgroundDependencyLoader] + private void load() + { + EditorBeatmap.TransactionBegan += updateInspectorText; + EditorBeatmap.TransactionEnded += updateInspectorText; + updateInspectorText(); + } + + private void updateInspectorText() + { + InspectorText.Clear(); + + double[] sliderVelocities = EditorBeatmap.HitObjects.OfType().Select(sv => sv.SliderVelocity).OrderBy(v => v).ToArray(); + + if (sliderVelocities.Length < 2) + return; + + double? modeSliderVelocity = sliderVelocities.GroupBy(v => v).MaxBy(v => v.Count())?.Key; + double? medianSliderVelocity = sliderVelocities[sliderVelocities.Length / 2]; + + AddHeader("Beatmap average velocity"); + AddValue($"{medianSliderVelocity:#,0.00}x"); + + AddHeader("Most used velocity"); + AddValue($"{modeSliderVelocity:#,0.00}x"); + + AddHeader("Velocity range"); + AddValue($"{sliderVelocities.First():#,0.00}x - {sliderVelocities.Last():#,0.00}x"); + } + } } From 3d55a0291f2c1378b0a28e360afd9a6189a4a5cc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 15:40:43 +0900 Subject: [PATCH 2844/2991] Prefer block scoped namespaces --- .editorconfig | 2 ++ osu.sln.DotSettings | 1 + 2 files changed, 3 insertions(+) diff --git a/.editorconfig b/.editorconfig index c0ea55f4c8..67c47000d3 100644 --- a/.editorconfig +++ b/.editorconfig @@ -191,6 +191,8 @@ csharp_style_prefer_index_operator = false:silent csharp_style_prefer_range_operator = false:silent csharp_style_prefer_switch_expression = false:none +csharp_style_namespace_declarations = block_scoped:warning + [*.{yaml,yml}] insert_final_newline = true indent_style = space diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 367dfccb71..d7486273fb 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -277,6 +277,7 @@ Explicit ExpressionBody BlockBody + BlockScoped ExplicitlyTyped True NEXT_LINE From 01581024678c6f4d99a54892cb95cbe7599f0f3c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 16:19:09 +0900 Subject: [PATCH 2845/2991] Rename class back to original name so I can read the diff --- osu.Game.Tests/Database/LegacyModelExporterTest.cs | 2 +- osu.Game/Database/LegacyArchiveExporter.cs | 2 +- .../Database/{LegacyModelExporter.cs => LegacyExporter.cs} | 4 ++-- osu.Game/Database/LegacyScoreExporter.cs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) rename osu.Game/Database/{LegacyModelExporter.cs => LegacyExporter.cs} (98%) diff --git a/osu.Game.Tests/Database/LegacyModelExporterTest.cs b/osu.Game.Tests/Database/LegacyModelExporterTest.cs index 27059c3058..1e9cdfd67d 100644 --- a/osu.Game.Tests/Database/LegacyModelExporterTest.cs +++ b/osu.Game.Tests/Database/LegacyModelExporterTest.cs @@ -107,7 +107,7 @@ namespace osu.Game.Tests.Database storage.Dispose(); } - private class TestLegacyModelExporter : LegacyModelExporter + private class TestLegacyModelExporter : LegacyExporter { public TestLegacyModelExporter(Storage storage) : base(storage) diff --git a/osu.Game/Database/LegacyArchiveExporter.cs b/osu.Game/Database/LegacyArchiveExporter.cs index 297139a20e..d37f9a5dca 100644 --- a/osu.Game/Database/LegacyArchiveExporter.cs +++ b/osu.Game/Database/LegacyArchiveExporter.cs @@ -17,7 +17,7 @@ using Logger = osu.Framework.Logging.Logger; namespace osu.Game.Database { - public abstract class LegacyArchiveExporter : LegacyModelExporter + public abstract class LegacyArchiveExporter : LegacyExporter where TModel : RealmObject, IHasNamedFiles, IHasGuidPrimaryKey { protected LegacyArchiveExporter(Storage storage) diff --git a/osu.Game/Database/LegacyModelExporter.cs b/osu.Game/Database/LegacyExporter.cs similarity index 98% rename from osu.Game/Database/LegacyModelExporter.cs rename to osu.Game/Database/LegacyExporter.cs index 0e4fefae5c..bb2143178b 100644 --- a/osu.Game/Database/LegacyModelExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -19,7 +19,7 @@ namespace osu.Game.Database /// /// A class which handles exporting legacy user data of a single type from osu-stable. /// - public abstract class LegacyModelExporter + public abstract class LegacyExporter where TModel : RealmObject, IHasNamedFiles, IHasGuidPrimaryKey { /// @@ -54,7 +54,7 @@ namespace osu.Game.Database /// Create a new exporter for each export, otherwise it will cause confusing notifications. /// /// Storage for storing exported files. Basically it is used to provide export stream - protected LegacyModelExporter(Storage storage) + protected LegacyExporter(Storage storage) { exportStorage = storage.GetStorageForDirectory(@"exports"); UserFileStorage = storage.GetStorageForDirectory(@"files"); diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index e7473c963b..927d36ea03 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -11,7 +11,7 @@ using osu.Game.Scoring; namespace osu.Game.Database { - public class LegacyScoreExporter : LegacyModelExporter + public class LegacyScoreExporter : LegacyExporter { public LegacyScoreExporter(Storage storage) : base(storage) From 6a4933a31c0cd861925826dec4d13595399e4fe6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 16:30:01 +0900 Subject: [PATCH 2846/2991] Remove need for `TestRealmLive` nonsense --- .../Database/LegacyModelExporterTest.cs | 42 ++++++------------- 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/osu.Game.Tests/Database/LegacyModelExporterTest.cs b/osu.Game.Tests/Database/LegacyModelExporterTest.cs index 1e9cdfd67d..09f776e8ea 100644 --- a/osu.Game.Tests/Database/LegacyModelExporterTest.cs +++ b/osu.Game.Tests/Database/LegacyModelExporterTest.cs @@ -38,7 +38,7 @@ namespace osu.Game.Tests.Database [Test] public void ExportFileWithNormalNameTest() { - var item = new TestRealmObject(short_filename); + var item = new TestModel(short_filename); Assert.That(item.Filename.Length, Is.LessThan(TestLegacyModelExporter.MAX_FILENAME_LENGTH)); @@ -48,7 +48,7 @@ namespace osu.Game.Tests.Database [Test] public void ExportFileWithNormalNameMultipleTimesTest() { - var item = new TestRealmObject(short_filename); + var item = new TestModel(short_filename); Assert.That(item.Filename.Length, Is.LessThan(TestLegacyModelExporter.MAX_FILENAME_LENGTH)); @@ -66,7 +66,7 @@ namespace osu.Game.Tests.Database int expectedLength = TestLegacyModelExporter.MAX_FILENAME_LENGTH - (legacyExporter.GetExtension().Length); string expectedName = long_filename.Remove(expectedLength); - var item = new TestRealmObject(long_filename); + var item = new TestModel(long_filename); Assert.That(item.Filename.Length, Is.GreaterThan(TestLegacyModelExporter.MAX_FILENAME_LENGTH)); exportItemAndAssert(item, expectedName); @@ -78,7 +78,7 @@ namespace osu.Game.Tests.Database int expectedLength = TestLegacyModelExporter.MAX_FILENAME_LENGTH - (legacyExporter.GetExtension().Length); string expectedName = long_filename.Remove(expectedLength); - var item = new TestRealmObject(long_filename); + var item = new TestModel(long_filename); Assert.That(item.Filename.Length, Is.GreaterThan(TestLegacyModelExporter.MAX_FILENAME_LENGTH)); @@ -90,11 +90,11 @@ namespace osu.Game.Tests.Database } } - private void exportItemAndAssert(TestRealmObject item, string expectedName) + private void exportItemAndAssert(TestModel item, string expectedName) { Assert.DoesNotThrow(() => { - Task t = Task.Run(() => legacyExporter.ExportAsync(new TestRealmLive(item))); + Task t = Task.Run(() => legacyExporter.ExportAsync(new RealmLiveUnmanaged(item))); t.WaitSafely(); }); Assert.That(storage.Exists($"exports/{expectedName}{legacyExporter.GetExtension()}"), Is.True); @@ -107,7 +107,7 @@ namespace osu.Game.Tests.Database storage.Dispose(); } - private class TestLegacyModelExporter : LegacyExporter + private class TestLegacyModelExporter : LegacyExporter { public TestLegacyModelExporter(Storage storage) : base(storage) @@ -116,45 +116,27 @@ namespace osu.Game.Tests.Database public string GetExtension() => FileExtension; - protected override void ExportToStream(TestRealmObject model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default) + protected override void ExportToStream(TestModel model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default) { } protected override string FileExtension => ".test"; } - private class TestRealmObject : RealmObject, IHasNamedFiles, IHasGuidPrimaryKey + private class TestModel : RealmObject, IHasNamedFiles, IHasGuidPrimaryKey { - public Guid ID => throw new NotImplementedException(); + public Guid ID => Guid.Empty; + public string Filename { get; } public IEnumerable Files { get; } = new List(); - public TestRealmObject(string filename) + public TestModel(string filename) { Filename = filename; } public override string ToString() => Filename; } - - private class TestRealmLive : Live - { - public override void PerformRead(Action perform) => perform(Value); - - public override TReturn PerformRead(Func perform) => perform(Value); - - public override void PerformWrite(Action perform) => throw new NotImplementedException(); - - public override bool IsManaged => throw new NotImplementedException(); - - public override TestRealmObject Value { get; } - - public TestRealmLive(TestRealmObject model) - : base(Guid.Empty) - { - Value = model; - } - } } } From f2dd457b3de9ae4c2cf66d259de86fa5e0f8ff6a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 16:31:48 +0900 Subject: [PATCH 2847/2991] Remove unnecessary local variable --- osu.Game.Tests/Database/LegacyModelExporterTest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Tests/Database/LegacyModelExporterTest.cs b/osu.Game.Tests/Database/LegacyModelExporterTest.cs index 09f776e8ea..2169bc73cd 100644 --- a/osu.Game.Tests/Database/LegacyModelExporterTest.cs +++ b/osu.Game.Tests/Database/LegacyModelExporterTest.cs @@ -94,8 +94,7 @@ namespace osu.Game.Tests.Database { Assert.DoesNotThrow(() => { - Task t = Task.Run(() => legacyExporter.ExportAsync(new RealmLiveUnmanaged(item))); - t.WaitSafely(); + Task.Run(() => legacyExporter.ExportAsync(new RealmLiveUnmanaged(item))).WaitSafely(); }); Assert.That(storage.Exists($"exports/{expectedName}{legacyExporter.GetExtension()}"), Is.True); } From 4ec98b0578869237d5cd60b7e27779740351ae1c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 16:45:45 +0900 Subject: [PATCH 2848/2991] Improve xmldoc and fix silly progress text in `LegacyArchiveExporter` --- osu.Game/Database/LegacyArchiveExporter.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/osu.Game/Database/LegacyArchiveExporter.cs b/osu.Game/Database/LegacyArchiveExporter.cs index d37f9a5dca..01d00b311d 100644 --- a/osu.Game/Database/LegacyArchiveExporter.cs +++ b/osu.Game/Database/LegacyArchiveExporter.cs @@ -17,6 +17,9 @@ using Logger = osu.Framework.Logging.Logger; namespace osu.Game.Database { + /// + /// An exporter which handles the common scenario of exporting a model to a zip-based archive, usually with a custom file extension. + /// public abstract class LegacyArchiveExporter : LegacyExporter where TModel : RealmObject, IHasNamedFiles, IHasGuidPrimaryKey { @@ -31,17 +34,18 @@ namespace osu.Game.Database /// /// Exports an item to Stream as a legacy (.zip based) package. /// - /// The model will be exported. + /// The model to be exported. /// The output stream to export to. - /// The notification will displayed to the user - /// The Cancellation token that can cancel the exporting. + /// An optional target notification to update with ongoing export progress. + /// The cancellation token. private void exportZipArchive(TModel model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default) { try { using var writer = new ZipWriter(outputStream, new ZipWriterOptions(CompressionType.Deflate)); - float i = 0; + int i = 0; + int fileCount = model.Files.Count(); bool fileMissing = false; foreach (var file in model.Files) @@ -66,13 +70,12 @@ namespace osu.Game.Database } } - i++; - if (notification != null) { - notification.Progress = i / model.Files.Count(); - notification.Text = $"Exporting... ({i}/{model.Files.Count()})"; + notification.Progress = (float)(i + 1) / fileCount; } + + i++; } } catch (ObjectDisposedException) From 9cafb20fcbe650580d5d1bea6510319cf61e5a5a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 16:50:05 +0900 Subject: [PATCH 2849/2991] Move file missing logging to a better location, and log actual filenames to logs --- osu.Game/Database/LegacyArchiveExporter.cs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game/Database/LegacyArchiveExporter.cs b/osu.Game/Database/LegacyArchiveExporter.cs index 01d00b311d..f148d6951d 100644 --- a/osu.Game/Database/LegacyArchiveExporter.cs +++ b/osu.Game/Database/LegacyArchiveExporter.cs @@ -54,20 +54,14 @@ namespace osu.Game.Database using (var stream = UserFileStorage.GetStream(file.File.GetStoragePath())) { - // Sometimes we cannot find the file(probably deleted by the user), so we handle this and post a error. if (stream == null) { - // Only pop up once to prevent spam. - if (!fileMissing) - { - Logger.Log("Some of model files are missing, they will not be included in the archive", LoggingTarget.Database, LogLevel.Error); - fileMissing = true; - } - } - else - { - writer.Write(file.Filename, stream); + Logger.Log($"File {file.Filename} is missing in local storage and will not be included in the export", LoggingTarget.Database); + fileMissing = true; + continue; } + + writer.Write(file.Filename, stream); } if (notification != null) @@ -77,6 +71,12 @@ namespace osu.Game.Database i++; } + + // Only pop up once to prevent spam. + if (fileMissing) + { + Logger.Log("Some of model files are missing, they will not be included in the archive", LoggingTarget.Database, LogLevel.Error); + } } catch (ObjectDisposedException) { From fc2d2de34c3b20fb012dadde3bf029686f9005b7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 16:53:27 +0900 Subject: [PATCH 2850/2991] Fix notification text not including export filename --- osu.Game/Database/LegacyExporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index bb2143178b..e5df2a4337 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -112,7 +112,7 @@ namespace osu.Game.Database ProgressNotification notification = new ProgressNotification { State = ProgressNotificationState.Active, - Text = "Exporting...", + Text = $"Exporting {itemFilename}...", }; PostNotification?.Invoke(notification); From 4ccfebc02be0c0c1275d8ae76344f11d18be1a79 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 21:01:10 +0900 Subject: [PATCH 2851/2991] Simplify `ExportToStreamAsync` implementation --- osu.Game/Database/LegacyExporter.cs | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index e5df2a4337..bc86420cd2 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -7,7 +7,6 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; -using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Extensions; using osu.Game.Overlays.Notifications; @@ -159,30 +158,8 @@ namespace osu.Game.Database /// The notification will displayed to the user /// The Cancellation token that can cancel the exporting. /// Whether the export was successful - public Task ExportToStreamAsync(Live model, Stream stream, ProgressNotification? notification = null, CancellationToken cancellationToken = default) - { - return Task.Run(() => - { - model.PerformRead(s => - { - ExportToStream(s, stream, notification, cancellationToken); - }); - }, cancellationToken).ContinueWith(t => - { - if (cancellationToken.IsCancellationRequested) - { - return false; - } - - if (t.IsFaulted) - { - Logger.Error(t.Exception, "An error occurred while exporting", LoggingTarget.Database); - throw t.Exception!; - } - - return true; - }, CancellationToken.None); - } + public Task ExportToStreamAsync(Live model, Stream stream, ProgressNotification? notification = null, CancellationToken cancellationToken = default) => + Task.Run(() => { model.PerformRead(s => ExportToStream(s, stream, notification, cancellationToken)); }, cancellationToken); /// /// Exports model to Stream. From 2a3e03695cad820002999e420797de7a0faf4cba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 21:04:13 +0900 Subject: [PATCH 2852/2991] Simplify `ExportAsync`, remove weird dedupe logic and unnecessary return `success` code --- osu.Game/Database/LegacyExporter.cs | 60 ++++++++--------------------- 1 file changed, 15 insertions(+), 45 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index bc86420cd2..a8d2fb116c 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -45,9 +45,6 @@ namespace osu.Game.Database public Action? PostNotification { get; set; } - // Store the model being exporting. - private static readonly List> exporting_models = new List>(); - /// /// Construct exporter. /// Create a new exporter for each export, otherwise it will cause confusing notifications. @@ -69,10 +66,8 @@ namespace osu.Game.Database /// If specified CancellationToken, then use it. Otherwise use PostNotification's CancellationToken. /// /// - public Task ExportAsync(TModel model, RealmAccess realm, CancellationToken cancellationToken = default) - { - return ExportAsync(model.ToLive(realm), cancellationToken); - } + public Task ExportAsync(TModel model, RealmAccess realm, CancellationToken cancellationToken = default) => + ExportAsync(model.ToLive(realm), cancellationToken); /// /// Export the model to default folder. @@ -83,71 +78,46 @@ namespace osu.Game.Database /// If specified CancellationToken, then use it. Otherwise use PostNotification's CancellationToken. /// /// - public async Task ExportAsync(Live model, CancellationToken cancellationToken = default) + public async Task ExportAsync(Live model, CancellationToken cancellationToken = default) { - // check if the model is being exporting already - if (!exporting_models.Contains(model)) - { - exporting_models.Add(model); - } - else - { - // model is being exported - return false; - } - string itemFilename = model.PerformRead(s => GetFilename(s).GetValidFilename()); if (itemFilename.Length > MAX_FILENAME_LENGTH - FileExtension.Length) itemFilename = itemFilename.Remove(MAX_FILENAME_LENGTH - FileExtension.Length); - IEnumerable existingExports = - exportStorage - .GetFiles(string.Empty, $"{itemFilename}*{FileExtension}") - .Concat(exportStorage.GetDirectories(string.Empty)); + IEnumerable existingExports = exportStorage + .GetFiles(string.Empty, $"{itemFilename}*{FileExtension}") + .Concat(exportStorage.GetDirectories(string.Empty)); + string filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); - bool success; ProgressNotification notification = new ProgressNotification { State = ProgressNotificationState.Active, Text = $"Exporting {itemFilename}...", }; + PostNotification?.Invoke(notification); try { using (var stream = exportStorage.CreateFileSafely(filename)) { - success = await ExportToStreamAsync(model, stream, notification, - cancellationToken == CancellationToken.None ? notification.CancellationToken : cancellationToken).ConfigureAwait(false); + await ExportToStreamAsync(model, stream, notification, cancellationToken == CancellationToken.None ? notification.CancellationToken : cancellationToken).ConfigureAwait(false); } } catch { notification.State = ProgressNotificationState.Cancelled; + + // cleanup if export is failed or canceled. + exportStorage.Delete(filename); throw; } - finally - { - // Determines whether to export repeatedly, so he must be removed from the list at the end whether there is a error. - exporting_models.Remove(model); - } - // cleanup if export is failed or canceled. - if (!success) - { - notification.State = ProgressNotificationState.Cancelled; - exportStorage.Delete(filename); - } - else - { - notification.CompletionText = $"Exported {itemFilename}! Click to view."; - notification.CompletionClickAction = () => exportStorage.PresentFileExternally(filename); - notification.State = ProgressNotificationState.Completed; - } - - return success; + notification.CompletionText = $"Exported {itemFilename}! Click to view."; + notification.CompletionClickAction = () => exportStorage.PresentFileExternally(filename); + notification.State = ProgressNotificationState.Completed; } /// From 5d78561aa36fb6dd2cbbdec343b7fcbb63c10683 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 21:05:57 +0900 Subject: [PATCH 2853/2991] Remove weird catch logic --- osu.Game/Database/LegacyArchiveExporter.cs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/osu.Game/Database/LegacyArchiveExporter.cs b/osu.Game/Database/LegacyArchiveExporter.cs index f148d6951d..306ac5f6a4 100644 --- a/osu.Game/Database/LegacyArchiveExporter.cs +++ b/osu.Game/Database/LegacyArchiveExporter.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.IO; using System.Linq; using System.Threading; @@ -40,10 +39,8 @@ namespace osu.Game.Database /// The cancellation token. private void exportZipArchive(TModel model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default) { - try + using (var writer = new ZipWriter(outputStream, new ZipWriterOptions(CompressionType.Deflate))) { - using var writer = new ZipWriter(outputStream, new ZipWriterOptions(CompressionType.Deflate)); - int i = 0; int fileCount = model.Files.Count(); bool fileMissing = false; @@ -78,14 +75,6 @@ namespace osu.Game.Database Logger.Log("Some of model files are missing, they will not be included in the archive", LoggingTarget.Database, LogLevel.Error); } } - catch (ObjectDisposedException) - { - // outputStream may close before writing when request cancel. - if (cancellationToken.IsCancellationRequested) - return; - - throw; - } } } } From 747f912af5d49ffe56cd1a1cca75b0b42d86bf06 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 21:08:01 +0900 Subject: [PATCH 2854/2991] Fix incorrect cancellation logic --- osu.Game/Database/LegacyExporter.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index a8d2fb116c..906e2083ff 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -99,11 +99,13 @@ namespace osu.Game.Database PostNotification?.Invoke(notification); + using var linkedSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, notification.CancellationToken); + try { using (var stream = exportStorage.CreateFileSafely(filename)) { - await ExportToStreamAsync(model, stream, notification, cancellationToken == CancellationToken.None ? notification.CancellationToken : cancellationToken).ConfigureAwait(false); + await ExportToStreamAsync(model, stream, notification, linkedSource.Token).ConfigureAwait(false); } } catch From 490df8073ca1f0950f7f22dda30317ac1ae82003 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 May 2023 21:15:26 +0900 Subject: [PATCH 2855/2991] Fix one incorrect namespace syntax file --- .../Objects/Types/IHasSliderVelocity.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Types/IHasSliderVelocity.cs b/osu.Game/Rulesets/Objects/Types/IHasSliderVelocity.cs index c0ac5036ee..80fd8dd8dc 100644 --- a/osu.Game/Rulesets/Objects/Types/IHasSliderVelocity.cs +++ b/osu.Game/Rulesets/Objects/Types/IHasSliderVelocity.cs @@ -3,17 +3,18 @@ using osu.Framework.Bindables; -namespace osu.Game.Rulesets.Objects.Types; - -/// -/// A HitObject that has a slider velocity multiplier. -/// -public interface IHasSliderVelocity +namespace osu.Game.Rulesets.Objects.Types { /// - /// The slider velocity multiplier. + /// A HitObject that has a slider velocity multiplier. /// - double SliderVelocity { get; set; } + public interface IHasSliderVelocity + { + /// + /// The slider velocity multiplier. + /// + double SliderVelocity { get; set; } - BindableNumber SliderVelocityBindable { get; } + BindableNumber SliderVelocityBindable { get; } + } } From 4393e53b4310cc30d9301095cdbcfe3cd2dc7fcb Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Fri, 5 May 2023 21:28:43 +0900 Subject: [PATCH 2856/2991] ExportToStream should be public --- osu.Game.Tests/Database/LegacyModelExporterTest.cs | 2 +- osu.Game/Database/LegacyArchiveExporter.cs | 2 +- osu.Game/Database/LegacyExporter.cs | 2 +- osu.Game/Database/LegacyScoreExporter.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Database/LegacyModelExporterTest.cs b/osu.Game.Tests/Database/LegacyModelExporterTest.cs index 2169bc73cd..0c4b0cc9c4 100644 --- a/osu.Game.Tests/Database/LegacyModelExporterTest.cs +++ b/osu.Game.Tests/Database/LegacyModelExporterTest.cs @@ -115,7 +115,7 @@ namespace osu.Game.Tests.Database public string GetExtension() => FileExtension; - protected override void ExportToStream(TestModel model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default) + public override void ExportToStream(TestModel model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default) { } diff --git a/osu.Game/Database/LegacyArchiveExporter.cs b/osu.Game/Database/LegacyArchiveExporter.cs index 306ac5f6a4..1afa19a162 100644 --- a/osu.Game/Database/LegacyArchiveExporter.cs +++ b/osu.Game/Database/LegacyArchiveExporter.cs @@ -27,7 +27,7 @@ namespace osu.Game.Database { } - protected override void ExportToStream(TModel model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default) + public override void ExportToStream(TModel model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default) => exportZipArchive(model, outputStream, notification, cancellationToken); /// diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 906e2083ff..3b24ab4f4a 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -140,6 +140,6 @@ namespace osu.Game.Database /// The output stream to export to. /// The notification will displayed to the user /// The Cancellation token that can cancel the exporting. - protected abstract void ExportToStream(TModel model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default); + public abstract void ExportToStream(TModel model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default); } } diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index 927d36ea03..fe5d1e8b47 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -28,7 +28,7 @@ namespace osu.Game.Database protected override string FileExtension => ".osr"; - protected override void ExportToStream(ScoreInfo model, Stream stream, ProgressNotification? notification, CancellationToken cancellationToken = default) + public override void ExportToStream(ScoreInfo model, Stream stream, ProgressNotification? notification, CancellationToken cancellationToken = default) { var file = model.Files.SingleOrDefault(); if (file == null) From 71864fbb932b980931033d2e8808d90a569d2a7c Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Fri, 5 May 2023 21:29:06 +0900 Subject: [PATCH 2857/2991] remove meanless comment --- osu.Game/Database/LegacyArchiveExporter.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Database/LegacyArchiveExporter.cs b/osu.Game/Database/LegacyArchiveExporter.cs index 1afa19a162..19ccc13a29 100644 --- a/osu.Game/Database/LegacyArchiveExporter.cs +++ b/osu.Game/Database/LegacyArchiveExporter.cs @@ -69,7 +69,6 @@ namespace osu.Game.Database i++; } - // Only pop up once to prevent spam. if (fileMissing) { Logger.Log("Some of model files are missing, they will not be included in the archive", LoggingTarget.Database, LogLevel.Error); From f536238554873f27cd8424e0a3547032b3c1e737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 5 May 2023 20:30:50 +0200 Subject: [PATCH 2858/2991] Use shorter copy --- .../Edit/Compose/Components/Timeline/DifficultyPointPiece.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs index 9192913fa0..e737d6b0ce 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs @@ -165,7 +165,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline double? modeSliderVelocity = sliderVelocities.GroupBy(v => v).MaxBy(v => v.Count())?.Key; double? medianSliderVelocity = sliderVelocities[sliderVelocities.Length / 2]; - AddHeader("Beatmap average velocity"); + AddHeader("Average velocity"); AddValue($"{medianSliderVelocity:#,0.00}x"); AddHeader("Most used velocity"); From e808a47811d0027f82037cbc5d58b0c7117cffba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 5 May 2023 20:33:27 +0200 Subject: [PATCH 2859/2991] Fix delegate leak --- .../Compose/Components/Timeline/DifficultyPointPiece.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs index e737d6b0ce..13a1c30cfe 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs @@ -174,5 +174,13 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline AddHeader("Velocity range"); AddValue($"{sliderVelocities.First():#,0.00}x - {sliderVelocities.Last():#,0.00}x"); } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + EditorBeatmap.TransactionBegan -= updateInspectorText; + EditorBeatmap.TransactionEnded -= updateInspectorText; + } } } From 7d1e73e36dcf67a5052395aa84f9c241d2d6696b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 4 May 2023 21:24:31 +0200 Subject: [PATCH 2860/2991] Add workflow for automated osu-web mod definition updates --- .../workflows/update-web-mod-definitions.yml | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 .github/workflows/update-web-mod-definitions.yml diff --git a/.github/workflows/update-web-mod-definitions.yml b/.github/workflows/update-web-mod-definitions.yml new file mode 100644 index 0000000000..32d3d37ffe --- /dev/null +++ b/.github/workflows/update-web-mod-definitions.yml @@ -0,0 +1,53 @@ +name: Update osu-web mod definitions +on: + push: + tags: + - '*' + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + update-mod-definitions: + name: Update osu-web mod definitions + runs-on: ubuntu-latest + steps: + - name: Install .NET 6.0.x + uses: actions/setup-dotnet@v3 + with: + dotnet-version: "6.0.x" + + - name: Checkout ppy/osu + uses: actions/checkout@v3 + with: + path: osu + + - name: Checkout ppy/osu-tools + uses: actions/checkout@v3 + with: + repository: ppy/osu-tools + path: osu-tools + + - name: Checkout ppy/osu-web + uses: actions/checkout@v3 + with: + repository: ppy/osu-web + path: osu-web + + - name: Setup local game checkout for tools + run: ./UseLocalOsu.sh + working-directory: ./osu-tools + + - name: Regenerate mod definitions + run: dotnet run --project PerformanceCalculator -- mods > ../osu-web/database/mods.json + working-directory: ./osu-tools + + - name: Create pull request with changes + uses: peter-evans/create-pull-request@v5 + with: + title: Update mod definitions + body: "This PR has been auto-generated to update the mod definitions to match ppy/osu@${{ github.ref_name }}." + branch: update-mod-definitions + commit-message: Update mod definitions + path: osu-web + token: ${{ secrets.OSU_WEB_PULL_REQUEST_PAT }} From 52e5835be6e8ae544ec9917d67409a2493b04c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 6 May 2023 14:52:33 +0200 Subject: [PATCH 2861/2991] Document and retouch `ReportPopover` --- .../Graphics/UserInterfaceV2/ReportPopover.cs | 32 +++++++++++++------ osu.Game/Overlays/Chat/ReportChatPopover.cs | 5 +-- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs b/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs index a5c60bb9e6..393cdef76d 100644 --- a/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs +++ b/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs @@ -16,17 +16,29 @@ using osuTK; namespace osu.Game.Graphics.UserInterfaceV2 { - public abstract partial class ReportPopover : OsuPopover - where T : struct, Enum + /// + /// A generic popover for sending an online report about something. + /// + /// An enumeration type with all valid reasons for the report. + public abstract partial class ReportPopover : OsuPopover + where TReportReason : struct, Enum { - public Action? Action; + /// + /// The action to run when the report is finalised. + /// The arguments to this action are: the reason for the report, and an optional additional comment. + /// + public Action? Action; - private OsuEnumDropdown reasonDropdown = null!; + private OsuEnumDropdown reasonDropdown = null!; private OsuTextBox commentsTextBox = null!; private RoundedButton submitButton = null!; private readonly LocalisableString header; + /// + /// Creates a new . + /// + /// The text to display in the header of the popover. protected ReportPopover(LocalisableString headerString) { header = headerString; @@ -68,7 +80,7 @@ namespace osu.Game.Graphics.UserInterfaceV2 { RelativeSizeAxes = Axes.X, Height = 40, - Child = reasonDropdown = new OsuEnumDropdown + Child = reasonDropdown = new OsuEnumDropdown { RelativeSizeAxes = Axes.X } @@ -110,12 +122,12 @@ namespace osu.Game.Graphics.UserInterfaceV2 private void updateStatus() { - submitButton.Enabled.Value = !string.IsNullOrWhiteSpace(commentsTextBox.Current.Value) || CheckCanSubmitEmptyComment(reasonDropdown.Current.Value); + submitButton.Enabled.Value = !string.IsNullOrWhiteSpace(commentsTextBox.Current.Value) || IsCommentRequired(reasonDropdown.Current.Value); } - protected virtual bool CheckCanSubmitEmptyComment(T reason) - { - return false; - } + /// + /// Determines whether an additional comment is required for submitting the report with the supplied . + /// + protected virtual bool IsCommentRequired(TReportReason reason) => false; } } diff --git a/osu.Game/Overlays/Chat/ReportChatPopover.cs b/osu.Game/Overlays/Chat/ReportChatPopover.cs index f02e52eb2e..625f44505b 100644 --- a/osu.Game/Overlays/Chat/ReportChatPopover.cs +++ b/osu.Game/Overlays/Chat/ReportChatPopover.cs @@ -27,10 +27,7 @@ namespace osu.Game.Overlays.Chat Action = report; } - protected override bool CheckCanSubmitEmptyComment(ChatReportReason reason) - { - return reason != ChatReportReason.Other; - } + protected override bool IsCommentRequired(ChatReportReason reason) => reason != ChatReportReason.Other; private void report(ChatReportReason reason, string comments) { From 6b4050ea5253bd70c1a4c2d691d7c49d2c53fbab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 6 May 2023 15:01:57 +0200 Subject: [PATCH 2862/2991] Remove invalid report reason (and add osu-web references) --- osu.Game/Overlays/Chat/ChatReportReason.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Chat/ChatReportReason.cs b/osu.Game/Overlays/Chat/ChatReportReason.cs index 55593d29ad..5fda11b61e 100644 --- a/osu.Game/Overlays/Chat/ChatReportReason.cs +++ b/osu.Game/Overlays/Chat/ChatReportReason.cs @@ -7,6 +7,11 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Chat { + /// + /// References: + /// https://github.com/ppy/osu-web/blob/0a41b13acf5f47bb0d2b08bab42a9646b7ab5821/app/Models/UserReport.php#L50 + /// https://github.com/ppy/osu-web/blob/0a41b13acf5f47bb0d2b08bab42a9646b7ab5821/app/Models/UserReport.php#L39 + /// public enum ChatReportReason { [Description("Insulting People")] @@ -17,10 +22,6 @@ namespace osu.Game.Overlays.Chat [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsSpam))] Spam, - [Description("Cheating")] - [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsCheating))] - FoulPlay, - [Description("Unwanted Content")] [LocalisableDescription(typeof(UsersStrings), nameof(UsersStrings.ReportOptionsUnwantedContent))] UnwantedContent, From fba3c587cfd11278247840de290463dbc19e1201 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 6 May 2023 15:26:29 +0200 Subject: [PATCH 2863/2991] Add test coverage for info message failing to display --- osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 99ce837665..55e6b54af7 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -648,6 +648,7 @@ namespace osu.Game.Tests.Visual.Online AddUntilStep("Overlay closed", () => !this.ChildrenOfType().Any()); AddStep("Complete request", () => requestLock.Set()); AddUntilStep("Request sent", () => request != null); + AddUntilStep("Info message displayed", () => channelManager.CurrentChannel.Value.Messages.Last(), () => Is.InstanceOf(typeof(InfoMessage))); } private void joinTestChannel(int i) From 1da5e69d5a6aeb573d0d538e84257ecbf6752455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 6 May 2023 15:27:27 +0200 Subject: [PATCH 2864/2991] Fix API success callback scheduling to dead drawable --- osu.Game/Overlays/Chat/ReportChatPopover.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Chat/ReportChatPopover.cs b/osu.Game/Overlays/Chat/ReportChatPopover.cs index 625f44505b..999c76ca10 100644 --- a/osu.Game/Overlays/Chat/ReportChatPopover.cs +++ b/osu.Game/Overlays/Chat/ReportChatPopover.cs @@ -33,10 +33,7 @@ namespace osu.Game.Overlays.Chat { var request = new ChatReportRequest(message.Id, reason, comments); - request.Success += () => Schedule(() => - { - channelManager.CurrentChannel.Value.AddNewMessages(new InfoMessage(UsersStrings.ReportThanks.ToString())); - }); + request.Success += () => channelManager.CurrentChannel.Value.AddNewMessages(new InfoMessage(UsersStrings.ReportThanks.ToString())); api.Queue(request); } From 3942281d13a4a23b3d8efbd2aed96e155831753d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 6 May 2023 15:34:55 +0200 Subject: [PATCH 2865/2991] Fix back-to-front logic --- osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs | 4 ++-- osu.Game/Overlays/Chat/ReportChatPopover.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs b/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs index 393cdef76d..7b3c32d60d 100644 --- a/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs +++ b/osu.Game/Graphics/UserInterfaceV2/ReportPopover.cs @@ -122,12 +122,12 @@ namespace osu.Game.Graphics.UserInterfaceV2 private void updateStatus() { - submitButton.Enabled.Value = !string.IsNullOrWhiteSpace(commentsTextBox.Current.Value) || IsCommentRequired(reasonDropdown.Current.Value); + submitButton.Enabled.Value = !string.IsNullOrWhiteSpace(commentsTextBox.Current.Value) || !IsCommentRequired(reasonDropdown.Current.Value); } /// /// Determines whether an additional comment is required for submitting the report with the supplied . /// - protected virtual bool IsCommentRequired(TReportReason reason) => false; + protected virtual bool IsCommentRequired(TReportReason reason) => true; } } diff --git a/osu.Game/Overlays/Chat/ReportChatPopover.cs b/osu.Game/Overlays/Chat/ReportChatPopover.cs index 999c76ca10..265a17c799 100644 --- a/osu.Game/Overlays/Chat/ReportChatPopover.cs +++ b/osu.Game/Overlays/Chat/ReportChatPopover.cs @@ -27,7 +27,7 @@ namespace osu.Game.Overlays.Chat Action = report; } - protected override bool IsCommentRequired(ChatReportReason reason) => reason != ChatReportReason.Other; + protected override bool IsCommentRequired(ChatReportReason reason) => reason == ChatReportReason.Other; private void report(ChatReportReason reason, string comments) { From e75ff33d629dfe4f8e368026ec55010637097479 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 6 May 2023 23:10:09 +0900 Subject: [PATCH 2866/2991] Remove redundant xmldoc and reword some remaining --- osu.Game/Database/LegacyExporter.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 3b24ab4f4a..468370809a 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -16,7 +16,7 @@ using Realms; namespace osu.Game.Database { /// - /// A class which handles exporting legacy user data of a single type from osu-stable. + /// Handles exporting models to files for sharing / consumption outside the game. /// public abstract class LegacyExporter where TModel : RealmObject, IHasNamedFiles, IHasGuidPrimaryKey @@ -45,11 +45,6 @@ namespace osu.Game.Database public Action? PostNotification { get; set; } - /// - /// Construct exporter. - /// Create a new exporter for each export, otherwise it will cause confusing notifications. - /// - /// Storage for storing exported files. Basically it is used to provide export stream protected LegacyExporter(Storage storage) { exportStorage = storage.GetStorageForDirectory(@"exports"); From 0d095c4bb703304b2df127db32de69ef3c69bef1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 6 May 2023 23:10:18 +0900 Subject: [PATCH 2867/2991] Remove non-`Live` pathway --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- osu.Game/Database/LegacyExporter.cs | 13 ------------- osu.Game/Scoring/ScoreManager.cs | 2 +- 3 files changed, 2 insertions(+), 15 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index e87e71ae33..61b234d88a 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -400,7 +400,7 @@ namespace osu.Game.Beatmaps public Task?> ImportAsUpdate(ProgressNotification notification, ImportTask importTask, BeatmapSetInfo original) => beatmapImporter.ImportAsUpdate(notification, importTask, original); - public Task Export(BeatmapSetInfo beatmap) => beatmapExporter.ExportAsync(beatmap, Realm); + public Task Export(BeatmapSetInfo beatmap) => beatmapExporter.ExportAsync(beatmap.ToLive(Realm)); private void updateHashAndMarkDirty(BeatmapSetInfo setInfo) { diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 468370809a..bd38e38888 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -51,19 +51,6 @@ namespace osu.Game.Database UserFileStorage = storage.GetStorageForDirectory(@"files"); } - /// - /// Export the model to default folder. - /// - /// The model should export. - /// Realm that convert model to Live. - /// - /// The Cancellation token that can cancel the exporting. - /// If specified CancellationToken, then use it. Otherwise use PostNotification's CancellationToken. - /// - /// - public Task ExportAsync(TModel model, RealmAccess realm, CancellationToken cancellationToken = default) => - ExportAsync(model.ToLive(realm), cancellationToken); - /// /// Export the model to default folder. /// diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index 5e432b6a96..3e6d09b74a 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -193,7 +193,7 @@ namespace osu.Game.Scoring public Task>> Import(ProgressNotification notification, ImportTask[] tasks, ImportParameters parameters = default) => scoreImporter.Import(notification, tasks); - public Task Export(ScoreInfo score) => scoreExporter.ExportAsync(score, Realm); + public Task Export(ScoreInfo score) => scoreExporter.ExportAsync(score.ToLive(Realm)); public Task> ImportAsUpdate(ProgressNotification notification, ImportTask task, ScoreInfo original) => scoreImporter.ImportAsUpdate(notification, task, original); From 38ebce8ee978738fbc1ccf1f57f07ad8b8c00d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 6 May 2023 16:21:48 +0200 Subject: [PATCH 2868/2991] Update framework again --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 59bef84bd2..e9ecbaa10b 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -11,7 +11,7 @@ manifestmerger.jar - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 404fbada95..7ab9810ab5 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index c4df0a2347..bfa0dc63bb 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -16,6 +16,6 @@ iossimulator-x64 - + From 808a44ac0c33377aae9b37ab64bd27d3049cb22b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 6 May 2023 16:23:00 +0200 Subject: [PATCH 2869/2991] Resolve code quality inspection --- osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs index e951197643..555610a3b6 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs @@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Osu.UI localCursorContainer?.Expire(); localCursorContainer = null; - GameplayCursor?.ActiveCursor?.Show(); + GameplayCursor?.ActiveCursor.Show(); } protected override bool OnHover(HoverEvent e) => true; From d2591368a6f21496fb4a00d326d0aac737f6a6d9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 6 May 2023 23:53:35 +0900 Subject: [PATCH 2870/2991] More xmldoc fixes --- osu.Game/Database/LegacyArchiveExporter.cs | 9 +---- osu.Game/Database/LegacyExporter.cs | 38 ++++++++++------------ 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/osu.Game/Database/LegacyArchiveExporter.cs b/osu.Game/Database/LegacyArchiveExporter.cs index 19ccc13a29..d18c6b1497 100644 --- a/osu.Game/Database/LegacyArchiveExporter.cs +++ b/osu.Game/Database/LegacyArchiveExporter.cs @@ -17,7 +17,7 @@ using Logger = osu.Framework.Logging.Logger; namespace osu.Game.Database { /// - /// An exporter which handles the common scenario of exporting a model to a zip-based archive, usually with a custom file extension. + /// Handles the common scenario of exporting a model to a zip-based archive, usually with a custom file extension. /// public abstract class LegacyArchiveExporter : LegacyExporter where TModel : RealmObject, IHasNamedFiles, IHasGuidPrimaryKey @@ -30,13 +30,6 @@ namespace osu.Game.Database public override void ExportToStream(TModel model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default) => exportZipArchive(model, outputStream, notification, cancellationToken); - /// - /// Exports an item to Stream as a legacy (.zip based) package. - /// - /// The model to be exported. - /// The output stream to export to. - /// An optional target notification to update with ongoing export progress. - /// The cancellation token. private void exportZipArchive(TModel model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default) { using (var writer = new ZipWriter(outputStream, new ZipWriterOptions(CompressionType.Deflate))) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index bd38e38888..c86873ea3f 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -52,14 +52,11 @@ namespace osu.Game.Database } /// - /// Export the model to default folder. + /// Exports a model to the default export location. + /// This will create a notification tracking the progress of the export, visible to the user. /// - /// The model should export. - /// - /// The Cancellation token that can cancel the exporting. - /// If specified CancellationToken, then use it. Otherwise use PostNotification's CancellationToken. - /// - /// + /// The model to export. + /// A cancellation token. public async Task ExportAsync(Live model, CancellationToken cancellationToken = default) { string itemFilename = model.PerformRead(s => GetFilename(s).GetValidFilename()); @@ -105,23 +102,22 @@ namespace osu.Game.Database } /// - /// Export model to stream. - /// - /// The model which have . - /// The stream to export. - /// The notification will displayed to the user - /// The Cancellation token that can cancel the exporting. - /// Whether the export was successful - public Task ExportToStreamAsync(Live model, Stream stream, ProgressNotification? notification = null, CancellationToken cancellationToken = default) => - Task.Run(() => { model.PerformRead(s => ExportToStream(s, stream, notification, cancellationToken)); }, cancellationToken); - - /// - /// Exports model to Stream. + /// Exports a model to a provided stream. /// /// The model to export. /// The output stream to export to. - /// The notification will displayed to the user - /// The Cancellation token that can cancel the exporting. + /// An optional notification to be updated with export progress. + /// A cancellation token. + public Task ExportToStreamAsync(Live model, Stream outputStream, ProgressNotification? notification = null, CancellationToken cancellationToken = default) => + Task.Run(() => { model.PerformRead(s => ExportToStream(s, outputStream, notification, cancellationToken)); }, cancellationToken); + + /// + /// Exports a model to a provided stream. + /// + /// The model to export. + /// The output stream to export to. + /// An optional notification to be updated with export progress. + /// A cancellation token. public abstract void ExportToStream(TModel model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default); } } From 64d7e0d8966fe1e1f922d5d20d4cc12119c4914f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 7 May 2023 00:24:30 +0900 Subject: [PATCH 2871/2991] Rename `outputStream` variable to match base class --- osu.Game/Database/LegacyScoreExporter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index fe5d1e8b47..f0514d5350 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -28,14 +28,14 @@ namespace osu.Game.Database protected override string FileExtension => ".osr"; - public override void ExportToStream(ScoreInfo model, Stream stream, ProgressNotification? notification, CancellationToken cancellationToken = default) + public override void ExportToStream(ScoreInfo model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default) { var file = model.Files.SingleOrDefault(); if (file == null) return; using (var inputStream = UserFileStorage.GetStream(file.File.GetStoragePath())) - inputStream.CopyTo(stream); + inputStream.CopyTo(outputStream); } } } From 5e64d25b2a977bc0edb6538aa8929763050c2fda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 6 May 2023 19:26:51 +0200 Subject: [PATCH 2872/2991] Make `UserFileStorage` `readonly` again --- osu.Game/Database/LegacyExporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index c86873ea3f..d1feb5f0cc 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -39,7 +39,7 @@ namespace osu.Game.Database /// protected abstract string FileExtension { get; } - protected Storage UserFileStorage; + protected readonly Storage UserFileStorage; private readonly Storage exportStorage; protected virtual string GetFilename(TModel item) => item.GetDisplayString(); From e0823ffd036b15fd202eb8169ab6c673d54b4951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 6 May 2023 19:29:08 +0200 Subject: [PATCH 2873/2991] Move lower and xmldoc `GetFilename(TModel)` --- osu.Game/Database/LegacyExporter.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index d1feb5f0cc..f9164e34cd 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -41,7 +41,6 @@ namespace osu.Game.Database protected readonly Storage UserFileStorage; private readonly Storage exportStorage; - protected virtual string GetFilename(TModel item) => item.GetDisplayString(); public Action? PostNotification { get; set; } @@ -51,6 +50,16 @@ namespace osu.Game.Database UserFileStorage = storage.GetStorageForDirectory(@"files"); } + /// + /// Returns the baseline name of the file to which the will be exported. + /// + /// + /// The name of the file will be run through to eliminate characters + /// which are not permitted by various filesystems. + /// + /// The item being exported. + protected virtual string GetFilename(TModel item) => item.GetDisplayString(); + /// /// Exports a model to the default export location. /// This will create a notification tracking the progress of the export, visible to the user. From 3afe198d1dfa840d97830271c17dc94e8165c2c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 6 May 2023 19:34:22 +0200 Subject: [PATCH 2874/2991] Remove weird single-use private method --- osu.Game/Database/LegacyArchiveExporter.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Database/LegacyArchiveExporter.cs b/osu.Game/Database/LegacyArchiveExporter.cs index d18c6b1497..4d5a1a767c 100644 --- a/osu.Game/Database/LegacyArchiveExporter.cs +++ b/osu.Game/Database/LegacyArchiveExporter.cs @@ -28,9 +28,6 @@ namespace osu.Game.Database } public override void ExportToStream(TModel model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default) - => exportZipArchive(model, outputStream, notification, cancellationToken); - - private void exportZipArchive(TModel model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default) { using (var writer = new ZipWriter(outputStream, new ZipWriterOptions(CompressionType.Deflate))) { From a56a5d563c6c4d80b6fca50a21c8d1468f57c0de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 6 May 2023 19:38:05 +0200 Subject: [PATCH 2875/2991] Unify error message wording --- osu.Game/Database/LegacyArchiveExporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Database/LegacyArchiveExporter.cs b/osu.Game/Database/LegacyArchiveExporter.cs index 4d5a1a767c..4ba6025e6a 100644 --- a/osu.Game/Database/LegacyArchiveExporter.cs +++ b/osu.Game/Database/LegacyArchiveExporter.cs @@ -61,7 +61,7 @@ namespace osu.Game.Database if (fileMissing) { - Logger.Log("Some of model files are missing, they will not be included in the archive", LoggingTarget.Database, LogLevel.Error); + Logger.Log("Some files are missing in local storage and will not be included in the export", LoggingTarget.Database, LogLevel.Error); } } } From bb17b684b00da1a0f00e36d4c0e62098cba27f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 6 May 2023 19:38:41 +0200 Subject: [PATCH 2876/2991] Rename flag --- osu.Game/Database/LegacyArchiveExporter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Database/LegacyArchiveExporter.cs b/osu.Game/Database/LegacyArchiveExporter.cs index 4ba6025e6a..feddf602b9 100644 --- a/osu.Game/Database/LegacyArchiveExporter.cs +++ b/osu.Game/Database/LegacyArchiveExporter.cs @@ -33,7 +33,7 @@ namespace osu.Game.Database { int i = 0; int fileCount = model.Files.Count(); - bool fileMissing = false; + bool anyFileMissing = false; foreach (var file in model.Files) { @@ -44,7 +44,7 @@ namespace osu.Game.Database if (stream == null) { Logger.Log($"File {file.Filename} is missing in local storage and will not be included in the export", LoggingTarget.Database); - fileMissing = true; + anyFileMissing = true; continue; } @@ -59,7 +59,7 @@ namespace osu.Game.Database i++; } - if (fileMissing) + if (anyFileMissing) { Logger.Log("Some files are missing in local storage and will not be included in the export", LoggingTarget.Database, LogLevel.Error); } From 3f63fd7f4d1f8ee6d87258bb309879e6f540cf8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 6 May 2023 19:39:52 +0200 Subject: [PATCH 2877/2991] Reorder increment to make progress update less weird --- osu.Game/Database/LegacyArchiveExporter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Database/LegacyArchiveExporter.cs b/osu.Game/Database/LegacyArchiveExporter.cs index feddf602b9..7689ffc13d 100644 --- a/osu.Game/Database/LegacyArchiveExporter.cs +++ b/osu.Game/Database/LegacyArchiveExporter.cs @@ -51,12 +51,12 @@ namespace osu.Game.Database writer.Write(file.Filename, stream); } + i++; + if (notification != null) { - notification.Progress = (float)(i + 1) / fileCount; + notification.Progress = (float)i / fileCount; } - - i++; } if (anyFileMissing) From 510484011c836cfd90c38c385fcaf8f4399a758c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 6 May 2023 19:42:28 +0200 Subject: [PATCH 2878/2991] Mark exporter extensions as untranslatable --- osu.Game/Database/LegacyBeatmapExporter.cs | 2 +- osu.Game/Database/LegacyScoreExporter.cs | 2 +- osu.Game/Database/LegacySkinExporter.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Database/LegacyBeatmapExporter.cs b/osu.Game/Database/LegacyBeatmapExporter.cs index e89d3da8c7..4ee8c0636e 100644 --- a/osu.Game/Database/LegacyBeatmapExporter.cs +++ b/osu.Game/Database/LegacyBeatmapExporter.cs @@ -13,6 +13,6 @@ namespace osu.Game.Database { } - protected override string FileExtension => ".osz"; + protected override string FileExtension => @".osz"; } } diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index f0514d5350..690070af85 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -26,7 +26,7 @@ namespace osu.Game.Database return filename; } - protected override string FileExtension => ".osr"; + protected override string FileExtension => @".osr"; public override void ExportToStream(ScoreInfo model, Stream outputStream, ProgressNotification? notification, CancellationToken cancellationToken = default) { diff --git a/osu.Game/Database/LegacySkinExporter.cs b/osu.Game/Database/LegacySkinExporter.cs index 4775a54c13..14a3907916 100644 --- a/osu.Game/Database/LegacySkinExporter.cs +++ b/osu.Game/Database/LegacySkinExporter.cs @@ -13,6 +13,6 @@ namespace osu.Game.Database { } - protected override string FileExtension => ".osk"; + protected override string FileExtension => @".osk"; } } From 8514b2758a69d344e59941427572c6b4d41db9a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 7 May 2023 21:07:38 +0200 Subject: [PATCH 2879/2991] Fix rapid back button test failure --- osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 0d081e8138..193cec8907 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -700,7 +700,7 @@ namespace osu.Game.Tests.Visual.Navigation AddStep("press escape twice rapidly", () => { InputManager.Key(Key.Escape); - InputManager.Key(Key.Escape); + Schedule(InputManager.Key, Key.Escape); }); pushEscape(); From 85d0c56cd28d8a299e570b891f3f208b7832674c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 8 May 2023 13:00:45 +0900 Subject: [PATCH 2880/2991] Fix incorrect special style description text Closes https://github.com/ppy/osu/issues/23428. --- osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs b/osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs index 508733ad14..98635c10a3 100644 --- a/osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs +++ b/osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Setup specialStyle = new LabelledSwitchButton { Label = "Use special (N+1) style", - Description = "Changes one column to act as a classic \"scratch\" or \"special\" column, which can be moved around by the user's skin (to the left/right/centre). Generally used in 5k (4+1) or 8key (7+1) configurations.", + Description = "Changes one column to act as a classic \"scratch\" or \"special\" column, which can be moved around by the user's skin (to the left/right/centre). Generally used in 6k (5+1) or 8k (7+1) configurations.", Current = { Value = Beatmap.BeatmapInfo.SpecialStyle } } }; From f7d44c3013f3bb11d6e2aa5476950e1d4036f3ac Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 7 May 2023 12:32:38 +0900 Subject: [PATCH 2881/2991] Rename `SliderMultiplier` to `BaseSliderVelocity` --- .../Editor/TestSceneJuiceStreamPlacementBlueprint.cs | 2 +- .../Editor/TestSceneJuiceStreamSelectionBlueprint.cs | 2 +- .../TestSceneAutoJuiceStream.cs | 2 +- .../TestSceneJuiceStream.cs | 2 +- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 4 ++-- .../Legacy/DistanceObjectPatternGenerator.cs | 2 +- osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs | 2 +- .../Editor/TestSceneOsuDistanceSnapGrid.cs | 2 +- .../Editor/TestSceneSliderStreamConversion.cs | 2 +- osu.Game.Rulesets.Osu/Objects/Slider.cs | 2 +- .../Editor/TestSceneTaikoEditorSaving.cs | 4 ++-- .../Beatmaps/TaikoBeatmapConverter.cs | 6 +++--- .../Mods/TaikoModDifficultyAdjust.cs | 2 +- osu.Game.Rulesets.Taiko/Mods/TaikoModEasy.cs | 2 +- osu.Game.Rulesets.Taiko/Mods/TaikoModHardRock.cs | 2 +- osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 2 +- .../Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 2 +- .../Beatmaps/Formats/OsuJsonDecoderTest.cs | 2 +- .../TestSceneHitObjectComposerDistanceSnapping.cs | 12 ++++++------ .../Visual/Editing/TestSceneDistanceSnapGrid.cs | 2 +- .../Gameplay/TestSceneDrawableScrollingRuleset.cs | 4 ++-- .../Gameplay/TestSceneGameplaySampleTriggerSource.cs | 2 +- osu.Game/Beatmaps/BeatmapDifficulty.cs | 8 ++++---- osu.Game/Beatmaps/BeatmapImporter.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 4 ++-- osu.Game/Beatmaps/IBeatmapDifficultyInfo.cs | 7 ++++--- osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs | 2 +- osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs | 2 +- .../UI/Scrolling/DrawableScrollingRuleset.cs | 6 +++--- 30 files changed, 49 insertions(+), 48 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamPlacementBlueprint.cs b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamPlacementBlueprint.cs index 2426f8c886..e729a09a18 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamPlacementBlueprint.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor { var playable = base.GetPlayableBeatmap(); playable.Difficulty.SliderTickRate = 5; - playable.Difficulty.SliderMultiplier = velocity_factor * 10; + playable.Difficulty.BaseSliderVelocity = velocity_factor * 10; return playable; } diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs index beba5811fe..634e1f5cbb 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs @@ -210,7 +210,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor X = x, Path = sliderPath, }; - EditorBeatmap.Difficulty.SliderMultiplier = velocity; + EditorBeatmap.Difficulty.BaseSliderVelocity = velocity; EditorBeatmap.Add(hitObject); EditorBeatmap.Update(hitObject); Assert.That(hitObject.Velocity, Is.EqualTo(velocity)); diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs index 40dc7d2403..d1f3f06971 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Catch.Tests { BeatmapInfo = new BeatmapInfo { - Difficulty = new BeatmapDifficulty { CircleSize = 6, SliderMultiplier = 3 }, + Difficulty = new BeatmapDifficulty { CircleSize = 6, BaseSliderVelocity = 3 }, Ruleset = ruleset } }; diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs index c91f07891c..71cb8964c3 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Catch.Tests { BeatmapInfo = new BeatmapInfo { - Difficulty = new BeatmapDifficulty { CircleSize = 5, SliderMultiplier = 2 }, + Difficulty = new BeatmapDifficulty { CircleSize = 5, BaseSliderVelocity = 2 }, Ruleset = ruleset }, HitObjects = new List diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 169e99c90c..301ecd6d66 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -64,8 +64,8 @@ namespace osu.Game.Rulesets.Catch.Objects TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); - velocityFactor = base_scoring_distance * difficulty.SliderMultiplier / timingPoint.BeatLength; - tickDistanceFactor = base_scoring_distance * difficulty.SliderMultiplier / difficulty.SliderTickRate; + velocityFactor = base_scoring_distance * difficulty.BaseSliderVelocity / timingPoint.BeatLength; + tickDistanceFactor = base_scoring_distance * difficulty.BaseSliderVelocity / difficulty.SliderTickRate; } protected override void CreateNestedHitObjects(CancellationToken cancellationToken) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 91b7be6e8f..ab6f5e8269 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy StartTime = (int)Math.Round(hitObject.StartTime); // This matches stable's calculation. - EndTime = (int)Math.Floor(StartTime + distanceData.Distance * beatLength * SpanCount * 0.01 / beatmap.Difficulty.SliderMultiplier); + EndTime = (int)Math.Floor(StartTime + distanceData.Distance * beatLength * SpanCount * 0.01 / beatmap.Difficulty.BaseSliderVelocity); SegmentDuration = (EndTime - StartTime) / SpanCount; } diff --git a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs index af8758fb5e..cb38551a43 100644 --- a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs @@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Mania.UI { // Mania doesn't care about global velocity p.Velocity = 1; - p.BaseBeatLength *= Beatmap.Difficulty.SliderMultiplier; + p.BaseBeatLength *= Beatmap.Difficulty.BaseSliderVelocity; // For non-mania beatmap, speed changes should only happen through timing points if (!isForCurrentRuleset) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs index 7579e8077b..b79d4efe1b 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs @@ -80,7 +80,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor [SetUp] public void Setup() => Schedule(() => { - editorBeatmap.Difficulty.SliderMultiplier = 1; + editorBeatmap.Difficulty.BaseSliderVelocity = 1; editorBeatmap.ControlPointInfo.Clear(); editorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = beat_length }); snapProvider.DistanceSpacingMultiplier.Value = 1; diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderStreamConversion.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderStreamConversion.cs index a162d9a491..938e093489 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderStreamConversion.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderStreamConversion.cs @@ -162,7 +162,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("change to these specific circumstances", () => { - EditorBeatmap.Difficulty.SliderMultiplier = 1; + EditorBeatmap.Difficulty.BaseSliderVelocity = 1; var timingPoint = EditorBeatmap.ControlPointInfo.TimingPointAt(slider.StartTime); timingPoint.BeatLength = 352.941176470588; slider.Path.ControlPoints[^1].Position = new Vector2(-110, 16); diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 4189f8ba1e..b86351e7cd 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.Osu.Objects TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); - double scoringDistance = BASE_SCORING_DISTANCE * difficulty.SliderMultiplier * SliderVelocity; + double scoringDistance = BASE_SCORING_DISTANCE * difficulty.BaseSliderVelocity * SliderVelocity; Velocity = scoringDistance / timingPoint.BeatLength; TickDistance = GenerateTicks ? (scoringDistance / difficulty.SliderTickRate * TickDistanceMultiplier) : double.PositiveInfinity; diff --git a/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneTaikoEditorSaving.cs b/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneTaikoEditorSaving.cs index 93b26624de..d79ca28c8f 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneTaikoEditorSaving.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneTaikoEditorSaving.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Editor [Test] public void TestTaikoSliderMultiplier() { - AddStep("Set slider multiplier", () => EditorBeatmap.Difficulty.SliderMultiplier = 2); + AddStep("Set slider multiplier", () => EditorBeatmap.Difficulty.BaseSliderVelocity = 2); SaveEditor(); @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Editor // therefore, ensure that we have that difficulty type by calling .CopyFrom(), which is a no-op if the type is already correct. var taikoDifficulty = new TaikoBeatmapConverter.TaikoMultiplierAppliedDifficulty(); taikoDifficulty.CopyFrom(EditorBeatmap.Difficulty); - return Precision.AlmostEquals(taikoDifficulty.SliderMultiplier, 2); + return Precision.AlmostEquals(taikoDifficulty.BaseSliderVelocity, 2); } } } diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index e298e313df..932211695a 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -189,7 +189,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps else beatLength = timingPoint.BeatLength; - double sliderScoringPointDistance = osu_base_scoring_distance * beatmap.Difficulty.SliderMultiplier / beatmap.Difficulty.SliderTickRate; + double sliderScoringPointDistance = osu_base_scoring_distance * beatmap.Difficulty.BaseSliderVelocity / beatmap.Difficulty.SliderTickRate; // The velocity and duration of the taiko hit object - calculated as the velocity of a drum roll. double taikoVelocity = sliderScoringPointDistance * beatmap.Difficulty.SliderTickRate; @@ -239,14 +239,14 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps { base.CopyTo(other); if (!(other is TaikoMultiplierAppliedDifficulty)) - other.SliderMultiplier /= LegacyBeatmapEncoder.LEGACY_TAIKO_VELOCITY_MULTIPLIER; + other.BaseSliderVelocity /= LegacyBeatmapEncoder.LEGACY_TAIKO_VELOCITY_MULTIPLIER; } public override void CopyFrom(IBeatmapDifficultyInfo other) { base.CopyFrom(other); if (!(other is TaikoMultiplierAppliedDifficulty)) - SliderMultiplier *= LegacyBeatmapEncoder.LEGACY_TAIKO_VELOCITY_MULTIPLIER; + BaseSliderVelocity *= LegacyBeatmapEncoder.LEGACY_TAIKO_VELOCITY_MULTIPLIER; } #endregion diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModDifficultyAdjust.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModDifficultyAdjust.cs index 99a064d35f..fe9c1f5815 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModDifficultyAdjust.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Taiko.Mods { base.ApplySettings(difficulty); - if (ScrollSpeed.Value != null) difficulty.SliderMultiplier *= ScrollSpeed.Value.Value; + if (ScrollSpeed.Value != null) difficulty.BaseSliderVelocity *= ScrollSpeed.Value.Value; } } } diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModEasy.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModEasy.cs index 009f2854f8..5aeb5a87d7 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModEasy.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModEasy.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Taiko.Mods public override void ApplyToDifficulty(BeatmapDifficulty difficulty) { base.ApplyToDifficulty(difficulty); - difficulty.SliderMultiplier *= slider_multiplier; + difficulty.BaseSliderVelocity *= slider_multiplier; } } } diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModHardRock.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModHardRock.cs index ba41175461..0f68750535 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModHardRock.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModHardRock.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Taiko.Mods public override void ApplyToDifficulty(BeatmapDifficulty difficulty) { base.ApplyToDifficulty(difficulty); - difficulty.SliderMultiplier *= slider_multiplier; + difficulty.BaseSliderVelocity *= slider_multiplier; } } } diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs index b4a12fd314..014fec9319 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Taiko.Objects TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); - double scoringDistance = base_distance * difficulty.SliderMultiplier * SliderVelocity; + double scoringDistance = base_distance * difficulty.BaseSliderVelocity * SliderVelocity; Velocity = scoringDistance / timingPoint.BeatLength; tickSpacing = timingPoint.BeatLength / TickRate; diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 2c4f193327..98ad6fc18d 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -136,7 +136,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(4, difficulty.CircleSize); Assert.AreEqual(8, difficulty.OverallDifficulty); Assert.AreEqual(9, difficulty.ApproachRate); - Assert.AreEqual(1.8, difficulty.SliderMultiplier); + Assert.AreEqual(1.8, difficulty.BaseSliderVelocity); Assert.AreEqual(2, difficulty.SliderTickRate); } } diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 3764467047..11c5f2a2fc 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -91,7 +91,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(4, difficulty.CircleSize); Assert.AreEqual(8, difficulty.OverallDifficulty); Assert.AreEqual(9, difficulty.ApproachRate); - Assert.AreEqual(1.8, difficulty.SliderMultiplier); + Assert.AreEqual(1.8, difficulty.BaseSliderVelocity); Assert.AreEqual(2, difficulty.SliderTickRate); } diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index 6399507aa0..ffbe16260b 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -57,7 +57,7 @@ namespace osu.Game.Tests.Editing BeatDivisor.Value = 1; - composer.EditorBeatmap.Difficulty.SliderMultiplier = 1; + composer.EditorBeatmap.Difficulty.BaseSliderVelocity = 1; composer.EditorBeatmap.ControlPointInfo.Clear(); composer.EditorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 }); }); @@ -66,7 +66,7 @@ namespace osu.Game.Tests.Editing [TestCase(2)] public void TestSliderMultiplier(float multiplier) { - AddStep($"set slider multiplier = {multiplier}", () => composer.EditorBeatmap.Difficulty.SliderMultiplier = multiplier); + AddStep($"set slider multiplier = {multiplier}", () => composer.EditorBeatmap.Difficulty.BaseSliderVelocity = multiplier); assertSnapDistance(100 * multiplier, null, true); } @@ -128,7 +128,7 @@ namespace osu.Game.Tests.Editing assertDurationToDistance(500, 50); assertDurationToDistance(1000, 100); - AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.Difficulty.SliderMultiplier = 2); + AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.Difficulty.BaseSliderVelocity = 2); assertDurationToDistance(500, 100); assertDurationToDistance(1000, 200); @@ -149,7 +149,7 @@ namespace osu.Game.Tests.Editing assertDistanceToDuration(50, 500); assertDistanceToDuration(100, 1000); - AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.Difficulty.SliderMultiplier = 2); + AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.Difficulty.BaseSliderVelocity = 2); assertDistanceToDuration(100, 500); assertDistanceToDuration(200, 1000); @@ -174,7 +174,7 @@ namespace osu.Game.Tests.Editing assertSnappedDuration(200, 2000); assertSnappedDuration(250, 3000); - AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.Difficulty.SliderMultiplier = 2); + AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.Difficulty.BaseSliderVelocity = 2); assertSnappedDuration(0, 0); assertSnappedDuration(50, 0); @@ -206,7 +206,7 @@ namespace osu.Game.Tests.Editing assertSnappedDistance(200, 200); assertSnappedDistance(250, 200); - AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.Difficulty.SliderMultiplier = 2); + AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.Difficulty.BaseSliderVelocity = 2); assertSnappedDistance(50, 0); assertSnappedDistance(100, 0); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs index 21b925a257..a99bd72e40 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Editing } }); editorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = beat_length }); - editorBeatmap.Difficulty.SliderMultiplier = 1; + editorBeatmap.Difficulty.BaseSliderVelocity = 1; } [SetUp] diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs index 287b7d43b4..735af9493c 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs @@ -184,7 +184,7 @@ namespace osu.Game.Tests.Visual.Gameplay { var beatmap = createBeatmap(); beatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = time_range }); - beatmap.Difficulty.SliderMultiplier = 2; + beatmap.Difficulty.BaseSliderVelocity = 2; createTest(beatmap, d => d.RelativeScaleBeatLengthsOverride = true); AddStep("adjust time range", () => drawableRuleset.TimeRange.Value = 5000); @@ -198,7 +198,7 @@ namespace osu.Game.Tests.Visual.Gameplay { var beatmap = createBeatmap(); beatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = time_range }); - beatmap.Difficulty.SliderMultiplier = 2; + beatmap.Difficulty.BaseSliderVelocity = 2; createTest(beatmap); AddStep("adjust time range", () => drawableRuleset.TimeRange.Value = 2000); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs index 114c554d28..28cc890fce 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs @@ -46,7 +46,7 @@ namespace osu.Game.Tests.Visual.Gameplay { BeatmapInfo = new BeatmapInfo { - Difficulty = new BeatmapDifficulty { CircleSize = 6, SliderMultiplier = 3 }, + Difficulty = new BeatmapDifficulty { CircleSize = 6, BaseSliderVelocity = 3 }, Ruleset = ruleset }, ControlPointInfo = controlPointInfo diff --git a/osu.Game/Beatmaps/BeatmapDifficulty.cs b/osu.Game/Beatmaps/BeatmapDifficulty.cs index f4bc5e7b77..cbea30f3b0 100644 --- a/osu.Game/Beatmaps/BeatmapDifficulty.cs +++ b/osu.Game/Beatmaps/BeatmapDifficulty.cs @@ -11,7 +11,7 @@ namespace osu.Game.Beatmaps public class BeatmapDifficulty : EmbeddedObject, IBeatmapDifficultyInfo { /// - /// The default value used for all difficulty settings except and . + /// The default value used for all difficulty settings except and . /// public const float DEFAULT_DIFFICULTY = 5; @@ -20,7 +20,7 @@ namespace osu.Game.Beatmaps public float OverallDifficulty { get; set; } = IBeatmapDifficultyInfo.DEFAULT_DIFFICULTY; public float ApproachRate { get; set; } = IBeatmapDifficultyInfo.DEFAULT_DIFFICULTY; - public double SliderMultiplier { get; set; } = 1; + public double BaseSliderVelocity { get; set; } = 1; public double SliderTickRate { get; set; } = 1; public BeatmapDifficulty() @@ -44,7 +44,7 @@ namespace osu.Game.Beatmaps difficulty.CircleSize = CircleSize; difficulty.OverallDifficulty = OverallDifficulty; - difficulty.SliderMultiplier = SliderMultiplier; + difficulty.BaseSliderVelocity = BaseSliderVelocity; difficulty.SliderTickRate = SliderTickRate; } @@ -55,7 +55,7 @@ namespace osu.Game.Beatmaps CircleSize = other.CircleSize; OverallDifficulty = other.OverallDifficulty; - SliderMultiplier = other.SliderMultiplier; + BaseSliderVelocity = other.BaseSliderVelocity; SliderTickRate = other.SliderTickRate; } } diff --git a/osu.Game/Beatmaps/BeatmapImporter.cs b/osu.Game/Beatmaps/BeatmapImporter.cs index 4731a70753..e96e38d249 100644 --- a/osu.Game/Beatmaps/BeatmapImporter.cs +++ b/osu.Game/Beatmaps/BeatmapImporter.cs @@ -353,7 +353,7 @@ namespace osu.Game.Beatmaps CircleSize = decodedDifficulty.CircleSize, OverallDifficulty = decodedDifficulty.OverallDifficulty, ApproachRate = decodedDifficulty.ApproachRate, - SliderMultiplier = decodedDifficulty.SliderMultiplier, + BaseSliderVelocity = decodedDifficulty.BaseSliderVelocity, SliderTickRate = decodedDifficulty.SliderTickRate, }; diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 5e98025c9a..891e627435 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -384,7 +384,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"SliderMultiplier": - difficulty.SliderMultiplier = Parsing.ParseDouble(pair.Value); + difficulty.BaseSliderVelocity = Parsing.ParseDouble(pair.Value); break; case @"SliderTickRate": diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 7fbcca9adb..fffead3a6c 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -155,8 +155,8 @@ namespace osu.Game.Beatmaps.Formats // Taiko adjusts the slider multiplier (see: LEGACY_TAIKO_VELOCITY_MULTIPLIER) writer.WriteLine(onlineRulesetID == 1 - ? FormattableString.Invariant($"SliderMultiplier: {beatmap.Difficulty.SliderMultiplier / LEGACY_TAIKO_VELOCITY_MULTIPLIER}") - : FormattableString.Invariant($"SliderMultiplier: {beatmap.Difficulty.SliderMultiplier}")); + ? FormattableString.Invariant($"SliderMultiplier: {beatmap.Difficulty.BaseSliderVelocity / LEGACY_TAIKO_VELOCITY_MULTIPLIER}") + : FormattableString.Invariant($"SliderMultiplier: {beatmap.Difficulty.BaseSliderVelocity}")); writer.WriteLine(FormattableString.Invariant($"SliderTickRate: {beatmap.Difficulty.SliderTickRate}")); } diff --git a/osu.Game/Beatmaps/IBeatmapDifficultyInfo.cs b/osu.Game/Beatmaps/IBeatmapDifficultyInfo.cs index dad9bbbd0b..bc2ee23da7 100644 --- a/osu.Game/Beatmaps/IBeatmapDifficultyInfo.cs +++ b/osu.Game/Beatmaps/IBeatmapDifficultyInfo.cs @@ -9,7 +9,7 @@ namespace osu.Game.Beatmaps public interface IBeatmapDifficultyInfo { /// - /// The default value used for all difficulty settings except and . + /// The default value used for all difficulty settings except and . /// const float DEFAULT_DIFFICULTY = 5; @@ -34,9 +34,10 @@ namespace osu.Game.Beatmaps float ApproachRate { get; } /// - /// The slider multiplier of the associated beatmap. + /// The base slider velocity of the associated beatmap. + /// This was known as "SliderMultiplier" in the .osu format and stable editor. /// - double SliderMultiplier { get; } + double BaseSliderVelocity { get; } /// /// The slider tick rate of the associated beatmap. diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index a8972775de..4adbb356da 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -240,7 +240,7 @@ namespace osu.Game.Rulesets.Edit public virtual float GetBeatSnapDistanceAt(HitObject referenceObject, bool useReferenceSliderVelocity = true) { - return (float)(100 * (useReferenceSliderVelocity && referenceObject is IHasSliderVelocity hasSliderVelocity ? hasSliderVelocity.SliderVelocity : 1) * EditorBeatmap.Difficulty.SliderMultiplier * 1 + return (float)(100 * (useReferenceSliderVelocity && referenceObject is IHasSliderVelocity hasSliderVelocity ? hasSliderVelocity.SliderVelocity : 1) * EditorBeatmap.Difficulty.BaseSliderVelocity * 1 / BeatSnapProvider.BeatDivisor); } diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index 7ddd372dc9..bdcf539033 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Objects.Legacy TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); - double scoringDistance = base_scoring_distance * difficulty.SliderMultiplier * SliderVelocity; + double scoringDistance = base_scoring_distance * difficulty.BaseSliderVelocity * SliderVelocity; Velocity = scoringDistance / timingPoint.BeatLength; } diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs index 4c7564b791..da1110506a 100644 --- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs @@ -123,7 +123,7 @@ namespace osu.Game.Rulesets.UI.Scrolling // The slider multiplier is post-multiplied to determine the final velocity, but for relative scale beat lengths // the multiplier should not affect the effective timing point (the longest in the beatmap), so it is factored out here - baseBeatLength /= Beatmap.Difficulty.SliderMultiplier; + baseBeatLength /= Beatmap.Difficulty.BaseSliderVelocity; } // Merge sequences of timing and difficulty control points to create the aggregate "multiplier" control point @@ -150,7 +150,7 @@ namespace osu.Game.Rulesets.UI.Scrolling return new MultiplierControlPoint(c.Time) { - Velocity = Beatmap.Difficulty.SliderMultiplier, + Velocity = Beatmap.Difficulty.BaseSliderVelocity, BaseBeatLength = baseBeatLength, TimingPoint = lastTimingPoint, EffectPoint = lastEffectPoint @@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.UI.Scrolling ControlPoints.AddRange(timingChanges); if (ControlPoints.Count == 0) - ControlPoints.Add(new MultiplierControlPoint { Velocity = Beatmap.Difficulty.SliderMultiplier }); + ControlPoints.Add(new MultiplierControlPoint { Velocity = Beatmap.Difficulty.BaseSliderVelocity }); } protected override void LoadComplete() From b109ee74a631a32df7195b077cd237e70ead1530 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 7 May 2023 13:20:57 +0900 Subject: [PATCH 2882/2991] Add "base velocity" adjustment to difficulty setup screen --- osu.Game/Localisation/EditorSetupStrings.cs | 10 ++++++++++ osu.Game/Screens/Edit/Setup/DifficultySection.cs | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/osu.Game/Localisation/EditorSetupStrings.cs b/osu.Game/Localisation/EditorSetupStrings.cs index 4ddacf2c5b..caea3dd130 100644 --- a/osu.Game/Localisation/EditorSetupStrings.cs +++ b/osu.Game/Localisation/EditorSetupStrings.cs @@ -126,6 +126,16 @@ namespace osu.Game.Localisation public static LocalisableString OverallDifficultyDescription => new TranslatableString(getKey(@"overall_difficulty_description"), @"The harshness of hit windows and difficulty of special objects (ie. spinners)"); + /// + /// "Base Velocity" + /// + public static LocalisableString BaseVelocity => new TranslatableString(getKey(@"base_velocity"), @"Base Velocity"); + + /// + /// "The base velocity of the beatmap, affecting things like slider velocity and scroll speed in some rulesets." + /// + public static LocalisableString BaseVelocityDescription => new TranslatableString(getKey(@"base_velocity_description"), @"The base velocity of the beatmap, affecting things like slider velocity and scroll speed in some rulesets."); + /// /// "Metadata" /// diff --git a/osu.Game/Screens/Edit/Setup/DifficultySection.cs b/osu.Game/Screens/Edit/Setup/DifficultySection.cs index 7026bde681..7c4b0e72d7 100644 --- a/osu.Game/Screens/Edit/Setup/DifficultySection.cs +++ b/osu.Game/Screens/Edit/Setup/DifficultySection.cs @@ -19,6 +19,7 @@ namespace osu.Game.Screens.Edit.Setup private LabelledSliderBar healthDrainSlider = null!; private LabelledSliderBar approachRateSlider = null!; private LabelledSliderBar overallDifficultySlider = null!; + private LabelledSliderBar baseVelocitySlider = null!; public override LocalisableString Title => EditorSetupStrings.DifficultyHeader; @@ -79,6 +80,19 @@ namespace osu.Game.Screens.Edit.Setup Precision = 0.1f, } }, + baseVelocitySlider = new LabelledSliderBar + { + Label = EditorSetupStrings.BaseVelocity, + FixedLabelWidth = LABEL_WIDTH, + Description = EditorSetupStrings.BaseVelocityDescription, + Current = new BindableDouble(Beatmap.Difficulty.BaseSliderVelocity) + { + Default = 1, + MinValue = 0.01, + MaxValue = 10, + Precision = 0.1f, + } + }, }; foreach (var item in Children.OfType>()) @@ -93,6 +107,7 @@ namespace osu.Game.Screens.Edit.Setup Beatmap.Difficulty.DrainRate = healthDrainSlider.Current.Value; Beatmap.Difficulty.ApproachRate = approachRateSlider.Current.Value; Beatmap.Difficulty.OverallDifficulty = overallDifficultySlider.Current.Value; + Beatmap.Difficulty.BaseSliderVelocity = baseVelocitySlider.Current.Value; Beatmap.UpdateAllHitObjects(); Beatmap.SaveState(); From 31de4de72031afdfa1e02ed201a5bbcacf9d8333 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 7 May 2023 13:21:39 +0900 Subject: [PATCH 2883/2991] Remove median/mode slider velocity display The intention was to give an idea of what the most common velocity of the beatmap is, but in hindsight, because the "base" velocity is being set elsewhere this doesn't make sense. It will/should be 1.0x. Showing this range is still valuable, though. --- .../Timeline/DifficultyPointPiece.cs | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs index 13a1c30cfe..545e54254a 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs @@ -159,20 +159,12 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline double[] sliderVelocities = EditorBeatmap.HitObjects.OfType().Select(sv => sv.SliderVelocity).OrderBy(v => v).ToArray(); - if (sliderVelocities.Length < 2) - return; + if (sliderVelocities.First() != sliderVelocities.Last()) + { + AddHeader("Used velocity range"); + AddValue($"{sliderVelocities.First():#,0.00}x - {sliderVelocities.Last():#,0.00}x"); + } - double? modeSliderVelocity = sliderVelocities.GroupBy(v => v).MaxBy(v => v.Count())?.Key; - double? medianSliderVelocity = sliderVelocities[sliderVelocities.Length / 2]; - - AddHeader("Average velocity"); - AddValue($"{medianSliderVelocity:#,0.00}x"); - - AddHeader("Most used velocity"); - AddValue($"{modeSliderVelocity:#,0.00}x"); - - AddHeader("Velocity range"); - AddValue($"{sliderVelocities.First():#,0.00}x - {sliderVelocities.Last():#,0.00}x"); } protected override void Dispose(bool isDisposing) From d9dd35c0202d10694721737c16675e4db236c45f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 7 May 2023 13:22:48 +0900 Subject: [PATCH 2884/2991] Show base velocity in slider adjustment popover --- .../Edit/Compose/Components/Timeline/DifficultyPointPiece.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs index 545e54254a..a02a3be430 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs @@ -165,6 +165,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline AddValue($"{sliderVelocities.First():#,0.00}x - {sliderVelocities.Last():#,0.00}x"); } + AddHeader("Beatmap base velocity"); + AddValue($"{EditorBeatmap.Difficulty.BaseSliderVelocity:#,0.00}x"); } protected override void Dispose(bool isDisposing) From 451af9d1b5b04e58cf034f65a2480366c3b9a34b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 8 May 2023 13:23:13 +0900 Subject: [PATCH 2885/2991] Fix beatmap values not being updated due to a varying data type --- osu.Game/Screens/Edit/Setup/DifficultySection.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Setup/DifficultySection.cs b/osu.Game/Screens/Edit/Setup/DifficultySection.cs index 7c4b0e72d7..66bb8a9b84 100644 --- a/osu.Game/Screens/Edit/Setup/DifficultySection.cs +++ b/osu.Game/Screens/Edit/Setup/DifficultySection.cs @@ -96,10 +96,13 @@ namespace osu.Game.Screens.Edit.Setup }; foreach (var item in Children.OfType>()) - item.Current.ValueChanged += onValueChanged; + item.Current.ValueChanged += _ => updateValues(); + + foreach (var item in Children.OfType>()) + item.Current.ValueChanged += _ => updateValues(); } - private void onValueChanged(ValueChangedEvent args) + private void updateValues() { // for now, update these on commit rather than making BeatmapMetadata bindables. // after switching database engines we can reconsider if switching to bindables is a good direction. From a91edd68d976df038c654feea6c1714d03ac11bc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 8 May 2023 13:42:25 +0900 Subject: [PATCH 2886/2991] Show post-multiplied velocity in main hit object inspector --- osu.Game/Screens/Edit/Compose/Components/HitObjectInspector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/HitObjectInspector.cs b/osu.Game/Screens/Edit/Compose/Components/HitObjectInspector.cs index 597925e3e2..60b9010aa8 100644 --- a/osu.Game/Screens/Edit/Compose/Components/HitObjectInspector.cs +++ b/osu.Game/Screens/Edit/Compose/Components/HitObjectInspector.cs @@ -73,7 +73,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (selected is IHasSliderVelocity sliderVelocity) { AddHeader("Slider Velocity"); - AddValue($"{sliderVelocity.SliderVelocity:#,0.00}x"); + AddValue($"{sliderVelocity.SliderVelocity:#,0.00}x ({sliderVelocity.SliderVelocity * EditorBeatmap.Difficulty.BaseSliderVelocity:#,0.00}x)"); } if (selected is IHasRepeats repeats) From a6cb1f90e4c9ab1b2e06bda043321f2795a56b8e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 8 May 2023 13:43:21 +0900 Subject: [PATCH 2887/2991] Change difficulty popover inspector display (yet again) I think this makes the most sense of the iterations I've tested so far, albeit maybe being a touch too verbose. --- .../Timeline/DifficultyPointPiece.cs | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs index a02a3be430..ac37101060 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs @@ -96,7 +96,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline RelativeSizeAxes = Axes.X, Text = "Hold shift while dragging the end of an object to adjust velocity while snapping." }, - new SliderVelocityInspector(), + new SliderVelocityInspector(sliderVelocitySlider.Current), } } }; @@ -145,28 +145,48 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline internal partial class SliderVelocityInspector : EditorInspector { + private readonly Bindable current; + + public SliderVelocityInspector(Bindable current) + { + this.current = current; + } + [BackgroundDependencyLoader] private void load() { EditorBeatmap.TransactionBegan += updateInspectorText; EditorBeatmap.TransactionEnded += updateInspectorText; + EditorBeatmap.BeatmapReprocessed += updateInspectorText; + current.ValueChanged += _ => updateInspectorText(); + updateInspectorText(); } private void updateInspectorText() { + double beatmapVelocity = EditorBeatmap.Difficulty.BaseSliderVelocity; + InspectorText.Clear(); double[] sliderVelocities = EditorBeatmap.HitObjects.OfType().Select(sv => sv.SliderVelocity).OrderBy(v => v).ToArray(); + AddHeader("Base velocity (from beatmap setup)"); + AddValue($"{beatmapVelocity:#,0.00}x"); + + AddHeader("Final velocity"); + AddValue($"{beatmapVelocity * current.Value:#,0.00}x"); + if (sliderVelocities.First() != sliderVelocities.Last()) { - AddHeader("Used velocity range"); - AddValue($"{sliderVelocities.First():#,0.00}x - {sliderVelocities.Last():#,0.00}x"); - } + AddHeader("Beatmap velocity range"); - AddHeader("Beatmap base velocity"); - AddValue($"{EditorBeatmap.Difficulty.BaseSliderVelocity:#,0.00}x"); + string range = $"{sliderVelocities.First():#,0.00}x - {sliderVelocities.Last():#,0.00}x"; + if (beatmapVelocity != 1) + range += $" ({beatmapVelocity * sliderVelocities.First():#,0.00}x - {beatmapVelocity * sliderVelocities.Last():#,0.00}x)"; + + AddValue(range); + } } protected override void Dispose(bool isDisposing) From 8c44d528e9f640d56a4834cb81d99cbf81bc630a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 8 May 2023 13:51:52 +0900 Subject: [PATCH 2888/2991] Use min/max values from stable --- osu.Game/Screens/Edit/Setup/DifficultySection.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Setup/DifficultySection.cs b/osu.Game/Screens/Edit/Setup/DifficultySection.cs index 66bb8a9b84..6c7e96f91d 100644 --- a/osu.Game/Screens/Edit/Setup/DifficultySection.cs +++ b/osu.Game/Screens/Edit/Setup/DifficultySection.cs @@ -88,9 +88,9 @@ namespace osu.Game.Screens.Edit.Setup Current = new BindableDouble(Beatmap.Difficulty.BaseSliderVelocity) { Default = 1, - MinValue = 0.01, - MaxValue = 10, - Precision = 0.1f, + MinValue = 0.4, + MaxValue = 3.6, + Precision = 0.01f, } }, }; From f0020381377f77f58d5374007aebbe16e70e8776 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 8 May 2023 15:29:04 +0900 Subject: [PATCH 2889/2991] Add test coverage of failing wiki return to page scenario --- .../Visual/Online/TestSceneWikiOverlay.cs | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs index b0e4303ca4..310e34262e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using System.Net; @@ -20,7 +18,7 @@ namespace osu.Game.Tests.Visual.Online { private DummyAPIAccess dummyAPI => (DummyAPIAccess)API; - private WikiOverlay wiki; + private WikiOverlay wiki = null!; [SetUp] public void SetUp() => Schedule(() => Child = wiki = new WikiOverlay()); @@ -73,7 +71,23 @@ namespace osu.Game.Tests.Visual.Online AddUntilStep("Error message correct", () => wiki.ChildrenOfType().Any(text => text.Text == "\"This_page_will_error_out\".")); } - private void setUpWikiResponse(APIWikiPage r, string redirectionPath = null) + [Test] + public void TestReturnAfterErrorPage() + { + setUpWikiResponse(responseArticlePage); + + AddStep("Show article page", () => wiki.ShowPage("Article_styling_criteria/Formatting")); + AddUntilStep("Wait for non-error page", () => wiki.CurrentPath == "Article_styling_criteria/Formatting"); + + AddStep("Show nonexistent page", () => wiki.ShowPage("This_page_will_error_out")); + AddUntilStep("Wait for error page", () => wiki.CurrentPath == "error"); + + AddStep("Show article page", () => wiki.ShowPage("Article_styling_criteria/Formatting")); + AddUntilStep("Wait for non-error page", () => wiki.CurrentPath == "Article_styling_criteria/Formatting"); + AddUntilStep("Error message not displayed", () => wiki.ChildrenOfType().All(text => text.Text != "\"This_page_will_error_out\".")); + } + + private void setUpWikiResponse(APIWikiPage r, string? redirectionPath = null) => AddStep("set up response", () => { dummyAPI.HandleRequest = request => From 715b735131d8c1c1b3073222175ebe8753fc51ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 8 May 2023 15:20:17 +0900 Subject: [PATCH 2890/2991] Fix "Return to main page" link not working on wiki after error --- osu.Game/Overlays/WikiOverlay.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/WikiOverlay.cs b/osu.Game/Overlays/WikiOverlay.cs index 2444aa4fa2..c816eca776 100644 --- a/osu.Game/Overlays/WikiOverlay.cs +++ b/osu.Game/Overlays/WikiOverlay.cs @@ -157,7 +157,9 @@ namespace osu.Game.Overlays private void onFail(string originalPath) { + wikiData.Value = null; path.Value = "error"; + LoadDisplay(articlePage = new WikiArticlePage($@"{api.WebsiteRootUrl}/wiki/", $"Something went wrong when trying to fetch page \"{originalPath}\".\n\n[Return to the main page](Main_Page).")); } From 9160711470035a7fbe6fd8227debe1934c943742 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 8 May 2023 15:32:00 +0900 Subject: [PATCH 2891/2991] Change "Show main page" test steps to actually load the main page --- osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs index 310e34262e..79c7e3a22e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneWikiOverlay.cs @@ -27,13 +27,13 @@ namespace osu.Game.Tests.Visual.Online public void TestMainPage() { setUpWikiResponse(responseMainPage); - AddStep("Show main page", () => wiki.Show()); + AddStep("Show main page", () => wiki.ShowPage()); } [Test] public void TestCancellationDoesntShowError() { - AddStep("Show main page", () => wiki.Show()); + AddStep("Show main page", () => wiki.ShowPage()); AddStep("Show another page", () => wiki.ShowPage("Article_styling_criteria/Formatting")); AddUntilStep("Current path is not error", () => wiki.CurrentPath != "error"); From 814f0b3fedf27661b721aecb17c1a9fbb7c5f000 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 8 May 2023 15:43:11 +0900 Subject: [PATCH 2892/2991] Add back early return in `OnReleased` for safety --- osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 20daab2447..e5a6aa1049 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -329,6 +329,10 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (HoldStartTime == null) return; + // do not run any of this logic when rewinding, as it inverts order of presses/releases. + if (Time.Elapsed < 0) + return; + Tail.UpdateResult(); endHold(); From 1b7dd32eb1f006393fb73969f215a4b2421619c8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 8 May 2023 16:55:29 +0900 Subject: [PATCH 2893/2991] Apply nullability in related classes and remove unused variable --- .../TestSceneHoldNoteInput.cs | 12 ++++-------- .../UI/Scrolling/Algorithms/IScrollAlgorithm.cs | 2 -- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs index 42e2099e3f..ce6a118d9b 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using NUnit.Framework; @@ -40,7 +38,7 @@ namespace osu.Game.Rulesets.Mania.Tests private const double time_tail = 4000; private const double time_after_tail = 5250; - private List judgementResults; + private List judgementResults = new List(); /// /// -----[ ]----- @@ -521,9 +519,9 @@ namespace osu.Game.Rulesets.Mania.Tests private void assertLastTickJudgement(HitResult result) => AddAssert($"last tick judged as {result}", () => judgementResults.Last(j => j.HitObject is HoldNoteTick).Type, () => Is.EqualTo(result)); - private ScoreAccessibleReplayPlayer currentPlayer; + private ScoreAccessibleReplayPlayer currentPlayer = null!; - private void performTest(List frames, Beatmap beatmap = null) + private void performTest(List frames, Beatmap? beatmap = null) { if (beatmap == null) { @@ -569,15 +567,13 @@ namespace osu.Game.Rulesets.Mania.Tests AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0); AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen()); - AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor?.HasCompleted.Value == true); + AddUntilStep("Wait for completion", () => currentPlayer.ScoreProcessor.HasCompleted.Value); } private partial class ScoreAccessibleReplayPlayer : ReplayPlayer { public new ScoreProcessor ScoreProcessor => base.ScoreProcessor; - public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer; - protected override bool PauseOnFocusLost => false; public ScoreAccessibleReplayPlayer(Score score) diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollAlgorithm.cs index f78509f919..437e5a5e38 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollAlgorithm.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.UI.Scrolling.Algorithms { public interface IScrollAlgorithm From d6ce56e6b1d7eec37ea19a32d5034f467fb96226 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 8 May 2023 16:55:48 +0900 Subject: [PATCH 2894/2991] Fix `GetMostCommonBeatLength` returning zero in case of not timing points --- osu.Game/Beatmaps/Beatmap.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 416d655cc3..4f81b26c3e 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -107,9 +107,12 @@ namespace osu.Game.Beatmaps // Aggregate durations into a set of (beatLength, duration) tuples for each beat length .GroupBy(t => Math.Round(t.beatLength * 1000) / 1000) .Select(g => (beatLength: g.Key, duration: g.Sum(t => t.duration))) - // Get the most common one, or 0 as a suitable default + // Get the most common one, or 0 as a suitable default (see handling below) .OrderByDescending(i => i.duration).FirstOrDefault(); + if (mostCommon.beatLength == 0) + return TimingControlPoint.DEFAULT_BEAT_LENGTH; + return mostCommon.beatLength; } From bcabe967141d8a55b42b4e3da42546c8f2520749 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 8 May 2023 17:49:41 +0900 Subject: [PATCH 2895/2991] Add extra tests of hold note input in more standard scenarios --- .../TestSceneHoldNoteInput.cs | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs index ce6a118d9b..77db1b0bd8 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs @@ -59,6 +59,44 @@ namespace osu.Game.Rulesets.Mania.Tests assertNoteJudgement(HitResult.IgnoreMiss); } + /// + /// -----[ ]----- + /// x o + /// + [Test] + public void TestCorrectInput() + { + performTest(new List + { + new ManiaReplayFrame(time_head, ManiaAction.Key1), + new ManiaReplayFrame(time_tail), + }); + + assertHeadJudgement(HitResult.Perfect); + assertTickJudgement(HitResult.LargeTickHit); + assertTailJudgement(HitResult.Perfect); + assertNoteJudgement(HitResult.IgnoreHit); + } + + /// + /// -----[ ]----- + /// x o + /// + [Test] + public void TestLateRelease() + { + performTest(new List + { + new ManiaReplayFrame(time_head, ManiaAction.Key1), + new ManiaReplayFrame(time_after_tail), + }); + + assertHeadJudgement(HitResult.Perfect); + assertTickJudgement(HitResult.LargeTickHit); + assertTailJudgement(HitResult.Miss); + assertNoteJudgement(HitResult.IgnoreMiss); + } + /// /// -----[ ]----- /// x o From d2380bd8401491d13d70bf0122ce1df341f8620e Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 8 May 2023 18:12:56 +0900 Subject: [PATCH 2896/2991] Remove usages of [ExcludeFromDynamicCompile] --- osu.Game/Beatmaps/BeatmapDifficulty.cs | 2 -- osu.Game/Beatmaps/BeatmapImporter.cs | 2 -- osu.Game/Beatmaps/BeatmapInfo.cs | 2 -- osu.Game/Beatmaps/BeatmapManager.cs | 2 -- osu.Game/Beatmaps/BeatmapMetadata.cs | 2 -- osu.Game/Beatmaps/BeatmapSetInfo.cs | 2 -- osu.Game/Beatmaps/BeatmapUpdaterMetadataLookup.cs | 2 -- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 -- osu.Game/Beatmaps/WorkingBeatmapCache.cs | 2 -- osu.Game/Configuration/DevelopmentOsuConfigManager.cs | 2 -- osu.Game/Configuration/OsuConfigManager.cs | 2 -- osu.Game/Database/RealmFileStore.cs | 2 -- osu.Game/Models/RealmFile.cs | 2 -- osu.Game/Models/RealmNamedFileUsage.cs | 2 -- osu.Game/Overlays/Settings/SettingsSubsection.cs | 2 -- osu.Game/Rulesets/Mods/Mod.cs | 2 -- osu.Game/Rulesets/Ruleset.cs | 2 -- osu.Game/Rulesets/RulesetInfo.cs | 2 -- osu.Game/Scoring/ScoreInfo.cs | 2 -- osu.Game/Skinning/SkinInfo.cs | 2 -- osu.Game/Skinning/SkinManager.cs | 2 -- osu.Game/Tests/Visual/OsuTestScene.cs | 1 - 22 files changed, 43 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapDifficulty.cs b/osu.Game/Beatmaps/BeatmapDifficulty.cs index f4bc5e7b77..217f3b89a4 100644 --- a/osu.Game/Beatmaps/BeatmapDifficulty.cs +++ b/osu.Game/Beatmaps/BeatmapDifficulty.cs @@ -1,12 +1,10 @@ // 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.Testing; using Realms; namespace osu.Game.Beatmaps { - [ExcludeFromDynamicCompile] [MapTo("BeatmapDifficulty")] public class BeatmapDifficulty : EmbeddedObject, IBeatmapDifficultyInfo { diff --git a/osu.Game/Beatmaps/BeatmapImporter.cs b/osu.Game/Beatmaps/BeatmapImporter.cs index 4731a70753..7d367ef77d 100644 --- a/osu.Game/Beatmaps/BeatmapImporter.cs +++ b/osu.Game/Beatmaps/BeatmapImporter.cs @@ -12,7 +12,6 @@ using osu.Framework.Extensions; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Logging; using osu.Framework.Platform; -using osu.Framework.Testing; using osu.Game.Beatmaps.Formats; using osu.Game.Collections; using osu.Game.Database; @@ -28,7 +27,6 @@ namespace osu.Game.Beatmaps /// /// Handles the storage and retrieval of Beatmaps/WorkingBeatmaps. /// - [ExcludeFromDynamicCompile] public class BeatmapImporter : RealmArchiveModelImporter { public override IEnumerable HandledExtensions => new[] { ".osz" }; diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 63e878b80d..393feff087 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -6,7 +6,6 @@ using System.Diagnostics; using System.Linq; using JetBrains.Annotations; using Newtonsoft.Json; -using osu.Framework.Testing; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Collections; using osu.Game.Database; @@ -27,7 +26,6 @@ namespace osu.Game.Beatmaps /// /// There are some legacy fields in this model which are not persisted to realm. These are isolated in a code region within the class and should eventually be migrated to `Beatmap`. /// - [ExcludeFromDynamicCompile] [Serializable] [MapTo("Beatmap")] public class BeatmapInfo : RealmObject, IHasGuidPrimaryKey, IBeatmapInfo, IEquatable diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 61b234d88a..305dc01844 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -15,7 +15,6 @@ using osu.Framework.Audio.Track; using osu.Framework.Extensions; using osu.Framework.IO.Stores; using osu.Framework.Platform; -using osu.Framework.Testing; using osu.Game.Beatmaps.Formats; using osu.Game.Database; using osu.Game.Extensions; @@ -33,7 +32,6 @@ namespace osu.Game.Beatmaps /// /// Handles general operations related to global beatmap management. /// - [ExcludeFromDynamicCompile] public class BeatmapManager : ModelManager, IModelImporter, IWorkingBeatmapCache { public ITrackStore BeatmapTrackStore { get; } diff --git a/osu.Game/Beatmaps/BeatmapMetadata.cs b/osu.Game/Beatmaps/BeatmapMetadata.cs index f645d914b1..811dc54e16 100644 --- a/osu.Game/Beatmaps/BeatmapMetadata.cs +++ b/osu.Game/Beatmaps/BeatmapMetadata.cs @@ -4,7 +4,6 @@ using System; using JetBrains.Annotations; using Newtonsoft.Json; -using osu.Framework.Testing; using osu.Game.Models; using osu.Game.Users; using osu.Game.Utils; @@ -23,7 +22,6 @@ namespace osu.Game.Beatmaps /// /// Note that difficulty name is not stored in this metadata but in . /// - [ExcludeFromDynamicCompile] [Serializable] [MapTo("BeatmapMetadata")] public class BeatmapMetadata : RealmObject, IBeatmapMetadataInfo, IDeepCloneable diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index b90dfdba05..59e413d935 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; using Newtonsoft.Json; -using osu.Framework.Testing; using osu.Game.Database; using osu.Game.Extensions; using osu.Game.Models; @@ -17,7 +16,6 @@ namespace osu.Game.Beatmaps /// /// A realm model containing metadata for a beatmap set (containing multiple s). /// - [ExcludeFromDynamicCompile] [MapTo("BeatmapSet")] public class BeatmapSetInfo : RealmObject, IHasGuidPrimaryKey, IHasRealmFiles, ISoftDelete, IEquatable, IBeatmapSetInfo { diff --git a/osu.Game/Beatmaps/BeatmapUpdaterMetadataLookup.cs b/osu.Game/Beatmaps/BeatmapUpdaterMetadataLookup.cs index 71d40b1a48..fac91c23f5 100644 --- a/osu.Game/Beatmaps/BeatmapUpdaterMetadataLookup.cs +++ b/osu.Game/Beatmaps/BeatmapUpdaterMetadataLookup.cs @@ -13,7 +13,6 @@ using osu.Framework.Development; using osu.Framework.IO.Network; using osu.Framework.Logging; using osu.Framework.Platform; -using osu.Framework.Testing; using osu.Game.Database; using osu.Game.Online.API; using osu.Game.Online.API.Requests; @@ -30,7 +29,6 @@ namespace osu.Game.Beatmaps /// On creating the component, a copy of a database containing metadata for a large subset of beatmaps (stored to ) will be downloaded if not already present locally. /// This will always be checked before doing a second online query to get required metadata. /// - [ExcludeFromDynamicCompile] public class BeatmapUpdaterMetadataLookup : IDisposable { private readonly IAPIProvider api; diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index ab790617bb..59a71fd80c 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -16,7 +16,6 @@ using osu.Framework.Audio.Track; using osu.Framework.Extensions; using osu.Framework.Graphics.Textures; using osu.Framework.Logging; -using osu.Framework.Testing; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; @@ -25,7 +24,6 @@ using osu.Game.Storyboards; namespace osu.Game.Beatmaps { - [ExcludeFromDynamicCompile] public abstract class WorkingBeatmap : IWorkingBeatmap { public readonly BeatmapInfo BeatmapInfo; diff --git a/osu.Game/Beatmaps/WorkingBeatmapCache.cs b/osu.Game/Beatmaps/WorkingBeatmapCache.cs index 76a31a6f78..ef843909d8 100644 --- a/osu.Game/Beatmaps/WorkingBeatmapCache.cs +++ b/osu.Game/Beatmaps/WorkingBeatmapCache.cs @@ -17,7 +17,6 @@ using osu.Framework.Lists; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Framework.Statistics; -using osu.Framework.Testing; using osu.Game.Beatmaps.Formats; using osu.Game.Database; using osu.Game.IO; @@ -121,7 +120,6 @@ namespace osu.Game.Beatmaps #endregion - [ExcludeFromDynamicCompile] private class BeatmapManagerWorkingBeatmap : WorkingBeatmap { [NotNull] diff --git a/osu.Game/Configuration/DevelopmentOsuConfigManager.cs b/osu.Game/Configuration/DevelopmentOsuConfigManager.cs index dda30c1d00..33329002a9 100644 --- a/osu.Game/Configuration/DevelopmentOsuConfigManager.cs +++ b/osu.Game/Configuration/DevelopmentOsuConfigManager.cs @@ -4,11 +4,9 @@ #nullable disable using osu.Framework.Platform; -using osu.Framework.Testing; namespace osu.Game.Configuration { - [ExcludeFromDynamicCompile] public class DevelopmentOsuConfigManager : OsuConfigManager { protected override string Filename => base.Filename.Replace(".ini", ".dev.ini"); diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 1e7d3cf84f..365ad37f4c 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -12,7 +12,6 @@ using osu.Framework.Extensions; using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Localisation; using osu.Framework.Platform; -using osu.Framework.Testing; using osu.Game.Beatmaps.Drawables.Cards; using osu.Game.Input; using osu.Game.Input.Bindings; @@ -26,7 +25,6 @@ using osu.Game.Skinning; namespace osu.Game.Configuration { - [ExcludeFromDynamicCompile] public class OsuConfigManager : IniConfigManager, IGameplaySettings { public OsuConfigManager(Storage storage) diff --git a/osu.Game/Database/RealmFileStore.cs b/osu.Game/Database/RealmFileStore.cs index f75d3be725..1da64d5be8 100644 --- a/osu.Game/Database/RealmFileStore.cs +++ b/osu.Game/Database/RealmFileStore.cs @@ -8,7 +8,6 @@ using osu.Framework.Extensions; using osu.Framework.IO.Stores; using osu.Framework.Logging; using osu.Framework.Platform; -using osu.Framework.Testing; using osu.Game.Extensions; using osu.Game.IO; using osu.Game.Models; @@ -19,7 +18,6 @@ namespace osu.Game.Database /// /// Handles the storing of files to the file system (and database) backing. /// - [ExcludeFromDynamicCompile] public class RealmFileStore { private readonly RealmAccess realm; diff --git a/osu.Game/Models/RealmFile.cs b/osu.Game/Models/RealmFile.cs index f96b717937..2faa3f0ca6 100644 --- a/osu.Game/Models/RealmFile.cs +++ b/osu.Game/Models/RealmFile.cs @@ -1,13 +1,11 @@ // 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.Testing; using osu.Game.IO; using Realms; namespace osu.Game.Models { - [ExcludeFromDynamicCompile] [MapTo("File")] public class RealmFile : RealmObject, IFileInfo { diff --git a/osu.Game/Models/RealmNamedFileUsage.cs b/osu.Game/Models/RealmNamedFileUsage.cs index c4310c4edb..c8e2c6f6d0 100644 --- a/osu.Game/Models/RealmNamedFileUsage.cs +++ b/osu.Game/Models/RealmNamedFileUsage.cs @@ -3,14 +3,12 @@ using System; using JetBrains.Annotations; -using osu.Framework.Testing; using osu.Game.Database; using osu.Game.IO; using Realms; namespace osu.Game.Models { - [ExcludeFromDynamicCompile] public class RealmNamedFileUsage : EmbeddedObject, INamedFile, INamedFileUsage { public RealmFile File { get; set; } = null!; diff --git a/osu.Game/Overlays/Settings/SettingsSubsection.cs b/osu.Game/Overlays/Settings/SettingsSubsection.cs index 784f20a6e8..eda18abaef 100644 --- a/osu.Game/Overlays/Settings/SettingsSubsection.cs +++ b/osu.Game/Overlays/Settings/SettingsSubsection.cs @@ -10,12 +10,10 @@ using osu.Game.Graphics.Sprites; using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Localisation; -using osu.Framework.Testing; using osu.Game.Graphics; namespace osu.Game.Overlays.Settings { - [ExcludeFromDynamicCompile] public abstract partial class SettingsSubsection : FillFlowContainer, IFilterable { protected override Container Content => FlowContent; diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 787da926ea..f9812d6c00 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -10,7 +10,6 @@ using osu.Framework.Bindables; using osu.Framework.Extensions.TypeExtensions; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; -using osu.Framework.Testing; using osu.Game.Configuration; using osu.Game.Extensions; using osu.Game.Rulesets.UI; @@ -21,7 +20,6 @@ namespace osu.Game.Rulesets.Mods /// /// The base class for gameplay modifiers. /// - [ExcludeFromDynamicCompile] public abstract class Mod : IMod, IEquatable, IDeepCloneable { [JsonIgnore] diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index fcf7a78090..a77068eb14 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -12,7 +12,6 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; using osu.Framework.IO.Stores; using osu.Framework.Localisation; -using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Legacy; using osu.Game.Configuration; @@ -34,7 +33,6 @@ using osu.Game.Users; namespace osu.Game.Rulesets { - [ExcludeFromDynamicCompile] public abstract class Ruleset { public RulesetInfo RulesetInfo { get; } diff --git a/osu.Game/Rulesets/RulesetInfo.cs b/osu.Game/Rulesets/RulesetInfo.cs index 6a4e0f0b48..56f073f74c 100644 --- a/osu.Game/Rulesets/RulesetInfo.cs +++ b/osu.Game/Rulesets/RulesetInfo.cs @@ -3,13 +3,11 @@ using System; using JetBrains.Annotations; -using osu.Framework.Testing; using osu.Game.Rulesets.Difficulty; using Realms; namespace osu.Game.Rulesets { - [ExcludeFromDynamicCompile] [MapTo("Ruleset")] public class RulesetInfo : RealmObject, IEquatable, IComparable, IRulesetInfo { diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index 02c7acf350..e084c45de0 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -7,7 +7,6 @@ using System.Linq; using JetBrains.Annotations; using Newtonsoft.Json; using osu.Framework.Localisation; -using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Database; using osu.Game.Models; @@ -25,7 +24,6 @@ namespace osu.Game.Scoring /// /// A realm model containing metadata for a single score. /// - [ExcludeFromDynamicCompile] [MapTo("Score")] public class ScoreInfo : RealmObject, IHasGuidPrimaryKey, IHasRealmFiles, ISoftDelete, IEquatable, IScoreInfo { diff --git a/osu.Game/Skinning/SkinInfo.cs b/osu.Game/Skinning/SkinInfo.cs index 9ad91f8725..c2b80b7ead 100644 --- a/osu.Game/Skinning/SkinInfo.cs +++ b/osu.Game/Skinning/SkinInfo.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using JetBrains.Annotations; using Newtonsoft.Json; -using osu.Framework.Testing; using osu.Game.Database; using osu.Game.IO; using osu.Game.Models; @@ -13,7 +12,6 @@ using Realms; namespace osu.Game.Skinning { - [ExcludeFromDynamicCompile] [MapTo("Skin")] [JsonObject(MemberSerialization.OptIn)] public class SkinInfo : RealmObject, IHasRealmFiles, IEquatable, IHasGuidPrimaryKey, ISoftDelete, IHasNamedFiles diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index 45536e04eb..51605c6045 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -18,7 +18,6 @@ using osu.Framework.Graphics.Rendering; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; using osu.Framework.Platform; -using osu.Framework.Testing; using osu.Framework.Threading; using osu.Framework.Utils; using osu.Game.Audio; @@ -36,7 +35,6 @@ namespace osu.Game.Skinning /// This is also exposed and cached as to allow for any component to potentially have skinning support. /// For gameplay components, see which adds extra legacy and toggle logic that may affect the lookup process. /// - [ExcludeFromDynamicCompile] public class SkinManager : ModelManager, ISkinSource, IStorageResourceProvider, IModelImporter { /// diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index 46c7c3a57c..0ec5a4c5c2 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -36,7 +36,6 @@ using osu.Game.Tests.Rulesets; namespace osu.Game.Tests.Visual { - [ExcludeFromDynamicCompile] public abstract partial class OsuTestScene : TestScene { [Cached] From 27c10cbdb7082e219400873ae72de33029e131bf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 8 May 2023 18:14:07 +0900 Subject: [PATCH 2897/2991] Remove clamping of `sizingContainer` in `DrawableHoldNote` to fix head note alignment --- .../Objects/Drawables/DrawableHoldNote.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 372ef1e164..09976827fe 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -3,7 +3,6 @@ #nullable disable -using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -246,8 +245,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (Head.IsHit && releaseTime == null && DrawHeight > 0) { // How far past the hit target this hold note is. Always a positive value. - float yOffset = Math.Max(0, Direction.Value == ScrollingDirection.Up ? -Y : Y); - sizingContainer.Height = Math.Clamp(1 - yOffset / DrawHeight, 0, 1); + float yOffset = Direction.Value == ScrollingDirection.Up ? -Y : Y; + sizingContainer.Height = 1 - yOffset / DrawHeight; } } From 64498e95a46915843625de96156c9e6ec6e0c0aa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 8 May 2023 18:56:29 +0900 Subject: [PATCH 2898/2991] Add an `IAnimationTimeReference` to `DrawableHitObject` to synchronise all animations --- .../Rulesets/Objects/Drawables/DrawableHitObject.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 79fc778287..07c0d1f8a1 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -30,7 +30,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Objects.Drawables { [Cached(typeof(DrawableHitObject))] - public abstract partial class DrawableHitObject : PoolableDrawableWithLifetime + public abstract partial class DrawableHitObject : PoolableDrawableWithLifetime, IAnimationTimeReference { /// /// Invoked after this 's applied has had its defaults applied. @@ -425,11 +425,13 @@ namespace osu.Game.Rulesets.Objects.Drawables LifetimeEnd = double.MaxValue; - double transformTime = HitObject.StartTime - InitialLifetimeOffset; - clearExistingStateTransforms(); - using (BeginAbsoluteSequence(transformTime)) + double initialTransformsTime = HitObject.StartTime - InitialLifetimeOffset; + + AnimationStartTime.Value = initialTransformsTime; + + using (BeginAbsoluteSequence(initialTransformsTime)) UpdateInitialTransforms(); using (BeginAbsoluteSequence(StateUpdateTime)) @@ -721,6 +723,8 @@ namespace osu.Game.Rulesets.Objects.Drawables if (CurrentSkin != null) CurrentSkin.SourceChanged -= skinSourceChanged; } + + public Bindable AnimationStartTime { get; } = new BindableDouble(); } public abstract partial class DrawableHitObject : DrawableHitObject From 1ff17309484e02aceb14efa3ba2fea8ebce67b88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 8 May 2023 22:35:41 +0200 Subject: [PATCH 2899/2991] Remove no-longer-correct remark --- osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 9ffd338d7c..ce34addeff 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -247,7 +247,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables // 2. The head note will move along with the new "head position" in the container. if (Head.IsHit && releaseTime == null && DrawHeight > 0) { - // How far past the hit target this hold note is. Always a positive value. + // How far past the hit target this hold note is. float yOffset = Direction.Value == ScrollingDirection.Up ? -Y : Y; sizingContainer.Height = 1 - yOffset / DrawHeight; } From 0a47ffcbdd4bacdba6a0ab1739e7eaaeaedef35f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 9 May 2023 07:03:13 +0200 Subject: [PATCH 2900/2991] Match generally used casing Co-authored-by: Joseph Madamba --- osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs b/osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs index 98635c10a3..d5a9a311bc 100644 --- a/osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs +++ b/osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Setup specialStyle = new LabelledSwitchButton { Label = "Use special (N+1) style", - Description = "Changes one column to act as a classic \"scratch\" or \"special\" column, which can be moved around by the user's skin (to the left/right/centre). Generally used in 6k (5+1) or 8k (7+1) configurations.", + Description = "Changes one column to act as a classic \"scratch\" or \"special\" column, which can be moved around by the user's skin (to the left/right/centre). Generally used in 6K (5+1) or 8K (7+1) configurations.", Current = { Value = Beatmap.BeatmapInfo.SpecialStyle } } }; From 944da06c108b9240190c297b5825365e10ccf49b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 9 May 2023 16:58:19 +0900 Subject: [PATCH 2901/2991] Rename slider multiplier variable back for now --- .../Editor/TestSceneJuiceStreamPlacementBlueprint.cs | 2 +- .../Editor/TestSceneJuiceStreamSelectionBlueprint.cs | 2 +- .../TestSceneAutoJuiceStream.cs | 2 +- .../TestSceneJuiceStream.cs | 2 +- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 4 ++-- .../Legacy/DistanceObjectPatternGenerator.cs | 2 +- osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs | 2 +- .../Editor/TestSceneOsuDistanceSnapGrid.cs | 2 +- .../Editor/TestSceneSliderStreamConversion.cs | 2 +- osu.Game.Rulesets.Osu/Objects/Slider.cs | 2 +- .../Editor/TestSceneTaikoEditorSaving.cs | 4 ++-- .../Beatmaps/TaikoBeatmapConverter.cs | 6 +++--- .../Mods/TaikoModDifficultyAdjust.cs | 2 +- osu.Game.Rulesets.Taiko/Mods/TaikoModEasy.cs | 2 +- osu.Game.Rulesets.Taiko/Mods/TaikoModHardRock.cs | 2 +- osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 2 +- .../Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 2 +- .../Beatmaps/Formats/OsuJsonDecoderTest.cs | 2 +- .../TestSceneHitObjectComposerDistanceSnapping.cs | 12 ++++++------ .../Visual/Editing/TestSceneDistanceSnapGrid.cs | 2 +- .../Gameplay/TestSceneDrawableScrollingRuleset.cs | 4 ++-- .../Gameplay/TestSceneGameplaySampleTriggerSource.cs | 2 +- osu.Game/Beatmaps/BeatmapDifficulty.cs | 8 ++++---- osu.Game/Beatmaps/BeatmapImporter.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 4 ++-- osu.Game/Beatmaps/IBeatmapDifficultyInfo.cs | 4 ++-- osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs | 2 +- osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs | 2 +- .../UI/Scrolling/DrawableScrollingRuleset.cs | 6 +++--- .../Edit/Compose/Components/HitObjectInspector.cs | 2 +- .../Components/Timeline/DifficultyPointPiece.cs | 2 +- osu.Game/Screens/Edit/Setup/DifficultySection.cs | 4 ++-- 33 files changed, 51 insertions(+), 51 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamPlacementBlueprint.cs b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamPlacementBlueprint.cs index e729a09a18..2426f8c886 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamPlacementBlueprint.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor { var playable = base.GetPlayableBeatmap(); playable.Difficulty.SliderTickRate = 5; - playable.Difficulty.BaseSliderVelocity = velocity_factor * 10; + playable.Difficulty.SliderMultiplier = velocity_factor * 10; return playable; } diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs index 634e1f5cbb..beba5811fe 100644 --- a/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch.Tests/Editor/TestSceneJuiceStreamSelectionBlueprint.cs @@ -210,7 +210,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor X = x, Path = sliderPath, }; - EditorBeatmap.Difficulty.BaseSliderVelocity = velocity; + EditorBeatmap.Difficulty.SliderMultiplier = velocity; EditorBeatmap.Add(hitObject); EditorBeatmap.Update(hitObject); Assert.That(hitObject.Velocity, Is.EqualTo(velocity)); diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs index d1f3f06971..40dc7d2403 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Catch.Tests { BeatmapInfo = new BeatmapInfo { - Difficulty = new BeatmapDifficulty { CircleSize = 6, BaseSliderVelocity = 3 }, + Difficulty = new BeatmapDifficulty { CircleSize = 6, SliderMultiplier = 3 }, Ruleset = ruleset } }; diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs index 71cb8964c3..c91f07891c 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneJuiceStream.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Catch.Tests { BeatmapInfo = new BeatmapInfo { - Difficulty = new BeatmapDifficulty { CircleSize = 5, BaseSliderVelocity = 2 }, + Difficulty = new BeatmapDifficulty { CircleSize = 5, SliderMultiplier = 2 }, Ruleset = ruleset }, HitObjects = new List diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 301ecd6d66..169e99c90c 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -64,8 +64,8 @@ namespace osu.Game.Rulesets.Catch.Objects TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); - velocityFactor = base_scoring_distance * difficulty.BaseSliderVelocity / timingPoint.BeatLength; - tickDistanceFactor = base_scoring_distance * difficulty.BaseSliderVelocity / difficulty.SliderTickRate; + velocityFactor = base_scoring_distance * difficulty.SliderMultiplier / timingPoint.BeatLength; + tickDistanceFactor = base_scoring_distance * difficulty.SliderMultiplier / difficulty.SliderTickRate; } protected override void CreateNestedHitObjects(CancellationToken cancellationToken) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index ab6f5e8269..91b7be6e8f 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy StartTime = (int)Math.Round(hitObject.StartTime); // This matches stable's calculation. - EndTime = (int)Math.Floor(StartTime + distanceData.Distance * beatLength * SpanCount * 0.01 / beatmap.Difficulty.BaseSliderVelocity); + EndTime = (int)Math.Floor(StartTime + distanceData.Distance * beatLength * SpanCount * 0.01 / beatmap.Difficulty.SliderMultiplier); SegmentDuration = (EndTime - StartTime) / SpanCount; } diff --git a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs index cb38551a43..af8758fb5e 100644 --- a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs @@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Mania.UI { // Mania doesn't care about global velocity p.Velocity = 1; - p.BaseBeatLength *= Beatmap.Difficulty.BaseSliderVelocity; + p.BaseBeatLength *= Beatmap.Difficulty.SliderMultiplier; // For non-mania beatmap, speed changes should only happen through timing points if (!isForCurrentRuleset) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs index b79d4efe1b..7579e8077b 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuDistanceSnapGrid.cs @@ -80,7 +80,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor [SetUp] public void Setup() => Schedule(() => { - editorBeatmap.Difficulty.BaseSliderVelocity = 1; + editorBeatmap.Difficulty.SliderMultiplier = 1; editorBeatmap.ControlPointInfo.Clear(); editorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = beat_length }); snapProvider.DistanceSpacingMultiplier.Value = 1; diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderStreamConversion.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderStreamConversion.cs index 938e093489..a162d9a491 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderStreamConversion.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderStreamConversion.cs @@ -162,7 +162,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddStep("change to these specific circumstances", () => { - EditorBeatmap.Difficulty.BaseSliderVelocity = 1; + EditorBeatmap.Difficulty.SliderMultiplier = 1; var timingPoint = EditorBeatmap.ControlPointInfo.TimingPointAt(slider.StartTime); timingPoint.BeatLength = 352.941176470588; slider.Path.ControlPoints[^1].Position = new Vector2(-110, 16); diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index b86351e7cd..4189f8ba1e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.Osu.Objects TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); - double scoringDistance = BASE_SCORING_DISTANCE * difficulty.BaseSliderVelocity * SliderVelocity; + double scoringDistance = BASE_SCORING_DISTANCE * difficulty.SliderMultiplier * SliderVelocity; Velocity = scoringDistance / timingPoint.BeatLength; TickDistance = GenerateTicks ? (scoringDistance / difficulty.SliderTickRate * TickDistanceMultiplier) : double.PositiveInfinity; diff --git a/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneTaikoEditorSaving.cs b/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneTaikoEditorSaving.cs index d79ca28c8f..93b26624de 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneTaikoEditorSaving.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Editor/TestSceneTaikoEditorSaving.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Editor [Test] public void TestTaikoSliderMultiplier() { - AddStep("Set slider multiplier", () => EditorBeatmap.Difficulty.BaseSliderVelocity = 2); + AddStep("Set slider multiplier", () => EditorBeatmap.Difficulty.SliderMultiplier = 2); SaveEditor(); @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Editor // therefore, ensure that we have that difficulty type by calling .CopyFrom(), which is a no-op if the type is already correct. var taikoDifficulty = new TaikoBeatmapConverter.TaikoMultiplierAppliedDifficulty(); taikoDifficulty.CopyFrom(EditorBeatmap.Difficulty); - return Precision.AlmostEquals(taikoDifficulty.BaseSliderVelocity, 2); + return Precision.AlmostEquals(taikoDifficulty.SliderMultiplier, 2); } } } diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 932211695a..e298e313df 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -189,7 +189,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps else beatLength = timingPoint.BeatLength; - double sliderScoringPointDistance = osu_base_scoring_distance * beatmap.Difficulty.BaseSliderVelocity / beatmap.Difficulty.SliderTickRate; + double sliderScoringPointDistance = osu_base_scoring_distance * beatmap.Difficulty.SliderMultiplier / beatmap.Difficulty.SliderTickRate; // The velocity and duration of the taiko hit object - calculated as the velocity of a drum roll. double taikoVelocity = sliderScoringPointDistance * beatmap.Difficulty.SliderTickRate; @@ -239,14 +239,14 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps { base.CopyTo(other); if (!(other is TaikoMultiplierAppliedDifficulty)) - other.BaseSliderVelocity /= LegacyBeatmapEncoder.LEGACY_TAIKO_VELOCITY_MULTIPLIER; + other.SliderMultiplier /= LegacyBeatmapEncoder.LEGACY_TAIKO_VELOCITY_MULTIPLIER; } public override void CopyFrom(IBeatmapDifficultyInfo other) { base.CopyFrom(other); if (!(other is TaikoMultiplierAppliedDifficulty)) - BaseSliderVelocity *= LegacyBeatmapEncoder.LEGACY_TAIKO_VELOCITY_MULTIPLIER; + SliderMultiplier *= LegacyBeatmapEncoder.LEGACY_TAIKO_VELOCITY_MULTIPLIER; } #endregion diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModDifficultyAdjust.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModDifficultyAdjust.cs index fe9c1f5815..99a064d35f 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModDifficultyAdjust.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Taiko.Mods { base.ApplySettings(difficulty); - if (ScrollSpeed.Value != null) difficulty.BaseSliderVelocity *= ScrollSpeed.Value.Value; + if (ScrollSpeed.Value != null) difficulty.SliderMultiplier *= ScrollSpeed.Value.Value; } } } diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModEasy.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModEasy.cs index 5aeb5a87d7..009f2854f8 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModEasy.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModEasy.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Taiko.Mods public override void ApplyToDifficulty(BeatmapDifficulty difficulty) { base.ApplyToDifficulty(difficulty); - difficulty.BaseSliderVelocity *= slider_multiplier; + difficulty.SliderMultiplier *= slider_multiplier; } } } diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModHardRock.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModHardRock.cs index 0f68750535..ba41175461 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModHardRock.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModHardRock.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Taiko.Mods public override void ApplyToDifficulty(BeatmapDifficulty difficulty) { base.ApplyToDifficulty(difficulty); - difficulty.BaseSliderVelocity *= slider_multiplier; + difficulty.SliderMultiplier *= slider_multiplier; } } } diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs index 014fec9319..b4a12fd314 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Taiko.Objects TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); - double scoringDistance = base_distance * difficulty.BaseSliderVelocity * SliderVelocity; + double scoringDistance = base_distance * difficulty.SliderMultiplier * SliderVelocity; Velocity = scoringDistance / timingPoint.BeatLength; tickSpacing = timingPoint.BeatLength / TickRate; diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 98ad6fc18d..2c4f193327 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -136,7 +136,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(4, difficulty.CircleSize); Assert.AreEqual(8, difficulty.OverallDifficulty); Assert.AreEqual(9, difficulty.ApproachRate); - Assert.AreEqual(1.8, difficulty.BaseSliderVelocity); + Assert.AreEqual(1.8, difficulty.SliderMultiplier); Assert.AreEqual(2, difficulty.SliderTickRate); } } diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 11c5f2a2fc..3764467047 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -91,7 +91,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(4, difficulty.CircleSize); Assert.AreEqual(8, difficulty.OverallDifficulty); Assert.AreEqual(9, difficulty.ApproachRate); - Assert.AreEqual(1.8, difficulty.BaseSliderVelocity); + Assert.AreEqual(1.8, difficulty.SliderMultiplier); Assert.AreEqual(2, difficulty.SliderTickRate); } diff --git a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs index ffbe16260b..6399507aa0 100644 --- a/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editing/TestSceneHitObjectComposerDistanceSnapping.cs @@ -57,7 +57,7 @@ namespace osu.Game.Tests.Editing BeatDivisor.Value = 1; - composer.EditorBeatmap.Difficulty.BaseSliderVelocity = 1; + composer.EditorBeatmap.Difficulty.SliderMultiplier = 1; composer.EditorBeatmap.ControlPointInfo.Clear(); composer.EditorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 }); }); @@ -66,7 +66,7 @@ namespace osu.Game.Tests.Editing [TestCase(2)] public void TestSliderMultiplier(float multiplier) { - AddStep($"set slider multiplier = {multiplier}", () => composer.EditorBeatmap.Difficulty.BaseSliderVelocity = multiplier); + AddStep($"set slider multiplier = {multiplier}", () => composer.EditorBeatmap.Difficulty.SliderMultiplier = multiplier); assertSnapDistance(100 * multiplier, null, true); } @@ -128,7 +128,7 @@ namespace osu.Game.Tests.Editing assertDurationToDistance(500, 50); assertDurationToDistance(1000, 100); - AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.Difficulty.BaseSliderVelocity = 2); + AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.Difficulty.SliderMultiplier = 2); assertDurationToDistance(500, 100); assertDurationToDistance(1000, 200); @@ -149,7 +149,7 @@ namespace osu.Game.Tests.Editing assertDistanceToDuration(50, 500); assertDistanceToDuration(100, 1000); - AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.Difficulty.BaseSliderVelocity = 2); + AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.Difficulty.SliderMultiplier = 2); assertDistanceToDuration(100, 500); assertDistanceToDuration(200, 1000); @@ -174,7 +174,7 @@ namespace osu.Game.Tests.Editing assertSnappedDuration(200, 2000); assertSnappedDuration(250, 3000); - AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.Difficulty.BaseSliderVelocity = 2); + AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.Difficulty.SliderMultiplier = 2); assertSnappedDuration(0, 0); assertSnappedDuration(50, 0); @@ -206,7 +206,7 @@ namespace osu.Game.Tests.Editing assertSnappedDistance(200, 200); assertSnappedDistance(250, 200); - AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.Difficulty.BaseSliderVelocity = 2); + AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.Difficulty.SliderMultiplier = 2); assertSnappedDistance(50, 0); assertSnappedDistance(100, 0); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs index a99bd72e40..21b925a257 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDistanceSnapGrid.cs @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Editing } }); editorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = beat_length }); - editorBeatmap.Difficulty.BaseSliderVelocity = 1; + editorBeatmap.Difficulty.SliderMultiplier = 1; } [SetUp] diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs index 735af9493c..287b7d43b4 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneDrawableScrollingRuleset.cs @@ -184,7 +184,7 @@ namespace osu.Game.Tests.Visual.Gameplay { var beatmap = createBeatmap(); beatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = time_range }); - beatmap.Difficulty.BaseSliderVelocity = 2; + beatmap.Difficulty.SliderMultiplier = 2; createTest(beatmap, d => d.RelativeScaleBeatLengthsOverride = true); AddStep("adjust time range", () => drawableRuleset.TimeRange.Value = 5000); @@ -198,7 +198,7 @@ namespace osu.Game.Tests.Visual.Gameplay { var beatmap = createBeatmap(); beatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = time_range }); - beatmap.Difficulty.BaseSliderVelocity = 2; + beatmap.Difficulty.SliderMultiplier = 2; createTest(beatmap); AddStep("adjust time range", () => drawableRuleset.TimeRange.Value = 2000); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs index 28cc890fce..114c554d28 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplaySampleTriggerSource.cs @@ -46,7 +46,7 @@ namespace osu.Game.Tests.Visual.Gameplay { BeatmapInfo = new BeatmapInfo { - Difficulty = new BeatmapDifficulty { CircleSize = 6, BaseSliderVelocity = 3 }, + Difficulty = new BeatmapDifficulty { CircleSize = 6, SliderMultiplier = 3 }, Ruleset = ruleset }, ControlPointInfo = controlPointInfo diff --git a/osu.Game/Beatmaps/BeatmapDifficulty.cs b/osu.Game/Beatmaps/BeatmapDifficulty.cs index cbea30f3b0..f4bc5e7b77 100644 --- a/osu.Game/Beatmaps/BeatmapDifficulty.cs +++ b/osu.Game/Beatmaps/BeatmapDifficulty.cs @@ -11,7 +11,7 @@ namespace osu.Game.Beatmaps public class BeatmapDifficulty : EmbeddedObject, IBeatmapDifficultyInfo { /// - /// The default value used for all difficulty settings except and . + /// The default value used for all difficulty settings except and . /// public const float DEFAULT_DIFFICULTY = 5; @@ -20,7 +20,7 @@ namespace osu.Game.Beatmaps public float OverallDifficulty { get; set; } = IBeatmapDifficultyInfo.DEFAULT_DIFFICULTY; public float ApproachRate { get; set; } = IBeatmapDifficultyInfo.DEFAULT_DIFFICULTY; - public double BaseSliderVelocity { get; set; } = 1; + public double SliderMultiplier { get; set; } = 1; public double SliderTickRate { get; set; } = 1; public BeatmapDifficulty() @@ -44,7 +44,7 @@ namespace osu.Game.Beatmaps difficulty.CircleSize = CircleSize; difficulty.OverallDifficulty = OverallDifficulty; - difficulty.BaseSliderVelocity = BaseSliderVelocity; + difficulty.SliderMultiplier = SliderMultiplier; difficulty.SliderTickRate = SliderTickRate; } @@ -55,7 +55,7 @@ namespace osu.Game.Beatmaps CircleSize = other.CircleSize; OverallDifficulty = other.OverallDifficulty; - BaseSliderVelocity = other.BaseSliderVelocity; + SliderMultiplier = other.SliderMultiplier; SliderTickRate = other.SliderTickRate; } } diff --git a/osu.Game/Beatmaps/BeatmapImporter.cs b/osu.Game/Beatmaps/BeatmapImporter.cs index e96e38d249..4731a70753 100644 --- a/osu.Game/Beatmaps/BeatmapImporter.cs +++ b/osu.Game/Beatmaps/BeatmapImporter.cs @@ -353,7 +353,7 @@ namespace osu.Game.Beatmaps CircleSize = decodedDifficulty.CircleSize, OverallDifficulty = decodedDifficulty.OverallDifficulty, ApproachRate = decodedDifficulty.ApproachRate, - BaseSliderVelocity = decodedDifficulty.BaseSliderVelocity, + SliderMultiplier = decodedDifficulty.SliderMultiplier, SliderTickRate = decodedDifficulty.SliderTickRate, }; diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 891e627435..5e98025c9a 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -384,7 +384,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"SliderMultiplier": - difficulty.BaseSliderVelocity = Parsing.ParseDouble(pair.Value); + difficulty.SliderMultiplier = Parsing.ParseDouble(pair.Value); break; case @"SliderTickRate": diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index fffead3a6c..7fbcca9adb 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -155,8 +155,8 @@ namespace osu.Game.Beatmaps.Formats // Taiko adjusts the slider multiplier (see: LEGACY_TAIKO_VELOCITY_MULTIPLIER) writer.WriteLine(onlineRulesetID == 1 - ? FormattableString.Invariant($"SliderMultiplier: {beatmap.Difficulty.BaseSliderVelocity / LEGACY_TAIKO_VELOCITY_MULTIPLIER}") - : FormattableString.Invariant($"SliderMultiplier: {beatmap.Difficulty.BaseSliderVelocity}")); + ? FormattableString.Invariant($"SliderMultiplier: {beatmap.Difficulty.SliderMultiplier / LEGACY_TAIKO_VELOCITY_MULTIPLIER}") + : FormattableString.Invariant($"SliderMultiplier: {beatmap.Difficulty.SliderMultiplier}")); writer.WriteLine(FormattableString.Invariant($"SliderTickRate: {beatmap.Difficulty.SliderTickRate}")); } diff --git a/osu.Game/Beatmaps/IBeatmapDifficultyInfo.cs b/osu.Game/Beatmaps/IBeatmapDifficultyInfo.cs index bc2ee23da7..78234a9dd9 100644 --- a/osu.Game/Beatmaps/IBeatmapDifficultyInfo.cs +++ b/osu.Game/Beatmaps/IBeatmapDifficultyInfo.cs @@ -9,7 +9,7 @@ namespace osu.Game.Beatmaps public interface IBeatmapDifficultyInfo { /// - /// The default value used for all difficulty settings except and . + /// The default value used for all difficulty settings except and . /// const float DEFAULT_DIFFICULTY = 5; @@ -37,7 +37,7 @@ namespace osu.Game.Beatmaps /// The base slider velocity of the associated beatmap. /// This was known as "SliderMultiplier" in the .osu format and stable editor. /// - double BaseSliderVelocity { get; } + double SliderMultiplier { get; } /// /// The slider tick rate of the associated beatmap. diff --git a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs index 4adbb356da..a8972775de 100644 --- a/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/DistancedHitObjectComposer.cs @@ -240,7 +240,7 @@ namespace osu.Game.Rulesets.Edit public virtual float GetBeatSnapDistanceAt(HitObject referenceObject, bool useReferenceSliderVelocity = true) { - return (float)(100 * (useReferenceSliderVelocity && referenceObject is IHasSliderVelocity hasSliderVelocity ? hasSliderVelocity.SliderVelocity : 1) * EditorBeatmap.Difficulty.BaseSliderVelocity * 1 + return (float)(100 * (useReferenceSliderVelocity && referenceObject is IHasSliderVelocity hasSliderVelocity ? hasSliderVelocity.SliderVelocity : 1) * EditorBeatmap.Difficulty.SliderMultiplier * 1 / BeatSnapProvider.BeatDivisor); } diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index bdcf539033..7ddd372dc9 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Objects.Legacy TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(StartTime); - double scoringDistance = base_scoring_distance * difficulty.BaseSliderVelocity * SliderVelocity; + double scoringDistance = base_scoring_distance * difficulty.SliderMultiplier * SliderVelocity; Velocity = scoringDistance / timingPoint.BeatLength; } diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs index da1110506a..4c7564b791 100644 --- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs +++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs @@ -123,7 +123,7 @@ namespace osu.Game.Rulesets.UI.Scrolling // The slider multiplier is post-multiplied to determine the final velocity, but for relative scale beat lengths // the multiplier should not affect the effective timing point (the longest in the beatmap), so it is factored out here - baseBeatLength /= Beatmap.Difficulty.BaseSliderVelocity; + baseBeatLength /= Beatmap.Difficulty.SliderMultiplier; } // Merge sequences of timing and difficulty control points to create the aggregate "multiplier" control point @@ -150,7 +150,7 @@ namespace osu.Game.Rulesets.UI.Scrolling return new MultiplierControlPoint(c.Time) { - Velocity = Beatmap.Difficulty.BaseSliderVelocity, + Velocity = Beatmap.Difficulty.SliderMultiplier, BaseBeatLength = baseBeatLength, TimingPoint = lastTimingPoint, EffectPoint = lastEffectPoint @@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.UI.Scrolling ControlPoints.AddRange(timingChanges); if (ControlPoints.Count == 0) - ControlPoints.Add(new MultiplierControlPoint { Velocity = Beatmap.Difficulty.BaseSliderVelocity }); + ControlPoints.Add(new MultiplierControlPoint { Velocity = Beatmap.Difficulty.SliderMultiplier }); } protected override void LoadComplete() diff --git a/osu.Game/Screens/Edit/Compose/Components/HitObjectInspector.cs b/osu.Game/Screens/Edit/Compose/Components/HitObjectInspector.cs index 60b9010aa8..7beaf7d086 100644 --- a/osu.Game/Screens/Edit/Compose/Components/HitObjectInspector.cs +++ b/osu.Game/Screens/Edit/Compose/Components/HitObjectInspector.cs @@ -73,7 +73,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (selected is IHasSliderVelocity sliderVelocity) { AddHeader("Slider Velocity"); - AddValue($"{sliderVelocity.SliderVelocity:#,0.00}x ({sliderVelocity.SliderVelocity * EditorBeatmap.Difficulty.BaseSliderVelocity:#,0.00}x)"); + AddValue($"{sliderVelocity.SliderVelocity:#,0.00}x ({sliderVelocity.SliderVelocity * EditorBeatmap.Difficulty.SliderMultiplier:#,0.00}x)"); } if (selected is IHasRepeats repeats) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs index ac37101060..76ad3e5b6a 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs @@ -165,7 +165,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private void updateInspectorText() { - double beatmapVelocity = EditorBeatmap.Difficulty.BaseSliderVelocity; + double beatmapVelocity = EditorBeatmap.Difficulty.SliderMultiplier; InspectorText.Clear(); diff --git a/osu.Game/Screens/Edit/Setup/DifficultySection.cs b/osu.Game/Screens/Edit/Setup/DifficultySection.cs index 6c7e96f91d..3a3fe7f747 100644 --- a/osu.Game/Screens/Edit/Setup/DifficultySection.cs +++ b/osu.Game/Screens/Edit/Setup/DifficultySection.cs @@ -85,7 +85,7 @@ namespace osu.Game.Screens.Edit.Setup Label = EditorSetupStrings.BaseVelocity, FixedLabelWidth = LABEL_WIDTH, Description = EditorSetupStrings.BaseVelocityDescription, - Current = new BindableDouble(Beatmap.Difficulty.BaseSliderVelocity) + Current = new BindableDouble(Beatmap.Difficulty.SliderMultiplier) { Default = 1, MinValue = 0.4, @@ -110,7 +110,7 @@ namespace osu.Game.Screens.Edit.Setup Beatmap.Difficulty.DrainRate = healthDrainSlider.Current.Value; Beatmap.Difficulty.ApproachRate = approachRateSlider.Current.Value; Beatmap.Difficulty.OverallDifficulty = overallDifficultySlider.Current.Value; - Beatmap.Difficulty.BaseSliderVelocity = baseVelocitySlider.Current.Value; + Beatmap.Difficulty.SliderMultiplier = baseVelocitySlider.Current.Value; Beatmap.UpdateAllHitObjects(); Beatmap.SaveState(); From 2085833a842c023ddb26e85e6fd54a2375867119 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 9 May 2023 17:08:03 +0900 Subject: [PATCH 2902/2991] Fix missing delegate unsubscribe --- .../Edit/Compose/Components/Timeline/DifficultyPointPiece.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs index 76ad3e5b6a..173a665d5c 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/DifficultyPointPiece.cs @@ -195,6 +195,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline EditorBeatmap.TransactionBegan -= updateInspectorText; EditorBeatmap.TransactionEnded -= updateInspectorText; + EditorBeatmap.BeatmapReprocessed -= updateInspectorText; } } } From ca5e8b290f30006c93116e7d1ef47fbdb663fc00 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 8 May 2023 14:05:59 +0900 Subject: [PATCH 2903/2991] Add clamping to `SliderMultiplier` and `SliderTickRate` at parsing time --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 5e98025c9a..49594ca969 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -384,11 +384,11 @@ namespace osu.Game.Beatmaps.Formats break; case @"SliderMultiplier": - difficulty.SliderMultiplier = Parsing.ParseDouble(pair.Value); + difficulty.SliderMultiplier = Math.Clamp(Parsing.ParseDouble(pair.Value), 0.4, 3.6); break; case @"SliderTickRate": - difficulty.SliderTickRate = Parsing.ParseDouble(pair.Value); + difficulty.SliderTickRate = Math.Clamp(Parsing.ParseDouble(pair.Value), 0.5, 8); break; } } From bdf8a78b4245dc008e8661820ea3cbcff42b97e8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 8 May 2023 14:14:54 +0900 Subject: [PATCH 2904/2991] Add the ability to adjust the beatmap tick rate in the editor --- osu.Game/Localisation/EditorSetupStrings.cs | 31 ++++++++++--------- .../Screens/Edit/Setup/DifficultySection.cs | 15 +++++++++ 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/osu.Game/Localisation/EditorSetupStrings.cs b/osu.Game/Localisation/EditorSetupStrings.cs index caea3dd130..401411365b 100644 --- a/osu.Game/Localisation/EditorSetupStrings.cs +++ b/osu.Game/Localisation/EditorSetupStrings.cs @@ -42,8 +42,7 @@ namespace osu.Game.Localisation /// /// "If enabled, an "Are you ready? 3, 2, 1, GO!" countdown will be inserted at the beginning of the beatmap, assuming there is enough time to do so." /// - public static LocalisableString CountdownDescription => new TranslatableString(getKey(@"countdown_description"), - @"If enabled, an ""Are you ready? 3, 2, 1, GO!"" countdown will be inserted at the beginning of the beatmap, assuming there is enough time to do so."); + public static LocalisableString CountdownDescription => new TranslatableString(getKey(@"countdown_description"), @"If enabled, an ""Are you ready? 3, 2, 1, GO!"" countdown will be inserted at the beginning of the beatmap, assuming there is enough time to do so."); /// /// "Countdown speed" @@ -53,8 +52,7 @@ namespace osu.Game.Localisation /// /// "If the countdown sounds off-time, use this to make it appear one or more beats early." /// - public static LocalisableString CountdownOffsetDescription => - new TranslatableString(getKey(@"countdown_offset_description"), @"If the countdown sounds off-time, use this to make it appear one or more beats early."); + public static LocalisableString CountdownOffsetDescription => new TranslatableString(getKey(@"countdown_offset_description"), @"If the countdown sounds off-time, use this to make it appear one or more beats early."); /// /// "Countdown offset" @@ -69,8 +67,7 @@ namespace osu.Game.Localisation /// /// "Allows storyboards to use the full screen space, rather than be confined to a 4:3 area." /// - public static LocalisableString WidescreenSupportDescription => - new TranslatableString(getKey(@"widescreen_support_description"), @"Allows storyboards to use the full screen space, rather than be confined to a 4:3 area."); + public static LocalisableString WidescreenSupportDescription => new TranslatableString(getKey(@"widescreen_support_description"), @"Allows storyboards to use the full screen space, rather than be confined to a 4:3 area."); /// /// "Epilepsy warning" @@ -80,8 +77,7 @@ namespace osu.Game.Localisation /// /// "Recommended if the storyboard or video contain scenes with rapidly flashing colours." /// - public static LocalisableString EpilepsyWarningDescription => - new TranslatableString(getKey(@"epilepsy_warning_description"), @"Recommended if the storyboard or video contain scenes with rapidly flashing colours."); + public static LocalisableString EpilepsyWarningDescription => new TranslatableString(getKey(@"epilepsy_warning_description"), @"Recommended if the storyboard or video contain scenes with rapidly flashing colours."); /// /// "Letterbox during breaks" @@ -91,8 +87,7 @@ namespace osu.Game.Localisation /// /// "Adds horizontal letterboxing to give a cinematic look during breaks." /// - public static LocalisableString LetterboxDuringBreaksDescription => - new TranslatableString(getKey(@"letterbox_during_breaks_description"), @"Adds horizontal letterboxing to give a cinematic look during breaks."); + public static LocalisableString LetterboxDuringBreaksDescription => new TranslatableString(getKey(@"letterbox_during_breaks_description"), @"Adds horizontal letterboxing to give a cinematic look during breaks."); /// /// "Samples match playback rate" @@ -102,8 +97,7 @@ namespace osu.Game.Localisation /// /// "When enabled, all samples will speed up or slow down when rate-changing mods are enabled." /// - public static LocalisableString SamplesMatchPlaybackRateDescription => new TranslatableString(getKey(@"samples_match_playback_rate_description"), - @"When enabled, all samples will speed up or slow down when rate-changing mods are enabled."); + public static LocalisableString SamplesMatchPlaybackRateDescription => new TranslatableString(getKey(@"samples_match_playback_rate_description"), @"When enabled, all samples will speed up or slow down when rate-changing mods are enabled."); /// /// "The size of all hit objects" @@ -123,8 +117,17 @@ namespace osu.Game.Localisation /// /// "The harshness of hit windows and difficulty of special objects (ie. spinners)" /// - public static LocalisableString OverallDifficultyDescription => - new TranslatableString(getKey(@"overall_difficulty_description"), @"The harshness of hit windows and difficulty of special objects (ie. spinners)"); + public static LocalisableString OverallDifficultyDescription => new TranslatableString(getKey(@"overall_difficulty_description"), @"The harshness of hit windows and difficulty of special objects (ie. spinners)"); + + /// + /// "Tick Rate" + /// + public static LocalisableString TickRate => new TranslatableString(getKey(@"tick_rate"), @"Tick Rate"); + + /// + /// "Determines how many "ticks" are generated within long hit objects. A tick rate of 1 will generate ticks on each beat, 2 would be twice per beat, etc." + /// + public static LocalisableString TickRateDescription => new TranslatableString(getKey(@"tick_rate_description"), @"Determines how many ""ticks"" are generated within long hit objects. A tick rate of 1 will generate ticks on each beat, 2 would be twice per beat, etc."); /// /// "Base Velocity" diff --git a/osu.Game/Screens/Edit/Setup/DifficultySection.cs b/osu.Game/Screens/Edit/Setup/DifficultySection.cs index 3a3fe7f747..4c062b0cb7 100644 --- a/osu.Game/Screens/Edit/Setup/DifficultySection.cs +++ b/osu.Game/Screens/Edit/Setup/DifficultySection.cs @@ -20,6 +20,7 @@ namespace osu.Game.Screens.Edit.Setup private LabelledSliderBar approachRateSlider = null!; private LabelledSliderBar overallDifficultySlider = null!; private LabelledSliderBar baseVelocitySlider = null!; + private LabelledSliderBar tickRateSlider = null!; public override LocalisableString Title => EditorSetupStrings.DifficultyHeader; @@ -93,6 +94,19 @@ namespace osu.Game.Screens.Edit.Setup Precision = 0.01f, } }, + tickRateSlider = new LabelledSliderBar + { + Label = EditorSetupStrings.TickRate, + FixedLabelWidth = LABEL_WIDTH, + Description = EditorSetupStrings.TickRateDescription, + Current = new BindableDouble(Beatmap.Difficulty.SliderTickRate) + { + Default = 1, + MinValue = 1, + MaxValue = 4, + Precision = 1, + } + }, }; foreach (var item in Children.OfType>()) @@ -111,6 +125,7 @@ namespace osu.Game.Screens.Edit.Setup Beatmap.Difficulty.ApproachRate = approachRateSlider.Current.Value; Beatmap.Difficulty.OverallDifficulty = overallDifficultySlider.Current.Value; Beatmap.Difficulty.SliderMultiplier = baseVelocitySlider.Current.Value; + Beatmap.Difficulty.SliderTickRate = tickRateSlider.Current.Value; Beatmap.UpdateAllHitObjects(); Beatmap.SaveState(); From 84efddcbc7cb09db82ccb58d2a57bd80c1b9c1fd Mon Sep 17 00:00:00 2001 From: timiimit Date: Tue, 9 May 2023 15:53:36 +0200 Subject: [PATCH 2905/2991] Fix default progress graph flipping with a hack --- osu.Game/Screens/Play/SquareGraph.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index 57b7c84e89..8636f08b00 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -75,18 +75,28 @@ namespace osu.Game.Screens.Play private Vector2 previousDrawSize; + private Vector2 previousParentScale; + protected override void Update() { base.Update(); - if (graphNeedsUpdate || (values != null && DrawSize != previousDrawSize)) + bool hasFlipped = previousParentScale != Parent.Scale; + if (graphNeedsUpdate || (values != null && DrawSize != previousDrawSize) || hasFlipped) { - columns?.FadeOut(500, Easing.OutQuint).Expire(); - scheduledCreate?.Cancel(); - scheduledCreate = Scheduler.AddDelayed(RecreateGraph, 500); + + if (!hasFlipped) + { + scheduledCreate = Scheduler.AddDelayed(RecreateGraph, 500); + } + else + { + RecreateGraph(); + } previousDrawSize = DrawSize; + previousParentScale = Parent.Scale; graphNeedsUpdate = false; } } From ad80e2ff5119322dfadaadfa57622bd6aca5afbe Mon Sep 17 00:00:00 2001 From: timiimit Date: Tue, 9 May 2023 17:15:54 +0200 Subject: [PATCH 2906/2991] More robust implementation --- osu.Game/Screens/Play/SquareGraph.cs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index 8636f08b00..a498917504 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -81,20 +81,31 @@ namespace osu.Game.Screens.Play { base.Update(); - bool hasFlipped = previousParentScale != Parent.Scale; - if (graphNeedsUpdate || (values != null && DrawSize != previousDrawSize) || hasFlipped) + bool extraUpdateConditions = + DrawSize != previousDrawSize || + previousParentScale != Parent.Scale; + + if (graphNeedsUpdate || (values != null && extraUpdateConditions)) { - scheduledCreate?.Cancel(); + bool hasFlipped = + previousParentScale.X == -Parent.Scale.X || + previousParentScale.Y == -Parent.Scale.Y; if (!hasFlipped) { - scheduledCreate = Scheduler.AddDelayed(RecreateGraph, 500); + columns?.FadeOut(500, Easing.OutQuint).Expire(); } else { - RecreateGraph(); + if (columns != null) + { + columns.Alpha = 0.0f; + } } + scheduledCreate?.Cancel(); + scheduledCreate = Scheduler.AddDelayed(RecreateGraph, 500); + previousDrawSize = DrawSize; previousParentScale = Parent.Scale; graphNeedsUpdate = false; From 745341ca6b4b5c1ed40b362a2fece9af58a7af86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 9 May 2023 21:55:53 +0200 Subject: [PATCH 2907/2991] Fix iOS build workflow failing A new version of `Microsoft.iOS.Sdk` was released on 2023-05-09T17:28:41.7300000. This version requires Xcode 14.3, which is not currently available on `macos-latest` runners (which currently alias to `macos-12`). To fix, migrate to `macos-13`, which is currently in beta, and explicitly use Xcode 14.3 (because even on the `macos-13` image, Xcode 14.3 is not yet the default). --- .github/workflows/ci.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e60e0a39ae..a8167ec4db 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -121,12 +121,24 @@ jobs: build-only-ios: name: Build only (iOS) - runs-on: macos-latest + # `macos-13` is required, because Xcode 14.3 is required (see below). + # TODO: can be changed to `macos-latest` once `macos-13` becomes latest (currently in beta) + runs-on: macos-13 timeout-minutes: 60 steps: - name: Checkout uses: actions/checkout@v3 + # newest Microsoft.iOS.Sdk versions require Xcode 14.3. + # 14.3 is currently not the default Xcode version (https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md#xcode), + # so set it manually. + # TODO: remove when 14.3 becomes the default Xcode version. + - name: Set Xcode version + shell: bash + run: | + sudo xcode-select -s "/Applications/Xcode_14.3.app" + echo "MD_APPLE_SDK_ROOT=/Applications/Xcode_14.3.app" >> $GITHUB_ENV + - name: Install .NET 6.0.x uses: actions/setup-dotnet@v3 with: From 4aa241daeab7d12eb8a32f1bb1da78ed5749a5c8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 10 May 2023 15:19:43 +0900 Subject: [PATCH 2908/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index e9ecbaa10b..ff76e17184 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -11,7 +11,7 @@ manifestmerger.jar - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 7ab9810ab5..93f22a31d8 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index bfa0dc63bb..c5477f765e 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -16,6 +16,6 @@ iossimulator-x64 - + From 3fc19553b4435211370cfd2655ed35992ae95aa7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 10 May 2023 15:19:46 +0900 Subject: [PATCH 2909/2991] Update resources --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 93f22a31d8..4315f44e07 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -37,7 +37,7 @@ - + From c1a85658b728614be2f25fbca7d8dda1916865f3 Mon Sep 17 00:00:00 2001 From: tsrk Date: Thu, 11 May 2023 14:58:17 +0100 Subject: [PATCH 2910/2991] feat(settings): add "import" as keywords for first run setup --- osu.Game/Overlays/Settings/Sections/GeneralSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs index c5274d6223..b12541b261 100644 --- a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs +++ b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Settings.Sections new SettingsButton { Text = GeneralSettingsStrings.RunSetupWizard, - Keywords = new[] { @"first run", @"initial", @"getting started" }, + Keywords = new[] { @"first run", @"initial", @"getting started", @"import" }, TooltipText = FirstRunSetupOverlayStrings.FirstRunSetupDescription, Action = () => firstRunSetupOverlay?.Show(), }, From 2d45d602a538532245f9fe4287700e27493e962b Mon Sep 17 00:00:00 2001 From: tsrk Date: Thu, 11 May 2023 15:03:42 +0100 Subject: [PATCH 2911/2991] feat(settings): more keyword for first run setup --- osu.Game/Overlays/Settings/Sections/GeneralSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs index b12541b261..f4a79d65e6 100644 --- a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs +++ b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Settings.Sections new SettingsButton { Text = GeneralSettingsStrings.RunSetupWizard, - Keywords = new[] { @"first run", @"initial", @"getting started", @"import" }, + Keywords = new[] { @"first run", @"initial", @"getting started", @"import", @"tutorial", @"recommended beatmaps" }, TooltipText = FirstRunSetupOverlayStrings.FirstRunSetupDescription, Action = () => firstRunSetupOverlay?.Show(), }, From 4732c8a06c73c8e8e63673f6bbf21c7dd45c1b92 Mon Sep 17 00:00:00 2001 From: alix Date: Thu, 11 May 2023 13:46:07 -0400 Subject: [PATCH 2912/2991] fix angle sharpness slider value from not always scaling by 0.5 --- osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs index 307d731fd4..b8ce667398 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Mods { MinValue = 1, MaxValue = 10, - Precision = 0.1f + Precision = 0.5f }; private static readonly float playfield_diagonal = OsuPlayfield.BASE_SIZE.LengthFast; From 3bce7ac58931806ddaa81191b04e744ffbdef680 Mon Sep 17 00:00:00 2001 From: js1086 Date: Thu, 11 May 2023 19:07:22 +0100 Subject: [PATCH 2913/2991] Copy SliderVelocity to strict tracking sliders --- osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs b/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs index 7e4ffc7408..72031b4958 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs @@ -98,6 +98,7 @@ namespace osu.Game.Rulesets.Osu.Mods ComboOffset = original.ComboOffset; LegacyLastTickOffset = original.LegacyLastTickOffset; TickDistanceMultiplier = original.TickDistanceMultiplier; + SliderVelocity = original.SliderVelocity; } protected override void CreateNestedHitObjects(CancellationToken cancellationToken) From a4954e64acb288a3a3ca1d6213ef63f68d812a64 Mon Sep 17 00:00:00 2001 From: alix Date: Thu, 11 May 2023 23:45:41 -0400 Subject: [PATCH 2914/2991] fix precision from making mouse input also go 0.5 --- osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs index b8ce667398..89767b29c1 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs @@ -22,18 +22,27 @@ namespace osu.Game.Rulesets.Osu.Mods /// /// Mod that randomises the positions of the s /// + + public partial class AngleSharpnessSlider : SettingsSlider + { + public AngleSharpnessSlider() + { + KeyboardStep = 0.5f; + } + } + public class OsuModRandom : ModRandom, IApplicableToBeatmap { public override LocalisableString Description => "It never gets boring!"; public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModTargetPractice)).ToArray(); - [SettingSource("Angle sharpness", "How sharp angles should be", SettingControlType = typeof(SettingsSlider))] + [SettingSource("Angle sharpness", "How sharp angles should be", SettingControlType = typeof(AngleSharpnessSlider))] public BindableFloat AngleSharpness { get; } = new BindableFloat(7) { MinValue = 1, MaxValue = 10, - Precision = 0.5f + Precision = 0.1f }; private static readonly float playfield_diagonal = OsuPlayfield.BASE_SIZE.LengthFast; From e50cab9e81196405011654019cd003a795018789 Mon Sep 17 00:00:00 2001 From: alix Date: Thu, 11 May 2023 23:48:31 -0400 Subject: [PATCH 2915/2991] move class to the bottom of the file --- osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs index 89767b29c1..3d19a4d6eb 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs @@ -22,15 +22,6 @@ namespace osu.Game.Rulesets.Osu.Mods /// /// Mod that randomises the positions of the s /// - - public partial class AngleSharpnessSlider : SettingsSlider - { - public AngleSharpnessSlider() - { - KeyboardStep = 0.5f; - } - } - public class OsuModRandom : ModRandom, IApplicableToBeatmap { public override LocalisableString Description => "It never gets boring!"; @@ -170,5 +161,13 @@ namespace osu.Game.Rulesets.Osu.Mods return previousObjectStartedCombo && random.NextDouble() < 0.6f; } + + public partial class AngleSharpnessSlider : SettingsSlider + { + public AngleSharpnessSlider() + { + KeyboardStep = 0.5f; + } + } } } From 53ab780796fdb4a83366e84e5c00b58be3ac1cb1 Mon Sep 17 00:00:00 2001 From: alix Date: Thu, 11 May 2023 23:50:45 -0400 Subject: [PATCH 2916/2991] fix indents --- osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs index 3d19a4d6eb..61fb9189bc 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs @@ -164,9 +164,9 @@ namespace osu.Game.Rulesets.Osu.Mods public partial class AngleSharpnessSlider : SettingsSlider { - public AngleSharpnessSlider() + public AngleSharpnessSlider() { - KeyboardStep = 0.5f; + KeyboardStep = 0.5f; } } } From b3a5e4d3052d4d97d4a97779f561359bf92c3217 Mon Sep 17 00:00:00 2001 From: alix Date: Fri, 12 May 2023 00:29:00 -0400 Subject: [PATCH 2917/2991] nest class outside of OsuModRandom --- osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs index 61fb9189bc..6affeb24d8 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs @@ -161,13 +161,13 @@ namespace osu.Game.Rulesets.Osu.Mods return previousObjectStartedCombo && random.NextDouble() < 0.6f; } + } - public partial class AngleSharpnessSlider : SettingsSlider + public partial class AngleSharpnessSlider : SettingsSlider + { + public AngleSharpnessSlider() { - public AngleSharpnessSlider() - { - KeyboardStep = 0.5f; - } + KeyboardStep = 0.5f; } } } From c0f869e685970af218ef68640cabe755f2f93db5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 May 2023 14:57:54 +0900 Subject: [PATCH 2918/2991] Fix some tablet settings being hidden when searching using "area" keyword As discussed in https://github.com/ppy/osu/discussions/23504. --- osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs index 951cf3802f..4c9320c2a6 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs @@ -3,6 +3,8 @@ #nullable disable +using System.Collections.Generic; +using System.Linq; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -23,6 +25,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input { public partial class TabletSettings : SettingsSubsection { + public override IEnumerable FilterTerms => base.FilterTerms.Concat(new LocalisableString[] { "area" }); + public TabletAreaSelection AreaSelection { get; private set; } private readonly ITabletHandler tabletHandler; From f443cfb93e41c4c33e3f51bccd1583b382b5dd3a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 May 2023 16:00:40 +0900 Subject: [PATCH 2919/2991] Move blueprint validity conditions to allow more correct external usage of `EndPlacement` Until now, these were haphazardly enforce inline in blueprint implementations. The only thing stopping complete breakage is that `EndPlacement` wasn't called (too much) from outside the blueprint, leaving them responsible for their own placement. By moving this conditional out of the provided paramters to `EndPlacement`, it allows more flexible usage of that method externally. Coming in a future PR. --- .../Blueprints/BananaShowerPlacementBlueprint.cs | 4 +++- .../Blueprints/JuiceStreamPlacementBlueprint.cs | 4 +++- .../Edit/Blueprints/HoldNotePlacementBlueprint.cs | 4 +++- .../Blueprints/Sliders/SliderPlacementBlueprint.cs | 4 +++- .../Edit/Blueprints/TaikoSpanPlacementBlueprint.cs | 4 +++- osu.Game/Rulesets/Edit/PlacementBlueprint.cs | 13 +++++++++++-- 6 files changed, 26 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerPlacementBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerPlacementBlueprint.cs index 5f22ef5c12..1e63d32c41 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerPlacementBlueprint.cs @@ -17,6 +17,8 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints private double placementStartTime; private double placementEndTime; + protected override bool IsValidForPlacement => HitObject.Duration > 0; + public BananaShowerPlacementBlueprint() { InternalChild = outline = new TimeSpanOutline(); @@ -49,7 +51,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints case PlacementState.Active: if (e.Button != MouseButton.Right) break; - EndPlacement(HitObject.Duration > 0); + EndPlacement(true); return true; } diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamPlacementBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamPlacementBlueprint.cs index 03ec674abb..9e50b5a80f 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamPlacementBlueprint.cs @@ -24,6 +24,8 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints private InputManager inputManager = null!; + protected override bool IsValidForPlacement => HitObject.Duration > 0; + public JuiceStreamPlacementBlueprint() { InternalChildren = new Drawable[] @@ -70,7 +72,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints return true; case MouseButton.Right: - EndPlacement(HitObject.Duration > 0); + EndPlacement(true); return true; } diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs index 21beee0769..381af8be7f 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs @@ -25,6 +25,8 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints [Resolved] private IScrollingInfo scrollingInfo { get; set; } + protected override bool IsValidForPlacement => HitObject.Duration > 0; + public HoldNotePlacementBlueprint() : base(new HoldNote()) { @@ -75,7 +77,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints return; base.OnMouseUp(e); - EndPlacement(HitObject.Duration > 0); + EndPlacement(true); } private double originalStartTime; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs index 50514865e1..28ceb80627 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs @@ -41,6 +41,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders [Resolved(CanBeNull = true)] private IDistanceSnapProvider snapProvider { get; set; } + protected override bool IsValidForPlacement => HitObject.Path.HasValidLength; + public SliderPlacementBlueprint() : base(new Slider()) { @@ -150,7 +152,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders private void endCurve() { updateSlider(); - EndPlacement(HitObject.Path.HasValidLength); + EndPlacement(true); } protected override void Update() diff --git a/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs b/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs index fcf2573d64..bc4129c982 100644 --- a/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Taiko/Edit/Blueprints/TaikoSpanPlacementBlueprint.cs @@ -25,6 +25,8 @@ namespace osu.Game.Rulesets.Taiko.Edit.Blueprints private readonly IHasDuration spanPlacementObject; + protected override bool IsValidForPlacement => spanPlacementObject.Duration > 0; + public TaikoSpanPlacementBlueprint(HitObject hitObject) : base(hitObject) { @@ -73,7 +75,7 @@ namespace osu.Game.Rulesets.Taiko.Edit.Blueprints return; base.OnMouseUp(e); - EndPlacement(spanPlacementObject.Duration > 0); + EndPlacement(true); } public override void UpdateTimeAndPosition(SnapResult result) diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs index bdcb334738..253d59751d 100644 --- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs +++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs @@ -47,6 +47,15 @@ namespace osu.Game.Rulesets.Edit [Resolved] private IPlacementHandler placementHandler { get; set; } + /// + /// Whether this blueprint is currently in a state that can be committed. + /// + /// + /// Override this with any preconditions that should be double-checked on committing. + /// If false is returned and a commit is attempted, the blueprint will be destroyed instead. + /// + protected virtual bool IsValidForPlacement => true; + protected PlacementBlueprint(HitObject hitObject) { HitObject = hitObject; @@ -88,7 +97,7 @@ namespace osu.Game.Rulesets.Edit /// Signals that the placement of has finished. /// This will destroy this , and add the HitObject.StartTime to the . /// - /// Whether the object should be committed. + /// Whether the object should be committed. Note that a commit may fail if is false. public void EndPlacement(bool commit) { switch (PlacementActive) @@ -102,7 +111,7 @@ namespace osu.Game.Rulesets.Edit break; } - placementHandler.EndPlacement(HitObject, commit); + placementHandler.EndPlacement(HitObject, IsValidForPlacement && commit); PlacementActive = PlacementState.Finished; } From 70e248b92790da42e5d74d4f966407af2c2e5e0e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 May 2023 15:48:53 +0900 Subject: [PATCH 2920/2991] Force placement of in-progress object when changing tools in the editor --- .../Components/ComposeBlueprintContainer.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index 453e4b9130..07fb450628 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -317,12 +317,16 @@ namespace osu.Game.Screens.Edit.Compose.Components } } + private void commitIfPlacementActive() + { + CurrentPlacement?.EndPlacement(CurrentPlacement.PlacementActive == PlacementBlueprint.PlacementState.Active); + removePlacement(); + } + private void removePlacement() { - if (CurrentPlacement == null) return; - - CurrentPlacement.EndPlacement(false); - CurrentPlacement.Expire(); + CurrentPlacement?.EndPlacement(false); + CurrentPlacement?.Expire(); CurrentPlacement = null; } @@ -342,7 +346,8 @@ namespace osu.Game.Screens.Edit.Compose.Components currentTool = value; - refreshTool(); + // As per stable editor, when changing tools, we should forcefully commit any pending placement. + commitIfPlacementActive(); } } } From 0c1959ef2ff93e2e743a6a1a32b74e18c4028d5d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 May 2023 15:50:33 +0900 Subject: [PATCH 2921/2991] Allow commiting / undoing placement of blueprints using back / select bindings --- osu.Game/Rulesets/Edit/PlacementBlueprint.cs | 28 +++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs index 253d59751d..12c0ea1807 100644 --- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs +++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs @@ -9,10 +9,12 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Input.Bindings; using osu.Game.Rulesets.Objects; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Compose; @@ -24,7 +26,7 @@ namespace osu.Game.Rulesets.Edit /// /// A blueprint which governs the creation of a new to actualisation. /// - public abstract partial class PlacementBlueprint : CompositeDrawable + public abstract partial class PlacementBlueprint : CompositeDrawable, IKeyBindingHandler { /// /// Whether the is currently mid-placement, but has not necessarily finished being placed. @@ -115,6 +117,30 @@ namespace osu.Game.Rulesets.Edit PlacementActive = PlacementState.Finished; } + public bool OnPressed(KeyBindingPressEvent e) + { + if (PlacementActive == PlacementState.Waiting) + return false; + + switch (e.Action) + { + case GlobalAction.Select: + EndPlacement(true); + return true; + + case GlobalAction.Back: + EndPlacement(false); + return true; + + default: + return false; + } + } + + public void OnReleased(KeyBindingReleaseEvent e) + { + } + /// /// Updates the time and position of this based on the provided snap information. /// From 6180d0d620bcf6f49ec8e22168d23c5a7d7bb465 Mon Sep 17 00:00:00 2001 From: timiimit Date: Fri, 12 May 2023 15:00:46 +0200 Subject: [PATCH 2922/2991] Remove cached frame buffer --- osu.Game/Screens/Play/SquareGraph.cs | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index 57b7c84e89..26283858a6 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -51,7 +51,8 @@ namespace osu.Game.Screens.Play if (value == values) return; values = value; - graphNeedsUpdate = true; + scheduledCreate?.Cancel(); + scheduledCreate = Scheduler.AddDelayed(RecreateGraph, 500); } } @@ -70,27 +71,6 @@ namespace osu.Game.Screens.Play } private ScheduledDelegate scheduledCreate; - - private bool graphNeedsUpdate; - - private Vector2 previousDrawSize; - - protected override void Update() - { - base.Update(); - - if (graphNeedsUpdate || (values != null && DrawSize != previousDrawSize)) - { - columns?.FadeOut(500, Easing.OutQuint).Expire(); - - scheduledCreate?.Cancel(); - scheduledCreate = Scheduler.AddDelayed(RecreateGraph, 500); - - previousDrawSize = DrawSize; - graphNeedsUpdate = false; - } - } - private CancellationTokenSource cts; /// @@ -98,7 +78,7 @@ namespace osu.Game.Screens.Play /// protected virtual void RecreateGraph() { - var newColumns = new BufferedContainer(cachedFrameBuffer: true) + var newColumns = new BufferedContainer { RedrawOnScale = false, RelativeSizeAxes = Axes.Both, From 159cacf9c7299dfa72cf091bb31dc99030879d4b Mon Sep 17 00:00:00 2001 From: timiimit Date: Sat, 13 May 2023 01:27:28 +0200 Subject: [PATCH 2923/2991] Fix logic in recalculateValues() --- osu.Game/Screens/Play/SquareGraph.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index 26283858a6..d521bb5448 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -139,18 +139,19 @@ namespace osu.Game.Screens.Play if (values == null) { for (float i = 0; i < ColumnCount; i++) + { newValues.Add(0); - - return; } - + } + else + { int max = values.Max(); - float step = values.Length / (float)ColumnCount; for (float i = 0; i < values.Length; i += step) { newValues.Add((float)values[(int)i] / max); + } } calculatedValues = newValues.ToArray(); From 21d7c62f303c2064dd99ae305d19c409f87cd4c6 Mon Sep 17 00:00:00 2001 From: timiimit Date: Sat, 13 May 2023 01:29:11 +0200 Subject: [PATCH 2924/2991] Add optimized UpdateGraph --- osu.Game/Screens/Play/SquareGraph.cs | 122 +++++++++++++++++++-------- 1 file changed, 88 insertions(+), 34 deletions(-) diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index d521bb5448..dd964b8908 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -16,6 +16,7 @@ using osuTK.Graphics; using osu.Framework.Graphics.Shapes; using osu.Framework.Allocation; using osu.Framework.Threading; +using osu.Framework.Layout; namespace osu.Game.Screens.Play { @@ -23,6 +24,8 @@ namespace osu.Game.Screens.Play { private BufferedContainer columns; + private readonly LayoutValue layout = new LayoutValue(Invalidation.DrawSize | Invalidation.DrawInfo); + public int ColumnCount => columns?.Children.Count ?? 0; private int progress; @@ -51,11 +54,13 @@ namespace osu.Game.Screens.Play if (value == values) return; values = value; - scheduledCreate?.Cancel(); - scheduledCreate = Scheduler.AddDelayed(RecreateGraph, 500); + haveValuesChanged = true; + layout.Invalidate(); } } + bool haveValuesChanged; + private Color4 fillColour; public Color4 FillColour @@ -70,43 +75,93 @@ namespace osu.Game.Screens.Play } } - private ScheduledDelegate scheduledCreate; - private CancellationTokenSource cts; - - /// - /// Recreates the entire graph. - /// - protected virtual void RecreateGraph() + public SquareGraph() { - var newColumns = new BufferedContainer + AddLayout(layout); + } + + [BackgroundDependencyLoader] + private void load() + { + Child = columns = new BufferedContainer(cachedFrameBuffer: true) { RedrawOnScale = false, - RelativeSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.Both }; + } - for (float x = 0; x < DrawWidth; x += Column.WIDTH) + + // private Vector2 parentScale; + + protected override void Update() + { + base.Update(); + + if (!layout.IsValid) { - newColumns.Add(new Column(DrawHeight) + UpdateGraph(); + layout.Validate(); + } + } + + /// + /// Updates the graph by either adding or removing columns based on DrawWidth. + /// Does nothing if correct number of columns already exists and/or if haven't changed. + /// + protected virtual void UpdateGraph() + { + int targetColumnCount = values == null ? 0 : (int)(DrawWidth / Column.WIDTH); + + // early exit the most frequent case + if (!haveValuesChanged && targetColumnCount == ColumnCount) + { + columns.ForceRedraw(); + return; + } + + ensureColumnCount(targetColumnCount); + + // fill graph data + recalculateValues(); + redrawFilled(); + redrawProgress(); + + haveValuesChanged = false; + } + + private void ensureColumnCount(int targetColumnCount) + { + // remove excess columns + while (targetColumnCount < ColumnCount) + { + columns.Remove(columns.Children[ColumnCount - 1], true); + } + + // update height of existing columns + foreach (var column in columns) + { + column.Height = DrawHeight; + } + + // add missing columns + float x = ColumnCount * Column.WIDTH; + while (targetColumnCount > ColumnCount) + { + var column = new Column() { + Height = DrawHeight, LitColour = fillColour, Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, Position = new Vector2(x, 0), State = ColumnState.Dimmed, - }); + }; + + LoadComponentAsync(column); + columns.Add(column); + + x += Column.WIDTH; } - - cts?.Cancel(); - - LoadComponentAsync(newColumns, c => - { - Child = columns = c; - columns.FadeInFromZero(500, Easing.OutQuint); - - recalculateValues(); - redrawFilled(); - redrawProgress(); - }, (cts = new CancellationTokenSource()).Token); } /// @@ -141,16 +196,16 @@ namespace osu.Game.Screens.Play for (float i = 0; i < ColumnCount; i++) { newValues.Add(0); - } + } } else { - int max = values.Max(); - float step = values.Length / (float)ColumnCount; + int max = values.Max(); + float step = values.Length / (float)ColumnCount; - for (float i = 0; i < values.Length; i += step) - { - newValues.Add((float)values[(int)i] / max); + for (float i = 0; i < values.Length; i += step) + { + newValues.Add((float)values[(int)i] / max); } } @@ -203,10 +258,9 @@ namespace osu.Game.Screens.Play } } - public Column(float height) + public Column() { Width = WIDTH; - Height = height; } [BackgroundDependencyLoader] From 04f7def798e365660a8e6e721c6309ba469f6a98 Mon Sep 17 00:00:00 2001 From: timiimit Date: Sat, 13 May 2023 01:31:12 +0200 Subject: [PATCH 2925/2991] Remove useless comment --- osu.Game/Screens/Play/SquareGraph.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index dd964b8908..7e8a8952cc 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -90,9 +90,6 @@ namespace osu.Game.Screens.Play }; } - - // private Vector2 parentScale; - protected override void Update() { base.Update(); From d39d552660d79ea2652c15e9201f2d65034e6d10 Mon Sep 17 00:00:00 2001 From: timiimit Date: Sat, 13 May 2023 01:35:48 +0200 Subject: [PATCH 2926/2991] Update test --- .../Visual/Gameplay/TestSceneDefaultSongProgressGraph.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneDefaultSongProgressGraph.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneDefaultSongProgressGraph.cs index 66671a506f..4e57a255be 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneDefaultSongProgressGraph.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneDefaultSongProgressGraph.cs @@ -63,10 +63,12 @@ namespace osu.Game.Tests.Visual.Gameplay { public int CreationCount { get; private set; } - protected override void RecreateGraph() + protected override void UpdateGraph() { - base.RecreateGraph(); - CreationCount++; + base.UpdateGraph(); + + if (base.ColumnCount > 0) + CreationCount++; } } } From 8cc0c5ad1ca7b27c13651a48f5ab5ebe9c673cc5 Mon Sep 17 00:00:00 2001 From: timiimit Date: Sat, 13 May 2023 01:39:01 +0200 Subject: [PATCH 2927/2991] Fix code style --- osu.Game/Screens/Play/SquareGraph.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index 7e8a8952cc..5ea17a7518 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Threading; using osu.Framework; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -15,7 +14,6 @@ using osuTK; using osuTK.Graphics; using osu.Framework.Graphics.Shapes; using osu.Framework.Allocation; -using osu.Framework.Threading; using osu.Framework.Layout; namespace osu.Game.Screens.Play @@ -59,7 +57,7 @@ namespace osu.Game.Screens.Play } } - bool haveValuesChanged; + private bool haveValuesChanged; private Color4 fillColour; @@ -93,7 +91,7 @@ namespace osu.Game.Screens.Play protected override void Update() { base.Update(); - + if (!layout.IsValid) { UpdateGraph(); From 80b6e014f16747173aa4240aebb709fda1187b82 Mon Sep 17 00:00:00 2001 From: timiimit Date: Sat, 13 May 2023 01:47:44 +0200 Subject: [PATCH 2928/2991] More code style --- .../Visual/Gameplay/TestSceneDefaultSongProgressGraph.cs | 2 +- osu.Game/Screens/Play/SquareGraph.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneDefaultSongProgressGraph.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneDefaultSongProgressGraph.cs index 4e57a255be..8d0c26996c 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneDefaultSongProgressGraph.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneDefaultSongProgressGraph.cs @@ -67,7 +67,7 @@ namespace osu.Game.Tests.Visual.Gameplay { base.UpdateGraph(); - if (base.ColumnCount > 0) + if (ColumnCount > 0) CreationCount++; } } diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index 5ea17a7518..27c6cae2fc 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -140,9 +140,10 @@ namespace osu.Game.Screens.Play // add missing columns float x = ColumnCount * Column.WIDTH; + while (targetColumnCount > ColumnCount) { - var column = new Column() + var column = new Column { Height = DrawHeight, LitColour = fillColour, From 2cfc4eb515d50dcdd387020764bcad744c9bb9f5 Mon Sep 17 00:00:00 2001 From: timiimit Date: Sat, 13 May 2023 10:12:46 +0200 Subject: [PATCH 2929/2991] Fix unconsidered height change --- osu.Game/Screens/Play/SquareGraph.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index 27c6cae2fc..d5d2f1d3c2 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -110,6 +110,7 @@ namespace osu.Game.Screens.Play // early exit the most frequent case if (!haveValuesChanged && targetColumnCount == ColumnCount) { + updateColumnHeight(); columns.ForceRedraw(); return; } @@ -124,6 +125,14 @@ namespace osu.Game.Screens.Play haveValuesChanged = false; } + private void updateColumnHeight() + { + foreach (var column in columns) + { + column.Height = DrawHeight; + } + } + private void ensureColumnCount(int targetColumnCount) { // remove excess columns @@ -132,11 +141,7 @@ namespace osu.Game.Screens.Play columns.Remove(columns.Children[ColumnCount - 1], true); } - // update height of existing columns - foreach (var column in columns) - { - column.Height = DrawHeight; - } + updateColumnHeight(); // add missing columns float x = ColumnCount * Column.WIDTH; From 4b544903cb7bcd768aab655e34f40da0285785b6 Mon Sep 17 00:00:00 2001 From: timiimit Date: Sat, 13 May 2023 10:13:09 +0200 Subject: [PATCH 2930/2991] Optimize recalculateValues --- osu.Game/Screens/Play/SquareGraph.cs | 33 +++++++++++++--------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index d5d2f1d3c2..061d1f7103 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -190,27 +190,24 @@ namespace osu.Game.Screens.Play /// private void recalculateValues() { - var newValues = new List(); - - if (values == null) + int columnCount = ColumnCount; + if (values == null || values.Length == 0 || columnCount == 0) { - for (float i = 0; i < ColumnCount; i++) - { - newValues.Add(0); - } - } - else - { - int max = values.Max(); - float step = values.Length / (float)ColumnCount; - - for (float i = 0; i < values.Length; i += step) - { - newValues.Add((float)values[(int)i] / max); - } + calculatedValues = new float[0]; + return; } - calculatedValues = newValues.ToArray(); + float ratio = values.Length / (float)columnCount; + + if (calculatedValues.Length != columnCount) + calculatedValues = new float[columnCount]; + + float max = (float)values.Max(); + + for (int i = 0; i < calculatedValues.Length; i++) + { + calculatedValues[i] = values[(int)(i * ratio)] / max; + } } public partial class Column : Container, IStateful From d81cdacb0d30368cfc1ab092c0465936c5fabe56 Mon Sep 17 00:00:00 2001 From: timiimit Date: Sat, 13 May 2023 11:28:05 +0200 Subject: [PATCH 2931/2991] Undo stupid changes --- .../TestSceneDefaultSongProgressGraph.cs | 8 +- osu.Game/Screens/Play/SquareGraph.cs | 126 +++++++----------- 2 files changed, 51 insertions(+), 83 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneDefaultSongProgressGraph.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneDefaultSongProgressGraph.cs index 8d0c26996c..66671a506f 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneDefaultSongProgressGraph.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneDefaultSongProgressGraph.cs @@ -63,12 +63,10 @@ namespace osu.Game.Tests.Visual.Gameplay { public int CreationCount { get; private set; } - protected override void UpdateGraph() + protected override void RecreateGraph() { - base.UpdateGraph(); - - if (ColumnCount > 0) - CreationCount++; + base.RecreateGraph(); + CreationCount++; } } } diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index 061d1f7103..037f2b5b78 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using osu.Framework; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -15,6 +16,7 @@ using osuTK.Graphics; using osu.Framework.Graphics.Shapes; using osu.Framework.Allocation; using osu.Framework.Layout; +using osu.Framework.Threading; namespace osu.Game.Screens.Play { @@ -22,8 +24,6 @@ namespace osu.Game.Screens.Play { private BufferedContainer columns; - private readonly LayoutValue layout = new LayoutValue(Invalidation.DrawSize | Invalidation.DrawInfo); - public int ColumnCount => columns?.Children.Count ?? 0; private int progress; @@ -52,13 +52,10 @@ namespace osu.Game.Screens.Play if (value == values) return; values = value; - haveValuesChanged = true; layout.Invalidate(); } } - private bool haveValuesChanged; - private Color4 fillColour; public Color4 FillColour @@ -73,96 +70,66 @@ namespace osu.Game.Screens.Play } } + private ScheduledDelegate scheduledCreate; + + private LayoutValue layout = new LayoutValue(Invalidation.DrawSize | Invalidation.DrawInfo); + public SquareGraph() { AddLayout(layout); } - [BackgroundDependencyLoader] - private void load() - { - Child = columns = new BufferedContainer(cachedFrameBuffer: true) - { - RedrawOnScale = false, - RelativeSizeAxes = Axes.Both - }; - } - protected override void Update() { base.Update(); if (!layout.IsValid) { - UpdateGraph(); + columns?.FadeOut(500, Easing.OutQuint).Expire(); + + scheduledCreate?.Cancel(); + scheduledCreate = Scheduler.AddDelayed(RecreateGraph, 500); + layout.Validate(); } } + private CancellationTokenSource cts; + /// - /// Updates the graph by either adding or removing columns based on DrawWidth. - /// Does nothing if correct number of columns already exists and/or if haven't changed. + /// Recreates the entire graph. /// - protected virtual void UpdateGraph() + protected virtual void RecreateGraph() { - int targetColumnCount = values == null ? 0 : (int)(DrawWidth / Column.WIDTH); - - // early exit the most frequent case - if (!haveValuesChanged && targetColumnCount == ColumnCount) + var newColumns = new BufferedContainer(cachedFrameBuffer: true) { - updateColumnHeight(); - columns.ForceRedraw(); - return; - } + RedrawOnScale = false, + RelativeSizeAxes = Axes.Both, + }; - ensureColumnCount(targetColumnCount); - - // fill graph data - recalculateValues(); - redrawFilled(); - redrawProgress(); - - haveValuesChanged = false; - } - - private void updateColumnHeight() - { - foreach (var column in columns) + for (float x = 0; x < DrawWidth; x += Column.WIDTH) { - column.Height = DrawHeight; - } - } - - private void ensureColumnCount(int targetColumnCount) - { - // remove excess columns - while (targetColumnCount < ColumnCount) - { - columns.Remove(columns.Children[ColumnCount - 1], true); - } - - updateColumnHeight(); - - // add missing columns - float x = ColumnCount * Column.WIDTH; - - while (targetColumnCount > ColumnCount) - { - var column = new Column + newColumns.Add(new Column(DrawHeight) { - Height = DrawHeight, LitColour = fillColour, Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, Position = new Vector2(x, 0), State = ColumnState.Dimmed, - }; - - LoadComponentAsync(column); - columns.Add(column); - - x += Column.WIDTH; + }); } + + cts?.Cancel(); + + LoadComponentAsync(newColumns, c => + { + Child = columns = c; + columns.FadeInFromZero(500, Easing.OutQuint); + + recalculateValues(); + redrawFilled(); + redrawProgress(); + }, (cts = new CancellationTokenSource()).Token); } /// @@ -190,24 +157,26 @@ namespace osu.Game.Screens.Play /// private void recalculateValues() { - int columnCount = ColumnCount; - if (values == null || values.Length == 0 || columnCount == 0) + var newValues = new List(); + + if (values == null) { - calculatedValues = new float[0]; + for (float i = 0; i < ColumnCount; i++) + newValues.Add(0); + return; } - float ratio = values.Length / (float)columnCount; + int max = values.Max(); - if (calculatedValues.Length != columnCount) - calculatedValues = new float[columnCount]; + float step = values.Length / (float)ColumnCount; - float max = (float)values.Max(); - - for (int i = 0; i < calculatedValues.Length; i++) + for (float i = 0; i < values.Length; i += step) { - calculatedValues[i] = values[(int)(i * ratio)] / max; + newValues.Add((float)values[(int)i] / max); } + + calculatedValues = newValues.ToArray(); } public partial class Column : Container, IStateful @@ -256,9 +225,10 @@ namespace osu.Game.Screens.Play } } - public Column() + public Column(float height) { Width = WIDTH; + Height = height; } [BackgroundDependencyLoader] From 18efdb0e4cb3d75fba4288fc7327a10a38214a82 Mon Sep 17 00:00:00 2001 From: timiimit Date: Sat, 13 May 2023 11:37:56 +0200 Subject: [PATCH 2932/2991] Make `layout` readonly --- osu.Game/Screens/Play/SquareGraph.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/SquareGraph.cs b/osu.Game/Screens/Play/SquareGraph.cs index 037f2b5b78..b53e86a41b 100644 --- a/osu.Game/Screens/Play/SquareGraph.cs +++ b/osu.Game/Screens/Play/SquareGraph.cs @@ -72,7 +72,7 @@ namespace osu.Game.Screens.Play private ScheduledDelegate scheduledCreate; - private LayoutValue layout = new LayoutValue(Invalidation.DrawSize | Invalidation.DrawInfo); + private readonly LayoutValue layout = new LayoutValue(Invalidation.DrawSize | Invalidation.DrawInfo); public SquareGraph() { From 2e6fd4b321c6223ad1dccb3df1992c9ced5e4a0a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 13 May 2023 20:54:22 +0900 Subject: [PATCH 2933/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index ff76e17184..c73c643d4b 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -11,7 +11,7 @@ manifestmerger.jar - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 4315f44e07..3ea4a57c2c 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index c5477f765e..a240dec963 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -16,6 +16,6 @@ iossimulator-x64 - + From 8c542c6c51134a7357a631f15a2d5fca0bfc5edc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 13 May 2023 21:12:21 +0900 Subject: [PATCH 2934/2991] Fix hold-for-right-click showing during gameplay --- osu.Game/Input/OsuUserInputManager.cs | 5 +++++ osu.Game/OsuGame.cs | 7 +++++++ osu.Game/Rulesets/UI/RulesetInputManager.cs | 2 ++ 3 files changed, 14 insertions(+) diff --git a/osu.Game/Input/OsuUserInputManager.cs b/osu.Game/Input/OsuUserInputManager.cs index ab43497156..c205636ab9 100644 --- a/osu.Game/Input/OsuUserInputManager.cs +++ b/osu.Game/Input/OsuUserInputManager.cs @@ -3,6 +3,7 @@ #nullable disable +using osu.Framework.Bindables; using osu.Framework.Input; using osuTK.Input; @@ -10,6 +11,10 @@ namespace osu.Game.Input { public partial class OsuUserInputManager : UserInputManager { + protected override bool AllowRightClickFromLongTouch => !LocalUserPlaying.Value; + + public readonly BindableBool LocalUserPlaying = new BindableBool(); + internal OsuUserInputManager() { } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 7c9b03bd5b..fe6e479d19 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -269,6 +269,13 @@ namespace osu.Game if (hideToolbar) Toolbar.Hide(); } + protected override UserInputManager CreateUserInputManager() + { + var userInputManager = base.CreateUserInputManager(); + (userInputManager as OsuUserInputManager)?.LocalUserPlaying.BindTo(LocalUserPlaying); + return userInputManager; + } + private DependencyContainer dependencies; protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) => diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index 2ae54a3afe..a24e22f22b 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -28,6 +28,8 @@ namespace osu.Game.Rulesets.UI public abstract partial class RulesetInputManager : PassThroughInputManager, ICanAttachHUDPieces, IHasReplayHandler, IHasRecordingHandler where T : struct { + protected override bool AllowRightClickFromLongTouch => false; + public readonly KeyBindingContainer KeyBindingContainer; [Resolved(CanBeNull = true)] From 9a327d95b883323a21c649519f7cacae30e95832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 14 May 2023 11:24:24 +0200 Subject: [PATCH 2935/2991] Add test coverage --- .../Editing/TestScenePlacementBlueprint.cs | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 osu.Game.Tests/Visual/Editing/TestScenePlacementBlueprint.cs diff --git a/osu.Game.Tests/Visual/Editing/TestScenePlacementBlueprint.cs b/osu.Game.Tests/Visual/Editing/TestScenePlacementBlueprint.cs new file mode 100644 index 0000000000..58eff9ade7 --- /dev/null +++ b/osu.Game.Tests/Visual/Editing/TestScenePlacementBlueprint.cs @@ -0,0 +1,83 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using NUnit.Framework; +using osu.Framework.Screens; +using osu.Framework.Testing; +using osu.Game.Beatmaps; +using osu.Game.Input.Bindings; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.UI; +using osu.Game.Screens.Edit.Compose.Components; +using osu.Game.Tests.Beatmaps; +using osuTK.Input; + +namespace osu.Game.Tests.Visual.Editing +{ + public partial class TestScenePlacementBlueprint : EditorTestScene + { + protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); + + protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(ruleset, false); + + private GlobalActionContainer globalActionContainer => this.ChildrenOfType().Single(); + + [Test] + public void TestCommitPlacementViaGlobalAction() + { + Playfield playfield = null!; + + AddStep("select slider placement tool", () => InputManager.Key(Key.Number3)); + AddStep("move mouse to top left of playfield", () => + { + playfield = this.ChildrenOfType().Single(); + var location = (3 * playfield.ScreenSpaceDrawQuad.TopLeft + playfield.ScreenSpaceDrawQuad.BottomRight) / 4; + InputManager.MoveMouseTo(location); + }); + AddStep("begin placement", () => InputManager.Click(MouseButton.Left)); + AddStep("move mouse to bottom right of playfield", () => + { + var location = (playfield.ScreenSpaceDrawQuad.TopLeft + 3 * playfield.ScreenSpaceDrawQuad.BottomRight) / 4; + InputManager.MoveMouseTo(location); + }); + AddStep("confirm via global action", () => + { + globalActionContainer.TriggerPressed(GlobalAction.Select); + globalActionContainer.TriggerReleased(GlobalAction.Select); + }); + AddAssert("slider placed", () => EditorBeatmap.HitObjects.Count, () => Is.EqualTo(1)); + } + + [Test] + public void TestAbortPlacementViaGlobalAction() + { + Playfield playfield = null!; + + AddStep("select slider placement tool", () => InputManager.Key(Key.Number3)); + AddStep("move mouse to top left of playfield", () => + { + playfield = this.ChildrenOfType().Single(); + var location = (3 * playfield.ScreenSpaceDrawQuad.TopLeft + playfield.ScreenSpaceDrawQuad.BottomRight) / 4; + InputManager.MoveMouseTo(location); + }); + AddStep("begin placement", () => InputManager.Click(MouseButton.Left)); + AddStep("move mouse to bottom right of playfield", () => + { + var location = (playfield.ScreenSpaceDrawQuad.TopLeft + 3 * playfield.ScreenSpaceDrawQuad.BottomRight) / 4; + InputManager.MoveMouseTo(location); + }); + AddStep("abort via global action", () => + { + globalActionContainer.TriggerPressed(GlobalAction.Back); + globalActionContainer.TriggerReleased(GlobalAction.Back); + }); + AddAssert("editor is still current", () => Editor.IsCurrentScreen()); + AddAssert("slider not placed", () => EditorBeatmap.HitObjects.Count, () => Is.EqualTo(0)); + AddAssert("no active placement", () => this.ChildrenOfType().Single().CurrentPlacement.PlacementActive, + () => Is.EqualTo(PlacementBlueprint.PlacementState.Waiting)); + } + } +} From a99bf0fc5a5befc1961e5e6d3eb175879a4973e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 14 May 2023 12:29:24 +0200 Subject: [PATCH 2936/2991] Add test coverage --- .../Editing/TestScenePlacementBlueprint.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/osu.Game.Tests/Visual/Editing/TestScenePlacementBlueprint.cs b/osu.Game.Tests/Visual/Editing/TestScenePlacementBlueprint.cs index 58eff9ade7..a5681bea4a 100644 --- a/osu.Game.Tests/Visual/Editing/TestScenePlacementBlueprint.cs +++ b/osu.Game.Tests/Visual/Editing/TestScenePlacementBlueprint.cs @@ -79,5 +79,28 @@ namespace osu.Game.Tests.Visual.Editing AddAssert("no active placement", () => this.ChildrenOfType().Single().CurrentPlacement.PlacementActive, () => Is.EqualTo(PlacementBlueprint.PlacementState.Waiting)); } + + [Test] + public void TestCommitPlacementViaToolChange() + { + Playfield playfield = null!; + + AddStep("select slider placement tool", () => InputManager.Key(Key.Number3)); + AddStep("move mouse to top left of playfield", () => + { + playfield = this.ChildrenOfType().Single(); + var location = (3 * playfield.ScreenSpaceDrawQuad.TopLeft + playfield.ScreenSpaceDrawQuad.BottomRight) / 4; + InputManager.MoveMouseTo(location); + }); + AddStep("begin placement", () => InputManager.Click(MouseButton.Left)); + AddStep("move mouse to bottom right of playfield", () => + { + var location = (playfield.ScreenSpaceDrawQuad.TopLeft + 3 * playfield.ScreenSpaceDrawQuad.BottomRight) / 4; + InputManager.MoveMouseTo(location); + }); + + AddStep("change tool to circle", () => InputManager.Key(Key.Number2)); + AddAssert("slider placed", () => EditorBeatmap.HitObjects.Count, () => Is.EqualTo(1)); + } } } From d503312788f5e39173a0b2c94ba1b4f3af117f22 Mon Sep 17 00:00:00 2001 From: alix Date: Sun, 14 May 2023 13:37:44 -0400 Subject: [PATCH 2937/2991] updates and add changes --- osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs index 6affeb24d8..3224ff9eaf 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRandom.cs @@ -9,7 +9,6 @@ using osu.Framework.Localisation; using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Configuration; -using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Beatmaps; @@ -28,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModTargetPractice)).ToArray(); - [SettingSource("Angle sharpness", "How sharp angles should be", SettingControlType = typeof(AngleSharpnessSlider))] + [SettingSource("Angle sharpness", "How sharp angles should be")] public BindableFloat AngleSharpness { get; } = new BindableFloat(7) { MinValue = 1, @@ -162,12 +161,4 @@ namespace osu.Game.Rulesets.Osu.Mods return previousObjectStartedCombo && random.NextDouble() < 0.6f; } } - - public partial class AngleSharpnessSlider : SettingsSlider - { - public AngleSharpnessSlider() - { - KeyboardStep = 0.5f; - } - } } From 26ed50d8fdf13996c749bb05eeb3e1d18239fd6e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 15 May 2023 21:42:48 +0900 Subject: [PATCH 2938/2991] Add abbreviations found in framework functions Brings total inspections down to zero when using local framework checkout (in conjuncation with https://github.com/ppy/osu-framework/pull/5793). --- osu.sln.DotSettings | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index d7486273fb..b54794cd6d 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -329,6 +329,7 @@ False AABB API + ARGB BPM EF FPS @@ -336,6 +337,7 @@ GL GLSL HID + HSL HSPA HSV HTML @@ -352,6 +354,7 @@ OS PM RGB + RGBA RNG SDL SHA From 83dcd788262fb3cc51f94ddaa56f3fb1e202ef17 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 16 May 2023 16:29:24 +0900 Subject: [PATCH 2939/2991] Make `HitSampleInfo.Bank` non-nullable --- .../Drawables/DrawablePippidonHitObject.cs | 3 +-- .../Drawables/DrawablePippidonHitObject.cs | 3 +-- .../TestSceneAutoJuiceStream.cs | 2 +- .../TestSceneSpinner.cs | 2 +- ...estSceneHitObjectSamplePointAdjustments.cs | 2 +- osu.Game/Audio/HitSampleInfo.cs | 7 ++++--- .../ControlPoints/SampleControlPoint.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 14 ++++++++----- osu.Game/Rulesets/Edit/PlacementBlueprint.cs | 2 +- .../Objects/Legacy/ConvertHitObjectParser.cs | 20 ++++++++++++++----- 10 files changed, 35 insertions(+), 22 deletions(-) diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs index 29203f0a20..c5ada4288d 100644 --- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs +++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.Audio; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osuTK; @@ -44,7 +43,7 @@ namespace osu.Game.Rulesets.Pippidon.Objects.Drawables public override IEnumerable GetSamples() => new[] { - new HitSampleInfo(HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK) + new HitSampleInfo(HitSampleInfo.HIT_NORMAL) }; protected override void CheckForResult(bool userTriggered, double timeOffset) diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs index 554d03c79f..d198fa81cb 100644 --- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs +++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/Drawables/DrawablePippidonHitObject.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.Audio; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Pippidon.UI; using osu.Game.Rulesets.Scoring; @@ -44,7 +43,7 @@ namespace osu.Game.Rulesets.Pippidon.Objects.Drawables public override IEnumerable GetSamples() => new[] { - new HitSampleInfo(HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK) + new HitSampleInfo(HitSampleInfo.HIT_NORMAL) }; protected override void CheckForResult(bool userTriggered, double timeOffset) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs index 40dc7d2403..9a78df23cf 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Catch.Tests NewCombo = i % 8 == 0, Samples = new List(new[] { - new HitSampleInfo(HitSampleInfo.HIT_NORMAL, "normal", volume: 100) + new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: 100) }) }); } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs index 74d0fb42a3..8cfd674f88 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs @@ -74,7 +74,7 @@ namespace osu.Game.Rulesets.Osu.Tests EndTime = Time.Current + delay + length, Samples = new List { - new HitSampleInfo("hitnormal") + new HitSampleInfo(HitSampleInfo.HIT_NORMAL) } }; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs index 7a0418cfec..230333ec35 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs @@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual.Editing Position = (OsuPlayfield.BASE_SIZE - new Vector2(100, 0)) / 2, Samples = new List { - new HitSampleInfo(HitSampleInfo.HIT_NORMAL, "normal", volume: 80) + new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: 80) } }); diff --git a/osu.Game/Audio/HitSampleInfo.cs b/osu.Game/Audio/HitSampleInfo.cs index efa5562cb8..665ae3e1a7 100644 --- a/osu.Game/Audio/HitSampleInfo.cs +++ b/osu.Game/Audio/HitSampleInfo.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using Newtonsoft.Json; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Utils; namespace osu.Game.Audio @@ -32,7 +33,7 @@ namespace osu.Game.Audio /// /// The bank to load the sample from. /// - public readonly string? Bank; + public readonly string Bank; /// /// An optional suffix to provide priority lookup. Falls back to non-suffixed . @@ -44,7 +45,7 @@ namespace osu.Game.Audio /// public int Volume { get; } - public HitSampleInfo(string name, string? bank = null, string? suffix = null, int volume = 0) + public HitSampleInfo(string name, string bank = SampleControlPoint.DEFAULT_BANK, string? suffix = null, int volume = 0) { Name = name; Bank = bank; @@ -76,7 +77,7 @@ namespace osu.Game.Audio /// An optional new volume. /// The new . public virtual HitSampleInfo With(Optional newName = default, Optional newBank = default, Optional newSuffix = default, Optional newVolume = default) - => new HitSampleInfo(newName.GetOr(Name), newBank.GetOr(Bank), newSuffix.GetOr(Suffix), newVolume.GetOr(Volume)); + => new HitSampleInfo(newName.GetOr(Name), newBank.GetOr(Bank) ?? Bank, newSuffix.GetOr(Suffix), newVolume.GetOr(Volume)); public bool Equals(HitSampleInfo? other) => other != null && Name == other.Name && Bank == other.Bank && Suffix == other.Suffix; diff --git a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs index 6cd4d74a31..522a8b7892 100644 --- a/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs +++ b/osu.Game/Beatmaps/ControlPoints/SampleControlPoint.cs @@ -69,7 +69,7 @@ namespace osu.Game.Beatmaps.ControlPoints /// The . This will not be modified. /// The modified . This does not share a reference with . public virtual HitSampleInfo ApplyTo(HitSampleInfo hitSampleInfo) - => hitSampleInfo.With(newBank: hitSampleInfo.Bank ?? SampleBank, newVolume: hitSampleInfo.Volume > 0 ? hitSampleInfo.Volume : SampleVolume); + => hitSampleInfo.With(newBank: hitSampleInfo.Bank, newVolume: hitSampleInfo.Volume > 0 ? hitSampleInfo.Volume : SampleVolume); public override bool IsRedundant(ControlPoint? existing) => existing is SampleControlPoint existingSample diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 704756e3dd..23440b8a1d 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -226,12 +226,16 @@ namespace osu.Game.Beatmaps.Formats public override HitSampleInfo ApplyTo(HitSampleInfo hitSampleInfo) { - var baseInfo = base.ApplyTo(hitSampleInfo); + if (hitSampleInfo is ConvertHitObjectParser.LegacyHitSampleInfo legacy) + { + return legacy.With( + newCustomSampleBank: legacy.CustomSampleBank > 0 ? legacy.CustomSampleBank : CustomSampleBank, + newVolume: hitSampleInfo.Volume > 0 ? hitSampleInfo.Volume : SampleVolume, + newBank: legacy.BankSpecified ? legacy.Bank : SampleBank + ); + } - if (baseInfo is ConvertHitObjectParser.LegacyHitSampleInfo legacy && legacy.CustomSampleBank == 0) - return legacy.With(newCustomSampleBank: CustomSampleBank); - - return baseInfo; + return base.ApplyTo(hitSampleInfo); } public override bool IsRedundant(ControlPoint? existing) diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs index 12c0ea1807..eae9f922a4 100644 --- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs +++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs @@ -63,7 +63,7 @@ namespace osu.Game.Rulesets.Edit HitObject = hitObject; // adding the default hit sample should be the case regardless of the ruleset. - HitObject.Samples.Add(new HitSampleInfo(HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK, volume: 100)); + HitObject.Samples.Add(new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: 100)); RelativeSizeAxes = Axes.Both; diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index ba5de6c14b..c0f02b0b5e 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -14,6 +14,7 @@ using System.Linq; using JetBrains.Annotations; using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Utils; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Legacy; using osu.Game.Skinning; using osu.Game.Utils; @@ -446,9 +447,9 @@ namespace osu.Game.Rulesets.Objects.Legacy if (string.IsNullOrEmpty(bankInfo.Filename)) { soundTypes.Add(new LegacyHitSampleInfo(HitSampleInfo.HIT_NORMAL, bankInfo.BankForNormal, bankInfo.Volume, bankInfo.CustomSampleBank, - // if the sound type doesn't have the Normal flag set, attach it anyway as a layered sample. - // None also counts as a normal non-layered sample: https://osu.ppy.sh/help/wiki/osu!_File_Formats/Osu_(file_format)#hitsounds - type != LegacyHitSoundType.None && !type.HasFlagFast(LegacyHitSoundType.Normal))); + // if the sound type doesn't have the Normal flag set, attach it anyway as a layered sample. + // None also counts as a normal non-layered sample: https://osu.ppy.sh/help/wiki/osu!_File_Formats/Osu_(file_format)#hitsounds + type != LegacyHitSoundType.None && !type.HasFlagFast(LegacyHitSoundType.Normal))); } else { @@ -479,12 +480,14 @@ namespace osu.Game.Rulesets.Objects.Legacy /// The bank identifier to use for the base ("hitnormal") sample. /// Transferred to when appropriate. /// + [CanBeNull] public string BankForNormal; /// /// The bank identifier to use for additions ("hitwhistle", "hitfinish", "hitclap"). /// Transferred to when appropriate. /// + [CanBeNull] public string BankForAdditions; /// @@ -518,10 +521,17 @@ namespace osu.Game.Rulesets.Objects.Legacy /// public readonly bool IsLayered; + /// + /// Whether a bank was specified locally to the relevant hitobject. + /// If false, a bank will be retrieved from the closest control point. + /// + public bool BankSpecified; + public LegacyHitSampleInfo(string name, string? bank = null, int volume = 0, int customSampleBank = 0, bool isLayered = false) - : base(name, bank, customSampleBank >= 2 ? customSampleBank.ToString() : null, volume) + : base(name, bank ?? SampleControlPoint.DEFAULT_BANK, customSampleBank >= 2 ? customSampleBank.ToString() : null, volume) { CustomSampleBank = customSampleBank; + BankSpecified = !string.IsNullOrEmpty(bank); IsLayered = isLayered; } @@ -531,7 +541,7 @@ namespace osu.Game.Rulesets.Objects.Legacy public virtual LegacyHitSampleInfo With(Optional newName = default, Optional newBank = default, Optional newVolume = default, Optional newCustomSampleBank = default, Optional newIsLayered = default) - => new LegacyHitSampleInfo(newName.GetOr(Name), newBank.GetOr(Bank), newVolume.GetOr(Volume), newCustomSampleBank.GetOr(CustomSampleBank), newIsLayered.GetOr(IsLayered)); + => new LegacyHitSampleInfo(newName.GetOr(Name), newBank.GetOr(Bank) ?? Bank, newVolume.GetOr(Volume), newCustomSampleBank.GetOr(CustomSampleBank), newIsLayered.GetOr(IsLayered)); public bool Equals(LegacyHitSampleInfo? other) // The additions to equality checks here are *required* to ensure that pooling works correctly. From d9ae8229669b0f371810b5334ea563056642a735 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 16 May 2023 16:34:49 +0900 Subject: [PATCH 2940/2991] Fix bank not correctly being assigned when adding sample additions in editor --- osu.Game/Rulesets/Objects/HitObject.cs | 2 +- .../Edit/Compose/Components/ComposeBlueprintContainer.cs | 2 +- .../Screens/Edit/Compose/Components/EditorSelectionHandler.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index a4cb976d50..f5b9e9c8cd 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -210,7 +210,7 @@ namespace osu.Game.Rulesets.Objects /// /// The name of the sample. /// A populated . - protected HitSampleInfo GetSampleInfo(string sampleName = HitSampleInfo.HIT_NORMAL) + public HitSampleInfo GetSampleInfo(string sampleName = HitSampleInfo.HIT_NORMAL) { var hitnormalSample = Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL); return hitnormalSample == null ? new HitSampleInfo(sampleName) : hitnormalSample.With(newName: sampleName); diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index 07fb450628..73e3baf509 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -185,7 +185,7 @@ namespace osu.Game.Screens.Edit.Compose.Components case TernaryState.True: if (existingSample == null) - samples.Add(new HitSampleInfo(sampleName)); + samples.Add(CurrentPlacement.HitObject.GetSampleInfo(sampleName)); break; } } diff --git a/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs index 357cc940f2..694b24c567 100644 --- a/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs @@ -122,7 +122,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (h.Samples.Any(s => s.Name == sampleName)) return; - h.Samples.Add(new HitSampleInfo(sampleName)); + h.Samples.Add(h.GetSampleInfo(sampleName)); EditorBeatmap.Update(h); }); } From 31fff72eb6f8da11fb5f6d11d06775a1cd78f2ad Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 16 May 2023 16:35:58 +0900 Subject: [PATCH 2941/2991] Fix bank not correctly being assigned to some taiko hit cases --- osu.Game.Rulesets.Taiko/Objects/Hit.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Hit.cs b/osu.Game.Rulesets.Taiko/Objects/Hit.cs index 787079bfee..d90c7016e9 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Hit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Hit.cs @@ -63,7 +63,7 @@ namespace osu.Game.Rulesets.Taiko.Objects if (isRimType != rimSamples.Any()) { if (isRimType) - Samples.Add(new HitSampleInfo(HitSampleInfo.HIT_CLAP)); + Samples.Add(GetSampleInfo(HitSampleInfo.HIT_CLAP)); else { foreach (var sample in rimSamples) From 8528fcaedc93bddd843be6fa6087cde82629f52e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 16 May 2023 18:31:10 +0900 Subject: [PATCH 2942/2991] Rename editor sample adjustment test scene to increase scope of tests --- ...intAdjustments.cs => TestSceneHitObjectSampleAdjustments.cs} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename osu.Game.Tests/Visual/Editing/{TestSceneHitObjectSamplePointAdjustments.cs => TestSceneHitObjectSampleAdjustments.cs} (99%) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSampleAdjustments.cs similarity index 99% rename from osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs rename to osu.Game.Tests/Visual/Editing/TestSceneHitObjectSampleAdjustments.cs index 230333ec35..6e3f403c19 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSamplePointAdjustments.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSampleAdjustments.cs @@ -24,7 +24,7 @@ using osuTK.Input; namespace osu.Game.Tests.Visual.Editing { - public partial class TestSceneHitObjectSamplePointAdjustments : EditorTestScene + public partial class TestSceneHitObjectSampleAdjustments : EditorTestScene { protected override Ruleset CreateEditorRuleset() => new OsuRuleset(); From ebce39cd1c4ef3db38d6dbb92682252eb7c463ca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 16 May 2023 18:52:35 +0900 Subject: [PATCH 2943/2991] Add test coverage of failing sample bank transfer --- .../TestSceneHitObjectSampleAdjustments.cs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSampleAdjustments.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSampleAdjustments.cs index 6e3f403c19..530bd5eb20 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSampleAdjustments.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSampleAdjustments.cs @@ -58,6 +58,26 @@ namespace osu.Game.Tests.Visual.Editing }); } + [Test] + public void TestAddSampleAddition() + { + AddStep("select both objects", () => EditorBeatmap.SelectedHitObjects.AddRange(EditorBeatmap.HitObjects)); + + AddStep("add clap addition", () => InputManager.Key(Key.R)); + + hitObjectHasSampleBank(0, "normal"); + hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_CLAP); + hitObjectHasSampleBank(1, "soft"); + hitObjectHasSamples(1, HitSampleInfo.HIT_NORMAL, HitSampleInfo.HIT_CLAP); + + AddStep("remove clap addition", () => InputManager.Key(Key.R)); + + hitObjectHasSampleBank(0, "normal"); + hitObjectHasSamples(0, HitSampleInfo.HIT_NORMAL); + hitObjectHasSampleBank(1, "soft"); + hitObjectHasSamples(1, HitSampleInfo.HIT_NORMAL); + } + [Test] public void TestPopoverHasFocus() { @@ -271,6 +291,12 @@ namespace osu.Game.Tests.Visual.Editing InputManager.Key(Key.Enter); }); + private void hitObjectHasSamples(int objectIndex, params string[] samples) => AddAssert($"{objectIndex.ToOrdinalWords()} has samples {string.Join(',', samples)}", () => + { + var h = EditorBeatmap.HitObjects.ElementAt(objectIndex); + return h.Samples.Select(s => s.Name).SequenceEqual(samples); + }); + private void hitObjectHasSampleBank(int objectIndex, string bank) => AddAssert($"{objectIndex.ToOrdinalWords()} has bank {bank}", () => { var h = EditorBeatmap.HitObjects.ElementAt(objectIndex); From ddfdd712bd61b32c1f00614a840156b234c2e070 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Wed, 17 May 2023 00:07:06 +0800 Subject: [PATCH 2944/2991] Update InspectCode to 2022.3.3 and enable C# 11 --- .config/dotnet-tools.json | 2 +- Directory.Build.props | 2 +- osu.Game/osu.Game.csproj | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 1f937e1837..d9f1e3985a 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "jetbrains.resharper.globaltools": { - "version": "2022.2.3", + "version": "2022.3.3", "commands": [ "jb" ] diff --git a/Directory.Build.props b/Directory.Build.props index 734374c840..fccac79a45 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@  - 10.0 + 11.0 true enable diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 3ea4a57c2c..bf0c1dde17 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -1,9 +1,8 @@ - + net6.0 Library true - 10 osu! From 84de463e2e9e11130fb8edd053796e1f722f15f6 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Wed, 17 May 2023 00:13:08 +0800 Subject: [PATCH 2945/2991] Turn off inspection of MSBuild unknown property --- osu.sln.DotSettings | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index b54794cd6d..5039831f76 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -234,6 +234,7 @@ WARNING WARNING HINT + DO_NOT_SHOW WARNING HINT HINT From 88ce627c8ed5428b087e5c25c16a541cd1e66b11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 16 May 2023 20:40:12 +0200 Subject: [PATCH 2946/2991] Avoid bindable/event feedback when changing resolution --- .../Sections/Graphics/LayoutSettings.cs | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 2e26d15105..d82b8b1ba3 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -244,7 +244,8 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics { Scheduler.AddOnce(d => { - displayDropdown.Items = d; + if (!displayDropdown.Items.SequenceEqual(d, DisplayListComparer.DEFAULT)) + displayDropdown.Items = d; updateDisplaySettingsVisibility(); }, displays); } @@ -376,5 +377,43 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics } } } + + /// + /// Contrary to , this comparer disregards the value of . + /// We want to just show a list of displays, and for the purposes of settings we don't care about their bounds when it comes to the list. + /// However, fires even if only the resolution of the current display was changed + /// (because it causes the bounds of all displays to also change). + /// We're not interested in those changes, so compare only the rest that we actually care about. + /// This helps to avoid a bindable/event feedback loop, in which a resolution change + /// would trigger a display "change", which would in turn reset resolution again. + /// + private class DisplayListComparer : IEqualityComparer + { + public static readonly DisplayListComparer DEFAULT = new DisplayListComparer(); + + public bool Equals(Display? x, Display? y) + { + if (ReferenceEquals(x, y)) return true; + if (ReferenceEquals(x, null)) return false; + if (ReferenceEquals(y, null)) return false; + + return x.Index == y.Index + && x.Name == y.Name + && x.DisplayModes.SequenceEqual(y.DisplayModes); + } + + public int GetHashCode(Display obj) + { + var hashCode = new HashCode(); + + hashCode.Add(obj.Index); + hashCode.Add(obj.Name); + hashCode.Add(obj.DisplayModes.Length); + foreach (var displayMode in obj.DisplayModes) + hashCode.Add(displayMode); + + return hashCode.ToHashCode(); + } + } } } From 0dcf1b540e0ee5a652e09982eeffd5174733891d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 16 May 2023 21:14:09 +0200 Subject: [PATCH 2947/2991] Attempt to preserve old resolution when switching displays --- .../Settings/Sections/Graphics/LayoutSettings.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index d82b8b1ba3..6a4ad63799 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -193,6 +193,12 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics currentDisplay.BindValueChanged(display => Schedule(() => { + // there is no easy way to perform an atomic swap on the `resolutions` list, which is bound to the dropdown via `ItemSource`. + // this means, if the old resolution isn't saved, the `RemoveRange()` call below will cause `resolutionDropdown.Current` to reset value, + // therefore making it impossible to select any dropdown value other than "Default". + // to circumvent this locally, store the old value here, so that we can attempt to restore it later. + var oldResolution = resolutionDropdown.Current.Value; + resolutions.RemoveRange(1, resolutions.Count - 1); if (display.NewValue != null) @@ -204,6 +210,9 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics .Distinct()); } + if (resolutions.Contains(oldResolution)) + resolutionDropdown.Current.Value = oldResolution; + updateDisplaySettingsVisibility(); }), true); From 2d7fe683110c18361d18ec979473e3ccb783e88e Mon Sep 17 00:00:00 2001 From: Susko3 Date: Tue, 16 May 2023 21:57:31 +0200 Subject: [PATCH 2948/2991] Prevent feedback by using atomic `.ReplaceRange()` `display.NewValue` will never be null, checked on SDL + osuTK/Android. On Android it's a 0x0 display, importantly not null. --- .../Settings/Sections/Graphics/LayoutSettings.cs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 2e26d15105..f3ff2e87ba 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -193,16 +193,11 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics currentDisplay.BindValueChanged(display => Schedule(() => { - resolutions.RemoveRange(1, resolutions.Count - 1); - - if (display.NewValue != null) - { - resolutions.AddRange(display.NewValue.DisplayModes - .Where(m => m.Size.Width >= 800 && m.Size.Height >= 600) - .OrderByDescending(m => Math.Max(m.Size.Height, m.Size.Width)) - .Select(m => m.Size) - .Distinct()); - } + resolutions.ReplaceRange(1, resolutions.Count - 1, display.NewValue.DisplayModes + .Where(m => m.Size.Width >= 800 && m.Size.Height >= 600) + .OrderByDescending(m => Math.Max(m.Size.Height, m.Size.Width)) + .Select(m => m.Size) + .Distinct()); updateDisplaySettingsVisibility(); }), true); From 70426a504223eb089b1bc1af2bcdeaca6f760d35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 16 May 2023 22:42:25 +0200 Subject: [PATCH 2949/2991] Add reference to youtrack issue to suppression --- osu.sln.DotSettings | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 5039831f76..f9aff99267 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -234,6 +234,7 @@ WARNING WARNING HINT + DO_NOT_SHOW WARNING HINT From c97b7a077e274493fec0dfbdd3e5193669c98fcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 16 May 2023 23:47:47 +0200 Subject: [PATCH 2950/2991] Use better issue reference --- osu.sln.DotSettings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index f9aff99267..9ca0fad2ab 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -234,7 +234,7 @@ WARNING WARNING HINT - + DO_NOT_SHOW WARNING HINT From d6fa44240d6009e3b902765f26feac6e648a96f3 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 16 May 2023 21:51:32 -0700 Subject: [PATCH 2951/2991] Fix storyboard video-only check being inverted --- osu.Game/Storyboards/Drawables/DrawableStoryboard.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs index aa264fa719..e674e7512c 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs @@ -69,7 +69,7 @@ namespace osu.Game.Storyboards.Drawables Size = new Vector2(640, 480); - bool onlyHasVideoElements = Storyboard.Layers.SelectMany(l => l.Elements).Any(e => !(e is StoryboardVideo)); + bool onlyHasVideoElements = Storyboard.Layers.SelectMany(l => l.Elements).All(e => e is StoryboardVideo); Width = Height * (storyboard.BeatmapInfo.WidescreenStoryboard || onlyHasVideoElements ? 16 / 9f : 4 / 3f); From a8bc337006918eb5579fb202c6537d0905075b17 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 17 May 2023 14:06:02 +0900 Subject: [PATCH 2952/2991] Change default volume when constructing a `HitSampleInfo` to non-zero --- osu.Game/Audio/HitSampleInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Audio/HitSampleInfo.cs b/osu.Game/Audio/HitSampleInfo.cs index 665ae3e1a7..3cf8e84d56 100644 --- a/osu.Game/Audio/HitSampleInfo.cs +++ b/osu.Game/Audio/HitSampleInfo.cs @@ -45,7 +45,7 @@ namespace osu.Game.Audio /// public int Volume { get; } - public HitSampleInfo(string name, string bank = SampleControlPoint.DEFAULT_BANK, string? suffix = null, int volume = 0) + public HitSampleInfo(string name, string bank = SampleControlPoint.DEFAULT_BANK, string? suffix = null, int volume = 100) { Name = name; Bank = bank; From dc51d5ecf32fb23e3c45048b9aa848116f913f31 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 17 May 2023 14:07:48 +0900 Subject: [PATCH 2953/2991] Rename `GetSampleInfo` to better describe what method does Also add full xmldoc --- osu.Game.Rulesets.Catch/Objects/BananaShower.cs | 2 +- osu.Game.Rulesets.Osu/Objects/Spinner.cs | 2 +- osu.Game.Rulesets.Taiko/Objects/Hit.cs | 2 +- .../Objects/TaikoStrongableHitObject.cs | 2 +- osu.Game/Rulesets/Objects/HitObject.cs | 14 ++++++++++---- .../Components/ComposeBlueprintContainer.cs | 2 +- .../Compose/Components/EditorSelectionHandler.cs | 2 +- 7 files changed, 16 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs index 5bd4ac86f5..b05c8e5f77 100644 --- a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Catch.Objects { StartTime = time, BananaIndex = i, - Samples = new List { new Banana.BananaHitSampleInfo(GetSampleInfo().Volume) } + Samples = new List { new Banana.BananaHitSampleInfo(CreateHitSampleInfo().Volume) } }); time += spacing; diff --git a/osu.Game.Rulesets.Osu/Objects/Spinner.cs b/osu.Game.Rulesets.Osu/Objects/Spinner.cs index df5898fd67..ba0981e781 100644 --- a/osu.Game.Rulesets.Osu/Objects/Spinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Spinner.cs @@ -72,7 +72,7 @@ namespace osu.Game.Rulesets.Osu.Objects AddNested(i < SpinsRequired ? new SpinnerTick { StartTime = startTime, SpinnerDuration = Duration } - : new SpinnerBonusTick { StartTime = startTime, SpinnerDuration = Duration, Samples = new[] { GetSampleInfo("spinnerbonus") } }); + : new SpinnerBonusTick { StartTime = startTime, SpinnerDuration = Duration, Samples = new[] { CreateHitSampleInfo("spinnerbonus") } }); } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Hit.cs b/osu.Game.Rulesets.Taiko/Objects/Hit.cs index d90c7016e9..303447e672 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Hit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Hit.cs @@ -63,7 +63,7 @@ namespace osu.Game.Rulesets.Taiko.Objects if (isRimType != rimSamples.Any()) { if (isRimType) - Samples.Add(GetSampleInfo(HitSampleInfo.HIT_CLAP)); + Samples.Add(CreateHitSampleInfo(HitSampleInfo.HIT_CLAP)); else { foreach (var sample in rimSamples) diff --git a/osu.Game.Rulesets.Taiko/Objects/TaikoStrongableHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/TaikoStrongableHitObject.cs index 0043f231d2..479ad8369a 100644 --- a/osu.Game.Rulesets.Taiko/Objects/TaikoStrongableHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/TaikoStrongableHitObject.cs @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Taiko.Objects if (IsStrongBindable.Value != strongSamples.Any()) { if (IsStrongBindable.Value) - Samples.Add(GetSampleInfo(HitSampleInfo.HIT_FINISH)); + Samples.Add(CreateHitSampleInfo(HitSampleInfo.HIT_FINISH)); else { foreach (var sample in strongSamples) diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index f5b9e9c8cd..ed3d3a6eb2 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -206,14 +206,20 @@ namespace osu.Game.Rulesets.Objects } /// - /// Create a SampleInfo based on the sample settings of the hit normal sample in . + /// Create a based on the sample settings of the first sample in . + /// If no sample is available, sane default settings will be used instead. /// + /// + /// In the case an existing sample exists, all settings apart from the sample name will be inherited. This includes volume, bank and suffix. + /// /// The name of the sample. /// A populated . - public HitSampleInfo GetSampleInfo(string sampleName = HitSampleInfo.HIT_NORMAL) + public HitSampleInfo CreateHitSampleInfo(string sampleName = HitSampleInfo.HIT_NORMAL) { - var hitnormalSample = Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL); - return hitnormalSample == null ? new HitSampleInfo(sampleName) : hitnormalSample.With(newName: sampleName); + if (Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL) is HitSampleInfo existingSample) + return existingSample.With(newName: sampleName); + + return new HitSampleInfo(sampleName); } } diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index 73e3baf509..b42118b983 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -185,7 +185,7 @@ namespace osu.Game.Screens.Edit.Compose.Components case TernaryState.True: if (existingSample == null) - samples.Add(CurrentPlacement.HitObject.GetSampleInfo(sampleName)); + samples.Add(CurrentPlacement.HitObject.CreateHitSampleInfo(sampleName)); break; } } diff --git a/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs index 694b24c567..3b49b76e7e 100644 --- a/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs +++ b/osu.Game/Screens/Edit/Compose/Components/EditorSelectionHandler.cs @@ -122,7 +122,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (h.Samples.Any(s => s.Name == sampleName)) return; - h.Samples.Add(h.GetSampleInfo(sampleName)); + h.Samples.Add(h.CreateHitSampleInfo(sampleName)); EditorBeatmap.Update(h); }); } From 510ebe1f234ffb9b1e8ca9c018e8ff2bb7839d3c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 17 May 2023 14:11:14 +0900 Subject: [PATCH 2954/2991] Fix weird optional usage in `HitSampleInfo.With` --- osu.Game.Rulesets.Catch/Objects/Banana.cs | 2 +- osu.Game/Audio/HitSampleInfo.cs | 4 ++-- .../Rulesets/Objects/Legacy/ConvertHitObjectParser.cs | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Banana.cs b/osu.Game.Rulesets.Catch/Objects/Banana.cs index 4c66c054e1..b80527f379 100644 --- a/osu.Game.Rulesets.Catch/Objects/Banana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Banana.cs @@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Catch.Objects { } - public sealed override HitSampleInfo With(Optional newName = default, Optional newBank = default, Optional newSuffix = default, Optional newVolume = default) + public sealed override HitSampleInfo With(Optional newName = default, Optional newBank = default, Optional newSuffix = default, Optional newVolume = default) => new BananaHitSampleInfo(newVolume.GetOr(Volume)); public bool Equals(BananaHitSampleInfo? other) diff --git a/osu.Game/Audio/HitSampleInfo.cs b/osu.Game/Audio/HitSampleInfo.cs index 3cf8e84d56..5d1ce27c9f 100644 --- a/osu.Game/Audio/HitSampleInfo.cs +++ b/osu.Game/Audio/HitSampleInfo.cs @@ -76,8 +76,8 @@ namespace osu.Game.Audio /// An optional new lookup suffix. /// An optional new volume. /// The new . - public virtual HitSampleInfo With(Optional newName = default, Optional newBank = default, Optional newSuffix = default, Optional newVolume = default) - => new HitSampleInfo(newName.GetOr(Name), newBank.GetOr(Bank) ?? Bank, newSuffix.GetOr(Suffix), newVolume.GetOr(Volume)); + public virtual HitSampleInfo With(Optional newName = default, Optional newBank = default, Optional newSuffix = default, Optional newVolume = default) + => new HitSampleInfo(newName.GetOr(Name), newBank.GetOr(Bank), newSuffix.GetOr(Suffix), newVolume.GetOr(Volume)); public bool Equals(HitSampleInfo? other) => other != null && Name == other.Name && Bank == other.Bank && Suffix == other.Suffix; diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index c0f02b0b5e..d9738ecd0a 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -535,13 +535,13 @@ namespace osu.Game.Rulesets.Objects.Legacy IsLayered = isLayered; } - public sealed override HitSampleInfo With(Optional newName = default, Optional newBank = default, Optional newSuffix = default, Optional newVolume = default) + public sealed override HitSampleInfo With(Optional newName = default, Optional newBank = default, Optional newSuffix = default, Optional newVolume = default) => With(newName, newBank, newVolume); - public virtual LegacyHitSampleInfo With(Optional newName = default, Optional newBank = default, Optional newVolume = default, + public virtual LegacyHitSampleInfo With(Optional newName = default, Optional newBank = default, Optional newVolume = default, Optional newCustomSampleBank = default, Optional newIsLayered = default) - => new LegacyHitSampleInfo(newName.GetOr(Name), newBank.GetOr(Bank) ?? Bank, newVolume.GetOr(Volume), newCustomSampleBank.GetOr(CustomSampleBank), newIsLayered.GetOr(IsLayered)); + => new LegacyHitSampleInfo(newName.GetOr(Name), newBank.GetOr(Bank), newVolume.GetOr(Volume), newCustomSampleBank.GetOr(CustomSampleBank), newIsLayered.GetOr(IsLayered)); public bool Equals(LegacyHitSampleInfo? other) // The additions to equality checks here are *required* to ensure that pooling works correctly. @@ -573,7 +573,7 @@ namespace osu.Game.Rulesets.Objects.Legacy Path.ChangeExtension(Filename, null) }; - public sealed override LegacyHitSampleInfo With(Optional newName = default, Optional newBank = default, Optional newVolume = default, + public sealed override LegacyHitSampleInfo With(Optional newName = default, Optional newBank = default, Optional newVolume = default, Optional newCustomSampleBank = default, Optional newIsLayered = default) => new FileHitSampleInfo(Filename, newVolume.GetOr(Volume)); From dc421bd2af6d093f9cd1f38a7080c3acde6fae35 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 17 May 2023 14:49:47 +0900 Subject: [PATCH 2955/2991] Revert "Merge pull request #23570 from huoyaoyuan/inspect-code-cs11" This reverts commit ab2bd123e7e29c098f29e92b547826f3844809bb, reversing changes made to 267e63320f5bfa1b83d15c85e9eea62106611a36. --- .config/dotnet-tools.json | 2 +- Directory.Build.props | 2 +- osu.Game/osu.Game.csproj | 3 ++- osu.sln.DotSettings | 2 -- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index d9f1e3985a..1f937e1837 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "jetbrains.resharper.globaltools": { - "version": "2022.3.3", + "version": "2022.2.3", "commands": [ "jb" ] diff --git a/Directory.Build.props b/Directory.Build.props index fccac79a45..734374c840 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@  - 11.0 + 10.0 true enable diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index bf0c1dde17..3ea4a57c2c 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -1,8 +1,9 @@ - + net6.0 Library true + 10 osu! diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 9ca0fad2ab..b54794cd6d 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -234,8 +234,6 @@ WARNING WARNING HINT - - DO_NOT_SHOW WARNING HINT HINT From 94b184712d175e075ed805741f730fd610a3e2f8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 17 May 2023 14:38:58 +0900 Subject: [PATCH 2956/2991] Fix random button hover state not correctly being reset on right click --- osu.Game/Screens/Select/FooterButtonRandom.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/FooterButtonRandom.cs b/osu.Game/Screens/Select/FooterButtonRandom.cs index f413126e87..3a4bad43b3 100644 --- a/osu.Game/Screens/Select/FooterButtonRandom.cs +++ b/osu.Game/Screens/Select/FooterButtonRandom.cs @@ -119,14 +119,13 @@ namespace osu.Game.Screens.Select protected override void OnMouseUp(MouseUpEvent e) { + base.OnMouseUp(e); + if (e.Button == MouseButton.Right && IsHovered) { rewindSearch = true; TriggerClick(); - return; } - - base.OnMouseUp(e); } public override bool OnPressed(KeyBindingPressEvent e) From 764f0323f4727d412e77316a35c4d7f470158263 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 17 May 2023 14:42:07 +0900 Subject: [PATCH 2957/2991] Show "rewind" text on random button when beginning a right mouse press --- osu.Game/Screens/Select/FooterButtonRandom.cs | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Select/FooterButtonRandom.cs b/osu.Game/Screens/Select/FooterButtonRandom.cs index 3a4bad43b3..2d5d049133 100644 --- a/osu.Game/Screens/Select/FooterButtonRandom.cs +++ b/osu.Game/Screens/Select/FooterButtonRandom.cs @@ -93,16 +93,22 @@ namespace osu.Game.Screens.Select protected override bool OnKeyDown(KeyDownEvent e) { - updateText(e.ShiftPressed); + updateText(e); return base.OnKeyDown(e); } protected override void OnKeyUp(KeyUpEvent e) { - updateText(e.ShiftPressed); + updateText(e); base.OnKeyUp(e); } + protected override bool OnMouseDown(MouseDownEvent e) + { + updateText(e); + return base.OnMouseDown(e); + } + protected override bool OnClick(ClickEvent e) { try @@ -126,6 +132,8 @@ namespace osu.Game.Screens.Select rewindSearch = true; TriggerClick(); } + + updateText(e); } public override bool OnPressed(KeyBindingPressEvent e) @@ -150,10 +158,12 @@ namespace osu.Game.Screens.Select } } - private void updateText(bool rewind = false) + private void updateText(UIEvent e) { - randomSpriteText.Alpha = rewind ? 0 : 1; - rewindSpriteText.Alpha = rewind ? 1 : 0; + bool aboutToRewind = e.ShiftPressed || e.CurrentState.Mouse.IsPressed(MouseButton.Right); + + randomSpriteText.Alpha = aboutToRewind ? 0 : 1; + rewindSpriteText.Alpha = aboutToRewind ? 1 : 0; } } } From 79e1d978e7581f5303fc37270f2bc02aa9c1b60e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 17 May 2023 15:42:38 +0900 Subject: [PATCH 2958/2991] Ensure scroll-to-top button is displayed above all overlay content --- osu.Game/Overlays/OnlineOverlay.cs | 8 ++++++++ osu.Game/Overlays/OverlayScrollContainer.cs | 2 +- osu.Game/Overlays/UserProfileOverlay.cs | 12 +++++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/OnlineOverlay.cs b/osu.Game/Overlays/OnlineOverlay.cs index 4d2c6bc9d0..8b7a82f899 100644 --- a/osu.Game/Overlays/OnlineOverlay.cs +++ b/osu.Game/Overlays/OnlineOverlay.cs @@ -77,6 +77,14 @@ namespace osu.Game.Overlays base.Content.Add(mainContent); } + protected override void LoadComplete() + { + base.LoadComplete(); + + // Ensure the scroll-to-top button is displayed above the fixed header. + AddInternal(ScrollFlow.Button.CreateProxy()); + } + protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); diff --git a/osu.Game/Overlays/OverlayScrollContainer.cs b/osu.Game/Overlays/OverlayScrollContainer.cs index 2a615f0e12..9ff0a65652 100644 --- a/osu.Game/Overlays/OverlayScrollContainer.cs +++ b/osu.Game/Overlays/OverlayScrollContainer.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays /// private const int button_scroll_position = 200; - protected ScrollBackButton Button; + public ScrollBackButton Button { get; private set; } private readonly Bindable lastScrollTarget = new Bindable(); diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index d1fe877e55..ab4f07b982 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -249,12 +249,14 @@ namespace osu.Game.Overlays private partial class ProfileSectionsContainer : SectionsContainer { + private OverlayScrollContainer scroll = null!; + public ProfileSectionsContainer() { RelativeSizeAxes = Axes.Both; } - protected override UserTrackingScrollContainer CreateScrollContainer() => new OverlayScrollContainer(); + protected override UserTrackingScrollContainer CreateScrollContainer() => scroll = new OverlayScrollContainer(); // Reverse child ID is required so expanding beatmap panels can appear above sections below them. // This can also be done by setting Depth when adding new sections above if using ReverseChildID turns out to have any issues. @@ -267,6 +269,14 @@ namespace osu.Game.Overlays Padding = new MarginPadding { Horizontal = 10 }, Margin = new MarginPadding { Bottom = 10 }, }; + + protected override void LoadComplete() + { + base.LoadComplete(); + + // Ensure the scroll-to-top button is displayed above the fixed header. + AddInternal(scroll.Button.CreateProxy()); + } } } } From 7d7d402d4e06459e6834db800018d7000b2fa61b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 17 May 2023 16:58:23 +0900 Subject: [PATCH 2959/2991] Apply NRT to `PlacementBlueprint` --- osu.Game/Rulesets/Edit/PlacementBlueprint.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs index 12c0ea1807..5eca4f8ccd 100644 --- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs +++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using System.Threading; using osu.Framework.Allocation; @@ -38,16 +36,16 @@ namespace osu.Game.Rulesets.Edit /// public readonly HitObject HitObject; - [Resolved(canBeNull: true)] - protected EditorClock EditorClock { get; private set; } + [Resolved] + protected EditorClock? EditorClock { get; private set; } [Resolved] - private EditorBeatmap beatmap { get; set; } + private EditorBeatmap beatmap { get; set; } = null!; - private Bindable startTimeBindable; + private Bindable startTimeBindable = null!; [Resolved] - private IPlacementHandler placementHandler { get; set; } + private IPlacementHandler placementHandler { get; set; } = null!; /// /// Whether this blueprint is currently in a state that can be committed. From e43f2c2c439bbc5c524606b20ee1bfb651cacb06 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 17 May 2023 16:58:43 +0900 Subject: [PATCH 2960/2991] Improve previous hitobject lookup efficient and correctness --- osu.Game/Rulesets/Edit/PlacementBlueprint.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs index 5eca4f8ccd..9ef208bcb5 100644 --- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs +++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs @@ -44,6 +44,8 @@ namespace osu.Game.Rulesets.Edit private Bindable startTimeBindable = null!; + private HitObject? getPreviousHitObject() => beatmap.HitObjects.TakeWhile(h => h.StartTime <= startTimeBindable.Value).LastOrDefault(); + [Resolved] private IPlacementHandler placementHandler { get; set; } = null!; @@ -84,7 +86,7 @@ namespace osu.Game.Rulesets.Edit protected void BeginPlacement(bool commitStart = false) { // Take the hitnormal sample of the last hit object - var lastHitNormal = beatmap.HitObjects.LastOrDefault(h => h.GetEndTime() < HitObject.StartTime)?.Samples?.FirstOrDefault(o => o.Name == HitSampleInfo.HIT_NORMAL); + var lastHitNormal = getPreviousHitObject()?.Samples?.FirstOrDefault(o => o.Name == HitSampleInfo.HIT_NORMAL); if (lastHitNormal != null) HitObject.Samples[0] = lastHitNormal; From 8d925c8a8a5f06c33bddcf28b543a784a159b71a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 17 May 2023 17:19:07 +0900 Subject: [PATCH 2961/2991] Move combo information updating to an interface level helper method --- osu.Game/Beatmaps/BeatmapProcessor.cs | 27 +++---------------- .../Objects/Types/IHasComboInformation.cs | 23 ++++++++++++++-- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapProcessor.cs b/osu.Game/Beatmaps/BeatmapProcessor.cs index 8f3d0b7445..fb5313469f 100644 --- a/osu.Game/Beatmaps/BeatmapProcessor.cs +++ b/osu.Game/Beatmaps/BeatmapProcessor.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Game.Rulesets.Objects.Types; @@ -22,34 +20,17 @@ namespace osu.Game.Beatmaps public virtual void PreProcess() { - IHasComboInformation lastObj = null; - - bool isFirst = true; + IHasComboInformation? lastObj = null; foreach (var obj in Beatmap.HitObjects.OfType()) { - if (isFirst) + if (lastObj == null) { - obj.NewCombo = true; - // first hitobject should always be marked as a new combo for sanity. - isFirst = false; - } - - obj.ComboIndex = lastObj?.ComboIndex ?? 0; - obj.ComboIndexWithOffsets = lastObj?.ComboIndexWithOffsets ?? 0; - obj.IndexInCurrentCombo = (lastObj?.IndexInCurrentCombo + 1) ?? 0; - - if (obj.NewCombo) - { - obj.IndexInCurrentCombo = 0; - obj.ComboIndex++; - obj.ComboIndexWithOffsets += obj.ComboOffset + 1; - - if (lastObj != null) - lastObj.LastInCombo = true; + obj.NewCombo = true; } + obj.UpdateComboInformation(lastObj); lastObj = obj; } } diff --git a/osu.Game/Rulesets/Objects/Types/IHasComboInformation.cs b/osu.Game/Rulesets/Objects/Types/IHasComboInformation.cs index b45ea989f3..d34e71021f 100644 --- a/osu.Game/Rulesets/Objects/Types/IHasComboInformation.cs +++ b/osu.Game/Rulesets/Objects/Types/IHasComboInformation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osu.Game.Skinning; using osuTK.Graphics; @@ -65,5 +63,26 @@ namespace osu.Game.Rulesets.Objects.Types { return skin.GetConfig(new SkinComboColourLookup(comboIndex, combo))?.Value ?? Color4.White; } + + /// + /// Given the previous object in the beatmap, update relevant combo information. + /// + /// The previous hitobject, or null if this is the first object in the beatmap. + void UpdateComboInformation(IHasComboInformation? lastObj) + { + ComboIndex = lastObj?.ComboIndex ?? 0; + ComboIndexWithOffsets = lastObj?.ComboIndexWithOffsets ?? 0; + IndexInCurrentCombo = (lastObj?.IndexInCurrentCombo + 1) ?? 0; + + if (NewCombo || lastObj == null) + { + IndexInCurrentCombo = 0; + ComboIndex++; + ComboIndexWithOffsets += ComboOffset + 1; + + if (lastObj != null) + lastObj.LastInCombo = true; + } + } } } From 9563d4f73004ad5794e0031f2046fdfd1bd5dda9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 17 May 2023 17:19:18 +0900 Subject: [PATCH 2962/2991] Fix weird purple tint on placement object in timeline --- .../Compose/Components/Timeline/TimelineBlueprintContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs index f93fb0679f..30f56814ba 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs @@ -83,7 +83,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { placementBlueprint = CreateBlueprintFor(obj.NewValue).AsNonNull(); - placementBlueprint.Colour = Color4.MediumPurple; + placementBlueprint.Colour = OsuColour.Gray(0.9f); SelectionBlueprints.Add(placementBlueprint); } From 0b25818bd218d0d6388af0a5da2d7a0f0190c68d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 17 May 2023 17:20:15 +0900 Subject: [PATCH 2963/2991] Update combo information on placement blueprint --- osu.Game/Rulesets/Edit/PlacementBlueprint.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs index 9ef208bcb5..84e32d99f8 100644 --- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs +++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs @@ -14,6 +14,7 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Input.Bindings; using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Compose; using osuTK; @@ -148,7 +149,12 @@ namespace osu.Game.Rulesets.Edit public virtual void UpdateTimeAndPosition(SnapResult result) { if (PlacementActive == PlacementState.Waiting) + { HitObject.StartTime = result.Time ?? EditorClock?.CurrentTime ?? Time.Current; + + if (HitObject is IHasComboInformation comboInformation) + comboInformation.UpdateComboInformation(getPreviousHitObject() as IHasComboInformation); + } } /// From 214d7e07fa1ad2b4016a751b2ee6f495384b6ac5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 17 May 2023 17:49:04 +0900 Subject: [PATCH 2964/2991] Add TODO regarding failing stack display code --- .../Compose/Components/Timeline/TimelineBlueprintContainer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs index 30f56814ba..b60e04afc1 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs @@ -85,6 +85,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline placementBlueprint.Colour = OsuColour.Gray(0.9f); + // TODO: this is out of order, causing incorrect stacking height. SelectionBlueprints.Add(placementBlueprint); } } From b58ab28765974714537a893a60e5bfff39e71f29 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 17 May 2023 20:54:17 +0900 Subject: [PATCH 2965/2991] Make `EditorClock` non-nullable in `PlacementBlueprint` --- .../Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs | 8 ++------ osu.Game/Rulesets/Edit/PlacementBlueprint.cs | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs index 73ee5df9dc..f59be0e0e9 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs @@ -1,10 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Input.Events; @@ -24,9 +21,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners private bool isPlacingEnd; - [Resolved(CanBeNull = true)] - [CanBeNull] - private IBeatSnapProvider beatSnapProvider { get; set; } + [Resolved] + private IBeatSnapProvider? beatSnapProvider { get; set; } public SpinnerPlacementBlueprint() : base(new Spinner { Position = OsuPlayfield.BASE_SIZE / 2 }) diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs index 84e32d99f8..b10f1a2af5 100644 --- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs +++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Edit public readonly HitObject HitObject; [Resolved] - protected EditorClock? EditorClock { get; private set; } + protected EditorClock EditorClock { get; private set; } = null!; [Resolved] private EditorBeatmap beatmap { get; set; } = null!; @@ -150,7 +150,7 @@ namespace osu.Game.Rulesets.Edit { if (PlacementActive == PlacementState.Waiting) { - HitObject.StartTime = result.Time ?? EditorClock?.CurrentTime ?? Time.Current; + HitObject.StartTime = result.Time ?? EditorClock.CurrentTime; if (HitObject is IHasComboInformation comboInformation) comboInformation.UpdateComboInformation(getPreviousHitObject() as IHasComboInformation); From 7ac6688a0fd8c57f5d04c846ff0c04e069d61c89 Mon Sep 17 00:00:00 2001 From: Dimmitsaras Date: Wed, 17 May 2023 18:34:39 +0300 Subject: [PATCH 2966/2991] Chat message notifications always play on unfocused window --- osu.Game/Online/Chat/MessageNotifier.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/Chat/MessageNotifier.cs b/osu.Game/Online/Chat/MessageNotifier.cs index 9b2ad666b2..cb29fc4535 100644 --- a/osu.Game/Online/Chat/MessageNotifier.cs +++ b/osu.Game/Online/Chat/MessageNotifier.cs @@ -12,6 +12,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; +using osu.Framework.Platform; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Online.API; @@ -35,6 +36,9 @@ namespace osu.Game.Online.Chat [Resolved] private ChannelManager channelManager { get; set; } + [Resolved] + private GameHost host { get; set; } + private Bindable notifyOnUsername; private Bindable notifyOnPrivateMessage; @@ -89,8 +93,8 @@ namespace osu.Game.Online.Chat if (channel == null) return; - // Only send notifications, if ChatOverlay and the target channel aren't visible. - if (chatOverlay.IsPresent && channelManager.CurrentChannel.Value == channel) + // Only send notifications, if ChatOverlay and the target channel aren't visible, or if the window is unfocused + if (chatOverlay.IsPresent && channelManager.CurrentChannel.Value == channel && host.IsActive.Value) return; foreach (var message in messages.OrderByDescending(m => m.Id)) @@ -99,6 +103,7 @@ namespace osu.Game.Online.Chat if (message.Id <= channel.LastReadId) return; + // ignore notifications triggered by your own chat messages if (message.Sender.Id == localUser.Value.Id) continue; From caa79704acb69efd92dff2c40dc450988bf0230d Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Wed, 17 May 2023 20:23:37 -0700 Subject: [PATCH 2967/2991] Add test coverage for failing case --- .../Resources/storyboard_only_video.osu | 31 +++++++++++++++++++ .../Visual/Gameplay/TestSceneStoryboard.cs | 18 ++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/Resources/storyboard_only_video.osu diff --git a/osu.Game.Tests/Resources/storyboard_only_video.osu b/osu.Game.Tests/Resources/storyboard_only_video.osu new file mode 100644 index 0000000000..25f1ff6361 --- /dev/null +++ b/osu.Game.Tests/Resources/storyboard_only_video.osu @@ -0,0 +1,31 @@ +osu file format v14 + +[Events] +//Background and Video events +0,0,"BG.jpg",0,0 +Video,0,"video.avi" +//Break Periods +//Storyboard Layer 0 (Background) +//Storyboard Layer 1 (Fail) +//Storyboard Layer 2 (Pass) +//Storyboard Layer 3 (Foreground) +//Storyboard Layer 4 (Overlay) +//Storyboard Sound Samples + +[TimingPoints] +1674,333.333333333333,4,2,1,70,1,0 +1674,-100,4,2,1,70,0,0 +3340,-100,4,2,1,70,0,0 +3507,-100,4,2,1,70,0,0 +3673,-100,4,2,1,70,0,0 + +[Colours] +Combo1 : 240,80,80 +Combo2 : 171,252,203 +Combo3 : 128,128,255 +Combo4 : 249,254,186 + +[HitObjects] +148,303,1674,5,6,3:2:0:0: +378,252,1840,1,0,0:0:0:0: +389,270,2340,5,2,0:1:0:0: diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs index dbce62cbef..a6663f3086 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.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 NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -8,6 +9,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Timing; +using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; using osu.Game.IO; @@ -42,6 +44,18 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("Load storyboard with missing video", () => loadStoryboard("storyboard_no_video.osu")); } + [Test] + public void TestVideoSize() + { + AddStep("load storyboard with only video", () => + { + // LegacyStoryboardDecoder doesn't parse WidescreenStoryboard, so it is set manually + loadStoryboard("storyboard_only_video.osu", s => s.BeatmapInfo.WidescreenStoryboard = false); + }); + + AddAssert("storyboard is correct width", () => Precision.AlmostEquals(storyboard?.Width ?? 0f, 480 * 16 / 9f)); + } + [BackgroundDependencyLoader] private void load() { @@ -102,7 +116,7 @@ namespace osu.Game.Tests.Visual.Gameplay decoupledClock.ChangeSource(Beatmap.Value.Track); } - private void loadStoryboard(string filename) + private void loadStoryboard(string filename, Action? setUpStoryboard = null) { Storyboard loaded; @@ -113,6 +127,8 @@ namespace osu.Game.Tests.Visual.Gameplay loaded = decoder.Decode(bfr); } + setUpStoryboard?.Invoke(loaded); + loadStoryboard(loaded); } } From ee522253cb0373b8ca231557e8d56ec2d888945f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 18 May 2023 14:12:57 +0900 Subject: [PATCH 2968/2991] Remove a couple of unnecessary `volume` declarations --- osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs | 2 +- osu.Game/Rulesets/Edit/PlacementBlueprint.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs index 9a78df23cf..f21825668f 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Catch.Tests NewCombo = i % 8 == 0, Samples = new List(new[] { - new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: 100) + new HitSampleInfo(HitSampleInfo.HIT_NORMAL) }) }); } diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs index eae9f922a4..919a3cdfdf 100644 --- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs +++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs @@ -63,7 +63,7 @@ namespace osu.Game.Rulesets.Edit HitObject = hitObject; // adding the default hit sample should be the case regardless of the ruleset. - HitObject.Samples.Add(new HitSampleInfo(HitSampleInfo.HIT_NORMAL, volume: 100)); + HitObject.Samples.Add(new HitSampleInfo(HitSampleInfo.HIT_NORMAL)); RelativeSizeAxes = Axes.Both; From e8cb19e40aead0744621afe052944f57fa81ea02 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 19 May 2023 17:49:26 +0900 Subject: [PATCH 2969/2991] Pin builds to .NET 6 As more things move to having the 7 SDK installed, let's pin for now. This helps with mobile build scenarios, which fall over on the new SDKs and require further attention. --- global.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 global.json diff --git a/global.json b/global.json new file mode 100644 index 0000000000..5dcd5f425a --- /dev/null +++ b/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "6.0.100", + "rollForward": "latestFeature" + } +} + From 8e0a97ca4965a5d058fc16abb03ec9bc91ad0067 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 20 May 2023 18:02:12 +0200 Subject: [PATCH 2970/2991] Remove usage of `HasSubmenu` Property has been removed in the appropriate framework-side PR and instead folded into `IsActionable`. See: https://github.com/ppy/osu-framework/pull/5658#discussion_r1114834647 --- osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs b/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs index 0adff11342..eb046932e6 100644 --- a/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs +++ b/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs @@ -77,12 +77,10 @@ namespace osu.Game.Graphics.UserInterface private void updateState() { - bool enabledState = IsActionable || HasSubmenu; + hoverClickSounds.Enabled.Value = IsActionable; + Alpha = IsActionable ? 1 : 0.2f; - hoverClickSounds.Enabled.Value = enabledState; - Alpha = enabledState ? 1 : 0.2f; - - if (IsHovered && enabledState) + if (IsHovered && IsActionable) { text.BoldText.FadeIn(transition_length, Easing.OutQuint); text.NormalText.FadeOut(transition_length, Easing.OutQuint); From a677d87d39b49e1ba9f471f720d61c292d9c3547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 20 May 2023 19:29:59 +0200 Subject: [PATCH 2971/2991] Touch up inline comments --- osu.Game/Online/Chat/MessageNotifier.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/Chat/MessageNotifier.cs b/osu.Game/Online/Chat/MessageNotifier.cs index cb29fc4535..52bdd36169 100644 --- a/osu.Game/Online/Chat/MessageNotifier.cs +++ b/osu.Game/Online/Chat/MessageNotifier.cs @@ -93,7 +93,7 @@ namespace osu.Game.Online.Chat if (channel == null) return; - // Only send notifications, if ChatOverlay and the target channel aren't visible, or if the window is unfocused + // Only send notifications if ChatOverlay or the target channel aren't visible, or if the window is unfocused if (chatOverlay.IsPresent && channelManager.CurrentChannel.Value == channel && host.IsActive.Value) return; @@ -103,7 +103,7 @@ namespace osu.Game.Online.Chat if (message.Id <= channel.LastReadId) return; - // ignore notifications triggered by your own chat messages + // ignore notifications triggered by local user's own chat messages if (message.Sender.Id == localUser.Value.Id) continue; From ec5f0bbf421828ee8d3ab42ddcec3ab2679baf1c Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 20 May 2023 16:29:49 -0700 Subject: [PATCH 2972/2991] Fix clicking area of news sidebar post links Side effect is that the hover color is yellow and pressing it opens an external dialog, but those are temporary (pending implementation of link underline to make `Light1` hover more readable and set at a higher level and news pages). --- .../Overlays/News/Sidebar/MonthSection.cs | 29 +++---------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/osu.Game/Overlays/News/Sidebar/MonthSection.cs b/osu.Game/Overlays/News/Sidebar/MonthSection.cs index 30d29048ba..4dccc07eff 100644 --- a/osu.Game/Overlays/News/Sidebar/MonthSection.cs +++ b/osu.Game/Overlays/News/Sidebar/MonthSection.cs @@ -20,7 +20,7 @@ using System.Diagnostics; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Extensions.LocalisationExtensions; -using osu.Framework.Platform; +using osu.Game.Online.Chat; namespace osu.Game.Overlays.News.Sidebar { @@ -123,35 +123,14 @@ namespace osu.Game.Overlays.News.Sidebar } } - private partial class PostButton : OsuHoverContainer + private partial class PostButton : LinkFlowContainer { - protected override IEnumerable EffectTargets => new[] { text }; - - private readonly TextFlowContainer text; - private readonly APINewsPost post; - public PostButton(APINewsPost post) + : base(t => t.Font = OsuFont.GetFont(size: 12)) { - this.post = post; - RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - Child = text = new TextFlowContainer(t => t.Font = OsuFont.GetFont(size: 12)) - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Text = post.Title - }; - } - - [BackgroundDependencyLoader] - private void load(OverlayColourProvider overlayColours, GameHost host) - { - IdleColour = overlayColours.Light2; - HoverColour = overlayColours.Light1; - - TooltipText = "view in browser"; - Action = () => host.OpenUrlExternally("https://osu.ppy.sh/home/news/" + post.Slug); + AddLink(post.Title, LinkAction.External, "https://osu.ppy.sh/home/news/" + post.Slug, "view in browser"); } } From 8aefb62532aebf3430f19aae09bbcedce8fce7c7 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 20 May 2023 16:38:56 -0700 Subject: [PATCH 2973/2991] Rename `PostButton` to `PostLink` --- osu.Game/Overlays/News/Sidebar/MonthSection.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/News/Sidebar/MonthSection.cs b/osu.Game/Overlays/News/Sidebar/MonthSection.cs index 4dccc07eff..b586d156ad 100644 --- a/osu.Game/Overlays/News/Sidebar/MonthSection.cs +++ b/osu.Game/Overlays/News/Sidebar/MonthSection.cs @@ -59,7 +59,7 @@ namespace osu.Game.Overlays.News.Sidebar new PostsContainer { Expanded = { BindTarget = Expanded }, - Children = posts.Select(p => new PostButton(p)).ToArray() + Children = posts.Select(p => new PostLink(p)).ToArray() } } }; @@ -123,9 +123,9 @@ namespace osu.Game.Overlays.News.Sidebar } } - private partial class PostButton : LinkFlowContainer + private partial class PostLink : LinkFlowContainer { - public PostButton(APINewsPost post) + public PostLink(APINewsPost post) : base(t => t.Font = OsuFont.GetFont(size: 12)) { RelativeSizeAxes = Axes.X; From 5229cf7343ea6d562598fbbdf67a6c2e19bb51b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 21 May 2023 16:47:16 +0200 Subject: [PATCH 2974/2991] Add failing test cases for drum roll/swell sample playback --- .../TestSceneDrumSampleTriggerSource.cs | 273 ++++++++++++++++++ .../UI/GameplaySampleTriggerSource.cs | 2 +- 2 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Taiko.Tests/TestSceneDrumSampleTriggerSource.cs diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumSampleTriggerSource.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumSampleTriggerSource.cs new file mode 100644 index 0000000000..0c8f18badd --- /dev/null +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumSampleTriggerSource.cs @@ -0,0 +1,273 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Timing; +using osu.Game.Audio; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.Objects.Drawables; +using osu.Game.Rulesets.Taiko.UI; +using osu.Game.Rulesets.UI; +using osu.Game.Rulesets.UI.Scrolling; +using osu.Game.Tests.Visual; + +namespace osu.Game.Rulesets.Taiko.Tests +{ + public partial class TestSceneDrumSampleTriggerSource : OsuTestScene + { + private readonly ManualClock manualClock = new ManualClock(); + + [Cached(typeof(IScrollingInfo))] + private ScrollingTestContainer.TestScrollingInfo info = new ScrollingTestContainer.TestScrollingInfo + { + Direction = { Value = ScrollingDirection.Left }, + TimeRange = { Value = 200 }, + }; + + private ScrollingHitObjectContainer hitObjectContainer = null!; + private TestDrumSampleTriggerSource triggerSource = null!; + + [SetUp] + public void SetUp() => Schedule(() => + { + hitObjectContainer = new ScrollingHitObjectContainer(); + manualClock.CurrentTime = 0; + + Child = new Container + { + Clock = new FramedClock(manualClock), + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + hitObjectContainer, + triggerSource = new TestDrumSampleTriggerSource(hitObjectContainer) + } + }; + }); + + [Test] + public void TestNormalHit() + { + AddStep("add hit with normal samples", () => + { + var hit = new Hit + { + StartTime = 100, + Samples = new List + { + new HitSampleInfo(HitSampleInfo.HIT_NORMAL) + } + }; + hit.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + var drawableHit = new DrawableHit(hit); + hitObjectContainer.Add(drawableHit); + }); + + AddAssert("most valid object is hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK); + + AddStep("seek past hit", () => manualClock.CurrentTime = 200); + AddAssert("most valid object is hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK); + } + + [Test] + public void TestSoftHit() + { + AddStep("add hit with soft samples", () => + { + var hit = new Hit + { + StartTime = 100, + Samples = new List + { + new HitSampleInfo(HitSampleInfo.HIT_NORMAL, "soft") + } + }; + hit.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + var drawableHit = new DrawableHit(hit); + hitObjectContainer.Add(drawableHit); + }); + + AddAssert("most valid object is hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "soft"); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "soft"); + + AddStep("seek past hit", () => manualClock.CurrentTime = 200); + AddAssert("most valid object is hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "soft"); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "soft"); + } + + [Test] + public void TestNormalDrumRoll() + { + AddStep("add drum roll with normal samples", () => + { + var drumRoll = new DrumRoll + { + StartTime = 100, + EndTime = 1100, + Samples = new List + { + new HitSampleInfo(HitSampleInfo.HIT_NORMAL) + } + }; + drumRoll.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + var drawableDrumRoll = new DrawableDrumRoll(drumRoll); + hitObjectContainer.Add(drawableDrumRoll); + }); + + AddAssert("most valid object is drum roll tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK); + + AddStep("seek to middle of drum roll", () => manualClock.CurrentTime = 600); + AddAssert("most valid object is drum roll tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK); + + AddStep("seek past drum roll", () => manualClock.CurrentTime = 1200); + AddAssert("most valid object is drum roll", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK); + } + + [Test] + public void TestSoftDrumRoll() + { + AddStep("add drum roll with soft samples", () => + { + var drumRoll = new DrumRoll + { + StartTime = 100, + EndTime = 1100, + Samples = new List + { + new HitSampleInfo(HitSampleInfo.HIT_NORMAL, "soft") + } + }; + drumRoll.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + var drawableDrumRoll = new DrawableDrumRoll(drumRoll); + hitObjectContainer.Add(drawableDrumRoll); + }); + + AddAssert("most valid object is drum roll tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "soft"); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "soft"); + + AddStep("seek to middle of drum roll", () => manualClock.CurrentTime = 600); + AddAssert("most valid object is drum roll tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "soft"); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "soft"); + + AddStep("seek past drum roll", () => manualClock.CurrentTime = 1200); + AddAssert("most valid object is drum roll", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "soft"); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "soft"); + } + + [Test] + public void TestNormalSwell() + { + AddStep("add swell with normal samples", () => + { + var swell = new Swell + { + StartTime = 100, + EndTime = 1100, + Samples = new List + { + new HitSampleInfo(HitSampleInfo.HIT_NORMAL) + } + }; + swell.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + var drawableSwell = new DrawableSwell(swell); + hitObjectContainer.Add(drawableSwell); + }); + + AddAssert("most valid object is swell tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK); + + AddStep("seek to middle of swell", () => manualClock.CurrentTime = 600); + AddAssert("most valid object is swell tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK); + + AddStep("seek past swell", () => manualClock.CurrentTime = 1200); + AddAssert("most valid object is swell", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, SampleControlPoint.DEFAULT_BANK); + } + + [Test] + public void TestDrumSwell() + { + AddStep("add swell with drum samples", () => + { + var swell = new Swell() + { + StartTime = 100, + EndTime = 1100, + Samples = new List + { + new HitSampleInfo(HitSampleInfo.HIT_NORMAL, "drum") + } + }; + swell.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + var drawableSwell = new DrawableSwell(swell); + hitObjectContainer.Add(drawableSwell); + }); + + AddAssert("most valid object is swell tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum"); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum"); + + AddStep("seek to middle of swell", () => manualClock.CurrentTime = 600); + AddAssert("most valid object is swell tick", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum"); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum"); + + AddStep("seek past swell", () => manualClock.CurrentTime = 1200); + AddAssert("most valid object is swell", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum"); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum"); + } + + private void checkSound(HitType hitType, string expectedName, string expectedBank) + { + AddStep($"hit {hitType}", () => triggerSource.Play(hitType)); + AddAssert($"last played sample is {expectedName}", () => triggerSource.LastPlayedSamples!.OfType().Single().Name, () => Is.EqualTo(expectedName)); + AddAssert($"last played sample has {expectedBank} bank", () => triggerSource.LastPlayedSamples!.OfType().Single().Bank, () => Is.EqualTo(expectedBank)); + } + + private partial class TestDrumSampleTriggerSource : DrumSampleTriggerSource + { + public ISampleInfo[]? LastPlayedSamples { get; private set; } + + public TestDrumSampleTriggerSource(HitObjectContainer hitObjectContainer) + : base(hitObjectContainer) + { + } + + protected override void PlaySamples(ISampleInfo[] samples) + { + base.PlaySamples(samples); + LastPlayedSamples = samples; + } + + public new HitObject GetMostValidObject() => base.GetMostValidObject(); + } + } +} diff --git a/osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs b/osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs index d4510a4519..fbb7a20a5d 100644 --- a/osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs +++ b/osu.Game/Rulesets/UI/GameplaySampleTriggerSource.cs @@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.UI PlaySamples(samples); } - protected void PlaySamples(ISampleInfo[] samples) => Schedule(() => + protected virtual void PlaySamples(ISampleInfo[] samples) => Schedule(() => { var hitSound = getNextSample(); hitSound.Samples = samples; From 6d325651dcca275091d51bbfbad3e59fa4ce4dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 21 May 2023 16:49:17 +0200 Subject: [PATCH 2975/2991] Propagate samples to drum roll/swell ticks for correct playback In d97daee96be2c10f90709cc30beceb1f369ae225, `DrumSampleTriggerSource` was changed such that in order to play sounds for the user's inputs, the bank of the normal sound would always be used. The problem is that in the case of taiko objects which have nested objects (swells and drum rolls), the samples were not propagated fully (drum rolls, where only the finish sample was kept, for the purposes of determining strongability), or not propagated at all (swells) to ticks. As ticks of both objects are valid return values of `GetMostValidHitObject()`, this would lead to the drum making no sounds if the next object was a drum roll or swell, until that drum roll or swell was completed. To fix, propagate the full set of samples, so that `DrumSampleTriggerSource` can retrieve the normal sound to copy the bank from. Note that this may not necessarily reproduce prior behaviour. This is because it is not guaranteed that all realised samples for a given hitobject have the same bank - some may have been overriden locally on a given hitobject. Previously, the bank would have been retrieved from the sample control point, wherein there is only one possible bank to use; however, when deciding the sound to play on the basis of a constructed hitobject, it is possible that there are cases wherein the hitnormal sample was overridden on that given hitobject, and in such cases, this PR would make samples _play_, but not necessarily the _same_ samples as prior to #23308. If that turns out to be the case, this will have to be revisited. --- osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 4 +--- osu.Game.Rulesets.Taiko/Objects/Swell.cs | 5 ++++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs index b4a12fd314..ba68967fbe 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs @@ -3,11 +3,9 @@ #nullable disable -using System.Linq; using osu.Game.Rulesets.Objects.Types; using System.Threading; using osu.Framework.Bindables; -using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Formats; @@ -98,7 +96,7 @@ namespace osu.Game.Rulesets.Taiko.Objects TickSpacing = tickSpacing, StartTime = t, IsStrong = IsStrong, - Samples = Samples.Where(s => s.Name == HitSampleInfo.HIT_FINISH).ToList() + Samples = Samples }); first = false; diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index cb91c46b4d..9ad783ba7e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -33,7 +33,10 @@ namespace osu.Game.Rulesets.Taiko.Objects for (int i = 0; i < RequiredHits; i++) { cancellationToken.ThrowIfCancellationRequested(); - AddNested(new SwellTick()); + AddNested(new SwellTick + { + Samples = Samples + }); } } From 812df9d652e73c55565a0667f09f8e0e480fcb29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 21 May 2023 17:14:24 +0200 Subject: [PATCH 2976/2991] Add failing test cases for strong object sample playback --- .../TestSceneDrumSampleTriggerSource.cs | 66 ++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumSampleTriggerSource.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumSampleTriggerSource.cs index 0c8f18badd..74da69e3eb 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumSampleTriggerSource.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumSampleTriggerSource.cs @@ -109,6 +109,35 @@ namespace osu.Game.Rulesets.Taiko.Tests checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "soft"); } + [Test] + public void TestDrumStrongHit() + { + AddStep("add strong hit with drum samples", () => + { + var hit = new Hit + { + StartTime = 100, + Samples = new List + { + new HitSampleInfo(HitSampleInfo.HIT_NORMAL, "drum"), + new HitSampleInfo(HitSampleInfo.HIT_FINISH, "drum") // implies strong + } + }; + hit.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + var drawableHit = new DrawableHit(hit); + hitObjectContainer.Add(drawableHit); + }); + + AddAssert("most valid object is strong nested hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum"); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum"); + + AddStep("seek past hit", () => manualClock.CurrentTime = 200); + AddAssert("most valid object is hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum"); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum"); + } + [Test] public void TestNormalDrumRoll() { @@ -177,6 +206,41 @@ namespace osu.Game.Rulesets.Taiko.Tests checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "soft"); } + [Test] + public void TestDrumStrongDrumRoll() + { + AddStep("add strong drum roll with drum samples", () => + { + var drumRoll = new DrumRoll + { + StartTime = 100, + EndTime = 1100, + Samples = new List + { + new HitSampleInfo(HitSampleInfo.HIT_NORMAL, "drum"), + new HitSampleInfo(HitSampleInfo.HIT_FINISH, "drum") // implies strong + } + }; + drumRoll.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + var drawableDrumRoll = new DrawableDrumRoll(drumRoll); + hitObjectContainer.Add(drawableDrumRoll); + }); + + AddAssert("most valid object is drum roll tick's nested strong hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum"); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum"); + + AddStep("seek to middle of drum roll", () => manualClock.CurrentTime = 600); + AddAssert("most valid object is drum roll tick's nested strong hit", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum"); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum"); + + AddStep("seek past drum roll", () => manualClock.CurrentTime = 1200); + AddAssert("most valid object is drum roll", () => triggerSource.GetMostValidObject(), Is.InstanceOf); + checkSound(HitType.Centre, HitSampleInfo.HIT_NORMAL, "drum"); + checkSound(HitType.Rim, HitSampleInfo.HIT_CLAP, "drum"); + } + [Test] public void TestNormalSwell() { @@ -216,7 +280,7 @@ namespace osu.Game.Rulesets.Taiko.Tests { AddStep("add swell with drum samples", () => { - var swell = new Swell() + var swell = new Swell { StartTime = 100, EndTime = 1100, From 4a7b011a53773d547b60401f609d7e394482a3ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 21 May 2023 18:28:30 +0200 Subject: [PATCH 2977/2991] Propagate samples to strong nested hits too The rationale is the same as in 6d325651dcca275091d51bbfbad3e59fa4ce4dc8. Due to the recursive nature of `GameplaySampleTriggerSource.GetMostValidObject()`, in the case of nested hits, drum rolls and drum roll ticks, the nested strong hits would become the most valid object, and so without propagating the samples down to that level too, nothing would play. --- osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 6 +++++- osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs | 6 +++++- osu.Game.Rulesets.Taiko/Objects/Hit.cs | 6 +++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs index ba68967fbe..aa5da6d710 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs @@ -107,7 +107,11 @@ namespace osu.Game.Rulesets.Taiko.Objects protected override HitWindows CreateHitWindows() => HitWindows.Empty; - protected override StrongNestedHitObject CreateStrongNestedHit(double startTime) => new StrongNestedHit { StartTime = startTime }; + protected override StrongNestedHitObject CreateStrongNestedHit(double startTime) => new StrongNestedHit + { + StartTime = startTime, + Samples = Samples + }; public class StrongNestedHit : StrongNestedHitObject { diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs index 6bcb8674e6..f8203d793d 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs @@ -33,7 +33,11 @@ namespace osu.Game.Rulesets.Taiko.Objects public override double MaximumJudgementOffset => HitWindow; - protected override StrongNestedHitObject CreateStrongNestedHit(double startTime) => new StrongNestedHit { StartTime = startTime }; + protected override StrongNestedHitObject CreateStrongNestedHit(double startTime) => new StrongNestedHit + { + StartTime = startTime, + Samples = Samples + }; public class StrongNestedHit : StrongNestedHitObject { diff --git a/osu.Game.Rulesets.Taiko/Objects/Hit.cs b/osu.Game.Rulesets.Taiko/Objects/Hit.cs index 303447e672..8935878f0e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Hit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Hit.cs @@ -72,7 +72,11 @@ namespace osu.Game.Rulesets.Taiko.Objects } } - protected override StrongNestedHitObject CreateStrongNestedHit(double startTime) => new StrongNestedHit { StartTime = startTime }; + protected override StrongNestedHitObject CreateStrongNestedHit(double startTime) => new StrongNestedHit + { + StartTime = startTime, + Samples = Samples + }; public class StrongNestedHit : StrongNestedHitObject { From 9915fac2c825a5b06555bf440f61748b10cccd06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 21 May 2023 18:31:26 +0200 Subject: [PATCH 2978/2991] Fix sample silence being one level too low 4a7b011a53773d547b60401f609d7e394482a3ab inadvertently unearthed that nested strong hits could play samples of their own accord, rather than delegating to `DrumSampleTriggerSource` as they were supposed to. This was an unfortunate omission due to how the inheritance structure of `TaikoHitObject` looks like (some irrelevant classes omitted for brevity): DrawableTaikoHitObject DrawableTaikoHitObject <-- `GetSamples()` was overridden to empty here DrawableTaikoStrongableHitObject DrawableHit DrawableDrumRoll DrawableDrumRollTick DrawableSwell DrawableSwellTick DrawableStrongNestedHit <-- all strong nested hits are here => didn't receive `GetSamples()` override DrawableHit.StrongNestedHit DrawableDrumRoll.StrongNestedHit DrawableDrumRollTick.StrongNestedHit To fix, move the `GetSamples()` override one level higher, to the non-generic `DrawableTaikoHitObject`, to suppress the spurious sample playbacks. The stale reference in the comment was also updated to match current code. --- .../Objects/Drawables/DrawableTaikoHitObject.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index f695c505a4..1b5d641612 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -118,6 +118,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { public override bool RemoveWhenNotAlive => false; } + + // Most osu!taiko hitsounds are managed by the drum (see DrumSampleTriggerSource). + public override IEnumerable GetSamples() => Enumerable.Empty(); } public abstract partial class DrawableTaikoHitObject : DrawableTaikoHitObject @@ -157,9 +160,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables Content.Add(MainPiece = CreateMainPiece()); } - // Most osu!taiko hitsounds are managed by the drum (see DrumSampleMapping). - public override IEnumerable GetSamples() => Enumerable.Empty(); - protected abstract SkinnableDrawable CreateMainPiece(); } } From 88c112612f05c71cb75b5364753cc38bb310848f Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 21 May 2023 10:35:22 -0700 Subject: [PATCH 2979/2991] Remove hardcoded website url MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Overlays/News/Sidebar/MonthSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/News/Sidebar/MonthSection.cs b/osu.Game/Overlays/News/Sidebar/MonthSection.cs index b586d156ad..9a748b2001 100644 --- a/osu.Game/Overlays/News/Sidebar/MonthSection.cs +++ b/osu.Game/Overlays/News/Sidebar/MonthSection.cs @@ -130,7 +130,7 @@ namespace osu.Game.Overlays.News.Sidebar { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - AddLink(post.Title, LinkAction.External, "https://osu.ppy.sh/home/news/" + post.Slug, "view in browser"); + AddLink(post.Title, LinkAction.External, @"/home/news/" + post.Slug, "view in browser"); } } From 19816ae0137d49709b53753dc55d137224be89a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 21 May 2023 20:38:27 +0200 Subject: [PATCH 2980/2991] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 4 ++-- osu.iOS.props | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index c73c643d4b..6aebae665d 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -11,7 +11,7 @@ manifestmerger.jar - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 3ea4a57c2c..0fd2b0c2c5 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -30,13 +30,13 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index a240dec963..e4a169f8e5 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -16,6 +16,6 @@ iossimulator-x64 - + From b3527b92b60670dd2f5a6d18af135987e0e08d60 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 22 May 2023 09:25:17 +0900 Subject: [PATCH 2981/2991] Handle case in tests where current display becomes null --- .../Overlays/Settings/Sections/Graphics/LayoutSettings.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index b76b9a40f9..a3290bc81c 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -193,6 +193,12 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics currentDisplay.BindValueChanged(display => Schedule(() => { + if (display.NewValue == null) + { + resolutions.Clear(); + return; + } + resolutions.ReplaceRange(1, resolutions.Count - 1, display.NewValue.DisplayModes .Where(m => m.Size.Width >= 800 && m.Size.Height >= 600) .OrderByDescending(m => Math.Max(m.Size.Height, m.Size.Width)) From 2279aad360a6f733068aa355855f17f383822782 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 21 May 2023 19:27:20 -0700 Subject: [PATCH 2982/2991] Apply NRT to `NewsCard` --- osu.Game/Overlays/News/NewsCard.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/News/NewsCard.cs b/osu.Game/Overlays/News/NewsCard.cs index e0be5cc4a9..18ca46a995 100644 --- a/osu.Game/Overlays/News/NewsCard.cs +++ b/osu.Game/Overlays/News/NewsCard.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using osu.Framework.Allocation; @@ -27,8 +25,8 @@ namespace osu.Game.Overlays.News private readonly APINewsPost post; - private Box background; - private TextFlowContainer main; + private Box background = null!; + private TextFlowContainer main = null!; public NewsCard(APINewsPost post) { From 7392109bcef1ff00170d26539cf13e29460790c4 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 21 May 2023 19:28:12 -0700 Subject: [PATCH 2983/2991] Apply same behavioral changes to `NewsCard` --- osu.Game/Overlays/News/NewsCard.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/News/NewsCard.cs b/osu.Game/Overlays/News/NewsCard.cs index 18ca46a995..b12aa4509e 100644 --- a/osu.Game/Overlays/News/NewsCard.cs +++ b/osu.Game/Overlays/News/NewsCard.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; -using osu.Framework.Platform; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; @@ -39,12 +38,12 @@ namespace osu.Game.Overlays.News } [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider, GameHost host) + private void load(OverlayColourProvider colourProvider, OsuGame? game) { if (post.Slug != null) { TooltipText = "view in browser"; - Action = () => host.OpenUrlExternally("https://osu.ppy.sh/home/news/" + post.Slug); + Action = () => game?.OpenUrlExternally(@"/home/news/" + post.Slug); } AddRange(new Drawable[] From 843d2903d237a12c92781ced262576f7a65c9ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 22 May 2023 21:17:21 +0200 Subject: [PATCH 2984/2991] Add failing test case for slider velocity undo --- ...TestSceneHitObjectDifficultyPointAdjustments.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectDifficultyPointAdjustments.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectDifficultyPointAdjustments.cs index 3b998b4219..c874b39028 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectDifficultyPointAdjustments.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectDifficultyPointAdjustments.cs @@ -92,6 +92,20 @@ namespace osu.Game.Tests.Visual.Editing hitObjectHasVelocity(1, 5); } + [Test] + public void TestUndo() + { + clickDifficultyPiece(1); + velocityPopoverHasSingleValue(2); + + setVelocityViaPopover(5); + hitObjectHasVelocity(1, 5); + dismissPopover(); + + AddStep("undo", () => Editor.Undo()); + hitObjectHasVelocity(1, 2); + } + [Test] public void TestMultipleSelectionWithSameSliderVelocity() { From f253d17a7f0af2d21985fbf92ca8835a510e9ee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 22 May 2023 22:19:10 +0200 Subject: [PATCH 2985/2991] Fix slider velocity changes not being applied in patcher --- .../Screens/Edit/LegacyEditorBeatmapPatcher.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs b/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs index b4647c2b64..33f8cd5c78 100644 --- a/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs +++ b/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs @@ -15,7 +15,9 @@ using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Formats; +using osu.Game.Beatmaps.Legacy; using osu.Game.IO; +using osu.Game.Rulesets.Objects.Types; using osu.Game.Skinning; using Decoder = osu.Game.Beatmaps.Formats.Decoder; @@ -42,6 +44,7 @@ namespace osu.Game.Screens.Edit editorBeatmap.BeginChange(); processHitObjects(result, () => newBeatmap ??= readBeatmap(newState)); processTimingPoints(() => newBeatmap ??= readBeatmap(newState)); + processSliderVelocity(() => newBeatmap ??= readBeatmap(newState)); editorBeatmap.EndChange(); } @@ -71,6 +74,17 @@ namespace osu.Game.Screens.Edit } } + private void processSliderVelocity(Func getNewBeatmap) + { + var legacyControlPoints = (LegacyControlPointInfo)getNewBeatmap().ControlPointInfo; + + foreach (var hitObject in editorBeatmap.HitObjects.Where(ho => ho is IHasSliderVelocity)) + { + var difficultyPoint = legacyControlPoints.DifficultyPointAt(hitObject.StartTime); + ((IHasSliderVelocity)hitObject).SliderVelocity = difficultyPoint.SliderVelocity; + } + } + private void processHitObjects(DiffResult result, Func getNewBeatmap) { findChangedIndices(result, LegacyDecoder.Section.HitObjects, out var removedIndices, out var addedIndices); From 2ce150ba2bbff1763a4be142ec802a5d942c96fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 22 May 2023 22:23:05 +0200 Subject: [PATCH 2986/2991] Add failing test case for sample undo --- .../TestSceneHitObjectSampleAdjustments.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSampleAdjustments.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSampleAdjustments.cs index 530bd5eb20..d812aed0f6 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSampleAdjustments.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectSampleAdjustments.cs @@ -109,6 +109,21 @@ namespace osu.Game.Tests.Visual.Editing hitObjectHasSampleBank(1, "drum"); } + [Test] + public void TestUndo() + { + clickSamplePiece(1); + samplePopoverHasSingleBank("soft"); + samplePopoverHasSingleVolume(60); + + setVolumeViaPopover(90); + hitObjectHasSampleVolume(1, 90); + dismissPopover(); + + AddStep("undo", () => Editor.Undo()); + hitObjectHasSampleVolume(1, 60); + } + [Test] public void TestMultipleSelectionWithSameSampleVolume() { From e0b7539c2a1338f079b8052bff0cf1eeb5e1de37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 22 May 2023 22:33:41 +0200 Subject: [PATCH 2987/2991] Fix sample changes not being applied in patcher --- .../Edit/LegacyEditorBeatmapPatcher.cs | 46 +++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs b/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs index 33f8cd5c78..ae7105ee34 100644 --- a/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs +++ b/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Text; @@ -15,7 +16,7 @@ using osu.Framework.Graphics.Textures; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Formats; -using osu.Game.Beatmaps.Legacy; +using osu.Game.Extensions; using osu.Game.IO; using osu.Game.Rulesets.Objects.Types; using osu.Game.Skinning; @@ -44,7 +45,7 @@ namespace osu.Game.Screens.Edit editorBeatmap.BeginChange(); processHitObjects(result, () => newBeatmap ??= readBeatmap(newState)); processTimingPoints(() => newBeatmap ??= readBeatmap(newState)); - processSliderVelocity(() => newBeatmap ??= readBeatmap(newState)); + processHitObjectLocalData(() => newBeatmap ??= readBeatmap(newState)); editorBeatmap.EndChange(); } @@ -74,17 +75,6 @@ namespace osu.Game.Screens.Edit } } - private void processSliderVelocity(Func getNewBeatmap) - { - var legacyControlPoints = (LegacyControlPointInfo)getNewBeatmap().ControlPointInfo; - - foreach (var hitObject in editorBeatmap.HitObjects.Where(ho => ho is IHasSliderVelocity)) - { - var difficultyPoint = legacyControlPoints.DifficultyPointAt(hitObject.StartTime); - ((IHasSliderVelocity)hitObject).SliderVelocity = difficultyPoint.SliderVelocity; - } - } - private void processHitObjects(DiffResult result, Func getNewBeatmap) { findChangedIndices(result, LegacyDecoder.Section.HitObjects, out var removedIndices, out var addedIndices); @@ -101,6 +91,36 @@ namespace osu.Game.Screens.Edit } } + private void processHitObjectLocalData(Func getNewBeatmap) + { + // This method handles data that are stored in control points in the legacy format, + // but were moved to the hitobjects themselves in lazer. + // Specifically, the data being referred to here consists of: slider velocity and sample information. + + // For simplicity, this implementation relies on the editor beatmap already having the same hitobjects in sequence as the new beatmap. + // To guarantee that, `processHitObjects()` must be ran prior to this method for correct operation. + // This is done to avoid the necessity of reimplementing/reusing parts of LegacyBeatmapDecoder that already treat this data correctly. + + var oldObjects = editorBeatmap.HitObjects; + var newObjects = getNewBeatmap().HitObjects; + + Debug.Assert(oldObjects.Count == newObjects.Count); + + foreach (var (oldObject, newObject) in oldObjects.Zip(newObjects)) + { + if (oldObject is IHasSliderVelocity oldWithVelocity && newObject is IHasSliderVelocity newWithVelocity) + oldWithVelocity.SliderVelocity = newWithVelocity.SliderVelocity; + + oldObject.Samples = newObject.Samples; + + if (oldObject is IHasRepeats oldWithRepeats && newObject is IHasRepeats newWithRepeats) + { + oldWithRepeats.NodeSamples.Clear(); + oldWithRepeats.NodeSamples.AddRange(newWithRepeats.NodeSamples); + } + } + } + private void findChangedIndices(DiffResult result, LegacyDecoder.Section section, out List removedIndices, out List addedIndices) { removedIndices = new List(); From 38b4bd8aefd738af26e26c1bf2309995f7253aee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 22 May 2023 22:45:39 +0200 Subject: [PATCH 2988/2991] Fix undo not behaving as expected sometimes --- osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs b/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs index ae7105ee34..2cf823ca0c 100644 --- a/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs +++ b/osu.Game/Screens/Edit/LegacyEditorBeatmapPatcher.cs @@ -108,6 +108,11 @@ namespace osu.Game.Screens.Edit foreach (var (oldObject, newObject) in oldObjects.Zip(newObjects)) { + // if `oldObject` and `newObject` are the same, it means that `oldObject` was inserted into `editorBeatmap` by `processHitObjects()`. + // in that case, there is nothing to do (and some of the subsequent changes may even prove destructive). + if (ReferenceEquals(oldObject, newObject)) + continue; + if (oldObject is IHasSliderVelocity oldWithVelocity && newObject is IHasSliderVelocity newWithVelocity) oldWithVelocity.SliderVelocity = newWithVelocity.SliderVelocity; From adf9a596b5fd4cb5e71519e79c990b371dbb7132 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 23 May 2023 17:58:10 +0900 Subject: [PATCH 2989/2991] Fix weird state when attempting to enter gameplay skin editor scene from multiplayer Closes https://github.com/ppy/osu/issues/23626. --- osu.Game/Overlays/SkinEditor/SkinEditorSceneLibrary.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorSceneLibrary.cs b/osu.Game/Overlays/SkinEditor/SkinEditorSceneLibrary.cs index 61195d7175..9b021632cf 100644 --- a/osu.Game/Overlays/SkinEditor/SkinEditorSceneLibrary.cs +++ b/osu.Game/Overlays/SkinEditor/SkinEditorSceneLibrary.cs @@ -113,7 +113,7 @@ namespace osu.Game.Overlays.SkinEditor if (replayGeneratingMod != null) screen.Push(new PlayerLoader(() => new ReplayPlayer((beatmap, mods) => replayGeneratingMod.CreateScoreFromReplayData(beatmap, mods)))); - }, new[] { typeof(Player), typeof(SongSelect) }) + }, new[] { typeof(Player), typeof(PlaySongSelect) }) }, } }, From 7cf50b1e18a74b74fc34396a1c4ddaf444d6dc6e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 23 May 2023 18:06:04 +0900 Subject: [PATCH 2990/2991] Disallow game to check for updates while gameplay is active --- osu.Desktop/Updater/SquirrelUpdateManager.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Desktop/Updater/SquirrelUpdateManager.cs b/osu.Desktop/Updater/SquirrelUpdateManager.cs index 3d4db88471..941ab335e8 100644 --- a/osu.Desktop/Updater/SquirrelUpdateManager.cs +++ b/osu.Desktop/Updater/SquirrelUpdateManager.cs @@ -9,6 +9,7 @@ using osu.Framework.Logging; using osu.Game; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; +using osu.Game.Screens.Play; using Squirrel; using Squirrel.SimpleSplat; using LogLevel = Squirrel.SimpleSplat.LogLevel; @@ -36,6 +37,9 @@ namespace osu.Desktop.Updater [Resolved] private OsuGameBase game { get; set; } = null!; + [Resolved] + private ILocalUserPlayInfo? localUserInfo { get; set; } + [BackgroundDependencyLoader] private void load(INotificationOverlay notifications) { @@ -55,6 +59,10 @@ namespace osu.Desktop.Updater try { + // Avoid any kind of update checking while gameplay is running. + if (localUserInfo?.IsPlaying.Value == true) + return false; + updateManager ??= new GithubUpdateManager(@"https://github.com/ppy/osu", false, github_token, @"osulazer"); var info = await updateManager.CheckForUpdate(!useDeltaPatching).ConfigureAwait(false); From 067328233cf5715e8ce00936a6ce6bbe1b9795cd Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 23 May 2023 13:14:57 -0700 Subject: [PATCH 2991/2991] Remove `OsuScreen.ApplyLogoArrivingDefaults()` --- osu.Game/Screens/OsuScreen.cs | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index bc4cc2b00f..9c098794a6 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -233,7 +233,13 @@ namespace osu.Game.Screens /// protected virtual void LogoArriving(OsuLogo logo, bool resuming) { - ApplyLogoArrivingDefaults(logo); + logo.Action = null; + logo.FadeOut(300, Easing.OutQuint); + logo.Anchor = Anchor.TopLeft; + logo.Origin = Anchor.Centre; + logo.RelativePositionAxes = Axes.Both; + logo.Triangles = true; + logo.Ripple = true; } private void applyArrivingDefaults(bool isResuming) @@ -244,22 +250,6 @@ namespace osu.Game.Screens }, true); } - /// - /// Applies default animations to an arriving logo. - /// Todo: This should not exist. - /// - /// The logo to apply animations to. - public static void ApplyLogoArrivingDefaults(OsuLogo logo) - { - logo.Action = null; - logo.FadeOut(300, Easing.OutQuint); - logo.Anchor = Anchor.TopLeft; - logo.Origin = Anchor.Centre; - logo.RelativePositionAxes = Axes.Both; - logo.Triangles = true; - logo.Ripple = true; - } - private void onExitingLogo() { logo?.AppendAnimatingAction(() => LogoExiting(logo), false);